30
30
import org .photonvision .common .dataflow .DataChangeService ;
31
31
import org .photonvision .common .dataflow .events .OutgoingUIEvent ;
32
32
import org .photonvision .common .hardware .Platform ;
33
+ import org .photonvision .common .hardware .Platform .OSType ;
33
34
import org .photonvision .common .logging .LogGroup ;
34
35
import org .photonvision .common .logging .Logger ;
35
36
import org .photonvision .common .util .TimedTaskManager ;
@@ -128,20 +129,26 @@ protected List<VisionSource> tryMatchCamImpl() {
128
129
return tryMatchCamImpl (null );
129
130
}
130
131
132
+ protected List <VisionSource > tryMatchCamImpl (ArrayList <CameraInfo > cameraInfos ) {
133
+ return tryMatchCamImpl (cameraInfos , Platform .getCurrentPlatform ());
134
+ }
135
+
131
136
/**
132
137
* @param cameraInfos Used to feed camera info for unit tests.
133
138
* @return New VisionSources.
134
139
*/
135
- protected List <VisionSource > tryMatchCamImpl (ArrayList <CameraInfo > cameraInfos ) {
140
+ protected List <VisionSource > tryMatchCamImpl (
141
+ ArrayList <CameraInfo > cameraInfos , Platform platform ) {
136
142
boolean createSources = true ;
137
143
List <CameraInfo > connectedCameras ;
138
144
if (cameraInfos == null ) {
139
145
// Detect USB cameras using CSCore
140
- connectedCameras = new ArrayList <>(filterAllowedDevices (getConnectedUSBCameras ()));
146
+ connectedCameras = new ArrayList <>(filterAllowedDevices (getConnectedUSBCameras (), platform ));
141
147
// Detect CSI cameras using libcamera
142
- connectedCameras .addAll (new ArrayList <>(filterAllowedDevices (getConnectedCSICameras ())));
148
+ connectedCameras .addAll (
149
+ new ArrayList <>(filterAllowedDevices (getConnectedCSICameras (), platform )));
143
150
} else {
144
- connectedCameras = new ArrayList <>(filterAllowedDevices (cameraInfos ));
151
+ connectedCameras = new ArrayList <>(filterAllowedDevices (cameraInfos , platform ));
145
152
createSources =
146
153
false ; // Dont create sources if we are using supplied camerainfo for unit tests.
147
154
}
@@ -162,15 +169,15 @@ protected List<VisionSource> tryMatchCamImpl(ArrayList<CameraInfo> cameraInfos)
162
169
// All cameras are already loaded return no new sources.
163
170
if (connectedCameras .isEmpty ()) return null ;
164
171
165
- logger .debug ("Matching " + connectedCameras .size () + " new cameras !" );
172
+ logger .debug ("Matching " + connectedCameras .size () + " new camera(s) !" );
166
173
167
174
// Debug prints
168
175
for (var info : connectedCameras ) {
169
176
logger .info ("Detected unmatched physical camera: " + info .toString ());
170
177
}
171
178
172
179
if (!unmatchedLoadedConfigs .isEmpty ())
173
- logger .debug ("Trying to match " + unmatchedLoadedConfigs .size () + " unmatched configs ..." );
180
+ logger .debug ("Trying to match " + unmatchedLoadedConfigs .size () + " unmatched config(s) ..." );
174
181
175
182
// Match camera configs to physical cameras
176
183
List <CameraConfiguration > matchedCameras =
@@ -182,7 +189,7 @@ protected List<VisionSource> tryMatchCamImpl(ArrayList<CameraInfo> cameraInfos)
182
189
() ->
183
190
"After matching, "
184
191
+ unmatchedLoadedConfigs .size ()
185
- + " configs remained unmatched. Is your camera disconnected?" );
192
+ + " config(s) remained unmatched. Is your camera disconnected?" );
186
193
logger .warn (
187
194
"Unloaded configs: "
188
195
+ unmatchedLoadedConfigs .stream ()
@@ -233,7 +240,7 @@ private final Predicate<CameraInfo> getCameraMatcher(
233
240
if (checkUSBPath && savedConfig .getUSBPath ().isEmpty ()) {
234
241
logger .debug (
235
242
"WARN: Camera has empty USB path, but asked to match by name: "
236
- + camCfgToString ( savedConfig ));
243
+ + savedConfig . toShortString ( ));
237
244
}
238
245
239
246
return (CameraInfo physicalCamera ) -> {
@@ -277,22 +284,6 @@ public List<CameraConfiguration> matchCameras(
277
284
ConfigManager .getInstance ().getConfig ().getNetworkConfig ().matchCamerasOnlyByPath );
278
285
}
279
286
280
- private static final String camCfgToString (CameraConfiguration c ) {
281
- return new StringBuilder ()
282
- .append ("[baseName=" )
283
- .append (c .baseName )
284
- .append (", uniqueName=" )
285
- .append (c .uniqueName )
286
- .append (", otherPaths=" )
287
- .append (Arrays .toString (c .otherPaths ))
288
- .append (", vid=" )
289
- .append (c .usbVID )
290
- .append (", pid=" )
291
- .append (c .usbPID )
292
- .append ("]" )
293
- .toString ();
294
- }
295
-
296
287
/**
297
288
* Create {@link CameraConfiguration}s based on a list of detected USB cameras and the configs on
298
289
* disk.
@@ -423,7 +414,7 @@ private List<CameraConfiguration> matchCamerasByStrategy(
423
414
logger .debug (
424
415
String .format (
425
416
"Trying to find a match for loaded camera %s (%s) with camera config: %s" ,
426
- config .baseName , config .uniqueName , camCfgToString ( config )));
417
+ config .baseName , config .uniqueName , config . toShortString ( )));
427
418
428
419
// Get matcher and filter against it, picking out the first match
429
420
Predicate <CameraInfo > matches =
@@ -463,7 +454,7 @@ private List<CameraConfiguration> createConfigsForCameras(
463
454
List <CameraConfiguration > loadedConfigs ) {
464
455
List <CameraConfiguration > ret = new ArrayList <CameraConfiguration >();
465
456
logger .debug (
466
- "After matching loaded configs, these configs remained unmatched: "
457
+ "After matching loaded configs, these cameras remained unmatched: "
467
458
+ detectedCameraList .stream ()
468
459
.map (n -> String .valueOf (n ))
469
460
.collect (Collectors .joining ("-" , "{" , "}" )));
@@ -537,7 +528,7 @@ public void setIgnoredCamerasRegex(String ignoredCamerasRegex) {
537
528
* @param allDevices
538
529
* @return list of devices with blacklisted or ignore devices removed.
539
530
*/
540
- private List <CameraInfo > filterAllowedDevices (List <CameraInfo > allDevices ) {
531
+ private List <CameraInfo > filterAllowedDevices (List <CameraInfo > allDevices , Platform platform ) {
541
532
List <CameraInfo > filteredDevices = new ArrayList <>();
542
533
for (var device : allDevices ) {
543
534
if (deviceBlacklist .contains (device .name )) {
@@ -546,6 +537,13 @@ private List<CameraInfo> filterAllowedDevices(List<CameraInfo> allDevices) {
546
537
} else if (device .name .matches (ignoredCamerasRegex )) {
547
538
logger .trace ("Skipping ignored device: \" " + device .name + "\" at \" " + device .path );
548
539
} else if (device .getIsV4lCsiCamera ()) {
540
+ } else if (device .otherPaths .length == 0
541
+ && platform .osType == OSType .LINUX
542
+ && device .cameraType == CameraType .UsbCamera ) {
543
+ logger .trace (
544
+ "Skipping device with no other paths: \" " + device .name + "\" at \" " + device .path );
545
+ // If cscore hasnt passed this other paths aka a path by id or a path as in usb port then we
546
+ // cant guarantee it is a valid camera.
549
547
} else {
550
548
filteredDevices .add (device );
551
549
logger .trace (
@@ -559,8 +557,6 @@ private static List<VisionSource> loadVisionSourcesFromCamConfigs(
559
557
List <CameraConfiguration > camConfigs , boolean createSources ) {
560
558
var cameraSources = new ArrayList <VisionSource >();
561
559
for (var configuration : camConfigs ) {
562
- logger .debug ("Creating VisionSource for " + camCfgToString (configuration ));
563
-
564
560
// In unit tests, create dummy
565
561
if (!createSources ) {
566
562
cameraSources .add (new TestSource (configuration ));
@@ -580,6 +576,7 @@ private static List<VisionSource> loadVisionSourcesFromCamConfigs(
580
576
cameraSources .add (newCam );
581
577
}
582
578
}
579
+ logger .debug ("Creating VisionSource for " + configuration .toShortString ());
583
580
}
584
581
return cameraSources ;
585
582
}
0 commit comments