I think I found the proximate cause of the first camera not being Published. It does appear to be a race condition that’s only troublesome on the first camera made by a Robot. It took me a full day to find that; I am hopeful you can resolve it easier than that.
Use of startAutomaticCapture(String, String)
goes fast enough to work without me (and probably the whole world) seeing any failure. I added a Timer.delay(3.)
between the UsbCamera camera = ...
and startAutomaticaCapture ...
and it fails every time on the first camera created by a Robot.
So if the camera and start with video source are close enough together they always work. Put a tiny bit of time between them and it fails. Thus I tried Timer.delay(-1.)
. I learned 60 years ago in engineering school that wouldn’t work but physicists discover wonderous new stuff all the time so I had to give it a shot. And it still doesn’t work!
I had no end of trouble running tests today with what worked yesterday - today - out of bandwidth on USB so I had to specify camera parameters including better paths to make tests reproducible. It’s messier looking but the minimum to get it running today.
I tried adding delays to make the failure go away but it’s the addition of a delay in a normally quick running spot that replicates the failure. I’ll paste below my complete tests including the stuff that didn’t help.
I watched Outline Viewer while the Robot starts. Previous CameraPublisher is deleted. Then the first camera shows if using startAutomaticCapture(String, String)
and then the 2nd and then the 3rd camera.
For the failure tests after the CameraPublisher table is deleted the first camera never makes an appearance in the table even with delays. The 2nd and 3rd cameras appear exactly as expected as they are created.
If only one camera is attempted to be created, it never appears - you have no camera at all.
public void robotInit() {
Timer.delay(3.);
if(true)
{
//good with WPILIb code but bad with my Timer.delay() added to startAutomaticCapture(String, String)
UsbCamera cam1 = Robot.startAutomaticCapture("intake", "/dev/v4l/by-id/usb-KYE_Systems_Corp._USB_Camera_200901010001-video-index0");
cam1.setResolution(160,120);
cam1.setExposureManual(0);
cam1.setFPS(10);
UsbCamera cam0 = Robot.startAutomaticCapture("target", "/dev/v4l/by-id/usb-Microsoft_Microsoft\u00AE_LifeCam_HD-3000-video-index0");
cam0.setResolution(160,120);
cam0.setExposureManual(0);
cam0.setFPS(10);
UsbCamera cam2 = Robot.startAutomaticCapture("test", "/dev/video2");
cam2.setResolution(160,120);
cam2.setExposureManual(0);
cam2.setFPS(10);
}
if(false)
{
//bad
UsbCamera cam1 = new UsbCamera("intake", "/dev/v4l/by-id/usb-KYE_Systems_Corp._USB_Camera_200901010001-video-index0");
CameraServerSharedStore.getCameraServerShared().reportUsbCamera(cam1.getHandle());
cam1.setResolution(160,120);
cam1.setExposureManual(0);
cam1.setFPS(10);
Robot.startAutomaticCapture(cam1);
UsbCamera cam0 = new UsbCamera("target", "/dev/v4l/by-id/usb-Microsoft_Microsoft\u00AE_LifeCam_HD-3000-video-index0");
CameraServerSharedStore.getCameraServerShared().reportUsbCamera(cam0.getHandle());
cam0.setResolution(160,120);
cam0.setExposureManual(0);
cam0.setFPS(10);
Robot.startAutomaticCapture(cam0);
UsbCamera cam2 = new UsbCamera("test", "/dev/video2");
CameraServerSharedStore.getCameraServerShared().reportUsbCamera(cam2.getHandle());
cam2.setResolution(160,120);
cam2.setExposureManual(0);
cam2.setFPS(10);
Robot.startAutomaticCapture(cam2);
}
}
I must add that the first camera is created and operable with its URL but it wasn’t Published so you can’t get to it by the “nice” name using ShuffleBoard or SmartDashBoard but there you can use the URL.