I have spent a few days planning for my talk at IPRUG tomorrow evening. One of the things I was hoping to do was demonstrate a standalone Raspberry Pi controlling a USB missile launcher that I have had laying around unused for a few years.
I got the device out of its box, found some batteries (I guess its tilt/swivel motors take too much current for USB bus power) and tried it out using the supplied Windows software. That worked, albeit manually, and with an ugly, proprietary, Windows-specific UI.
Having verified that the hardware was working, I then took a look at controlling it from the Raspberry Pi. This turned out to be much more complex and tricky than I had hoped.
I had already installed Ruby using sudo apt-get install ruby1.9.3, so it seemed that I just needed a USB library. A bit of poking around the web turned up that there seem to be two main USB gems for Ruby, both delegating the real work to a C library “libusb“. The difference between the Ruby gems is also present in the underlying C library. Two versions (0.1 and 1.0) are in widespread use, and their APIs are quite different. The two gems use different versions of the C library. The “libusb” gem requires version 1.0, and the “ruby-usb gem uses version 0.1. A lot of forum posts and the like seemed to recommend the more recent version, so I went with libusb 1.0 and the libusb gem. Installation was pretty straightforward as these things go:
wget http://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-1.0.9/libusb-1.0.9.tar.bz2 tar xjf libusb-1.0.9.tar.bz2 cd libusb-1.0.9 ./configure make sudo make install sudo apt-get install libusb-1.0-0-dev sudo gem install libusb
When it came to software to drive the USB missile launcher things were quite different. I hadn’t realized at the start of this (a) how complex the USB specification actually is, and (b) how little information there is on the web about using USB from Ruby or the details of communicating with this device.
I quickly found that not all missile launchers are the same. There are plenty of tutorial and project examples, but mostly they seem to be for a different (“Dream Cheeky”) missile launcher which has a different USB identifier and completely different commands required to drive it. The examples I did find which might control the launcher I have were all either for a different programming language (C, Python etc.) or for the 0.1 version of the libusb API.
Attempting to port some of these examples raised more questions than answers, and the paucity of detailed API explanations for the Ruby libusb wrapper left me even more confused. Despite all sorts of efforts, I simply could not get the Pi to control the launcher, so I eventually decided to call it a night.
At some point I intend to attack this more methodically: sniff the USB traffic from the Windows box, perhaps using something such as usbsnoop, then write my own driver wrapper to send the same data from the Raspberry Pi.