We have been using the built-in CameraServer class in WPILIB to stream our robot’s USB camera to shuffleboard. We have found that, at random, the camera will cut out and this error gets reported to the console: USB Camera 0 ioctl VIDIOC_STREAMON failed Input/output error UsbCameraImpl.cpp:590
We have two USB cameras running: 1 for the driver and 1 for vision. We initialize their streams the same way during robotInit(): UsbCamera driverCamera = CameraServer.getInstance().startAutomaticCapture(RobotSettings.DRIVER_CAM_ID);
(DRIVER_CAM_ID is 0 and the vision camera is 1)
The vision camera is processed using an implementation of the VisionPipeline (only when actually looking at a target though) and the driver camera is streamed to the driverstation. I could understand the issue occurring when the robot code is restarted (which sometimes it does) but the issue also sometimes occurs randomly while the robot is running.
On a side note, when we turn off compression and use the camera in a natively supported resolution (like 320x240) we can get reasonable framerates. But if we enable compression on the stream, the frame rate drops as low as 3-4 fps. We would like to be able to use compression to get higher framerates with the limited bandwidth on the field, but in its current state, it is unusable.
Are there any other errors (e.g. talking about reconnecting to camera), or just that one? Assuming it’s just that message, call setConnectionStrategy(ConnectionStrategy.kKeepOpen) on both the driverCamera and visionCamera. This will keep CameraServer from stopping streaming because it thinks there’s no clients attached (I think what is happening is that you’re getting dropouts between the DS and robot for some other reason; this error message is a symptom rather than a cause, but it can cause a longer dropout than otherwise necessary as it stops and restarts streaming).
The stream between the camera server and the dashboard is always compressed. When you say “enable compression” are you talking about changing the video mode on the camera from YUYV to MJPEG? If the camera mode is set to YUYV, compression to MJPEG is performed in software.
Thanks. I’ll try your solution for the error i’m getting.
As for the compression, I’m referring to setting the compression in shuffleboard to -1 as opposed to a value from 1-100. When the compression there is set to a value from 1-100 the FPS drops significantly, presumably because the roborio is struggling to compress the images. I’m not sure if the camera is currently set to do any compression (MJPEG) or not.
That’s correct. Compression set to -1 in the dashboard means it lets the server choose. If the camera is set to MJPEG video mode (the default), the camera supports MJPEG mode (most do), and the dashboard stream resolution matches the camera resolution (or the dashboard doesn’t specify the resolution), CameraServer will send the JPEG images it gets from the camera hardware directly to the DS without software recompression. Changing compression to some other value or picking a different resolution forces the server to decompress and recompress the image, which takes significantly more CPU and on the roboRio will generally impact FPS.
There’s no way to “fix” this other than to use different hardware than the roboRio or perhaps using a lower resolution. I personally recommend teams use a coprocessor such as a Raspberry Pi with FRCVision for camera streams as this provides both a faster processor and doesn’t share that processor with robot code.