Using Raspberry Pi as coprocessor

Our team is looking at using a raspberry pi 3 B+ as a co processor on our promo bot and I was wondering if anyone had any examples on networking the pi to the roborio via ethernet. Thanks!

Its pretty common to use as a coprocessor. Lots of teams have published code online on places like Github to view it. The most common way is gonna be pynetworktables which publishes data to network tables which can be viewed using the network table library on the rio. You could also use a different communication library such as ZeroMQ.

I thought I’d add a couple thoughts on the use of the rPi for a coprocessor. Other teams may have mitigated some of these; I’d be interested to hear how you did so.

In experimenting, I found that I could quite easily corrupt the SD card by pulling power while Raspbian was still running. Not every time, but once is too much. The forced a rebuild of all of openCV (a good day’s worth of compiling). That itself led to finding out the SD card had bad blocks that resulted in kernel panics on boot. Which led me to buy new SD cards and rebuild everything (3 - 4 times)

This has me concerned about the fragility of the unit.

Since I can’t imagine any student remembering to sudo halt the pi prior to power shutdown, I’m envisioning polling a network table boolean on the pi, to determine when to do an automated halt. This boolean would be set by the driver station when the match is over, the pi would pick up the change and halt itself.

Question about this though… how do I determine the match is over? I was thinking of overloading DisabledInit(), but (haven’t experimented yet), maybe that gets called on the transition from Auto to Tele-op?

I also intend to create a backup .img on an external laptop and burn the 2nd card as a backup. Should the 1st card get smoked, putting the 2nd card in would be the fast ‘restore’. Then reflash the original from the saved .img file. Note - for a 32gb card, I found this to take upwards of 1hr. Granted I was going SDcard to external USB drive to do this - maybe it doesn’t take as long if one uses USB3.0 and goes directly to the laptop disk instead of an external drive.

What have others experienced with the pi in terms of fragility? What mitigations did you put in place?

Many thanks, Otto

I’ve been working on an off-the-shelf rPi image with Java 11 and all the libraries (ntcore, cscore, cameraserver) bundled, along with a web dashboard and some other goodies. Basically you just image a microSD card and it’s plug and play. It’s in an alpha state at present but should be feature-complete in the next week or so, and we’re working on screensteps documentation.

To address the corruption concern, the image defaults to a read-only filesystem and you have to make it explicitly writable. I did this with 294’s raspberry pi image for a couple of seasons and never had an image corruption issue over hundreds of hard power offs.

We use a BeagleBone Black (same idea as a Pi) as our vision coprocessor and WS2812 LED controller. The BeagleBone has a power button that, when pressed, will trigger a clean shutdown in Linux. By the end of the build season, we had everyone who ever powered off the robot trained to push the BeagleBone power button, wait for the BeagleBone LEDs to go out, then hit the main breaker.

This worked, although I suspect we ESD’d a BeagleBone to death after one match, so we modified step 1 to be “‘ground’ yourself to the robot, far away from the BeagleBone, then press the BeagleBone power button.” I also suspect that we irked field staff a few times because it looked like we were standing around, not powering off our robot post-match.

This off-season, we implemented a simple NetworkTables listener running on the coprocessor that waits for a specific Boolean entry to be set true. When the listener sees that flag is set, it shuts down the BeagleBone. On the robot side, that flag is indeed set in DisabledInit(), but only if AutonomousInit() and TeleopInit() have both run. (AutonomousInit() and TeleopInit() both set global variables that are checked by DisabledInit() to determine whether or not the first two functions have run.) The goal here was to shut down after a real match, but not after just testing auto or teleop (or when the robot powers up and runs DisabledInit() for the first time!). I suspect we could also query the driver station to determine whether FMS is connected, and only set the shutdown flag when that is also the case.

So, recommendations:

  1. Have a shutdown button for your coprocessor, and teach everyone to use it before hitting the main breaker. You can rig a shutdown button for a Pi using a GPIO pin and a little bit of software to monitor it.
  2. Avoid post-match ESD and field staff irking by making your coprocessor shut down automatically after a match.
  3. At competitions, have a spare coprocessor configured and ready to go as a drop-in replacement. Having a backup SD card and having the SD card image backed up to a laptop are both good practices, but they won’t help if the whole coprocessor gets smoked.

A few thoughts, since we played with this in the 2016-2017-2018 timeframe:

We had similar concerns about Pi shutdown issues - infrequent but highly inconvenient when the image corrupts. The read-only filesystem would seem to be the trick. Even hooking some function to trigger the shutdown at match end won’t be a complete solution, especially when you’re just running the bot back at the shop.

One other answer that worked in 2018 is to power the coprocessor off of a separate battery pack (and maybe even rig it to charge from the 12V of the robot). The coprocessor would listen for a heartbeat from the RIO. When the robot powers down, the heartbeat stops, and the coprocessor knows to shut down after some debounce period.

Having fiddled with both Beaglebone Black and Pi, I was much happier with the results from the BBB. Still, we managed to fry one during competition too (ESD? Metal shavings? No idea). So always have a backup programmed and ready to go.

Thank you all for your responses.

I went the RO route, following (more/less) the instructions at:
https://hallard.me/raspberry-pi-read-only/

Surprisingly, this is close to what we do on an embedded ARM device we have at work.

I did make backup images of the RO card, so we’ll see how resilient it is once the kiddies get a hold of it.

Otto

Yes, this is the same guide I used when doing the work for 294 and the new off-the-shelf image as well (with a few tweaks).

See https://www.chiefdelphi.com/forums/showthread.php?threadid=186643 for the announcement of an off-the-shelf Raspberry Pi image for coprocessor use.