I first heard about the about 2 months before it was held in 2014. It sounded like something I would love to enter, so with the help of my friends at the Boulder Hacker Space, Solid State Depot, I managed to scrape together a somewhat working entry. I figure it’s about time I write up my experience and write about my plans for next year.
The AVC has a few different categories: fixed wing aircraft, rotating wing aircraft, and ground vehicles. I entered the ground competition because I don’t have much experience with flying, and I was worried about the expense and consequences of crashes during testing: with a ground vehicle, it just bounces off whatever obstacle it ran into, but a flying vehicle can be destroyed. Ground vehicles that malfunction also won’t go very far, but an aerial vehicle might never be seen again.
The ground competition has a few different classes, 3 based on price and size of the vehicle, and the 4th contains vehicles with non-tradional (i.e. not wheeled) locomotion. The cheapest class encompasses vehicles under $350 total. This might just be sour grapes, but I think this class is the most interesting, because it really forces you to prioritize your spending and to come up with creative cost-effective solutions. I entered this class and barely came under the limit.
I don’t know a lot about electronics, so I wanted to use an off the shelf vehicle and modify it as little as possible. Since reading how to turn the Raspberry Pi into an FM transmitter, I figured that it would be possible to modify the code to control an off the shelf remote controlled car. This would solve two things: I could avoid hardware hacking by keeping the control entirely in software and I could easily swap out a car for another model if I needed to. I spent a while tinkering with it, but I eventually got it working!
All of my command software ran on a Raspberry Pi. I wrote the navigation code in Python. I was initially worried about CPU load with using an interpreted language, but with an update interval of 10 Hz, the CPU load was around 5%, so this wasn’t a problem. For next year, I’m going to try rewriting it in Rust so that I can increase the update interval and do some image processing concurrently.
I’ve had several problems with the Raspberry Pi corrupting its file system when the power was suddenly cut. The best solution is to always shut down the system cleanly when powering it down, but with the vehicle running into obstacles and wires becoming dislodged, this wasn’t always an option. I ended up replacing Raspbian with Industrial Perennial Environment, a distro that mounts the root filesystem as read-only by default. This fixed all of the corruption problems I was seeing. For logging and video and other things where I needed a writeable filesystem, I just made a separate partition on the SD card.
The Raspberry Pi can only broadcast at frequencies up to 250 MHz. A lot of new, high-end RC cars operate at 2.4 GHz, so I was limited to lower end vehicles. A lot of cheap RC cars only have 6 directional controls: forward, reverse, and some combination of left, right, or straight. This would have worked fine, but I wanted to have proportional steering. I ended up using a RadioShack Dune Warrior, which has proportional steering and operates in the 27 MHz spectrum. I used an oscilloscope attached to the transmitter to observe the signals that it broadcast and reverse engineered the commands.
The Dune Warrior worked pretty well at first, but if you read the reviews, you’ll see that one big flaw is that the steering gears wear down over time. This ended up being a problem during the competition, as the vehicle would drift slightly left or right when it was in the resting straight position. I’m planning on seeing if I can 3D print a new gear to replace the current one, but if that doesn’t work, I might go with a simpler 6 directional control vehicle instead next year.
Most of the people I talked to at the competition used GPS to navigate around the track, and I was no exception. The cheapest module I could find cost around $40 and required an Arduino or other real-time processing. Linux isn’t a real-time OS, so it really wasn’t appropriate. Instead, I ended up purchasing a cheap Android phone that already had GPS sensors built in. I liked this plan because the phone is already ruggedized and shielded, comes with its own battery supply, has a touch-screen display, and it comes with a whole bunch of sensors.
To collect data from an Android phone, you need some way for it to communicate with the Raspberry Pi. I originally tried to set up an adhoc wireless network using a USB WiFi adapter, but older versions of Android can’t connect to adhoc networks. I ended up setting up the Pi to act as an access point and then having the phone connect to it. This also had the benefit of making it easy to monitor the vehicle – just connect a laptop to the virtual access point and SSH into the Pi.
I spoke with Michael Shimniok at the Colorado Maker Faire, and he gave me a lot of advice. One thing that he suggested is that compasses are unreliable, and instead, one should use the heading computed by the GPS module. I ended up ignoring this advice because the compass seemed reliable when I was testing in my local parking lot, but sure enough, I had problems at the competition. A lot of other competitors I spoke to had similar problems. Next year, I’ll try to avoid it. It should be noted that there was interference in the magnetometer readings from the vehicle itself, but I worked around this by subtracting the raw magnetometer readings when the phone was mounted on the vehicle from the raw readings when the phone was alone.
I read a few different blog posts where people’s otherwise successful runs were stopped short when the vehicle collided with an obstacle. Some entrants I talked to used echolocation distance sensors to avoid obstacles, while others used image processing. I was already close to the spending limit, so I took a different approach. Rather than trying to avoid obstacles, I detected collisions and then backed the vehicle up to try to drive around it. The accelerometer sensors in the phone were too noisy to provide useful data when the car was moving, but when it stopped, there was a huge drop in the magnitude of the readings, which made it easy to detect collisions.
So how did my entry wind up doing in the end? Simply, not great. I only got the car to follow some basic waypoints the night before the competition at 3 AM (note to self: start earlier next year!). One big problem I had was that the compass was slow to update when the vehicle was turning, so it ended up turning past the correct heading and driving a swerving S-pattern towards the next waypoint. To work around this, I calculated the estimated turn time required to point to the next waypoint, turned for that amount of time, and then drove straight for 2 seconds to let the compass update.
At the competition, the compass caused even more problems. In the 1st heat, my car took off the line and immediately veered left into the curb. Looking at the logs, I was getting weird readings from the compass. On the plus side, the vehicle recognized that it had stopped, backed up, and tried to go around the obstacle. It ended up repeating this action a dozen times, eventually going around the first corner and netting me 25 points (the only points I would get that day). The other 2 heats ended similarly, with my vehicle turning completely around, driving straight for 2 seconds, and then turning back.
In all, I had a lot of fun working on my vehicle and am looking forward to the competition next year. I’m planning on starting earlier so that I can hopefully avoid 3 AM debugging sessions before the competition this time 🙂