More Than Two USB Cameras??

Hello FRC programming community,
I am the lead programmer on team 5854, this is the team’s second year and my first as lead programmer.

I am using usb cameras to get images to my vision system. I have two cameras hooked up to the usb slots on the roborio and I am using a custom class I made using the built in CameraServer library. (Code Example below) I was wondering if there is a way to make a third camera streaming service. Or if there would be a problem using a usb splitter because I’m not sure how the rio will handle it.

Thnak you in advance.
And sorry if the text is confusing or misspelled, I’m dyslexic.

Code on how I’m making the camera server:


usbCamera = new UsbCamera("USB Camera 0", cameraId);
usbCamera.setResolution(640, 400);
usbCamera.setBrightness(1);

mjpegServer1 = new MjpegServer("serve_USB Camera 0", 1181);

mjpegServer1.setSource(usbCamera); 
	    
cvSink = new CvSink("opencv_USB Camera 0");

cvSink.setSource(usbCamera);

outputStream = new CvSource("Blur", PixelFormat.kMJPEG, 640, 480, 30);

mjpegServer2 = new MjpegServer("serve_Blur", 1182);

mjpegServer2.setSource(outputStream);

Using more than two cameras is certainly possibly. Don’t use a “USB Splitter”, instead just simply use a USB hub on the robot. It may get a little funky with too many because of current draw. Once plugged in, they should simply show up on the roboRIO dashboard, and you should be able to create another CameraServer class.

We’ve used 3 HD-3000’s. You have to be careful with the resolution and fps, because you can run into USB bandwidth issues.

I highly recommend using something along these lines to make sure that you are only ever streaming the camera you want, instead of wasting bandwidth by streaming multiple cameras at the same time.

public void robotInit() {
    	
    	Thread t = new Thread(() -> {
    		
    		boolean allowCam1 = false;
    		
    		UsbCamera camera1 = CameraServer.getInstance().startAutomaticCapture(0);
            camera1.setResolution(320, 240);
            camera1.setFPS(30);
            UsbCamera camera2 = CameraServer.getInstance().startAutomaticCapture(1);
            camera2.setResolution(320, 240);
            camera2.setFPS(30);
            
            CvSink cvSink1 = CameraServer.getInstance().getVideo(camera1);
            CvSink cvSink2 = CameraServer.getInstance().getVideo(camera2);
            CvSource outputStream = CameraServer.getInstance().putVideo("Switcher", 320, 240);
            
            Mat image = new Mat();
            
            while(!Thread.interrupted()) {
            	
            	if(oi.getGamepad().getRawButton(9)) {
            		allowCam1 = !allowCam1;
            	}
            	
                if(allowCam1){
                  cvSink2.setEnabled(false);
                  cvSink1.setEnabled(true);
                  cvSink1.grabFrame(image);
                } else{
                  cvSink1.setEnabled(false);
                  cvSink2.setEnabled(true);
                  cvSink2.grabFrame(image);     
                }
                
                outputStream.putFrame(image);
            }
            
        });
        t.start();

I’ve seen this code in multiple threads here but I have never been able to get it to work. We always end up with the “too many simultaneous client streams” error whenever we try to switch to the second camera (setting allowcam1 to true). Any ideas on why this isn’t working for us?

EDIT: We just tried a new robot program with just this code and got it to work. If anyone else has this error, we had to change the source in smartdashboard to “switcher,” then RESTART the smartdashboard and the robot, and then it would work. I think the problem was that since the smartdashboard had started off streaming the usb cam 0, it never stopped streaming after switching sources.

What do you mean when you say you have to change the source to “switcher?”

In SmartDashboard, the USB Camera Viewer widget has a source property. In the code above, it says “putVideo(“Switcher”, 320, 240);” so that is the new video source. The Java code automatically adds a “Camera 0” or “cam0” source for the webcam, but using that produces an error when switching cameras because you are still trying to stream that single camera rather than the special source that will switch between the two.

My team tried this code and it’s not working. We are getting the same error “to many camera streams” we tried setting up smartdash board the way described above. Method-

Start Robot -> add camera stream -> go into editable mode-> set the camera stream to “Switcher” -> close out smart dashboard and save -> power cycle robot -> start back up smart dashboard and the robot

When we enable robot we get the same error. The settings on rthr smartdashboard changed back to USB camera 0

I would try using a MJPEG stream view on the smart dashboard rather than the CameraServer viewer. With the stream viewer, you can point it to the stream url so that way it doesn’t revert back to one of the webcams direct. In my case, the IP is http://roborio-3602-frc.local:1183/?action=stream. Might have to try different ports starting with 1180, but I think that would be a more elegant solution.

Would that work with the switching code?

Yes, that doesn’t change anything on the robot side, just changes how you view the switcher stream.