Tag Archives: SparkFun

AVC – 2014 Report

The Sparkfun Autonomous Vehicle Competition this year was lots of fun, as usual. I ran a similar setup to last year, with the same chassis, mBed microcontroller, Magnetometer & GPS. The only difference was a new controller PCB with some extra features, and some changes in the code. The new control board has some incremental improvements from last year, with on-board battery monitor, better layout, built in Mux to multiplex RC and Autonomous control, and an on-board RS232-TLL converter (MAX3221).

AVC 2014 controller PCB v3.2

AVC 2014 controller PCB v3.2

 

AVC 2014 controller board v3.2

AVC 2014 controller board v3.2

The battery monitor uses a shift register to control the 8 LEDs, so I only need 4 IO lines to control 8 LEDs. The mux uses a 74S157D to multiplex the PWM lines from the RC receiver and mBed out to the RC car steering servo and speed controller. By changing the mux select line, I can control the RC car from the RC controller or the mBed, either forced with a jumper (RC_SEL) or by using channel 3 on my RC transmitter. To decode the channel 3 signal and give me a digital output I use a Pololu RC Switch with Digital Output.

The other useful addition was a 1F super capacitor, attached to the vBAT pin on the mBed. One problem from last year was that all my log files were dated “1/1/1970” as when the mBed boots the clock isn’t set, and I create the log file on boot. I set the clock once I have a GPS lock, with the time from the GPS, but until I have GPS lock, I don’t know what the time is. The mBed has a real time clock, I just need to keep it powered between power downs.

Supplying 3.3v to vBAT keeps the RTC running, even when the main power is off. Usually, you would use a small lithium coil cell, but I had just bought some super caps to play with and they seemed perfect. I used a diode and resistor from the 3.3v power rail to charge the super cap while the power is on and limit the charge current. It works perfectly and kept the clock running for days while the main power was discounted. Now, all my log files have the correct date and time, and once I get a good GPS lock, I reset the RTC, just in case it has drifted.

The bot was ready a couple of weeks before the competition, but as usual, I didn’t have time to do much testing, and my flight only got in to Boulder the night before the competition, so I couldn’t spend the day before at the course. The day of the competition arrived and I got there early to setup and do some last minute testing.

I was in group 7 of the Peloton class. Team : “Mostly Robots”. Robot : “Eleanor”.

There are 3 heats (3 attempts at the course). The are timed, with bonus points for navigating obstacles.

AVC Ground Course ((c) Sparkfun)

AVC Ground Course ((c) Sparkfun)

Heat 1

Heat 1 got off to a good start.  I’m always apprehensive as the bot approaches the first corner. Anyone can build a bot that just drives in a straight line and crashes in to the fence. Turning at the first corner autonomously is a good feeling ! 🙂 The bot was swerving badly on the straight, more than last year. Same old magnetometer issues from last year, but it turned perfectly on the 1st corner. Its programmed to avoid the barrels and zig-zag through them, which it did, and made the 2nd corner. However on the 3rd straight it started to wobble more and zig-zag quite badly instead of driving in a straight line. It made the 3rd corner, but then started to get a bit confused. It spun round in circles a couple of times, then crashed in to a bollard. Disappointing, but not bad for a first run.

AVC 2014 - Heat 1 GPS log

AVC 2014 – Heat 1 GPS log

Heat 2

The less said about heat 2 the better :-). It all went wrong, and straight off the start line the bot crashed in the kerb.

Heat 3

Heat 3 started well, the bot made the 1st corner, avoided the barrels and made the 2nd corner. But on the back straight got confused again and crashed in to the kerb.

AVC 2014 - Heat 3 GPS log

AVC 2014 – Heat 3 GPS log

In the end, a fun but disappointing day, as I know the bot can navigate autonomously, as it makes it round three quarters of the course, but the gremlins stopped me from completing all of the three heats.

I came 14th overall out of 25 in my class. Respectable, but I could have done better.

The problem is always the magnetometer. I need to find some time before the next event to work on fine tuning it and experimenting with some different positions to stop interference from the car’s motor and servos.

Roll on next year ! 🙂

 

AVC – All ready for AVC2014 next week

So, my bot is ready (ish) for this weekend. I have the new controller board installed. Only found 3 mistakes (and isolated ground, the wrong supply voltage on the RS232 header, and the SD card holder hasn’t soldered correctly.) everything else worked. I have fixed the first two, but I cant reflow the board again to fix the SD card holder, as I’ve already soldered all the plastic headers on. I can live without the SD card, I will use the internal flash disk on the mBed. It has a few restrictions, but I only store a waypoint file and a config file on it.

AVC 2014 Robot

AVC 2014 Robot

I’m running an updated version of last years code. But seeing as it worked last year, I’l stick with it and improve it slightly. Now I have a reliable xBee connection, the compass calibration process is much easier. No more cables. I will try this year to calibrate the compass, with the main motor running (albeit slowly) to ensure any interference from the motor is present in the calibration settings.

However, I’ve been so busy recently, that again I have not manage to complete a full outside test of the bot before getting on a plane for Boulder ! 😦 the first full test will be in the car park in the hotel the night before.

Not to self – find more time to tinker next year before the competition !

Wish me luck …

AVC – Round 1 video with on board camera

This is a video of my first fully autonomous round 1 attempt. I made the first corner and avoided two barrels, but then ran in to the inside fence. I don’t have any footage from the other rounds as my camera gave up shortly afterwards.

AVC – Outdoor testing video compilation

This is a video of the first few outdoor test runs of my AVC robot. As you can see, I had a lot of magnetometer issues, but eventually, the last run does make it to the waypoint, albeit a rather scenic route. 🙂

AVC – Competition Day

The morning of the competition arrived. After getting up early so I could be at the course as it opened to spend the final hour tuning my way points, I released when I arrived at the venue, I’d left my wallet in the hotel, and had to drive back to the hotel and get it, taking all the time I would have had to practice, driving up and down the motorway in Boulder. 😦

AVC 2013 Ground Course ((c) Sparkfun)

AVC 2013 Ground Course ((c) Sparkfun)

AVC 2013 Waypoints v1

AVC 2013 Waypoints v1

The competition began. I was in heat 8, so I had a good 45 minutes to tinker before my first run. I mounted a GoPro and double checked my way pints on Google Maps. I was kind of pleased to see that almost no one in the first few heats made it past the first corner. In fact by heat 8, I think only 2 robots had made it round the course, out of about 30.

It was time for my first run. I was actually nervous !? Even thought I knew I wouldn’t win, I wanted to make it round the course, and not look like an idiot. Also I was the only Brit in a sea of Yanks … I need to represent my country ! 🙂

The countdown began, then Go! I pressed the big red button and my bot shot off ! To my surprise and great relief in the right direction !!! and to my amazement, it made the first corner and turned 90 degrees at exactly the right waypoint, on to the second straight. My heart was pounding as my bot swerved to the 2nd way point. I had 3 waypoints on the second straight to avoid the barrels. It swerved and missed the first barrel, I was actually amazed it was working !

I turned again and aimed to miss the second barrel … but then it didn’t straighten up and started to veer in to the centre of the course … within a few seconds it had hit the boundary fencing, and toppled over. Disaster! I was out in the first round mid-way up the second straight.

Not bad all things considered. Seeing as it was the first time all that code had run at the same time, completely autonomously. Although I was disappointed, I was actually quite chuffed it had made the first corner and hit the first three waypoints. My code was working !
During the beak between rounds I debugged the code and analysed the log from the first run. The bot was working, but was veering to the left, so I adjusted the 3rd waypoint to pull the bot further in to the centre of the course.

The second round. Go! I hit the button and my bot shoots off in the right direction again, but where it had neatly turned 90 degree at the first way point on the first round, this time, it span in circles at the first way point, driving in endless circles until it hit a hay bail.

In theory that shouldn’t be possible. The code should have dropped out of the loop when the waypoint was close, plus the circle was also tight, i.e. full lock. There must be something else wrong.

I spent lunch time debugging the logs and analysing the data. To my horror, the magnetometer was completely out of whack. It would reading north to be 90 degree from where it should be. And in various walking tests didn’t even change readings as I rotated the bot. My magnetometer reading were the plague of this project.

I decided to run another calibration over lunch, it takes a while, as I have to change some connections as I can’t do it reliably over xBee, so I run the calibration over a direct serial connection.

It took about 30 mins to complete the calibration and the bot was reading north again. I had about 20 minutes left of lunch to test on the course before the final heat. I pressed the button for a final practice and the bot shot off in the right direction, first waypoint hit, second way point hit, barrel avoided. Third way point hit, this was the furthest I’d ever got on the course. The back straight was perfect. I purposely avoided the hoop, I wanted to get round, and wasn’t so bothered about points. On the third straight, it actually hit the ramp and completed a jump, without toppling. It hit the final corner turned perfectly and flew over the finish line ! I had completed the course perfectly ! Shame it was over lunch in a practice session and no one saw ! 😦 I do have some video from the GoPro to prove it through !
I decide not to touch ANYTHING and wait for the final round. More and more bots were completing the course. Each run they were getting better. It was now or never.

Finally the third round was here. Nate (The Owner of SparkFun!) was my referee for the final round. No pressure then !?

The referee counted down 5,4,3,2,1 – Go ! I paused slightly to let the faster bots shoot off before me, to try and minimise any potential collisions. Previous rounds had a number of collisions right off the start line, where out of control bots took smaller bots out completely. I saw one completely smashed to pieces. My bot shot off in the right direction … turned perfectly on the first courser … weaved perfectly in through the barrels, detoured slightly wide at the second corner, my heart pounded as it headed for the fence, but with a meter to go, it turned sharply and headed off past the hoop. It started to oscillate on the back straight – shame I never got the PID controller tuned I thought – the bot headed straight for the cameraman on the 3rd corner, again with a meter to spare turned sharply 90 degrees and headed down the final straight … missing the jump (shame. It made it perfectly in the practice, and I could have got some bonus points). The curb of the final corner loomed, the bot shimmied perfectly round it, turn sharply on the final straight and headed for the finish line. I held my breath as the bot bounced over the finish line perfectly, running over the SparkFun GoPro that was balanced on the start/finish line capturing the action … 2 or 3 meters after the finish line it ground to a halt. I was so happy ! I think I actually kissed it (which someone caught on camera) 3 months of late nights and constant problems culminated on a perfect run on the final round. I was elated. I’ll post a video …

What’s next ?

I want to finish the bot off, even though the competition is over. Not only to have something ready if I manage to find a way to enter again next year, but also to understand what’s wrong. I still don’t fully understand why the magnetometer is so shonky. It’s not the device, I’ve tried 3 different devices, and they all do the same strange things.

At the competition, nearly all the other bots has their magnetometer in the car, on the main PCB, not floating on a broom handle above it like mine. I need to understand what my issues are.

I want to finish the PID tuning and increase the speed. The RC chassis is very fast, and I’m running at about 1/10th speed. If I can remove the broom handle, the bot won’t topple over so easily and can turn faster. I also want to include a proportional speed control so the bot accelerates fast if it’s far away and on a straight heading, then brakes to make the turn as it gets close to the waypoint.

I also want to finish the obstacle avoidance, so if I do head for a barrel, I can veer away from it.

All in all and very pleasant way to spend a weekend. I got to talk to lot of interesting people with a similar passion, I got to spend the weekend in 90 degree sunshine and I got to indulge my passion for robotics and spend the weekend geeking out … 🙂

Thanks to everyone at SparkFun for running the event and organising it so well.

Roll on AVC 2014 … 🙂

Other posts in this series :

AVC – First test run

The mBed versions of the AVC PCBs arrived. I built the first version, with surface mount components in my oven at home. It works first time. It turns out I made one mistake on the PCB, using the wrong ratio SMD resistors with the battery divider in to the mBed, so I had to take them off and modify it with standard through hole resistors, as I couldn’t hand solder the 0602 surface mount resistors. I made the modification for the SPI connection for the IMU, and swapped a couple of sensor to different pins to give me SPI and Serial in the right places.

AVC 2013 mBed Custom PCB

AVC 2013 mBed Custom PCB

AVC 2013 mBed Custom PCB

AVC 2013 mBed Custom PCB

AVC 2013 mBed Custom PCB

AVC 2013 mBed Custom PCB

I mounted the circuit in a Tupperware box on the car to keep it water tight.

My first outside test of the complete system was very exciting, but a little disappointing. Not only did I manage to run my wife over with the car, giving her a nasty bruise, but also the car seemed to like to take the scenic route to the way point, rather than a more direct route. All down to magnetometer issues again. I was still getting erroneous and unstable readings. In fact this plagued me from start to finish on this project, and still hasn’t gone away.

The only solution I have found to improving the magnetometer readings is to re-run the magnetometer re-calibration process regularly (before each run). The numbers always come out slightly different?

The first end to end test of the system in my garden was one week before the competition. I still hadn’t written a lot of the other functions in the code. Sections of the code like; how to tell if I had reached a waypoint, loading way points from SD, obstacle avoidance using the sonar, and tuning the PID parameters. I also hadn’t actually mapped my waypoints for the route I was going to take through the course.

The PID tuning would have to wait. I was getting pretty good steering results just with the “P” terms. This would mean I was in danger of oscillations, but that was the least of my worries. I could hardly drive in a straight line at the moment …

I didn’t have time to write any sonar obstacle avoidance code. I had a plan to read the distance data from the sonar and if an object got within 2 metres, add an offset in to the steering calculation to veer slightly left or right to miss the object. However, I hadn’t quite worked out how to tell if I had “passed” it to remove the offset, as I only had a forward facing sonar. The other option was to just stop the bot if an object appeared less than 20cm in front of the bot, stop, turn a few degrees, go forwards, then continue under GPS control… I’ll get round to adding this later …

I arrived in the US for a conference about a week before the competition and spent the evenings in the hotel writing the missing code. I wrote a basic file reader to load way points and basic config data from file, plus as my xBee worked for about 2m at best, I wrote a simple logging function, which meant I had some debug data after each test run to investigate. My waypoint algorithm was relatively simple;

  1. Calculate the heading and distance to the next way point
  2. Use the PID control to steer on that heading.
  3. If the distance to the way point was less than 2m meters, we’re very close. At this point these it a danger the bot will drive in circles, as the turning radius is greater that the heading it needs to hit the way point exactly. So, once we get close, I no change the steering to steer to the waypoint, instead, continue on the heading I was on just before we got close. You can assume the heading I was on would hit the waypoint pretty close. So, if I stay on that heading, and monitor the GPS vector to the waypoint, as I pass the way point I should see the GPS vector increase to 90 degrees as I pass by the waypoint. i.e. the vector will go from straight ahead, to 10, 20, 30, 45, eventually 90 degrees. At this point I’m within 2m meters and its 45 degrees or 90 degrees to my left or right, so, that’s a pretty good assumption of hitting the way point, so I assume I’ve passed it, and move on to the next way point.
  4. Once the bot has visited all the way point it has loaded, it stops. Course complete.
Way Point Diagram

Way Point Diagram

I didn’t have time to write the obstacle avoidance code or tune the PID in time for the competition.

The day before the competition I spent the afternoon at the location planning the course and testing the code. I rewrote my magnetometer code again, this time using my own simple trigonometry rather than the library function. Plus I debugged the “hitting the way point” logic. By sunset, I’d navigated to a series of way points for the first time, but still careering off course occasionally. In addition I suddenly remembered that I hadn’t compensated for magnetic vs. true north, so added some Magnetic deviation code. This link has a great calculator for magnetic variance. It shows that Colorado has a deviation of about 8 degree, which would have been a big issue if I hadn’t remembered to compensate for it.

Other posts in this series :

AVC – Problems

The basic prototype worked on the bench, but as I built it on to the chassis, it started to have issues. The magnetometer would give very random and unreliable readings. I kind of assumed I’ve get some interference, but this was reading north sometimes 180 degree out. In addition, the reading changed when the motors ran and the servos moved. I assumed I was getting magnetic flux from the motors and servos, and this was interfering with the magnetometer. However, without the motors running, I was also getting bad drift from the magnetometer. For example, I would point the car north, take a magnetometer reading, then rotate the car 360 degrees, the reading wouldn’t give me a 360 change. When I get back to north I would read 280 odd degrees, in addition, if I did the same experiment in different places in the room, or at different times, I got different readings. The magnetometer be useless if I couldn’t reliably know where “north” was.

The xBee also had issues, and seemed to only work up to about 1-2m away … which wasn’t very useful. I only had 1mW series 1 devices, which on the data sheet said they’d get 600m, so I expected a bit better than 2m, but I assume this was also due to interference. This wasn’t a deal breaker, as most of the testing could be done with the car no actually driving. All the debugging was around the steering, so 2m was fine to just not have a cable in the way. But it was frustrating … I had to follow the car around carrying the laptop, instead of just sitting in the garden at a table and taking reading as it drove around.

I stuck with the xBee but I moved the magnetometer away from the main board and chassis, to try and reduce the interference. I assumed the interference was magnetic flux coming from the huge brushless motor and large powerful steering servo in the car. If I mounted the magnetometer away from these, perhaps I’d get a more reliable reading. And so was born “broom-handle-bot”

SparkFun AVC 2013 autonomous robot

SparkFun AVC 2013 autonomous robot

While working on the prototype I was also researching better GPS solutions. The basic GPS module I was using only had an accuracy of about 2-5m. This would be tricky to avoid a barrel or hit a jump 1m wide. I had stumbled across SBAS while research GPS issues and this potentially could give me accuracy down to 1-2m. Much better. You can read the wiki page for more details, but effectively (IIUIC) the SBAS system sends a separate signal from a different set of satellites that contains data to improve the accuracy of the main GPS signal. It compensates for atmospheric interface, and other transmission errors. There are different SBAS systems in different parts of the world, WAAS in North America and GLONASS in Europe. I would need a GPS receiver that supported both. Again, with some googling, I found NaviLock and the NL-622MP MD6 GPS Receiver. The data sheet confirmed it supported WAAS and GLONASS, it uses the latest u-Blox chipset, and came in a handy mountable self-contained puck. I ordered one and it arrived. The only downside was the output was RS232 (+/- 15v) not TTL, so I’d need a level shifter board to connect it to the mBed. If I had spent more time looking, they do do a TTL version, which would have been easier …

The very first test of the new GPS puck was transformational. The old GPS wouldn’t get a lock inside my house, which made testing a real pain. I would have to write the code, upload it, then disconnect the system, walk outside in to the garden, test it in the cold, then come back in and debug it, then repeat. This wouldn’t have been so bad, if this was on a Sunday afternoon, but due to my job and family commitments, nearly all my tinkering was done at night, between the hours of 10pm and 2am. It was also the back end of winter, and still snowy some weekend. Testing in the garden at midnight in the snow wasn’t fun.
The new GPS got a lock inside. Plus it got a lock really quickly, within seconds. The old GPS took minutes. It was clear from the first few outside tests that the accuracy was much better and the reading more stable. The GPS used the uBlox 6 chipset, with came with a very detailed and advance desktop config and debug utility.

The basic system was working. However I still had magnetometer issues. The reading would vary wildly if the magnetometer was close to the car. Even if it was some distance way, it wasn’t reliable. It would point north, then I would rotate it 180 and it wouldn’t point S, it would read 160 degrees, then I point it north again and it would read -30. If I rotated it 360 degrees sometimes it didn’t move, sometimes it rotated 250 degrees. I tried lots of different configurations. Even on the bench with no magnets or metal close it wasn’t reliable.
After some extensive Googling, it seemed I need to perform a calibration. This would calibrate out basic interference if the interference was constant, like a steel mounting screw that was always in the same relative position to the sensor. This link explains the process. You take lots of readings from every orientation, imaging mounting the sensor on gimbals and spinning it on all axis, so the tip of the sensor scribes the outline of a sphere. Ideally you want a data cloud of points in all orientations from all three sensors; x, y & z.
Once you have the data set you need to do three things;

  1. You need to remove “erroneous” readings, called outliners. There are clearly (statistically) incorrect. These are obvious to spot manually as the sit outside the circle/sphere of normal readings.
  2. You need to normalise the data in all three axis, so all the maximum readings from all the of the x, y & z sensors have the same magnitude
  3. You need to shift the data so to each set of readings is centred on zero.

Imagine a point cloud that is slightly oval shaped. The normalisation process shifts and scales the cloud so it’s a perfect circle, orgined around zero.These scaling and offset numbers are then used to scale the raw reading to give better accuracy.

Compass Calibration - Before

Compass Calibration – Before

Compass Calibration - After

Compass Calibration – After

This worked to an extent, and the magnetometer was noticeably more accurate and stable, but I still had problems. So I thought I’d tried a different approach. I had an IMU sensor from a previous project. This sensor has 9 DoF (gyro, accelerometer & magnetometer) plus a CPU and contains a kalman filter to process the data. It will give Euler angles, and all I was after was “yaw” – Phi. The issue was the device was not I2C, but serial or SPI. The serial interface had complex packet structure and I didn’t have time to write and debug a parser, so I opted for SPI. I modified the code to read SPI and got a basic Phi reading from the device.
This was more accurate. But it now had a different problem. The issue with yaw calculating with a 9 DoF board, is the yaw cannot use the accelerometer data, as it rotates around the accelerometer axis so it never changes. It can only merge the magnetometer and gyro data. And this is susceptible to gyro drift. This manifested itself in the yaw reading slowing rotating even when the unit was stationary. There was a function in the devices to zero the gyros when the unit was at a known stationary position, but after time the drift returned. That clearly wasn’t going to work.

The final option was to try the same basic magnetometer code, but with these IMU magnetometer readings. You can read all the raw gyro, accelerometer, magnetometer readings, plus the processed (filtered) version, plus the Euler angles from the device.
It turned out the process (filtered) raw magnetometer readings were pretty stable. So I had my final solution. However … about a week before the competition!

Other posts in this series :

AVC – Switching from Arduino to mBed

Once the initial Arduino prototype was built I started having problems with the board. I rigged it on the bench with two servos attached directly to the speed and steering outputs. The code kept crashing and the board would hang. Normally in strange ways. I would comment out lines of code, and it would be more stable, then I’d put different code in and it would crash again. It seemed to have little to do with the content of the code, and more to do with the *amount* of code…

I had this problem before with my balance bot. The code randomly crashed there too and if you run some basic compiler tools on the code, the code is very close to the RAM limit of the microcontroller.

I had been looking at mBed for a few months and had bought a board to play with and this seemed like a perfect project to learn mBed on. I could have switched to an Arduino Mega, which is what I did on my Balance Bot, but the Mega is physically so much larger, and I wanted to fit the resulting controller inside the RC car, so I bit the bullet and scrapped everything I’d done to date, and started again with mBed. There’s nothing better than a looming deadline and nothing currently working to focus the mind on learning a new platform. 🙂

I had an LPC1768 mBed which had much better specs. I would classify its advantages over Arduino as :

  • Faster – 100 MHz vs. 16 MHz. Six times more instructions per second means more power. I could read the GPS and magnetometer at a much faster frequency and baud giving me better accuracy and control.
  • More hardware serial ports – 1 UART on the Arduino vs. 3 UARTs on the mBed – I needed a fast serial port for the GPS and one for debugging via xBee.
  • Hardware I2C for the magnetometer.
  • More RAM (32 KB vs. 2KB on the Arduino) more than enough to run all the various libraries and calculations without crashing.
  • Hardware floating point – This is important for GPS as the LAT/LON coordinates are all floating point numbers. There would be lots of complex trigonometry with floating point numbers happening every second. Hardware floating point would be a huge improvement in performance.
  • The last benefit was unexpected. The mBed has an RTOS library that allows you to run multiple independent threads. This made the code design much simpler. Rather than having one big main loop, that has to do everything, I could split up the tasks in the threads. E.g. one just ingesting and parsing GPS NEMA data, one outputting debug information, one running the PID control loop, etc.

The design changed from Arduino to mBed over night and I planned a new board. Although this has only taken a couple of blog pages to explain, it took about 6 weeks in elapsed time. Lots of late night debugging, scratching my head, reading on the interweb and chatting to people on forums.

I designed another PCB for the mBed solution and using the cheap PCB fabs I calculated it would arrive a couple of weeks before the competition. I had no choice but to commit to this design. There would be no time to reinvent the solution a third time. In fact if it didn’t go well, I’d be soldering it on the plane, if I wasn’t lucky … 🙂

AVC 2013 mBed Custom PCB v2.1 layout

AVC 2013 mBed Custom PCB v2.1 layout

I added a battery meter to the final PCB design as a last minute addition. I had seen this video on the EEVblog describing the LM3914 LED driver. The worked example on the video was exactly what I needed to monitor the charge of my LiPo’s, so I added the circuit and LEDs to the final PCB. This would give me an easy visual reading of the battery condition before each run, reducing the risk of the run failing due to a low battery. In retrospect, I perhaps should have done this a different way. The LED driver was actually more complex and more expensive that driving the LEDs from the mBed directly. I have enough IO pins and I’m already taking an ADC reading of the battery voltage, but it seemed like a good idea at the time.

I sent the PCB design off which would give me a few weeks to convert the code.

I should point out here why I like having custom PCBs, instead of wire wrap or breadboards. I do jump to custom PCB very quickly in my prototyping phase. The simple answer is reliability. In the past I have run projects from a breadboard. But as always happens you drop the project, or it has to travel somewhere in a box, and suddenly two of the wires have popped out of the bread board. Typically you now waste hours tracing every connection to work out where they went and which ones have popped out. Plus with moving robots, the momentum of the bot tends to throw the boards around unless they are stuck down well, giving the same problem with wires coming lose. I like having a custom PCB. They are very cheap and easy to make (once you’ve used Eagle a few times) and they make the circuit an order of magnitude more reliable, much smaller and less messy. In addition they are just as easy to change if something is wrong, you can cut a trace and solder in a jumper wire in. Plus things like xBee, which has 2mm pitch legs, aren’t breadboard friendly, so you end up with breakout boards, again that come lose. Custom PCBs are just easy, cheap, and more reliable.

I started by porting the existing Arduino GPS and magnetometer libraries to mBed, which meant the bulk of my code would just migrate to the new platform. The mBed platform is fantastic. Its “proper” C++, not the cut down libraries of Arduino. I got things like printf back 🙂 which are huge resource hogs on Arduino.

There were other benefits too. There is a simple SD Card library, so I could store my waypoints on an SD card, which would mean making small edits during the competition wouldn’t mean I needed to recompile the code and upload it to the mBed, I could just edit the text file in an editor and re-read them.

I structured my code slightly differently to make use of the multithreading benefits of mBed too. I had three threads;

  • The first was dedicated to just ingesting the GPS NEMA strings and converting them in to numbers that were stored in a global variable structure. I ran the GPS at 4 Hz to give me good accuracy.
  • The second thread was dedicated to providing debug data. It ran every second, (or every 2 seconds) and dumped all the current readings of all the sensors and internal variables over the xBee. These would then be read by the desktop app and displayed in a user friendly way.
  • The final thread was the main loop. This ran the PID control and used the data from the GPS structure and magnetometer to feed the PID, and then set the steering servo with the output of the PID.

I got a prototype working on an mBed development board while I waited for the custom PCB to arrive. I used wire wrap as usual, with some jumper leads to plug in to the mBed. The prototype worked OK and I started to get a basic system working.

AVC 2013 mBed wire wrap prototype

AVC 2013 mBed wire wrap prototype

 

AVC 2013 mBed wire wrap prototype

AVC 2013 mBed wire wrap prototype

Here’s the test video the full system working on the bench for the first time. You can see the third channel switch the control between RC and mBed. During mBed control, the compass on the mBed controls the steering servo, and the wheels track the position of the compass. During RC control, the transmitter has control and the mBed does nothing.

Other posts in this series :

AVC – How difficult can it be ?

Ever since the SparkFun AVC started a few years ago, I’ve wanted to enter. But living in the UK made it difficult to justify the expense of flying to Colorado for a robot competition. This year, purely coincidentally I was in the US for a conference the week before the competition. The opportunity was there to enter so I decided to build a robot and enter the SparkFun AVC 2013.

The AVC on paper sounds simple 🙂 … Build an autonomous vehicle that can navigate an obstacle course without human intervention. The course is timed and you get bonus points for achieving certain tasks (going under a hoop, going over a ramp, etc.).

I decided to enter the ground competition, as the aerial challenge sounded way more complex. I’ve never built an aerial robot, so I thought I stick to something I had experience in. I decided to base my robot on a radio controller car chassis. I had an HPi Racing Savage Flux XS, which was perfect. It’s a 4×4 mini monster truck, that’s fast and simple. Just two controls, steering and speed. In addition, the radio it comes with has three channels, so I could use the 3rd channel as a control to switch between radio control and autonomous control, and quickly switch back to radio control during testing in the event it went berserk and headed for a tree.

My bot has a GPS receiver to provide its current position, and a magnetometer to provide its current heading. A microcontroller controls the speed and steering servos and a Radio Control switch can switch between autonomous control and manual control using the third channel. In addition the course has obstacles, so I need some basic obstacle avoidance. I used a small sonar to provide the distance to obstacles directly in front.

I needed a way to monitor and debug the car while it was hurtling round my garden during testing. I decide to add an xBee so I could get basic debug information from the car in real time, and (as I did with the balance bot) write a simple PC desktop app to display them in a user friendly way.

AVC 2013 High level system diagram

AVC 2013 High level system diagram

SparkFun provide the course details with all the GPS coordinates. The course is roughly rectangular with four sides, a start finish straight, a side with 4 barrels as obstacles, a side with a hoop to go under for bonus points and a side with a small ramp to jump, again for bonus points. The course is about 200 feet square, with the course being about 20 feet wide. With basic GPS accuracy of 2-4m this made the challenge perfectly achievable … easy huh !? If only …

AVC 2013 Ground Course ((c) Sparkfun)

AVC 2013 Ground Course ((c) Sparkfun)

Initial components

I started with components I already had. An EM-406A GPS module and a Pololu 3D magnetometer breakout board. I bought a MaxSonar sonar from CoolComponents and an RC switch from Pololu to give me a failsafe control.

The initial plan was to use an Arduino, as I have lots of them and lots of experience programming them. As mentioned before, I like old school wire wrap for prototyping, so I prototyped a basic Arduino shield to tie the 3 sensors together.

The initial testing went well. I used a third party GPS library and magnetometer library to ingest the data and I could get a basic heading to a GPS waypoint, and get a bearing from the magnetometer on the bench. The PWM output worked controlling two test servos, so confidently I sketched a custom PCB to shrink the design and make it more feasible to fit in the RC car, so I could start field testing in the garden.

AVC 2013 Arduino Custom PCB v1.0 board

AVC 2013 Arduino Custom PCB v1.0 board

AVC 2013 Arduino Custom PCB with components

AVC 2013 Arduino Custom PCB with components

Once the PCB arrived I had the basic software running. The premise of the control system is to navigate to waypoints, so the GPS coordinates as used to calculate a bearing from the current position to the next way point. This is the heading the car needs to steer. However, the car is on rough terrain and will never steer in a straight line. The course the car is taking is provided by the magnetometer, which gives the bearing the car is pointing. To reach the waypoint the difference between the car’s heading and the GPS bearing need to be kept as close to zero. One of the best ways of doing this is to use a PID controller.

I had a basic control loop written, for the Arduino, which looks something like this pseudo code:

While(CurrentWaypoint < TotalWaypoints) {
  MagneticHeading = GetMagnetometerHeading();
  GPSLocation = GetGPSLocation();
  GPSHeading = GetGPSHeadingToWayPoint(GPSLocation,WayPoint);
  PID_input = MagneticHeading – GPSHeading;
  ComputePID();
  SetSteering(PID_output);
  If (DistanceToWaypoint < 2m) then CurrentWaypoint++;
}

This should steer the car in a straight line from wherever it is, to a defined GPS waypoint. Once it gets within 2m of the way point, it moves on to the next waypoint. Once all the waypoints have been reached, it ends.

This is when the problems began…

Other posts in this series :

AVC – It’s ready !

It’s ready ! My entry for the Autonomous Vehicle Competition in the US next week is built and (partially) tested. I’ve entered the Autonomous Vehicle Competition run by SparkFun Electronics, held in Boulder, Colorado. See : http://avc.sparkfun.com & http://www.sparkfun.com

Tupperware Bot !

Tupperware Bot !

I’ll do a series of more detailed posts after I come back, but here is a brief synopsis.

It’s an HPi Savage Flux XS radio controlled car underneath (The “world’s fastest mini monster truck”) It will do 55 MPH on a good day, but I won’t be running it anywhere near that fast. The brain is an mBed (ARM base microcontroller). Attached is a high accuracy GPS (I’m getting about 1.5-2m accuracy using SBAS), an electronic compass (So I know which way the car is pointing), an ultrasound range finder (to sense obstacles) and a big red “go” button ! 🙂

The mBed ingests the GPS data, range finder and compass data and works out where it’s currently pointing and the delta to where it needs to point to reach the next waypoint. The delta is fed in to a PID control algorithm that controls the steering servo. Currently the speed controller is a static speed (slow) but as I get more confidence in the testing, it will be proportional to the distance from the next waypoint (i.e. faster, then slowing as you near the turn point.) The range finder is processed and inserts an offset in to the PID control input if it detects an obstacle, to try and steer round it.

Other posts in this series :