From 173b6d9ca81193d3aa1416a7a0158eaef79bd3e8 Mon Sep 17 00:00:00 2001 From: Gautam Date: Mon, 1 Jul 2024 15:54:20 -0700 Subject: [PATCH] Adds support for OV9782's quirks (#1284) The OV9782 camera has a specific exposure range, so a camera quirk for it needs to exist. The default white balance is also pretty bad, so it must be adjusted. Closes #1204 --------- Co-authored-by: Matt Co-authored-by: Cameron (3539) --- docs/.readthedocs.yaml | 15 +++++++++++ .../components/cameras/CameraSettingsCard.vue | 12 ++++++++- photon-client/src/types/SettingTypes.ts | 2 ++ .../vision/camera/CameraQuirk.java | 4 +++ .../vision/camera/QuirkyCamera.java | 8 ++++++ .../vision/camera/USBCameraSource.java | 27 ++++++++++++++++--- 6 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 docs/.readthedocs.yaml diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml new file mode 100644 index 0000000000..3b80b77b96 --- /dev/null +++ b/docs/.readthedocs.yaml @@ -0,0 +1,15 @@ +version: 2 + +sphinx: + builder: html + configuration: source/conf.py + fail_on_warning: true + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +python: + install: + - requirements: requirements.txt diff --git a/photon-client/src/components/cameras/CameraSettingsCard.vue b/photon-client/src/components/cameras/CameraSettingsCard.vue index 73f6106425..5c58b688be 100644 --- a/photon-client/src/components/cameras/CameraSettingsCard.vue +++ b/photon-client/src/components/cameras/CameraSettingsCard.vue @@ -15,6 +15,7 @@ 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; else return 0; }, set: (v) => { @@ -22,14 +23,22 @@ const arducamSelectWrapper = computed({ case 1: tempSettingsStruct.value.quirksToChange.ArduOV9281 = true; tempSettingsStruct.value.quirksToChange.ArduOV2311 = false; + tempSettingsStruct.value.quirksToChange.ArduOV9782 = false; break; case 2: tempSettingsStruct.value.quirksToChange.ArduOV9281 = false; tempSettingsStruct.value.quirksToChange.ArduOV2311 = true; + tempSettingsStruct.value.quirksToChange.ArduOV9782 = false; + break; + case 3: + tempSettingsStruct.value.quirksToChange.ArduOV9281 = false; + tempSettingsStruct.value.quirksToChange.ArduOV2311 = false; + tempSettingsStruct.value.quirksToChange.ArduOV9782 = true; break; default: tempSettingsStruct.value.quirksToChange.ArduOV9281 = false; tempSettingsStruct.value.quirksToChange.ArduOV2311 = false; + tempSettingsStruct.value.quirksToChange.ArduOV9782 = false; break; } } @@ -129,7 +138,8 @@ watchEffect(() => { :items="[ { name: 'None', value: 0, disabled: true }, { name: 'OV9281', value: 1 }, - { name: 'OV2311', value: 2 } + { name: 'OV2311', value: 2 }, + { name: 'OV9782', value: 3 } ]" :select-cols="8" /> diff --git a/photon-client/src/types/SettingTypes.ts b/photon-client/src/types/SettingTypes.ts index 87f954ce6c..9c088e1d63 100644 --- a/photon-client/src/types/SettingTypes.ts +++ b/photon-client/src/types/SettingTypes.ts @@ -150,6 +150,7 @@ export enum ValidQuirks { AdjustableFocus = "AdjustableFocus", ArduOV9281 = "ArduOV9281", ArduOV2311 = "ArduOV2311", + ArduOV9782 = "ArduOV9782", ArduCamCamera = "ArduCamCamera", CompletelyBroken = "CompletelyBroken", FPSCap100 = "FPSCap100", @@ -279,6 +280,7 @@ export const PlaceholderCameraSettings: CameraSettings = { AdjustableFocus: false, ArduOV9281: false, ArduOV2311: false, + ArduOV9782: false, ArduCamCamera: false, CompletelyBroken: false, FPSCap100: false, diff --git a/photon-core/src/main/java/org/photonvision/vision/camera/CameraQuirk.java b/photon-core/src/main/java/org/photonvision/vision/camera/CameraQuirk.java index 02afa9ac1d..ab2aca7663 100644 --- a/photon-core/src/main/java/org/photonvision/vision/camera/CameraQuirk.java +++ b/photon-core/src/main/java/org/photonvision/vision/camera/CameraQuirk.java @@ -41,4 +41,8 @@ public enum CameraQuirk { ArduOV9281, /** 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 + */ + ArduOV9782 } diff --git a/photon-core/src/main/java/org/photonvision/vision/camera/QuirkyCamera.java b/photon-core/src/main/java/org/photonvision/vision/camera/QuirkyCamera.java index a73e6e188c..d7e830b31b 100644 --- a/photon-core/src/main/java/org/photonvision/vision/camera/QuirkyCamera.java +++ b/photon-core/src/main/java/org/photonvision/vision/camera/QuirkyCamera.java @@ -74,6 +74,14 @@ public class QuirkyCamera { "OV9281", "OV9281", CameraQuirk.ArduCamCamera, + CameraQuirk.ArduOV9281), + // Arducam OV + new QuirkyCamera( + 0x0c45, + 0x6366, + "OV9782", + "OV9782", + CameraQuirk.ArduCamCamera, CameraQuirk.ArduOV9281)); public static final QuirkyCamera DefaultCamera = new QuirkyCamera(0, 0, ""); diff --git a/photon-core/src/main/java/org/photonvision/vision/camera/USBCameraSource.java b/photon-core/src/main/java/org/photonvision/vision/camera/USBCameraSource.java index 10f6fef578..9b9fad845d 100644 --- a/photon-core/src/main/java/org/photonvision/vision/camera/USBCameraSource.java +++ b/photon-core/src/main/java/org/photonvision/vision/camera/USBCameraSource.java @@ -69,6 +69,15 @@ public USBCameraSource(CameraConfiguration config) { logger.info("Quirky camera detected: " + getCameraConfiguration().cameraQuirks.baseName); } + if (getCameraConfiguration().cameraQuirks.hasQuirk(CameraQuirk.ArduOV9782)) { + try { + // Set white balance temperature to 3500 for OV9782 camera + camera.getProperty("white_balance_temperature").set(3500); + } catch (VideoException e) { + logger.error("Failed to set white balance temperature for OV9782 camera!", e); + } + } + if (getCameraConfiguration().cameraQuirks.hasQuirk(CameraQuirk.CompletelyBroken)) { // set some defaults, as these should never be used. logger.info( @@ -190,9 +199,18 @@ public void setAutoExposure(boolean cameraAutoExposure) { // Linux kernel bump changed names -- now called white_balance_automatic and // white_balance_temperature if (camera.getProperty("white_balance_automatic").getKind() != Kind.kNone) { - // 1=auto, 0=manual - camera.getProperty("white_balance_automatic").set(0); - camera.getProperty("white_balance_temperature").set(4000); + if (getCameraConfiguration().cameraQuirks.hasQuirk(CameraQuirk.ArduOV9782)) { + try { + // Set white balance temperature to 3500 for OV9782 camera + camera.getProperty("white_balance_temperature").set(3500); + } catch (VideoException e) { + logger.error("Failed to set white balance temperature for OV9782 camera!", e); + } + } else { + // 1=auto, 0=manual + camera.getProperty("white_balance_automatic").set(0); + camera.getProperty("white_balance_temperature").set(4000); + } } else { camera.setWhiteBalanceManual(4000); // Auto white-balance disabled, 4000K preset } @@ -273,6 +291,9 @@ public void setExposure(double exposure) { } else if (getCameraConfiguration().cameraQuirks.hasQuirk(CameraQuirk.ArduOV2311)) { propMin = 1; propMax = 140; + } else if (getCameraConfiguration().cameraQuirks.hasQuirk(CameraQuirk.ArduOV9782)) { + propMin = 1; + propMax = 60; } var exposure_manual_val = MathUtils.map(Math.round(exposure), 0, 100, propMin, propMax);