diff --git a/photon-client/src/types/SettingTypes.ts b/photon-client/src/types/SettingTypes.ts index cd3ac8883e..4f17096c1f 100644 --- a/photon-client/src/types/SettingTypes.ts +++ b/photon-client/src/types/SettingTypes.ts @@ -148,6 +148,7 @@ export interface CameraCalibrationResult { export enum ValidQuirks { AWBGain = "AWBGain", AdjustableFocus = "AdjustableFocus", + InnoOV9281Controls = "InnoOV9281Controls", ArduOV9281Controls = "ArduOV9281Controls", ArduOV2311Controls = "ArduOV2311Controls", ArduOV9782Controls = "ArduOV9782Controls", 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 22253f8986..9258c53b42 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 @@ -37,11 +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 */ ArduOV9281Controls, /** Dummy quirk to tell OV2311 from OV9281 */ ArduOV2311Controls, ArduOV9782Controls, + /** + * Camera is innomaker USB OV9281 which also has incorrect v4l exposure times Real range is more + * like 0-500 + */ + InnoOV9281Controls, } diff --git a/photon-core/src/main/java/org/photonvision/vision/camera/FileVisionSource.java b/photon-core/src/main/java/org/photonvision/vision/camera/FileVisionSource.java index ecb3b56b89..ab3dea261e 100644 --- a/photon-core/src/main/java/org/photonvision/vision/camera/FileVisionSource.java +++ b/photon-core/src/main/java/org/photonvision/vision/camera/FileVisionSource.java @@ -74,6 +74,12 @@ 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 diff --git a/photon-core/src/main/java/org/photonvision/vision/camera/LibcameraGpuSource.java b/photon-core/src/main/java/org/photonvision/vision/camera/LibcameraGpuSource.java index 6783f61e3c..8db27a5d73 100644 --- a/photon-core/src/main/java/org/photonvision/vision/camera/LibcameraGpuSource.java +++ b/photon-core/src/main/java/org/photonvision/vision/camera/LibcameraGpuSource.java @@ -58,6 +58,12 @@ public VisionSourceSettables getSettables() { return settables; } + @Override + public void remakeSettables() { + // Nothing to do, settables for this type of VisionSource should never be remade. + return; + } + /** * On the OV5649 the actual FPS we want to request from the GPU can be higher than the FPS that we * can do after processing. On the IMX219 these FPSes match pretty closely, except for the 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 f21b0e560a..2eb1982fd9 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 @@ -80,7 +80,10 @@ public class QuirkyCamera { "OV9782", "OV9782", CameraQuirk.ArduCamCamera, - CameraQuirk.ArduOV9782Controls)); + CameraQuirk.ArduOV9782Controls), + // Innomaker OV9281 + new QuirkyCamera( + 0x0c45, 0x636d, "USB Camera", "USB Camera", CameraQuirk.InnoOV9281Controls)); public static final QuirkyCamera DefaultCamera = new QuirkyCamera(0, 0, ""); public static final QuirkyCamera ZeroCopyPiCamera = diff --git a/photon-core/src/main/java/org/photonvision/vision/camera/TestSource.java b/photon-core/src/main/java/org/photonvision/vision/camera/TestSource.java index deef4b69a8..38b8b56afc 100644 --- a/photon-core/src/main/java/org/photonvision/vision/camera/TestSource.java +++ b/photon-core/src/main/java/org/photonvision/vision/camera/TestSource.java @@ -38,6 +38,12 @@ public TestSource(CameraConfiguration config) { QuirkyCamera.getQuirkyCamera(config.usbVID, config.usbVID, config.baseName); } + @Override + public void remakeSettables() { + // Nothing to do, settables for this type of VisionSource should never be remade. + return; + } + @Override public FrameProvider getFrameProvider() { return new FrameProvider() { diff --git a/photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/InnoOV9281CameraSettables.java b/photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/InnoOV9281CameraSettables.java new file mode 100644 index 0000000000..3cb710e5aa --- /dev/null +++ b/photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/InnoOV9281CameraSettables.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) Photon Vision. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.photonvision.vision.camera.USBCameras; + +import edu.wpi.first.cscore.UsbCamera; +import org.photonvision.common.configuration.CameraConfiguration; + +public class InnoOV9281CameraSettables extends GenericUSBCameraSettables { + public InnoOV9281CameraSettables(CameraConfiguration configuration, UsbCamera camera) { + super(configuration, camera); + } + + @Override + protected void setUpExposureProperties() { + super.setUpExposureProperties(); + + // Property limits are incorrect + this.minExposure = 1; + this.maxExposure = 500; + } +} diff --git a/photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/USBCameraSource.java b/photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/USBCameraSource.java index 56cb8b699f..433c5d7666 100644 --- a/photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/USBCameraSource.java +++ b/photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/USBCameraSource.java @@ -94,7 +94,6 @@ public USBCameraSource(CameraConfiguration config) { } else { // Functional camera, set up the frame provider and configure defaults usbFrameProvider = new USBFrameProvider(cvSink, settables); - settables.setUpExposureProperties(); settables.setAllCamDefaults(); } } @@ -128,18 +127,33 @@ private GenericUSBCameraSettables createSettables(CameraConfiguration config, Us settables = new ArduOV2311CameraSettables(config, camera); } else if (quirks.hasQuirk(CameraQuirk.ArduOV9281Controls)) { logger.debug("Using Arducam OV9281 Settables"); - settables = new ArduOV9281CameraSettables(config, camera); + settables = new InnoOV9281CameraSettables(config, camera); } else if (quirks.hasQuirk(CameraQuirk.ArduOV9782Controls)) { logger.debug("Using Arducam OV9782 Settables"); settables = new ArduOV9782CameraSettables(config, camera); + } else if (quirks.hasQuirk(CameraQuirk.InnoOV9281Controls)) { + settables = new InnoOV9281CameraSettables(config, camera); } else { logger.debug("Using Generic USB Cam Settables"); settables = new GenericUSBCameraSettables(config, camera); } + settables.setUpExposureProperties(); + return settables; } + /** + * Must be called after createSettables Using the current config/camera and modified quirks, make + * a new settables + */ + public void remakeSettables() { + var oldConfig = this.cameraConfiguration; + var oldCamera = this.camera; + + this.settables = createSettables(oldConfig, oldCamera); + } + private void printCameraProperaties() { VideoProperty[] cameraProperties = null; try { diff --git a/photon-core/src/main/java/org/photonvision/vision/processes/VisionModule.java b/photon-core/src/main/java/org/photonvision/vision/processes/VisionModule.java index 4941a0b072..02c66393b7 100644 --- a/photon-core/src/main/java/org/photonvision/vision/processes/VisionModule.java +++ b/photon-core/src/main/java/org/photonvision/vision/processes/VisionModule.java @@ -621,6 +621,7 @@ public void addCalibrationToConfig(CameraCalibrationCoefficients newCalibration) */ public void changeCameraQuirks(HashMap quirksToChange) { visionSource.getCameraConfiguration().cameraQuirks.updateQuirks(quirksToChange); + visionSource.remakeSettables(); saveAndBroadcastAll(); } } diff --git a/photon-core/src/main/java/org/photonvision/vision/processes/VisionSource.java b/photon-core/src/main/java/org/photonvision/vision/processes/VisionSource.java index dd0ff14f8e..618d4fa144 100644 --- a/photon-core/src/main/java/org/photonvision/vision/processes/VisionSource.java +++ b/photon-core/src/main/java/org/photonvision/vision/processes/VisionSource.java @@ -38,4 +38,6 @@ public CameraConfiguration getCameraConfiguration() { public abstract boolean isVendorCamera(); public abstract boolean hasLEDs(); + + public abstract void remakeSettables(); } diff --git a/photon-core/src/test/java/org/photonvision/vision/processes/VisionModuleManagerTest.java b/photon-core/src/test/java/org/photonvision/vision/processes/VisionModuleManagerTest.java index 330d6968d8..ccb7473739 100644 --- a/photon-core/src/test/java/org/photonvision/vision/processes/VisionModuleManagerTest.java +++ b/photon-core/src/test/java/org/photonvision/vision/processes/VisionModuleManagerTest.java @@ -73,6 +73,11 @@ public boolean isVendorCamera() { public boolean hasLEDs() { return false; } + + @Override + public void remakeSettables() { + return; + } } private static class TestSettables extends VisionSourceSettables {