From 8eaa6904dd6965053a1b63a9a6cbb82ffc20e184 Mon Sep 17 00:00:00 2001 From: "Cameron (3539)" Date: Mon, 21 Oct 2024 10:37:00 -0400 Subject: [PATCH] Equal only by usb paths (#1481) This bug would only appear when there are cameras with the same naming. Old config matching would also match using the by-id this was problematic. When one camera is disconnected it would assign the by-id path to the other camera with the same name. When the camera is replugged in it would not be reassigned the by-id path and would fail the camerainfo equals check. --- .../vision/camera/CameraInfo.java | 2 +- .../processes/VisionSourceManagerTest.java | 53 +++++++++++++++++-- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/photon-core/src/main/java/org/photonvision/vision/camera/CameraInfo.java b/photon-core/src/main/java/org/photonvision/vision/camera/CameraInfo.java index 2c702d33f..750679f77 100644 --- a/photon-core/src/main/java/org/photonvision/vision/camera/CameraInfo.java +++ b/photon-core/src/main/java/org/photonvision/vision/camera/CameraInfo.java @@ -95,7 +95,7 @@ public class CameraInfo extends UsbCameraInfo { if (!path.equals(other.path)) return false; if (!name.equals(other.name)) return false; - if (!Arrays.asList(this.otherPaths).containsAll(Arrays.asList(other.otherPaths))) return false; + if (!Arrays.asList(this.getUSBPath()).contains(other.getUSBPath())) return false; if (vendorId != other.vendorId) return false; if (productId != other.productId) return false; diff --git a/photon-core/src/test/java/org/photonvision/vision/processes/VisionSourceManagerTest.java b/photon-core/src/test/java/org/photonvision/vision/processes/VisionSourceManagerTest.java index 4b800d1dc..467501e2f 100644 --- a/photon-core/src/test/java/org/photonvision/vision/processes/VisionSourceManagerTest.java +++ b/photon-core/src/test/java/org/photonvision/vision/processes/VisionSourceManagerTest.java @@ -521,8 +521,11 @@ public class VisionSourceManagerTest { "/dev/video0", "Arducam OV2311 USB Camera", new String[] { - "/dev/v4l/by-id/usb-Arducam_Technology_Co.__Ltd._Arducam_OV2311_USB_Camera_UC621-video-index0", - "/dev/v4l/by-path/platform-fc800000.usb-usb-0:1:1.0-video-index0" + "/dev/v4l/by-path/platform-fc800000.usb-usb-0:1:1.0-video-index0" // V4l doesnt assign + // by-id paths that + // are identical to + // two different + // cameras }, 3141, 25446); @@ -576,8 +579,11 @@ public class VisionSourceManagerTest { "/dev/video0", "Arducam OV2311 USB Camera", new String[] { - "/dev/v4l/by-id/usb-Arducam_Technology_Co.__Ltd._Arducam_OV2311_USB_Camera_UC621-video-index0", - "/dev/v4l/by-path/platform-fc800000.usb-usb-0:1:1.0-video-index0" + "/dev/v4l/by-path/platform-fc800000.usb-usb-0:1:1.0-video-index0" // V4l doesnt assign + // by-id paths that + // are identical to + // two different + // cameras }, 3141, 25446); @@ -602,5 +608,44 @@ public class VisionSourceManagerTest { assertTrue(inst.knownCameras.contains(info1_dup)); assertTrue(inst.knownCameras.contains(info2_dup)); assertEquals(2, inst.knownCameras.size()); + + // duplciate cameras this simulates unplugging one and plugging the other in where v4l assigns + // the same by-id path to the other camera + var duplicateCameraInfos1 = new ArrayList(); + CameraInfo info3_dup = + new CameraInfo( + 0, + "/dev/video0", + "Arducam OV2311 USB Camera", + new String[] { + "/dev/v4l/by-id/usb-Arducam_Technology_Co.__Ltd._Arducam_OV2311_USB_Camera_UC621-video-index0", + "/dev/v4l/by-path/platform-fc800000.usb-usb-0:1:1.0-video-index0" + }, + 3141, + 25446); + CameraInfo info4_dup = + new CameraInfo( + 0, + "/dev/video2", + "Arducam OV2311 USB Camera", + new String[] { + "/dev/v4l/by-path/platform-fc880000.usb-usb-0:1:1.0-video-index0" // V4l doesnt assign + // by-id paths that + // are identical to + // two different + // cameras + }, + 3141, + 25446); + + duplicateCameraInfos1.add(info3_dup); + duplicateCameraInfos1.add(info4_dup); + + inst.tryMatchCamImpl(duplicateCameraInfos); + + // Our cameras should be "known", and we should only "know" two cameras still + assertTrue(inst.knownCameras.contains(info3_dup)); + assertTrue(inst.knownCameras.contains(info4_dup)); + assertEquals(2, inst.knownCameras.size()); } }