USB Acting as IP Camera with Shuffleboard

We have two USB cameras plugged into a Raspberry Pi on our robot, with a camera server hosted on it that converts the streams into an MJPEG stream. How would use pynetworktables to post the feed into a table that Shuffleboard can read? Could I see an example implementation of it?

Our streams are hosted on

http://10.4.70.12:5800/video_feed
http://10.4.70.12:5801/video_feed

-Thanks!
-Dalton Smith, Grizzly Robotics

For Python, see https://github.com/robotpy/robotpy-cscore/blob/master/cscore/cameraserver.py (in particuler the comment starting at line 234). If you use robotpy-cscore to do the camera feeds, it will take care of this for you.

Okay. So I’ve gotten the feed to show up in Shuffleboard but for some reason it is extremely laggy. Skipping many frames and it’s basically a slideshow. It works flawless when I access it from a browser and from SmartDashboard. Here is how I’m implementing it. Right now it’s running off a Windows 10 Computer.

from networktables import NetworkTables

NetworkTables.initialize("localhost")
Table = NetworkTables.getTable("CameraPublisher")
stream = "http://localhost:5000/video_feed"]
Table.putStringArray("TestCam/streams", stream)

You shouldn’t need to publish to NetworkTables manually, you can use the CameraServer class to do this.

See the https://github.com/robotpy/robotpy-cscore/blob/master/examples/quick_cameraserver.py example and other examples in that folder.

How is the actual Mjpeg stream server implemented? Are you using cscore, write it yourself, or something else? What cameras and what version of Shuffleboard?

I’ve wrote it myself through some handy dandy tutorials on the internet. And I don’t want to use the entire CScore library.

Sent from my SM-N920V using Tapatalk

The reason I’m asking is that Shuffleboard uses cscore to grab the camera images; cscore is fairly picky about adherence to the mjpeg over http standard, and that’s likely causing the choppiness you’re seeing. Can you share your source code so I can help with that problem?

It’s worth noting cscore isn’t much more than just a camera interface and a http/mjpeg server. However, one of the main things it provides over most other solutions is robust camera disconnect/reconnect (hotplug) behavior.

I’m really just using this code with minor modifications (change certain variables into a constants.py). I’d be happy to use CScore but I find it hard to read documentation and I could never find a step by step guide of how to set it up. Especially on a Raspberry Pi3.

Something I believe I have already noted is that the when using SmartDashboard, the stream works flawless.

Lastly, I apologize ahead of time about saying I wrote it myself. I did not, I did not copy and paste but instead followed the creators tutorial and did it with the tutorial step by step. I do not take credit for any of the code. :slight_smile:

Step-by-step… like this? http://robotpy.readthedocs.io/en/stable/install/cscore.html#compile-from-source

No. I saw that. A step by step guide on setting up a camera server and how to access it.

Sent from my SM-N920V using Tapatalk

Did you intend to include a link? There isn’t one in your post. If it’s this code or something similar to it (Simple Python Motion Jpeg (mjpeg server) from webcam. Using: OpenCV,BaseHTTPServer · GitHub), there’s a bug in that code: the content-type header for multipart/x-mixed-replace should NOT have a “–” before the contents of the boundary. E.g. this line:


self.send_header('Content-type','multipart/x-mixed-replace; boundary=--jpgboundary')

should be:


self.send_header('Content-type','multipart/x-mixed-replace; boundary=jpgboundary')

Including the dashes (and then trying to send a boundary of “–jpgboundary” rather than “----jpgboundary”) is not compliant to RFC1341.

Oh. I apologize a ton. I thought I sent it. I tried the link you sent previously but it doesn’t allow multiple simultaneous streams which is a requirement for us. We use. https://github.com/miguelgrinberg/flask-video-streaming

Sent from my SM-N920V using Tapatalk

The cscore code for dual cameras is pretty trivial.


#!/usr/bin/env python3
#
# Uses the CameraServer class to automatically capture video from two USB
# webcams and send it to the FRC dashboard without doing any vision
# processing. 
#
# Warning: If you're using this with a python-based robot, do not run this
# in the same program as your robot code!
#

from cscore import CameraServer, UsbCamera

def main():
    cs = CameraServer.getInstance()
    cs.enableLogging()
    
    usb1 = cs.startAutomaticCapture(dev=0)
    usb2 = cs.startAutomaticCapture(dev=1)
    
    cs.waitForever()

if __name__ == '__main__':
    
    # To see messages from networktables, you must setup logging
    import logging
    logging.basicConfig(level=logging.DEBUG)
    
    # You should uncomment these to connect to the RoboRIO
    #import networktables
    #networktables.initialize(server='10.xx.xx.2')
    
    main()

Thanks a ton! I’m definitely going to use this. How would I access the stream from a browser? We use the cameras for two things, vision in the field and vision tracking.

Sent from my SM-N920V using Tapatalk

When it starts, it outputs what port it’s listening on. Just point your browser there. If you uncomment the networktables connection piece, then shuffleboard should be able to find the camera without any issues.

If you want to do image processing also via opencv, that’s also doable. Look at the other cscore examples.

Everything works great! Thanks a ton!