Add matching by base-name only (fused off by only by path) (#1238)

This commit is contained in:
Matt
2024-02-18 21:00:14 -05:00
committed by GitHub
parent 39216db143
commit 2a9502be3d
5 changed files with 59 additions and 15 deletions

View File

@@ -281,11 +281,29 @@ watchEffect(() => {
</v-banner> </v-banner>
<pv-switch <pv-switch
v-model="tempSettingsStruct.matchCamerasOnlyByPath" v-model="tempSettingsStruct.matchCamerasOnlyByPath"
label="Match cameras by-path ONLY" label="Strictly match ONLY known cameras"
tooltip="ONLY match cameras by the USB port they're plugged into + (basename or USB VID/PID), and never only by the device product string" tooltip="ONLY match cameras by the USB port they're plugged into + (basename or USB VID/PID), and never only by the device product string. Also disables automatic detection of new cameras."
class="mt-3 mb-2" class="mt-3 mb-2"
:label-cols="4" :label-cols="4"
/> />
<v-banner
v-show="tempSettingsStruct.matchCamerasOnlyByPath"
rounded
color="red"
class="mb-3"
text-color="white"
icon="mdi-information-outline"
>
Physical cameras will be strictly matched to camera configurations using physical USB port they are plugged
into, in addition to device name and other USB metadata. Additionally, no new cameras are allowed to be added.
This setting is useful for guaranteeing that an already known and configured camera can never be matched as an
"unknown"/"new" camera, which resets pipelines and calibration data.
<p />
Cameras will NOT be matched if they change USB ports, and new cameras plugged into this coprocessor will NOT
be automatically recognized or configured for vision processing.
<p />
To add a new camera to this coprocessor, disable this setting, connect the camera, and re-enable.
</v-banner>
<v-divider class="mb-3" /> <v-divider class="mb-3" />
</v-form> </v-form>
<v-btn <v-btn

View File

@@ -41,7 +41,9 @@ public class NetworkConfig {
/** /**
* If we should ONLY match cameras by path, and NEVER only by base-name. For now default to false * If we should ONLY match cameras by path, and NEVER only by base-name. For now default to false
* to preserve old matching logic * to preserve old matching logic.
*
* <p>This also disables creating new CameraConfigurations for detected "new" cameras.
*/ */
public boolean matchCamerasOnlyByPath = false; public boolean matchCamerasOnlyByPath = false;

View File

@@ -101,6 +101,8 @@ public class CameraInfo extends UsbCameraInfo {
+ vendorId + vendorId
+ ", pid=" + ", pid="
+ productId + productId
+ ", path="
+ path
+ ", otherPaths=" + ", otherPaths="
+ Arrays.toString(otherPaths) + Arrays.toString(otherPaths)
+ "]"; + "]";

View File

@@ -57,8 +57,8 @@ public class USBCameraSource extends VisionSource {
cvSink = CameraServer.getVideo(this.camera); cvSink = CameraServer.getVideo(this.camera);
// set vid/pid if not done already for future matching // set vid/pid if not done already for future matching
if (config.usbVID < 0) config.usbVID = this.camera.getInfo().vendorId; if (config.usbVID <= 0) config.usbVID = this.camera.getInfo().vendorId;
if (config.usbPID < 0) config.usbPID = this.camera.getInfo().productId; if (config.usbPID <= 0) config.usbPID = this.camera.getInfo().productId;
if (getCameraConfiguration().cameraQuirks == null) if (getCameraConfiguration().cameraQuirks == null)
getCameraConfiguration().cameraQuirks = getCameraConfiguration().cameraQuirks =

View File

@@ -317,8 +317,7 @@ public class VisionSourceManager {
logger.info("Matching by usb port & name & USB VID/PID..."); logger.info("Matching by usb port & name & USB VID/PID...");
cameraConfigurations.addAll( cameraConfigurations.addAll(
matchCamerasByStrategy(detectedCameraList, unloadedConfigs, true, true, true, false)); matchCamerasByStrategy(detectedCameraList, unloadedConfigs, true, true, true, false));
} else }
logger.debug("Skipping match by usb port/name/vid/pid, no configs or cameras left to match");
// On windows, the v4l path is actually useful and tells us the port the camera is physically // On windows, the v4l path is actually useful and tells us the port the camera is physically
// connected to which is neat // connected to which is neat
@@ -327,16 +326,23 @@ public class VisionSourceManager {
logger.info("Matching by windows-path & USB VID/PID only..."); logger.info("Matching by windows-path & USB VID/PID only...");
cameraConfigurations.addAll( cameraConfigurations.addAll(
matchCamerasByStrategy(detectedCameraList, unloadedConfigs, false, true, true, true)); matchCamerasByStrategy(detectedCameraList, unloadedConfigs, false, true, true, true));
} else }
logger.debug(
"Skipping matching by windiws-path/name/vid/pid, no configs or cameras left to match");
} }
if (detectedCameraList.size() > 0 || unloadedConfigs.size() > 0) { if (detectedCameraList.size() > 0 || unloadedConfigs.size() > 0) {
logger.info("Matching by usb port & USB VID/PID..."); logger.info("Matching by usb port & USB VID/PID...");
cameraConfigurations.addAll( cameraConfigurations.addAll(
matchCamerasByStrategy(detectedCameraList, unloadedConfigs, true, true, false, false)); matchCamerasByStrategy(detectedCameraList, unloadedConfigs, true, true, false, false));
} else logger.debug("Skipping match by port/vid/pid, no configs or cameras left to match"); }
// Legacy migration -- VID/PID will be unset, so we have to try with our most relaxed strategy
// at least once. We _should_ still have a valid USB path (assuming cameras have not moved), so
// try that first, then fallback to base name only beloow
if (detectedCameraList.size() > 0 || unloadedConfigs.size() > 0) {
logger.info("Matching by base-name & usb port...");
cameraConfigurations.addAll(
matchCamerasByStrategy(detectedCameraList, unloadedConfigs, true, false, true, false));
}
// handle disabling only-by-base-name matching // handle disabling only-by-base-name matching
if (!matchCamerasOnlyByPath) { if (!matchCamerasOnlyByPath) {
@@ -344,13 +350,29 @@ public class VisionSourceManager {
logger.info("Matching by base-name & USB VID/PID only..."); logger.info("Matching by base-name & USB VID/PID only...");
cameraConfigurations.addAll( cameraConfigurations.addAll(
matchCamerasByStrategy(detectedCameraList, unloadedConfigs, false, true, true, false)); matchCamerasByStrategy(detectedCameraList, unloadedConfigs, false, true, true, false));
} else }
logger.debug("Skipping match by base-name/viid/pid, no configs or cameras left to match");
// Legacy migration for if no USB VID/PID set
if (detectedCameraList.size() > 0 || unloadedConfigs.size() > 0) {
logger.info("Matching by base-name only...");
cameraConfigurations.addAll(
matchCamerasByStrategy(detectedCameraList, unloadedConfigs, false, false, true, false));
}
} else logger.info("Skipping match by filepath/vid/pid, disabled by user"); } else logger.info("Skipping match by filepath/vid/pid, disabled by user");
if (detectedCameraList.size() > 0) { if (detectedCameraList.size() > 0) {
cameraConfigurations.addAll( // handle disabling only-by-base-name matching
createConfigsForCameras(detectedCameraList, unloadedConfigs, cameraConfigurations)); if (!matchCamerasOnlyByPath) {
cameraConfigurations.addAll(
createConfigsForCameras(detectedCameraList, unloadedConfigs, cameraConfigurations));
} else {
logger.warn(
"Not creating 'new' Photon CameraConfigurations for ["
+ detectedCamInfos.stream()
.map(CameraInfo::toString)
.collect(Collectors.joining(";"))
+ "], disabled by user");
}
} }
logger.debug("Matched or created " + cameraConfigurations.size() + " camera configs!"); logger.debug("Matched or created " + cameraConfigurations.size() + " camera configs!");