Skip to content

Commit

Permalink
Formatting cleanup, unit test cleanup (mocks for usb camera)
Browse files Browse the repository at this point in the history
  • Loading branch information
gerth2 committed Jun 28, 2024
1 parent 71177ba commit f52b381
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 81 deletions.
4 changes: 2 additions & 2 deletions photon-client/src/types/PipelineTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ export interface PipelineSettings {
outputShowMultipleTargets: boolean;
contourSortMode: number;
cameraExposureRaw: number;
cameraMinexposureRaw: number;
cameraMaxexposureRaw: number;
cameraMinExposureRaw: number;
cameraMaxExposureRaw: number;
offsetSinglePoint: { x: number; y: number };
cameraBrightness: number;
offsetDualPointAArea: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ private static class FileSourceSettables extends VisionSourceSettables {
}

@Override
public void setexposureRaw(double exposureRaw) {}
public void setExposureRaw(double exposureRaw) {}

public void setAutoExposure(boolean cameraAutoExposure) {}

Expand All @@ -124,12 +124,12 @@ public HashMap<Integer, VideoMode> getAllVideoModes() {
}

@Override
public double getMinexposureRaw() {
public double getMinExposureRaw() {
return 1f;
}

@Override
public double getMaxexposureRaw() {
public double getMaxExposureRaw() {
return 100f;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public void setAutoExposure(boolean cameraAutoExposure) {
}

@Override
public void setexposureRaw(double exposureRaw) {
public void setExposureRaw(double exposureRaw) {
if (exposureRaw < 0.0 || lastAutoExposureActive) {
// Auto-exposure is active right now, don't set anything.
return;
Expand Down Expand Up @@ -227,7 +227,7 @@ protected void setVideoModeInternal(VideoMode videoMode) {

// We don't store last settings on the native side, and when you change video mode these get
// reset on MMAL's end
setexposureRaw(lastManualExposure);
setExposureRaw(lastManualExposure);
setAutoExposure(lastAutoExposureActive);
setBrightness(lastBrightness);
setGain(lastGain);
Expand All @@ -248,12 +248,12 @@ public LibCameraJNI.SensorModel getModel() {
}

@Override
public double getMinexposureRaw() {
public double getMinExposureRaw() {
return this.minExposure;
}

@Override
public double getMaxexposureRaw() {
public double getMaxExposureRaw() {
return this.maxExposure;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
public class USBCameraSource extends VisionSource {
private final Logger logger;
private final UsbCamera camera;
private final USBCameraSettables usbCameraSettables;
private FrameProvider usbFrameProvider;
protected USBCameraSettables usbCameraSettables;
protected FrameProvider usbFrameProvider;
private final CvSink cvSink;

private VideoProperty exposureAbsProp = null;
Expand Down Expand Up @@ -116,7 +116,7 @@ public USBCameraSource(CameraConfiguration config) {
// Functional camera, set up the frame provider and configure defaults
usbFrameProvider = new USBFrameProvider(cvSink, usbCameraSettables);
setAllCamDefaults();
exposureAbsProp = expProp.get();
exposureAbsProp = expProp.get();
autoExposureProp = autoExpProp.get();

this.minExposure = exposureAbsProp.getMin();
Expand All @@ -141,22 +141,6 @@ public USBCameraSource(CameraConfiguration config) {
}
}

/**
* Mostly just used for unit tests to better simulate a usb camera without a camera being present.
*/
public USBCameraSource(CameraConfiguration config, int pid, int vid, boolean unitTest) {
this(config);

getCameraConfiguration().cameraQuirks = QuirkyCamera.getQuirkyCamera(pid, vid, config.baseName);

if (unitTest)
usbFrameProvider =
new FileFrameProvider(
TestUtils.getWPIImagePath(
TestUtils.WPI2019Image.kCargoStraightDark72in_HighRes, false),
TestUtils.WPI2019Image.FOV);
}

/**
* Returns the first property with a name in the list. Useful to find gandolf property that goes
* by many names in different os/releases/whatever
Expand All @@ -183,7 +167,7 @@ private Optional<VideoProperty> findProperty(String... options) {
retProp = null;
}

return Optional.of(retProp);
return Optional.ofNullable(retProp);
}

/**
Expand All @@ -207,29 +191,36 @@ private void softSet(String property, int value) {
}

private void printCameraProperaties() {
VideoProperty[] cameraProperties = camera.enumerateProperties();
String cameraPropertiesStr = "Cam Properties Dump:\n";

for (int i = 0; i < cameraProperties.length; i++) {
cameraPropertiesStr +=
"Name: "
+ cameraProperties[i].getName()
+ ", Kind: "
+ cameraProperties[i].getKind()
+ ", Value: "
+ cameraProperties[i].getKind().getValue()
+ ", Min: "
+ cameraProperties[i].getMin()
+ ", Max: "
+ cameraProperties[i].getMax()
+ ", Dflt: "
+ cameraProperties[i].getDefault()
+ ", Step: "
+ cameraProperties[i].getStep()
+ "\n";

VideoProperty[] cameraProperties = null;
try {
cameraProperties = camera.enumerateProperties();
} catch (VideoException e){
logger.error("Failed to list camera properties!", e);
}

logger.debug(cameraPropertiesStr);
if(cameraProperties != null){
String cameraPropertiesStr = "Cam Properties Dump:\n";
for (int i = 0; i < cameraProperties.length; i++) {
cameraPropertiesStr +=
"Name: "
+ cameraProperties[i].getName()
+ ", Kind: "
+ cameraProperties[i].getKind()
+ ", Value: "
+ cameraProperties[i].getKind().getValue()
+ ", Min: "
+ cameraProperties[i].getMin()
+ ", Max: "
+ cameraProperties[i].getMax()
+ ", Dflt: "
+ cameraProperties[i].getDefault()
+ ", Step: "
+ cameraProperties[i].getStep()
+ "\n";
}
logger.debug(cameraPropertiesStr);
}
}

private void setAllCamDefaults() {
Expand Down Expand Up @@ -261,20 +252,21 @@ public VisionSourceSettables getSettables() {
public class USBCameraSettables extends VisionSourceSettables {
// We need to remember the last exposure set when exiting
// auto exposure mode so we can restore it
private double lastexposureRaw = -1;
private double lastExposureRaw = -1;

// Some cameras need logic where we re-apply brightness after
// changing exposure
private int lastBrightness = -1;

protected USBCameraSettables(CameraConfiguration configuration) {
public USBCameraSettables(CameraConfiguration configuration) {
super(configuration);
getAllVideoModes();
if (!configuration.cameraQuirks.hasQuirk(CameraQuirk.StickyFPS))
if (!videoModes.isEmpty()) setVideoMode(videoModes.get(0)); // fixes double FPS set
}

public void setAutoExposure(boolean cameraAutoExposure) {

logger.debug("Setting auto exposure to " + cameraAutoExposure);

if (!cameraAutoExposure) {
Expand All @@ -289,7 +281,7 @@ public void setAutoExposure(boolean cameraAutoExposure) {

// Most cameras leave exposure time absolute at the last value from their AE algorithm.
// Set it back to the exposure slider value
setexposureRaw(this.lastexposureRaw);
setExposureRaw(this.lastExposureRaw);

} else {
// Pick a bunch of reasonable setting to make the picture nice-for-humans
Expand All @@ -303,17 +295,17 @@ public void setAutoExposure(boolean cameraAutoExposure) {
}

@Override
public double getMinexposureRaw() {
public double getMinExposureRaw() {
return minExposure;
}

@Override
public double getMaxexposureRaw() {
public double getMaxExposureRaw() {
return maxExposure;
}

@Override
public void setexposureRaw(double exposureRaw) {
public void setExposureRaw(double exposureRaw) {
if (exposureRaw >= 0.0) {
try {
autoExposureProp.set(PROP_AUTO_EXPOSURE_DISABLED);
Expand All @@ -336,7 +328,7 @@ public void setexposureRaw(double exposureRaw) {

exposureAbsProp.set(propVal);

this.lastexposureRaw = exposureRaw;
this.lastExposureRaw = exposureRaw;

if (getCameraConfiguration().cameraQuirks.hasQuirk(CameraQuirk.LifeCamExposure)) {
// Lifecam requires setting brightness again after exposure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ public class CVPipelineSettings implements Cloneable {
public boolean cameraAutoExposure = false;
// manual exposure only used if cameraAutoExposure is false
public double cameraExposureRaw = 20;
public double cameraMinexposureRaw = 1;
public double cameraMaxexposureRaw = 100;
public double cameraMinExposureRaw = 1;
public double cameraMaxExposureRaw = 100;
public int cameraBrightness = 50;
// Currently only used by a few cameras (notably the zero-copy Pi Camera driver) with the Gain
// quirk
Expand All @@ -65,8 +65,8 @@ public boolean equals(Object o) {
CVPipelineSettings that = (CVPipelineSettings) o;
return pipelineIndex == that.pipelineIndex
&& Double.compare(that.cameraExposureRaw, cameraExposureRaw) == 0
&& Double.compare(that.cameraMinexposureRaw, cameraMinexposureRaw) == 0
&& Double.compare(that.cameraMaxexposureRaw, cameraMaxexposureRaw) == 0
&& Double.compare(that.cameraMinExposureRaw, cameraMinExposureRaw) == 0
&& Double.compare(that.cameraMaxExposureRaw, cameraMaxExposureRaw) == 0
&& Double.compare(that.cameraBrightness, cameraBrightness) == 0
&& Double.compare(that.cameraGain, cameraGain) == 0
&& Double.compare(that.cameraRedGain, cameraRedGain) == 0
Expand All @@ -89,8 +89,8 @@ public int hashCode() {
inputImageRotationMode,
pipelineNickname,
cameraExposureRaw,
cameraMinexposureRaw,
cameraMaxexposureRaw,
cameraMinExposureRaw,
cameraMaxExposureRaw,
cameraBrightness,
cameraGain,
cameraRedGain,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ boolean setPipeline(int index) {
pipelineSettings.cameraExposureRaw = 10; // reasonable default
}

visionSource.getSettables().setexposureRaw(pipelineSettings.cameraExposureRaw);
visionSource.getSettables().setExposureRaw(pipelineSettings.cameraExposureRaw);
try {
visionSource.getSettables().setAutoExposure(pipelineSettings.cameraAutoExposure);
} catch (VideoException e) {
Expand Down Expand Up @@ -511,8 +511,8 @@ public PhotonConfiguration.UICameraConfiguration toUICameraConfig() {
ret.currentPipelineIndex = pipelineManager.getRequestedIndex();
ret.pipelineNicknames = pipelineManager.getPipelineNicknames();
ret.cameraQuirks = visionSource.getSettables().getConfiguration().cameraQuirks;
ret.maxExposureRaw = visionSource.getSettables().getMaxexposureRaw();
ret.minExposureRaw = visionSource.getSettables().getMinexposureRaw();
ret.maxExposureRaw = visionSource.getSettables().getMaxExposureRaw();
ret.minExposureRaw = visionSource.getSettables().getMinExposureRaw();

// TODO refactor into helper method
var temp = new HashMap<Integer, HashMap<String, Object>>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ public CameraConfiguration getConfiguration() {
return configuration;
}

public abstract void setexposureRaw(double exposureRaw);
public abstract void setExposureRaw(double exposureRaw);

public abstract double getMinexposureRaw();
public abstract double getMinExposureRaw();

public abstract double getMaxexposureRaw();
public abstract double getMaxExposureRaw();

public abstract void setAutoExposure(boolean cameraAutoExposure);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ public void ps3EyeTest() {
HashMap<CameraQuirk, Boolean> ps3EyeQuirks = new HashMap<>();
ps3EyeQuirks.put(CameraQuirk.Gain, true);
ps3EyeQuirks.put(CameraQuirk.FPSCap100, true);
ps3EyeQuirks.put(CameraQuirk.OneZeroAutoExposure, true);
for (var q : CameraQuirk.values()) {
ps3EyeQuirks.putIfAbsent(q, false);
}

QuirkyCamera psEye = QuirkyCamera.getQuirkyCamera(0x2000, 0x1415);
QuirkyCamera psEye = QuirkyCamera.getQuirkyCamera(0x1415, 0x2000);
Assertions.assertEquals(psEye.quirks, ps3EyeQuirks);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.photonvision.vision.processes;

import org.photonvision.common.configuration.CameraConfiguration;
import org.photonvision.common.util.TestUtils;
import org.photonvision.vision.camera.QuirkyCamera;
import org.photonvision.vision.camera.USBCameraSource;
import org.photonvision.vision.frame.provider.FileFrameProvider;

public class MockUsbCameraSource extends USBCameraSource{

/**
* Used for unit tests to better simulate a usb camera without a camera being present.
*/
public MockUsbCameraSource(CameraConfiguration config, int pid, int vid) {
super(config);

getCameraConfiguration().cameraQuirks = QuirkyCamera.getQuirkyCamera(pid, vid, config.baseName);

/**
* File used as frame provider
*/
usbFrameProvider =
new FileFrameProvider(
TestUtils.getWPIImagePath(
TestUtils.WPI2019Image.kCargoStraightDark72in_HighRes, false),
TestUtils.WPI2019Image.FOV);

usbCameraSettables = new MockUsbCameraSettables(config);

}

private class MockUsbCameraSettables extends USBCameraSettables{

public MockUsbCameraSettables(CameraConfiguration config){
super(config);
}

/**
* Hardware-specific implementation - do nothing in test
*/
@Override
public void setExposureRaw(double exposureRaw){}

/**
* Hardware-specific implementation - do nothing in test
*/
@Override
public void setAutoExposure(boolean cameraAutoExposure) {};

}

}
Loading

0 comments on commit f52b381

Please sign in to comment.