From 41395665143659ff47fcc270873795cb3526a389 Mon Sep 17 00:00:00 2001 From: Matt Morley Date: Sun, 25 Jan 2026 16:11:14 -0800 Subject: [PATCH] Add OV9281 AE startup quirk (#1814) ## Description In https://github.com/PhotonVision/photonvision/issues/1771, we discovered that the OV9281 on Linux seems to sometimes ignore our exposure requests on first boot if we're in manual mode. Cycling the camera's auto exposure with pauses in-between seems to fix it, which is what this PR does. Tested by [Team 2881 on Discord](https://discord.com/channels/725836368059826228/725846784131203222/1465098110765105456); thanks for helping us test this fix out! ## Meta Closes https://github.com/PhotonVision/photonvision/issues/1771 Merge checklist: - [x] Pull Request title is [short, imperative summary](https://cbea.ms/git-commit/) of proposed changes - [x] The description documents the _what_ and _why_ - [ ] If this PR changes behavior or adds a feature, user documentation is updated - [ ] If this PR touches photon-serde, all messages have been regenerated and hashes have not changed unexpectedly - [ ] If this PR touches configuration, this is backwards compatible with settings back to v2024.3.1 - [ ] If this PR addresses a bug, a regression test for it is added --------- Co-authored-by: Gold856 <117957790+Gold856@users.noreply.github.com> --- .../USBCameras/GenericUSBCameraSettables.java | 20 +++++++++++++++++++ .../vision/processes/VisionModule.java | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/GenericUSBCameraSettables.java b/photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/GenericUSBCameraSettables.java index 7d956643e..f6ee0ecd0 100644 --- a/photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/GenericUSBCameraSettables.java +++ b/photon-core/src/main/java/org/photonvision/vision/camera/USBCameras/GenericUSBCameraSettables.java @@ -167,7 +167,27 @@ public class GenericUSBCameraSettables extends VisionSourceSettables { } } + @Override public void setAutoExposure(boolean cameraAutoExposure) { + if (configuration.cameraQuirks.hasQuirk(CameraQuirk.ArduOV9281Controls) + && !cameraAutoExposure) { + // OV9281 on Linux seems to sometimes ignore our exposure requests on first boot if we're in + // manual mode. Poking the camera into and out of auto exposure seems to fix it. + try { + setAutoExposureImpl(false); + Thread.sleep(2000); + setAutoExposureImpl(true); + Thread.sleep(2000); + setAutoExposureImpl(false); + } catch (InterruptedException e) { + logger.error("Thread interrupted while setting OV9281 exposure!", e); + } + } else { + setAutoExposureImpl(cameraAutoExposure); + } + } + + public void setAutoExposureImpl(boolean cameraAutoExposure) { logger.debug("Setting auto exposure to " + cameraAutoExposure); if (!cameraAutoExposure) { 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 e0843e391..b57b01d96 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 @@ -465,13 +465,13 @@ public class VisionModule { pipelineSettings.cameraExposureRaw = 10; // reasonable default } - settables.setExposureRaw(pipelineSettings.cameraExposureRaw); try { settables.setAutoExposure(pipelineSettings.cameraAutoExposure); } catch (VideoException e) { logger.error("Unable to set camera auto exposure!"); logger.error(e.toString()); } + settables.setExposureRaw(pipelineSettings.cameraExposureRaw); if (cameraQuirks.hasQuirk(CameraQuirk.Gain)) { // If the gain is disabled for some reason, re-enable it if (pipelineSettings.cameraGain == -1) pipelineSettings.cameraGain = 75;