Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move to using Absolute Exposure Range #1352

Merged
merged 40 commits into from
Aug 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
66b82bd
wip - tied to libcamera PR to remove some of the hacks associated wit…
gerth2 Jun 24, 2024
9c0a322
WIP changing all camera settings to be absolute time
gerth2 Jun 26, 2024
3d43a15
bugfix
gerth2 Jun 26, 2024
b1d4d5f
picam cleanup, better lifecam support
gerth2 Jun 27, 2024
d46efd1
Further wip dynamic min/max
gerth2 Jun 27, 2024
8b4a2de
renamed things for better reflection of what it actually is
gerth2 Jun 28, 2024
71177ba
Spotless, reset index.html
gerth2 Jun 28, 2024
f52b381
Formatting cleanup, unit test cleanup (mocks for usb camera)
gerth2 Jun 28, 2024
bd5371e
More wpi format
gerth2 Jun 28, 2024
5182ff4
npm format
gerth2 Jun 28, 2024
a696e89
Cherry-Pick splitting out settables
gerth2 Jul 12, 2024
8d3d321
wip lifecam experiments, not running yet
gerth2 Jul 18, 2024
05314d4
more WIP with usb cam sources. Not yet working with lifecam after ref…
gerth2 Jul 18, 2024
909cef7
Attempting reorder, no difference
gerth2 Jul 18, 2024
4a15f27
Bugfixes. I think we're finally working acceptably with lifecams on w…
gerth2 Jul 19, 2024
e5c9cdf
Renames, improved camera-specific settables
gerth2 Jul 19, 2024
99942fd
Formatting
gerth2 Jul 19, 2024
a454295
review notes cleanup
gerth2 Jul 19, 2024
cac1646
actually use the new settables
gerth2 Jul 19, 2024
5cc620f
formatting
gerth2 Jul 19, 2024
27705ff
it ain't mmal anymore
gerth2 Jul 19, 2024
7fbb93d
Merge remote-tracking branch 'origin/master' Includes fixups to quirk…
gerth2 Jul 19, 2024
dfcc5bf
fixups for supporting unit tests
gerth2 Jul 19, 2024
6578bef
Merge branch 'master' into HEAD
gerth2 Jul 19, 2024
dfb7a2e
spotless/format
gerth2 Jul 19, 2024
4f127e5
reset index.html
gerth2 Jul 19, 2024
94324ed
aligned ts/vue
gerth2 Jul 21, 2024
3d1181b
formatting
gerth2 Jul 21, 2024
353b6d2
Even more formatting
gerth2 Jul 21, 2024
dbdd691
Adding settings remake implementation, innomaker camera support.
gerth2 Jul 26, 2024
cfddf23
reset libcamera jni loader
gerth2 Jul 26, 2024
1ae9358
Merge remote-tracking branch 'origin/master'
gerth2 Jul 26, 2024
c209420
fix failing unit test
gerth2 Jul 26, 2024
8d4afca
actually fix test
gerth2 Jul 26, 2024
f6a9f7f
spotless
gerth2 Jul 26, 2024
7978309
Run lint
mcm001 Jul 29, 2024
61d87ab
Merge remote-tracking branch 'origin/run-lint'
gerth2 Jul 31, 2024
72d5bad
whuppyfermant
gerth2 Jul 31, 2024
b6379ee
Merge branch 'master' into master
gerth2 Aug 2, 2024
db42646
Merge branch 'master' into master
gerth2 Aug 8, 2024
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
14 changes: 8 additions & 6 deletions photon-client/src/components/cameras/CameraCalibrationCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -389,15 +389,17 @@ const setSelectedVideoFormat = (format: VideoFormat) => {
<v-row v-if="isCalibrating">
<v-col cols="12" class="pt-0">
<pv-slider
v-model="useCameraSettingsStore().currentPipelineSettings.cameraExposure"
v-model="useCameraSettingsStore().currentPipelineSettings.cameraExposureRaw"
:disabled="useCameraSettingsStore().currentCameraSettings.pipelineSettings.cameraAutoExposure"
label="Exposure"
tooltip="Directly controls how much light is allowed to fall onto the sensor, which affects apparent brightness"
:min="0"
:max="100"
tooltip="Directly controls how long the camera shutter remains open. Units are dependant on the underlying driver."
:min="useCameraSettingsStore().minExposureRaw"
:max="useCameraSettingsStore().maxExposureRaw"
:slider-cols="8"
:step="0.1"
@input="(args) => useCameraSettingsStore().changeCurrentPipelineSetting({ cameraExposure: args }, false)"
:step="1"
@input="
(args) => useCameraSettingsStore().changeCurrentPipelineSetting({ cameraExposureRaw: args }, false)
"
/>
<pv-slider
v-model="useCameraSettingsStore().currentPipelineSettings.cameraBrightness"
Expand Down
30 changes: 15 additions & 15 deletions photon-client/src/components/cameras/CameraSettingsCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,32 @@ const tempSettingsStruct = ref<CameraSettingsChangeRequest>({

const arducamSelectWrapper = computed<number>({
get: () => {
if (tempSettingsStruct.value.quirksToChange.ArduOV9281) return 1;
else if (tempSettingsStruct.value.quirksToChange.ArduOV2311) return 2;
else if (tempSettingsStruct.value.quirksToChange.ArduOV9782) return 3;
if (tempSettingsStruct.value.quirksToChange.ArduOV9281Controls) return 1;
else if (tempSettingsStruct.value.quirksToChange.ArduOV2311Controls) return 2;
else if (tempSettingsStruct.value.quirksToChange.ArduOV9782Controls) return 3;
else return 0;
},
set: (v) => {
switch (v) {
case 1:
tempSettingsStruct.value.quirksToChange.ArduOV9281 = true;
tempSettingsStruct.value.quirksToChange.ArduOV2311 = false;
tempSettingsStruct.value.quirksToChange.ArduOV9782 = false;
tempSettingsStruct.value.quirksToChange.ArduOV9281Controls = true;
tempSettingsStruct.value.quirksToChange.ArduOV2311Controls = false;
tempSettingsStruct.value.quirksToChange.ArduOV9782Controls = false;
break;
case 2:
tempSettingsStruct.value.quirksToChange.ArduOV9281 = false;
tempSettingsStruct.value.quirksToChange.ArduOV2311 = true;
tempSettingsStruct.value.quirksToChange.ArduOV9782 = false;
tempSettingsStruct.value.quirksToChange.ArduOV9281Controls = false;
tempSettingsStruct.value.quirksToChange.ArduOV2311Controls = true;
tempSettingsStruct.value.quirksToChange.ArduOV9782Controls = false;
break;
case 3:
tempSettingsStruct.value.quirksToChange.ArduOV9281 = false;
tempSettingsStruct.value.quirksToChange.ArduOV2311 = false;
tempSettingsStruct.value.quirksToChange.ArduOV9782 = true;
tempSettingsStruct.value.quirksToChange.ArduOV9281Controls = false;
tempSettingsStruct.value.quirksToChange.ArduOV2311Controls = false;
tempSettingsStruct.value.quirksToChange.ArduOV9782Controls = true;
break;
default:
tempSettingsStruct.value.quirksToChange.ArduOV9281 = false;
tempSettingsStruct.value.quirksToChange.ArduOV2311 = false;
tempSettingsStruct.value.quirksToChange.ArduOV9782 = false;
tempSettingsStruct.value.quirksToChange.ArduOV9281Controls = false;
tempSettingsStruct.value.quirksToChange.ArduOV2311Controls = false;
tempSettingsStruct.value.quirksToChange.ArduOV9782Controls = false;
break;
}
}
Expand Down
12 changes: 6 additions & 6 deletions photon-client/src/components/dashboard/tabs/InputTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ const interactiveCols = computed(() =>
<template>
<div>
<pv-slider
v-model="useCameraSettingsStore().currentPipelineSettings.cameraExposure"
v-model="useCameraSettingsStore().currentPipelineSettings.cameraExposureRaw"
:disabled="useCameraSettingsStore().currentCameraSettings.pipelineSettings.cameraAutoExposure"
label="Exposure"
tooltip="Directly controls how much light is allowed to fall onto the sensor, which affects apparent brightness"
:min="0"
:max="100"
tooltip="Directly controls how long the camera shutter remains open. Units are dependant on the underlying driver."
:min="useCameraSettingsStore().minExposureRaw"
:max="useCameraSettingsStore().maxExposureRaw"
:slider-cols="interactiveCols"
:step="0.1"
@input="(args) => useCameraSettingsStore().changeCurrentPipelineSetting({ cameraExposure: args }, false)"
:step="1"
@input="(args) => useCameraSettingsStore().changeCurrentPipelineSetting({ cameraExposureRaw: args }, false)"
/>
<pv-slider
v-model="useCameraSettingsStore().currentPipelineSettings.cameraBrightness"
Expand Down
8 changes: 8 additions & 0 deletions photon-client/src/stores/settings/CameraSettingsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ export const useCameraSettingsStore = defineStore("cameraSettings", {
},
isCSICamera(): boolean {
return this.currentCameraSettings.isCSICamera;
},
minExposureRaw(): number {
return this.currentCameraSettings.minExposureRaw;
},
maxExposureRaw(): number {
return this.currentCameraSettings.maxExposureRaw;
}
},
actions: {
Expand Down Expand Up @@ -102,6 +108,8 @@ export const useCameraSettingsStore = defineStore("cameraSettings", {
})),
completeCalibrations: d.calibrations,
isCSICamera: d.isCSICamera,
minExposureRaw: d.minExposureRaw,
maxExposureRaw: d.maxExposureRaw,
pipelineNicknames: d.pipelineNicknames,
currentPipelineIndex: d.currentPipelineIndex,
pipelineSettings: d.currentPipelineSettings,
Expand Down
16 changes: 9 additions & 7 deletions photon-client/src/types/PipelineTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ export interface PipelineSettings {
hueInverted: boolean;
outputShowMultipleTargets: boolean;
contourSortMode: number;
cameraExposure: number;
cameraExposureRaw: number;
cameraMinExposureRaw: number;
cameraMaxExposureRaw: number;
offsetSinglePoint: { x: number; y: number };
cameraBrightness: number;
offsetDualPointAArea: number;
Expand Down Expand Up @@ -97,7 +99,7 @@ export type ConfigurablePipelineSettings = Partial<
// Omitted settings are changed for all pipeline types
export const DefaultPipelineSettings: Omit<
PipelineSettings,
"cameraGain" | "targetModel" | "ledMode" | "outputShowMultipleTargets" | "cameraExposure" | "pipelineType"
"cameraGain" | "targetModel" | "ledMode" | "outputShowMultipleTargets" | "cameraExposureRaw" | "pipelineType"
> = {
offsetRobotOffsetMode: RobotOffsetPointMode.None,
streamingFrameDivisor: 0,
Expand Down Expand Up @@ -151,7 +153,7 @@ export const DefaultReflectivePipelineSettings: ReflectivePipelineSettings = {
targetModel: TargetModel.InfiniteRechargeHighGoalOuter,
ledMode: true,
outputShowMultipleTargets: false,
cameraExposure: 6,
cameraExposureRaw: 6,
pipelineType: PipelineType.Reflective,

contourFilterRangeY: 2,
Expand Down Expand Up @@ -182,7 +184,7 @@ export const DefaultColoredShapePipelineSettings: ColoredShapePipelineSettings =
targetModel: TargetModel.InfiniteRechargeHighGoalOuter,
ledMode: true,
outputShowMultipleTargets: false,
cameraExposure: 20,
cameraExposureRaw: 20,
pipelineType: PipelineType.ColoredShape,

erode: false,
Expand Down Expand Up @@ -222,7 +224,7 @@ export const DefaultAprilTagPipelineSettings: AprilTagPipelineSettings = {
targetModel: TargetModel.AprilTag6p5in_36h11,
ledMode: false,
outputShowMultipleTargets: true,
cameraExposure: 20,
cameraExposureRaw: 20,
pipelineType: PipelineType.AprilTag,

hammingDist: 0,
Expand Down Expand Up @@ -264,7 +266,7 @@ export const DefaultArucoPipelineSettings: ArucoPipelineSettings = {
cameraGain: 75,
outputShowMultipleTargets: true,
targetModel: TargetModel.AprilTag6p5in_36h11,
cameraExposure: -1,
cameraExposureRaw: -1,
cameraAutoExposure: true,
ledMode: false,
pipelineType: PipelineType.Aruco,
Expand Down Expand Up @@ -299,7 +301,7 @@ export const DefaultObjectDetectionPipelineSettings: ObjectDetectionPipelineSett
targetModel: TargetModel.InfiniteRechargeHighGoalOuter,
ledMode: true,
outputShowMultipleTargets: false,
cameraExposure: 6,
cameraExposureRaw: 6,
confidence: 0.9,
nms: 0.45,
box_thresh: 0.25
Expand Down
18 changes: 13 additions & 5 deletions photon-client/src/types/SettingTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,18 @@ export interface CameraCalibrationResult {
export enum ValidQuirks {
AWBGain = "AWBGain",
AdjustableFocus = "AdjustableFocus",
ArduOV9281 = "ArduOV9281",
ArduOV2311 = "ArduOV2311",
ArduOV9782 = "ArduOV9782",
InnoOV9281Controls = "InnoOV9281Controls",
ArduOV9281Controls = "ArduOV9281Controls",
ArduOV2311Controls = "ArduOV2311Controls",
ArduOV9782Controls = "ArduOV9782Controls",
ArduCamCamera = "ArduCamCamera",
CompletelyBroken = "CompletelyBroken",
FPSCap100 = "FPSCap100",
Gain = "Gain",
PiCam = "PiCam",
StickyFPS = "StickyFPS"
StickyFPS = "StickyFPS",
LifeCamControls = "LifeCamControls",
PsEyeControls = "PsEyeControls"
}

export interface QuirkyCamera {
Expand Down Expand Up @@ -190,6 +193,9 @@ export interface CameraSettings {

cameraQuirks: QuirkyCamera;
isCSICamera: boolean;

minExposureRaw: number;
maxExposureRaw: number;
}

export interface CameraSettingsChangeRequest {
Expand Down Expand Up @@ -289,7 +295,9 @@ export const PlaceholderCameraSettings: CameraSettings = {
StickyFPS: false
}
},
isCSICamera: false
isCSICamera: false,
minExposureRaw: 1,
maxExposureRaw: 100
};

export enum CalibrationBoardTypes {
Expand Down
2 changes: 2 additions & 0 deletions photon-client/src/types/WebsocketDataTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export interface WebsocketCameraSettingsUpdate {
pipelineNicknames: string[];
videoFormatList: WebsocketVideoFormat;
cameraQuirks: QuirkyCamera;
minExposureRaw: number;
maxExposureRaw: number;
}
export interface WebsocketNTUpdate {
connected: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,5 +178,7 @@ public static class UICameraConfiguration {
public boolean isFovConfigurable = true;
public QuirkyCamera cameraQuirks;
public boolean isCSICamera;
public double minExposureRaw;
public double maxExposureRaw;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,23 @@ public static long nanosToMicros(long nanos) {
return nanos / 1000;
}

/**
* Constrain a value to only take on certain values. Pick the next-highest allowed value in the
* array if in-between.
*
* @param value value to quantize
* @param allowableSteps sorted array of the allowed values
* @return quantized value
*/
public static int quantize(int value, int[] allowableSteps) {
for (int step : allowableSteps) {
if (value <= step) {
return step;
}
}
return allowableSteps[allowableSteps.length - 1];
}

public static double map(
double value, double in_min, double in_max, double out_min, double out_max) {
return (value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
public enum CameraQuirk {
/** Camera settable for controllable image gain */
Gain,
/** For the Raspberry Pi Camera */
PiCam,
/** Only certain discrete exposure settings work */
LifeCamControls,
/** Auto-Exposure property uses 1/0, rather than 3/1 */
PsEyeControls,
/** Cap at 100FPS for high-bandwidth cameras */
FPSCap100,
/** Separate red/blue gain controls available */
Expand All @@ -35,14 +37,16 @@ public enum CameraQuirk {
/** Camera is an arducam. This means it shares VID/PID with other arducams (ew) */
ArduCamCamera,
/**
* Camera is an arducam ov9281 which has a funky exposure issue where it is defined in v4l as
* Camera is an arducam USB ov9281 which has a funky exposure issue where it is defined in v4l as
* 1-5000 instead of 1-75
*/
ArduOV9281,
ArduOV9281Controls,
/** Dummy quirk to tell OV2311 from OV9281 */
ArduOV2311,
/*
* Camera is an arducam ov9782 which has specific exposure ranges and needs a specific white balance issue
ArduOV2311Controls,
ArduOV9782Controls,
/**
* Camera is innomaker USB OV9281 which also has incorrect v4l exposure times Real range is more
* like 0-500
*/
ArduOV9782
InnoOV9281Controls,
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ public boolean isVendorCamera() {
return false;
}

@Override
public void remakeSettables() {
// Nothing to do, settables for this type of VisionSource should never be remade.
return;
}

@Override
public boolean hasLEDs() {
return false; // Assume USB cameras do not have photonvision-controlled LEDs
}

private static class FileSourceSettables extends VisionSourceSettables {
private final VideoMode videoMode;

Expand All @@ -93,7 +104,7 @@ private static class FileSourceSettables extends VisionSourceSettables {
}

@Override
public void setExposure(double exposure) {}
public void setExposureRaw(double exposureRaw) {}

public void setAutoExposure(boolean cameraAutoExposure) {}

Expand All @@ -117,5 +128,15 @@ protected void setVideoModeInternal(VideoMode videoMode) {
public HashMap<Integer, VideoMode> getAllVideoModes() {
return videoModes;
}

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

@Override
public double getMaxExposureRaw() {
return 100f;
}
}
}
Loading
Loading