Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions photon-client/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export default new Vuex.Store({
// Settings that apply to all pipeline types
cameraExposure: 1,
cameraBrightness: 2,
cameraAutoExposure: false,
cameraRedGain: 3,
cameraBlueGain: 4,
inputImageRotationMode: 0,
Expand Down
33 changes: 30 additions & 3 deletions photon-client/src/views/PipelineViews/InputTab.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div>
<CVslider
v-if="cameraExposure !== -1"
:disabled="cameraAutoExposure"
v-model="cameraExposure"
name="Exposure"
min="0"
Expand All @@ -22,10 +22,27 @@
@input="handlePipelineData('cameraBrightness')"
@rollback="e => rollback('cameraBrightness', e)"
/>
<CVswitch
v-model="cameraAutoExposure"
class="pt-2"
name="Auto exposure"
@input="handlePipelineData('cameraAutoExposure')"
/>
<CVslider
v-if="cameraGain >= 0"
v-model="cameraGain"
name="Camera gain"
min="0"
max="100"
tooltip="Controls camera gain, similar to brightness"
:slider-cols="largeBox"
@input="handlePipelineData('cameraRedGain')"
@rollback="e => rollback('cameraRedGain', e)"
/>
<CVslider
v-if="cameraRedGain !== -1"
v-model="cameraRedGain"
name="Red AWB Gain"
name="Red Balance"
min="0"
max="100"
tooltip="Controls red automatic white balance gain, which affects how the camera captures colors in different conditions"
Expand All @@ -36,7 +53,7 @@
<CVslider
v-if="cameraBlueGain !== -1"
v-model="cameraBlueGain"
name="Blue AWB Gain"
name="Blue Balance"
min="0"
max="100"
tooltip="Controls blue automatic white balance gain, which affects how the camera captures colors in different conditions"
Expand Down Expand Up @@ -76,6 +93,7 @@
<script>
import CVslider from '../../components/common/cv-slider'
import CVselect from '../../components/common/cv-select'
import CVswitch from '../../components/common/cv-switch'
const unfilteredStreamDivisors = [1, 2, 4, 6];
Expand All @@ -84,6 +102,7 @@
components: {
CVslider,
CVselect,
CVswitch,
},
// eslint-disable-next-line vue/require-prop-types
props: ['value'],
Expand All @@ -109,6 +128,14 @@
this.$store.commit("mutatePipeline", {"cameraExposure": parseFloat(val)});
}
},
cameraAutoExposure: {
get() {
return this.$store.getters.currentPipelineSettings.cameraAutoExposure;
},
set(val) {
this.$store.commit("mutatePipeline", {"cameraAutoExposure": val});
}
},
cameraBrightness: {
get() {
return parseInt(this.$store.getters.currentPipelineSettings.cameraBrightness)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,14 @@ private static class FileSourceSettables extends VisionSourceSettables {
@Override
public void setExposure(double exposure) {}

public void setAutoExposure(boolean cameraAutoExposure) {}

@Override
public void setBrightness(int brightness) {}

@Override
public void setGain(int gain) {}

@Override
public void setLowExposureOptimization(boolean mode) {}

@Override
public VideoMode getCurrentVideoMode() {
return videoMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ public USBCameraSource(CameraConfiguration config) {
usbFrameProvider = null;
} else {
// Normal init
setLowExposureOptimizationImpl(false);
// auto exposure/brightness/gain will be set by the visionmodule later
disableAutoFocus();

usbCameraSettables = new USBCameraSettables(config);
usbFrameProvider = new USBFrameProvider(cvSink, usbCameraSettables);
}
Expand All @@ -79,58 +80,6 @@ void disableAutoFocus() {
}
}

void setLowExposureOptimizationImpl(boolean lowExposureMode) {
if (cameraQuirks.hasQuirk(CameraQuirk.PiCam)) {
// Case, we know this is a picam. Go through v4l2-ctl interface directly

// Common settings
camera
.getProperty("image_stabilization")
.set(0); // No image stabilization, as this will throw off odometry
camera.getProperty("power_line_frequency").set(2); // Assume 60Hz USA
camera.getProperty("scene_mode").set(0); // no presets
camera.getProperty("exposure_metering_mode").set(0);
camera.getProperty("exposure_dynamic_framerate").set(0);

if (lowExposureMode) {
// Pick a bunch of reasonable setting defaults for vision processing retroreflective
camera.getProperty("auto_exposure_bias").set(0);
camera.getProperty("iso_sensitivity_auto").set(0); // Disable auto ISO adjustement
camera.getProperty("iso_sensitivity").set(0); // Manual ISO adjustement
camera.getProperty("white_balance_auto_preset").set(2); // Auto white-balance disabled
camera.getProperty("auto_exposure").set(1); // auto exposure disabled
} else {
// Pick a bunch of reasonable setting defaults for driver, fiducials, or otherwise
// nice-for-humans
camera.getProperty("auto_exposure_bias").set(12);
camera.getProperty("iso_sensitivity_auto").set(1);
camera.getProperty("iso_sensitivity").set(1); // Manual ISO adjustement by default
camera.getProperty("white_balance_auto_preset").set(1); // Auto white-balance enabled
camera.getProperty("auto_exposure").set(0); // auto exposure enabled
}

} else {
// Case - this is some other USB cam. Default to wpilib's implementation

var canSetWhiteBalance = !cameraQuirks.hasQuirk(CameraQuirk.Gain);

if (lowExposureMode) {
// Pick a bunch of reasonable setting defaults for vision processing retroreflective
if (canSetWhiteBalance) {
camera.setWhiteBalanceManual(4000); // Auto white-balance disabled, 4000K preset
}
this.getSettables().setExposure(50); // auto exposure disabled, put a sane default
} else {
// Pick a bunch of reasonable setting defaults for driver, fiducials, or otherwise
// nice-for-humans
if (canSetWhiteBalance) {
camera.setWhiteBalanceAuto(); // Auto white-balance enabled
}
camera.setExposureAuto(); // auto exposure enabled
}
}
}

@Override
public FrameProvider getFrameProvider() {
return usbFrameProvider;
Expand All @@ -148,6 +97,59 @@ protected USBCameraSettables(CameraConfiguration configuration) {
setVideoMode(videoModes.get(0));
}

public void setAutoExposure(boolean cameraAutoExposure) {
logger.debug("Setting auto exposure to " + cameraAutoExposure);

if (cameraQuirks.hasQuirk(CameraQuirk.PiCam)) {
// Case, we know this is a picam. Go through v4l2-ctl interface directly

// Common settings
camera
.getProperty("image_stabilization")
.set(0); // No image stabilization, as this will throw off odometry
camera.getProperty("power_line_frequency").set(2); // Assume 60Hz USA
camera.getProperty("scene_mode").set(0); // no presets
camera.getProperty("exposure_metering_mode").set(0);
camera.getProperty("exposure_dynamic_framerate").set(0);

if (!cameraAutoExposure) {
// Pick a bunch of reasonable setting defaults for vision processing retroreflective
camera.getProperty("auto_exposure_bias").set(0);
camera.getProperty("iso_sensitivity_auto").set(0); // Disable auto ISO adjustement
camera.getProperty("iso_sensitivity").set(0); // Manual ISO adjustement
camera.getProperty("white_balance_auto_preset").set(2); // Auto white-balance disabled
camera.getProperty("auto_exposure").set(1); // auto exposure disabled
} else {
// Pick a bunch of reasonable setting defaults for driver, fiducials, or otherwise
// nice-for-humans
camera.getProperty("auto_exposure_bias").set(12);
camera.getProperty("iso_sensitivity_auto").set(1);
camera.getProperty("iso_sensitivity").set(1); // Manual ISO adjustement by default
camera.getProperty("white_balance_auto_preset").set(1); // Auto white-balance enabled
camera.getProperty("auto_exposure").set(0); // auto exposure enabled
}

} else {
// Case - this is some other USB cam. Default to wpilib's implementation

var canSetWhiteBalance = !cameraQuirks.hasQuirk(CameraQuirk.Gain);

if (!cameraAutoExposure) {
// Pick a bunch of reasonable setting defaults for vision processing retroreflective
if (canSetWhiteBalance) {
camera.setWhiteBalanceManual(4000); // Auto white-balance disabled, 4000K preset
}
} else {
// Pick a bunch of reasonable setting defaults for driver, fiducials, or otherwise
// nice-for-humans
if (canSetWhiteBalance) {
camera.setWhiteBalanceAuto(); // Auto white-balance enabled
}
camera.setExposureAuto(); // auto exposure enabled
}
}
}

private int timeToPiCamRawExposure(double time_us) {
int retVal =
(int)
Expand All @@ -166,11 +168,6 @@ private double pctToExposureTimeUs(double pct_in) {
+ (pct_in / 100.0) * ((1e6 / (double) camera.getVideoMode().fps) - PADDING_HIGH_US);
}

@Override
public void setLowExposureOptimization(boolean mode) {
setLowExposureOptimizationImpl(mode);
}

@Override
public void setExposure(double exposure) {
if (exposure >= 0.0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,6 @@ public ZeroCopyPicamSource(CameraConfiguration configuration) {

settables = new PicamSettables(configuration);
frameProvider = new AcceleratedPicamFrameProvider(settables);

setLowExposureOptimizationImpl(false);
}

static void setLowExposureOptimizationImpl(boolean mode) {
// TODO - ZeroCopy does not... yet? ... have the configuration params necessary to make this
// work well.
}

@Override
Expand Down Expand Up @@ -94,6 +87,7 @@ public static class PicamSettables extends VisionSourceSettables {
private FPSRatedVideoMode currentVideoMode;
private double lastExposure = 50;
private int lastBrightness = 50;
private boolean lastExposureMode;
private int lastGain = 50;
private Pair<Integer, Integer> lastAwbGains = new Pair(18, 18);

Expand Down Expand Up @@ -150,9 +144,15 @@ public double getFOV() {
return getCurrentVideoMode().fovMultiplier * getConfiguration().FOV;
}

@Override
public void setAutoExposure(boolean cameraAutoExposure) {
lastExposureMode = cameraAutoExposure;
// TODO (Matt) -- call PicamJNI's auto exposure function, when that exists
}

@Override
public void setExposure(double exposure) {
// Todo - for now, handle auto exposure by using 100% exposure
// Todo (Chris) - for now, handle auto exposure by using 100% exposure
if (exposure < 0.0) {
exposure = 100.0;
}
Expand All @@ -162,11 +162,6 @@ public void setExposure(double exposure) {
if (failure) logger.warn("Couldn't set Pi Camera exposure");
}

@Override
public void setLowExposureOptimization(boolean mode) {
setLowExposureOptimizationImpl(mode);
}

@Override
public void setBrightness(int brightness) {
lastBrightness = brightness;
Expand Down Expand Up @@ -218,6 +213,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
setExposure(lastExposure);
setAutoExposure(lastExposureMode);
setBrightness(lastBrightness);
setGain(lastGain);
setAwbGain(lastAwbGains.getFirst(), lastAwbGains.getSecond());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public AprilTagPipelineSettings() {
outputShowMultipleTargets = true;
targetModel = TargetModel.k200mmAprilTag;
cameraExposure = -1;
cameraAutoExposure = true;
ledMode = false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public class CVPipelineSettings implements Cloneable {
public ImageFlipMode inputImageFlipMode = ImageFlipMode.NONE;
public ImageRotationMode inputImageRotationMode = ImageRotationMode.DEG_0;
public String pipelineNickname = "New Pipeline";
// Only used if the pipeline type does not enable auto-exposure
public boolean cameraAutoExposure = false;
// manual exposure only used if cameraAutoExposure if false
public double cameraExposure = 100;
public int cameraBrightness = 50;
// Currently only used by a few cameras (notably the zero-copy Pi Camera driver) with the Gain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
import org.photonvision.vision.frame.consumer.MJPGFrameConsumer;
import org.photonvision.vision.pipeline.AdvancedPipelineSettings;
import org.photonvision.vision.pipeline.OutputStreamPipeline;
import org.photonvision.vision.pipeline.PipelineType;
import org.photonvision.vision.pipeline.ReflectivePipelineSettings;
import org.photonvision.vision.pipeline.UICalibrationData;
import org.photonvision.vision.pipeline.result.CVPipelineResult;
Expand Down Expand Up @@ -361,7 +360,7 @@ public void startCalibration(UICalibrationData data) {
settings.cameraBlueGain = -1;
}

settings.cameraExposure = -1;
settings.cameraAutoExposure = true;

setPipeline(PipelineManager.CAL_3D_INDEX);
}
Expand Down Expand Up @@ -400,22 +399,14 @@ void setPipeline(int index) {
visionSource.getSettables().setBrightness(pipelineSettings.cameraBrightness);
visionSource.getSettables().setGain(pipelineSettings.cameraGain);

// set to true to change camera gain/exposure settings for low exposure
// false will keep the camera running in a more "nice-for-humans" mode
// Each camera type is allowed to decide what settings that exactly means
boolean lowExposureOptimization =
(pipelineSettings.pipelineType == PipelineType.ColoredShape
|| pipelineSettings.pipelineType == PipelineType.Reflective);
visionSource.getSettables().setLowExposureOptimization(lowExposureOptimization);

if (lowExposureOptimization) {
if (pipelineSettings.cameraExposure == -1)
// If manual exposure, force exposure slider to be valid
if (!pipelineSettings.cameraAutoExposure) {
if (pipelineSettings.cameraExposure < 0)
pipelineSettings.cameraExposure = 10; // reasonable default
} else {
// in human-friendly mode, exposure is automatic
pipelineSettings.cameraExposure = -1;
}

visionSource.getSettables().setExposure(pipelineSettings.cameraExposure);
visionSource.getSettables().setAutoExposure(pipelineSettings.cameraAutoExposure);

if (cameraQuirks.hasQuirk(CameraQuirk.Gain)) {
// If the gain is disabled for some reason, re-enable it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public CameraConfiguration getConfiguration() {

public abstract void setExposure(double exposure);

public abstract void setAutoExposure(boolean cameraAutoExposure);

public abstract void setBrightness(int brightness);

public abstract void setGain(int gain);
Expand All @@ -64,8 +66,6 @@ public void setVideoMode(VideoMode mode) {
calculateFrameStaticProps();
}

public abstract void setLowExposureOptimization(boolean mode);

protected abstract void setVideoModeInternal(VideoMode videoMode);

@SuppressWarnings("unused")
Expand Down
Loading