This is another write-up of my Sparkfun AVC experience. This year I worked closely with Roadrunner, who ran a similar vehicle and the same code. We collaborated using google code and SVN, which made us feel like "real" programmers.
Minuteman's twin, Roadrunner.
Minuteman uses a dead reckoning navigation system with a gyro for direction, and an optical encoder for distance. The car starts at a known position and direction which is designated as coordinates (0,0) and angle 0. As the car moves, the direction and distance are used to compute the new position approximately every inch. This process is all interrupt-driven, so the position is computed, even when the car is under manual control.
Programming the car is done by manually driving it around a course and recording waypoints (4 waypoints for a square course, for example). To re-run the course, it is set back at the original starting position (and angle), and set to auto-mode. The car uses a proportional steering algorithm to steer to the waypoints with open-loop throttle control. If the car doesn’t hit the waypoints exactly as programmed, the waypoints may be edited on a spreadsheet for fine-tuning. Generally, if allowed to temperature-stabilize, it is very repeatable from run to run.
I chose an ardupilot (original) for this project. It’s basically an arduino with a multiplexer and attiny chip for switching between manual and auto modes. It is powered directly from the ESC and has worked like a real champ throughout much testing and countless crashes.
The gyro is an Analog Devices ADXRS613, single axis, analog output, from Sparkfun. It is sampled at 19.4 kHz by a free-running ADC on the ardupilot. My testing has shown that the null value shifts linearly with temperature, so letting the car temperature-stabilize for 5 or 10 minutes before running is important. Once stabilized, the drift over 1 minute is negligible. The gyro rate is very stable over the temperature range of interest, and is assumed to be linear over all rates (within specification).
The encoder is attached to the transmission input shaft. It’s made with parts from an old computer mouse, and has 8 divisions per revolution. The signal is very clean, and is able to drive an interrupt on the ardupilot with no signal conditioning. With the light shield in place, I believe it’s completely immune to noise.
Optical encoder, on transmission
Losi XXX roller: $60
brushless ESC and motor: $60
On Friday I went with RR to the sparkfun building for testing. There were probably 10 other teams there doing the same. Testing went well, and I was able to establish some waypoints for the corners and some possible barrel locations. My best lap times were around 40 sec.The car can go much faster, but goes out of sight quickly and would be destroyed by a curb--so I didn't want to take any chances.
On the day of the race we got to sparkfun at about 7:45 and started testing. My first problem was that a food truck had parked in front of the electric pole I had been sighting the car to (have to set the initial angle for dead reckoning). I re-sighted on a tree, which was later covered by another food truck. I tried not to take it personally :)
I use a scope for setting the initial angle
After setting up my waypoints for the hoop, I did a bit more testing, and ran an entire loop. Then I had to put together a complete course and adjust some waypoint locations, however the testing period was over. I made the adjustments in the spreadsheet and uploaded it to the car. I had not tested the full programmed course, so I crossed my fingers, sighted-in the initial angle, calibrated the gyro, and sent it off at the starting "gun". To my surprise and relief, all the adjustments were right on, and the car navigated perfectly. My time was about 50 seconds - 30 = 20 seconds (I think). This was faster than any previous official time, so just like last year I held the course record, at least for a brief time. I maintained my first place throughout the heat, until round 8 when team 0x27 clocked a very fast time by plowing straight through barrels and through the hoop. It was a huge 1:5 scale car and had no problem swatting the barrels aside. I believe their time, with hoop deduction, was 6 seconds.
Start of heat 1
The second round, I was feeling good. I would have to turn the speed up very high to beat 0x27, and I wasn’t ready to do that yet. So, instead I cranked it up to 40% (1700 us) which is still pretty fast. I changed nothing else, including the waypoints. I lined it up, and it took off. As it rounded the first turn and headed to the hoop, I could tell something was a little off. It was a tad to the right and headed very close to a barrel. As it went by, the front right tire nicked the barrel, breaking the steering linkage. My initial reaction was that the run was over, and I was about to hit the kill switch. I let it go, though, just out of curiosity. The bump had steered the car a bit to the left, and it went directly through the hoop. As it continued to the second turn I had a glimmer of hope that it may somehow still be able to steer. All the turns were right-hand, which favored the left (and unbroken) wheel. As it shakily rounded the turn I started to smile. It rounded the third turn a bit off course, but close enough to keep going. With dead reckoning, any small course errors near the beginning can mean total failure the further you go. It headed down the straightaway, going wide left, and nearing the boundary poles. It stayed in, though and headed around the final turn. By this point it was far ahead of me, and I didn’t get to see it go for the finish line. I counted off a few seconds, trying to estimate when it would cross the finish line, then hit the kill switch. I could tell from the announcements and applause that it must have made it! I jogged around the corner to see it lying about ten feet past the finish line, one wheel folded up. This point hadn’t gone unnoticed, by the announcer, who was graciously pointing it out to the crowd. As my time came back, I had even more reason to smile. It had completed the course, with a broken steering linkage, in 9.4 seconds (including bonus). I was now only 5 seconds outside of first!
Stepping it up
Now my attention was turned to fixing the steering. I didn't have a replacement for the part that had broken, but only the mounting hole had broken. Fortunately, there were other mounting holes available, so the fix was quick. Now, I waited for Team 0x27. I need to see just how fast I might have to go in the final round. As it turns out, they bested their previous time, and were now at 2 seconds. So, this meant that it was time to pull out all the stops. Go for broke. I felt my second place was pretty secure (only to find out later that it wasn’t). My car, with its Velineon brushless motor and lipo battery is capable of some insanely fast speeds. So I decided to crank it up to 100% throttle. I had never tested it at anything close to this speed. If it made it around without crashing, it would probably be well under 30 seconds--remember, it had just done 40 seconds (unadjusted) at 40% throttle and a broken wheel. So, I made the changes, and decided to do a bit of testing.
As no testing is allowed on the course, I went to a neighboring parking lot to test it. There wasn’t as much space there, but I really wanted to see how it would do in a straight line, and around a single turn. I pointed the car straight down a corridor, and let her rip. It took off like a banshee, the slipper clutch screaming wildly to keep the front wheels on the ground. Instantly, it veers at about a 20 degree angle (doh my first waypoint was at an angle!) It’s screaming along, headed perpendicular to a curb, and still picking up speed. I panick, fumbling for the kill switch, but it’s too late. The car slams into the curb with such force that the entire steering assembly is severed. I see the main chassis fly in one direction, and the steering assembly in another. I know immediately that my day is over. I’m happy that I did well for two rounds, but frustrated at my stupidity. This is exactly why I never tested it at these speeds. Failures are catastrophic.
Assessing the damage
Cursing myself, I go pick up the pieces. The brushless controller, with its huge heat sink has separated in 3 parts. The LCD has broken from its mounting and separated from the cable. The car is lifeless. The chassis is sheared in two. I take it back to the pit to more closely assess the condition. I plug everything back together and flip the switch. It turns on. I pull the trigger, and the wheels spin. The steering servo is OK also. Hmmm. I put the two pieces of the chassis together--it’s a pretty clean break.
Speed control in bad shape
It’s announced that the next heat will start in about 45 min. A crazy idea starts to form. I need some epoxy, and some kind of stiff strut. I raid Roadrunner’s tool kit for some hex wrenches. I go in search of some epoxy, and one of the aero guys lends me a bit. Meanwhile sparkfun goes looking for some as well. I apply some of the epoxy to the hex keys and hold them in place on the bottom of the chassis. My son, Eric helps with the application, while I hold it together. Sparkfun comes to the rescue with a larger tube, and we start liberally applying the epoxy. Within about about 20 minutes it’s firm enough to stay together on its own weight, but still feels much too soft to run on. On the suggestion of a fellow competitor, I borrow a head gun, hoping to accelerate the curing process. It’s 5 min. epoxy, but that seems awfully optimistic.
Epoxy patch, hex keys and all
The first round of heat 3 starts, and I’m done with the heat gun. The epoxy still isn’t hard to the touch, but it’s starting to feel pretty strong. I put it on the ground a run it around a bit. Seems OK. I can’t believe I’m about to race after what I had just witnessed 45 minutes ago. I get everything set for the run. My heat comes up, and I line up next to the monster truck (a stampede). The race starts, and my car jogs off the line for a few feet. See, with the speed dialed up so high, I didn’t want it to jump the start line too much, so I had it go out slowly for the first few feet before accelerating. This is a deviation from the other two runs, where the car immediately jumped out to the lead and stayed there. This time, though, the monster truck gets a few feet out in front, and when my car finally decides to take off, it angles to the first waypoint and slams aggressively into the back of the monster truck, flipping them both over. My run is over, and I have unfortunately ruined the other car’s run as well. Surprisingly, the epoxy holds, and the chassis is fine.
Pile-up on starting line
Now, I wait for the other heats, feeling confident that I’ve got 2nd place in the bag. My most probable competitor, Roadrunner, has an amazing heat which involves weaving around multiple barrels, through the hoop, breaking a wheel, and ultimately crashing out on the 3rd turn. He was on pace to beat me. The last heat features team 0x27 which inexplicably has a glitch at the starting line, and doesn’t make it to the first turn. GPS jamming, they thought (?) I see data bus head out around the first turn, not thinking much of it. When it flies around the last turn about 30 seconds later, and catches some major air crossing the finish line, I have flashbacks to the previous year when I had been beaten in the very last heat. Fortunately for me, data bus missed the hoop--his 37 second lap time would have torpedoed me. I’m lucky for once, I guess.
Data Bus, catching air
Mano a Mano
As a final competition, just for fun, I am asked if I want to go head to head with team 0x27, and I accept. We both go to line-up, but realize that we want the same starting position. We separate the cars by about a foot, my sleek and sporty Losi XXX next to the 1:5 scale behemoth. I’m assured that the proximity won’t be a problem, since team 0x27’s car will be gone before minuteman has a chance to get in the way. The race starts, and I smile when minuteman gets out to the first corner well ahead of the other car. Unfortunately, that’s where the fun ends.
I have never tested minuteman to go all-out. It’s just too fast. Under manual control I have briefly taken it to full throttle, and any small twitches of the steering usually result in a heinous roll that makes me wonder what I’ve destroyed. My code is a little better than that, though and knows to apply brakes when approaching a waypoint. The braking level has been set to not cause skidding, but that may not apply at really high speeds. As the car approaches the first turn, it applies brakes, fishtails a bit, and swerves, causing a rollover. When the steering null point is off, minuteman tends to swerve at the last moment to hit a waypoint. The previous crash and re-attachment of the front end had resulted in a change in the steering null, as well as the hard braking at high speed was a recipe for failure.
Goliath 1 - David 0
Team 0x27 finished the course in an (unofficial) record time of 27 seconds, Their car did amazingly well, and was easily the most robust. The huge 1:5 scale size allowed it to plow through barrels and glide over potholes with relative impunity. They had worked on obstacle avoidance software, but it was apparently un-needed and not used. They benefitted from good programmers, financial support from sponsors, and top notch navigation equipment not available to most hobby enthusiasts. Their GPS unit was an industrial-grade Hemisphere, the kind of equipment that isn’t listed with a price, just a “contact us”. It has a 20Hz update rate, and didn’t seem to have any trouble navigating on the side of the building where most GPS’s get lost. In chatting with their lead programmer, it sounds like their algorithms were very robust, and they apparently had about 3000 lines of code. It was an impressive project all around.
It appears now that vehicles will be going fast enough that an average “basher” has no chance of winning. Stampede? Grasshopper? Emaxx? electric wheelchair? All of these will likely be too ponderous to navigate turns at 20+ mph. I think you will need a well-tuned race car to take the top spot. Fortunately for me, my Losi XXX already fits that bill. It would be nice to have a 1:5 scale brushless monster, but that’s not in my budget. Maybe it’s time to start looking for a sponsor.
Minuteman is set-up for a dirt track with jumps and washboards. This means the suspension is plush, and tends to roll when cornering at high speed. To counter this, I’ll lower the suspension, using shock spacers, and stiffen it up with different springs and more viscous oil. I’ll play with the toe and camber and hopefully end up with a car that zips through the turns on pavement. I considered going with a road-specific car, maybe AWD. With the rough conditions of the sparkfun parking lot, though, I guess I’ll stick with the Losi.
On the software side, there isn’t much to do. I’ll probably add in some cross-track correction, and smarter speed management (closed loop). Maybe at some point I’ll play around with object detection. I’m thinking opencv on an android or something. I’d also like to be able to edit waypoints over bluetooth, using my android. It’s hard to plan too much without knowing if Sparkfun will decide to drastically change the rules. We’ll just have to wait and see.
And finally, I’d like to thank Sparkfun for making it all happen. From the organizers, to the volunteers, the guy who found some epoxy for me, and the nice lady trying to interview socially-awkward engineers about their nerdy projects. The cool announcer, the race director, all the guys that loaded and unloaded heavy equipment. You’re all awesome!