USB Cameras with roboRIO

Because of space restrictions on our robot, we were hoping to use a smaller USB camera instead of an axis camera or the Microsoft lifecam camera. Specifically, we got this endoscope camera to use. Unfortunately when we try to get an image from it using the roboRIO we just get a message that mentions something of an invalid image. Is there anything special that I need to do to get cameras that aren’t the Microsoft camera to work or will the roboRIO only work with the one USB camera?

Most USB cameras will work. Are you by any chance using the SmartDashboard? If so, then try the Labview (“default”) Dashboard and set it to USB Camera (HW). Once you get a video feed there, you can then switch the SmartDashboard.

This is due to a bug in the WPILib CameraServer class (that’s been there for at least two years). We made our own version that fixed the bug.

We are using the Labview dashboard and setting the camera to HW. I know the camera works because we tried it on our laptop and it ran right away. We just can’t get an image with it connected to the roboRIO

You might try using Vision Assistant. Connect your laptop to the roboRIO, camera to roboRIO. Open Vision Assistant and select Acquire Image. Choose the second acquisition method that includes USB. Change the target from My Computer to the roboRIO. See if the camera shows up there and see if it works.

Some USB cameras do not work with UVC, the linux mechanism for USB webcams, but do work with DirectShow, the MS mechanism. If it works in Vision Assistant, it should work with the WPILib VIs.

Greg McKaskle

Thanx for this note. The camera is much more important this year than last year. Last year we just gave up on the HD-3000 usb camera. This year we switched to a Logitech Usb camera and we get consistent image exposures.

We find that having to go to the Default Dashboard to get the video feed going (via USB Camera HW), then switching to SmartDashboard annoying. One of those things that we would rather not have to do while frantically setting up for a match.

We are using USBcamera class and code in C++.

We re-tooled much of the CameraServer class in C++ ourselves in order to switch between two USB cameras on the RoboRIO (ugh, bandwidth). In general, the whole class just seemed poorly written and way too touchy.

Yes, we did exactly the same thing for the same reason, although last year we only wrapped the CameraServer class to switch feeds. This year, we made our own version of it, primarily to get around the bug that rod@3711 complained about.

The student who did that fix posted his code on TeamForge (we couldn’t figure out how to formally submit it).

The cause of the bug is trivial – when the CameraServer on the robot parses a request for a frame from the client (e.g. SmartDashboard running on the laptop), it expects a packet with a twelve octet header – representing three 4-byte integers, the 2nd of which must be -1, indicating hardware compression (which is the only option supported). It reads this packet with:

if (read(conn, &req, sizeof(req)) == -1) 

and then a few lines later checks:

if (req.compression != kHardwareCompression) ...

Unfortunately, about 90% of the time, the request from the SmartDashboard or the SFX Dashboard (but apparently not the LabView dashboard! – likely due to different timing) is sent in two packets – the first packet containing only two bytes, and the second containing the remaining 10 bytes. The read call above asks for however many octets there are at that instant and doesn’t make any effort to read the octets that come later. So the req.compression word it’s comparing to hasn’t even been read yet and is thus zero, so the call fails.

keco195 – if you’re using the (default) LabView dashboard, this isn’t your issue, and I apologize for hijacking your thread!