Multiple USB Cameras on MjpegServer not in Network Tables CameraPublisher

Failing to get all our cameras into ShuffleBoard and we think it’s because they aren’t all listed in NetworkTables CameraPublisher. The last camera created is the only one to show in CameraPublisher.

This shows both cameras in CameraPublisher but doesn’t reveal the Mjpeg server.setCmpression(35) that we need.

UsbCamera cam0 = CameraServer.startAutomaticCapture("target", "/dev/video0");
UsbCamera cam1 = CameraServer.startAutomaticCapture("intake", "/dev/video1"); 

This way creates cameras that work as we want except only the second camera created shows in CameraPublisher.

UsbCamera cam0 = new UsbCamera("target", "/dev/video0");
CameraServer.startAutomaticCapture(cam0);
UsbCamera cam1 = new UsbCamera("intake", "/dev/video1");
CameraServer.startAutomaticCapture(cam1);

Reverse the order of creation and we get the other camera only

We can get all the cameras running as desired to SmartDashboard and a web browser but not in ShuffleBoard.

A third stream from OpenCV does always show in CameraPublisher NetworkTables.

The USB cameras and Java code are on roboRIO v2 with latest WPILib installed.

Dozens of various test cases have been tried but none have found the secret knock to let in two cameras. Can anyone point out the error of our ways? Thanks

I’ll try to reproduce this tonight, but your first two sets of code do exactly the same thing. Here’s the source code to startAutomaticCapture(String, String):

About the only thing I can think of is if there’s a race condition that’s being avoided due to the tiny delay added by the reportUsbCamera call. Try adding a short sleep between the two camera creations?

Thanks. Yes, that was one of many tries. Tried it again this way now and the last camera always wins. Even tossed in a reboot of the roboRIO for good measure.

UsbCamera cam0 = new UsbCamera("target", "/dev/video0");
CameraServer.startAutomaticCapture(cam0);

    Timer.delay(5.);
    
UsbCamera cam1 = new UsbCamera("intake", "/dev/video1");
CameraServer.startAutomaticCapture(cam1);

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.

Be sure to check that your camera natively supports 160x120 10 fps. You can do that either programmatically or through the web interface CameraServer Web Interface — FIRST Robotics Competition documentation

I changed all 3 camera’s fps to ones listed by the camera. Two decreased slightly and one increased. I reran all tests with the same results as above - we still have a problem.

It’s not unheard of that I’m the first to see this problem but I have to assume I’m the only person with this problem so what could be different from my team’s setup and all the others? We are using roboRIOv2 which is faster so others should tend to see more of this problem.