From f1d1d325e0e087580348dd3eb52ec27f5083a1bc Mon Sep 17 00:00:00 2001 From: Chris Gerth Date: Sat, 17 Aug 2024 10:02:59 -0500 Subject: [PATCH] Move to using Absolute Exposure Range (#1352) Uses logic in https://github.com/PhotonVision/photon-libcamera-gl-driver/pull/16 to push the ov9281 down to its true minimum exposure. Updates UI to list the exposure settings in ~~microseconds.~~ Native units - not everyone works in microseconds. Does its darndest to actually try to set the exposure in ~~microseconds.~~ Native Units. To do this... Lifecam is funky when doing this - [cscore limits the exposure settings to certain quantized values](https://github.com/wpilibsuite/allwpilib/blob/main/cscore/src/main/native/linux/UsbCameraImpl.cpp#L129). Add a new camera quirk to allow that. ~~Updated camera quirks to re-evaluate every camera load (rather than recalling from settings - this shouldn't be necessary)~~ This should be rolled back, needed for arducam type selection. Updated camera quirk matching logic to make PID/VID optional, and basename optional (and only match trailing characters). This enables mirroring CSCore's logic for identifying lifecams by name. Updated the USBCamera to primarily use cscore's exposed property names. Since camera manufacturers use a potpourri of names for the same thing.... For nice-to-have settings: new soft-set logic to try all possible names, but gracefully pass if the property isn't there. For required settings: Search a list for the first setting that's supported, fail if none are supported. More logging of camera properties to help debug. Note: most of this work is because cscore doesn't directly expose a massaged exposure-setting-absolute API (and, given what we've seen, probably _shouldn't_, this struggle is not for the faint of heart). --------- Co-authored-by: Matt --- .../cameras/CameraCalibrationCard.vue | 14 +- .../components/cameras/CameraSettingsCard.vue | 30 +- .../components/dashboard/tabs/InputTab.vue | 12 +- .../stores/settings/CameraSettingsStore.ts | 8 + photon-client/src/types/PipelineTypes.ts | 16 +- photon-client/src/types/SettingTypes.ts | 18 +- photon-client/src/types/WebsocketDataTypes.ts | 2 + .../configuration/PhotonConfiguration.java | 2 + .../common/util/math/MathUtils.java | 17 + .../vision/camera/CameraQuirk.java | 20 +- .../vision/camera/FileVisionSource.java | 23 +- .../vision/camera/LibcameraGpuSettables.java | 47 +- .../vision/camera/LibcameraGpuSource.java | 11 + .../vision/camera/QuirkyCamera.java | 77 +-- .../vision/camera/TestSource.java | 16 +- .../vision/camera/USBCameraSource.java | 495 ------------------ .../USBCameras/ArduOV2311CameraSettables.java | 36 ++ .../USBCameras/ArduOV9281CameraSettables.java | 36 ++ .../USBCameras/ArduOV9782CameraSettables.java | 37 ++ .../USBCameras/GenericUSBCameraSettables.java | 306 +++++++++++ .../USBCameras/InnoOV9281CameraSettables.java | 36 ++ .../USBCameras/LifeCam3kCameraSettables.java | 88 ++++ .../LifeCam3kWindowsCameraSettables.java | 86 +++ .../USBCameras/PsEyeCameraSettables.java | 56 ++ .../camera/USBCameras/USBCameraSource.java | 250 +++++++++ .../pipeline/AprilTagPipelineSettings.java | 2 +- .../pipeline/ArucoPipelineSettings.java | 2 +- .../vision/pipeline/CVPipelineSettings.java | 16 +- .../ColoredShapePipelineSettings.java | 2 +- .../vision/pipeline/DriverModePipeline.java | 5 - .../ObjectDetectionPipelineSettings.java | 2 +- .../pipeline/ReflectivePipelineSettings.java | 2 +- .../vision/processes/VisionModule.java | 14 +- .../vision/processes/VisionSource.java | 4 + .../vision/processes/VisionSourceManager.java | 2 +- .../processes/VisionSourceSettables.java | 6 +- .../photonvision/vision/QuirkyCameraTest.java | 15 +- .../vision/processes/MockUsbCameraSource.java | 76 +++ .../processes/VisionModuleManagerTest.java | 28 +- photon-server/build.gradle | 6 - 40 files changed, 1275 insertions(+), 646 deletions(-) delete mode 100644 photon-core/src/main/java/org/photonvision/vision/camera/USBCameraSource.java create mode 100644 photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/ArduOV2311CameraSettables.java create mode 100644 photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/ArduOV9281CameraSettables.java create mode 100644 photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/ArduOV9782CameraSettables.java create mode 100644 photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/GenericUSBCameraSettables.java create mode 100644 photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/InnoOV9281CameraSettables.java create mode 100644 photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/LifeCam3kCameraSettables.java create mode 100644 photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/LifeCam3kWindowsCameraSettables.java create mode 100644 photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/PsEyeCameraSettables.java create mode 100644 photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/USBCameraSource.java create mode 100644 photon-core/src/test/java/org/photonvision/vision/processes/MockUsbCameraSource.java diff --git a/photon-client/src/components/cameras/CameraCalibrationCard.vue b/photon-client/src/components/cameras/CameraCalibrationCard.vue index c24cb4dbe..59198a221 100644 --- a/photon-client/src/components/cameras/CameraCalibrationCard.vue +++ b/photon-client/src/components/cameras/CameraCalibrationCard.vue @@ -389,15 +389,17 @@ const setSelectedVideoFormat = (format: VideoFormat) => { ({ const arducamSelectWrapper = computed({ 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; } } diff --git a/photon-client/src/components/dashboard/tabs/InputTab.vue b/photon-client/src/components/dashboard/tabs/InputTab.vue index 086cb3220..9c883ad20 100644 --- a/photon-client/src/components/dashboard/tabs/InputTab.vue +++ b/photon-client/src/components/dashboard/tabs/InputTab.vue @@ -74,15 +74,15 @@ const interactiveCols = computed(() =>