Friday, March 25, 2011

GPS, Gyro, and Compass Errors

Continuing to flail, here. I still don't have reliable navigation working and I'm a month away. That sounds like a lot of time but it's a flash in the pan. I'm very nearly screwed.

My recent test runs suggest various possible errors in the navigation sensors. Here's what I've come up with so far based on two test runs last night and some offline analysis of the raw sensor data.

GPS Errors

I equipped Data Bus with the iGPS-500 and collected data for both GPS units simultaneously. I thought because the Locosys was getting a fix that it was to be trusted.

But it's been unreliable. Last night the iGPS-500 was the only one of the two modules getting a fix... inside the house!  A multi-satellite fix, at that.  Long story short the iGPS-500 frequently seems to produce better data.

Below, the iGPS is pictured in blue, the Locosys LS20031 in green. It's all over the map. In my other test run,  the iGPS did ok, but went squirrely in the upper right near the big tree. The Locosys looked better in terms of shape but was offset about 50 feet.


The dark red path above is the dead reckoning plot using compass. The lighter red is the dead reckoning plot produced offline with a perl script, using raw gyro data with a hand-tuned gyro bias. It's easily the closest to reality.

Compass Error

I wanted to see if the compass simply had a bias so I tried correcting and replotting for 20 degrees then 25 degrees.

The pink path below is the original on-board dead reckoning plot. The green is the same plot rotated 20 degrees and the blue, 25 degrees. The red plot is the hand-tuned gyro-based dead reckoning.


Clearly the issue isn't a simple bias.  The compass heading does not seem to change with the correct proportion during turns.

Part of that may be due to the tilt from the convex surface of the road throwing off the heading. Possibly also because the road itself slopes slightly downhill. I don't really know for sure. I need to...

  • recalibrate the compass with the on-board calibration routine
  • gather data a few more times from a site with flat ground
  • experiment plotting my prior 3 test runs
  • if the error is still there, determine the nature of the error

If the error isn't due to the sloping street, and if I can describe the error in state space form along with the heading and heading rate (gyro), then I 'should' be able to build a Kalman Filter to deal with it.

Gyro Error

I had been trusting the compass most. It looked so good on a graph. But I was wrong. Using it to plot dead reckoning shows the real truth. I hadn't really trusted the gyro until now.

Experimenting with different bias values, the gyro provides the best dead reckoning information and in fact the best positioning information. It appears that the biggest contributor of error is the bias (or drift of the bias). Which suggests that if could only find a way to calibrate for the bias, I'd have reliable navigation.

The plot shows dead reckoning plots with different bias values. The purple plot shows a previously measured bias of 2027 (that's the raw, 12-bit ADC conversion value, approximately equal to 2.4496V). The blue corresponds to 2028 (2.4508V), green to 2029 (2.4520V). So I tried 2028.5 (2.4514V), the red, and I think that's probably the closest match.


I can't just take an average at standstill because I tried averaging the first several seconds of the data before the robot started moving. The resulting plot was off quite a bit from reality. So... is there a bias that comes into play when in motion, or during turns? Or was it due to temperature effects?

At worst, maybe I can make test runs and hand calibrate bias until the plots look right, and somehow correlate that to temperature. What super sucks is that we're talking about nailing the bias down to the nearest half a millivolt.

Dead Reckoning Integration Error

All the off-line plots were done by integrating heading and distance measurements every 20ms intervals, an order of magnitude more often than the robot's onboard code. Yet, the difference between the plots is pretty negligible. So integration error doesn't seem to play in.


I wonder if there's some distance error due to using straight line interpolation to represent the curved vehicle path. If that error was large, I'd expect to see a bigger discrepancy in plot length visible at the end of the path in the lower left part of the pic above. Instead, the length of the two plots are within 10cm of each other.

Kalman Filtering, Fusion

Maybe this is inexperience talking but at this point I don't see how Kalman filtering can possibly make use of the massive compass and gps errors to stand any chance of correcting for bias on the gyro and producing reliable heading information. I would expect a Kalman filter would basically tune out the measurements from GPS and compass to the point of ignoring them.


Oh yeah, almost forgot, I still have to dodge barrels.

And I haven't done squat with obstacle detection let alone avoidance.

Yup, I'm Screwed

Now I'm struggling to get a reliable 5V power supply for the robot that can deal with massive voltage sags from the BEC under heavy acceleration.

And as of last night, I'm fighting with that stupid, buggy RC switch board again. It switches off control of the MCU but doesn't switch on transmitter control. Great.

And on top of everything else, my espresso machine has been broken for a week and my efforts to revive it last night were in vain.

I'm just not winning right now.

But hey, I'm not complaining. Ok, maybe I am.

Meanwhile, you may wonder why I'm bothering to write all this when I should be working on the robot. Believe me I have been working very hard on the 'bot. These posts help me to collect my thoughts. Also, I feel more accountable to get busy when the time permits.

Tuesday, March 22, 2011

AVC Bot: Dead Reckoning

Eeek!  Only 30 days left before race day!!

You may be wondering what happened. Why Data Bus crashed repeatedly.

I've a high level of confidence that GPS error and, to a lesser degree, heading error were the causes. As I continue to collect more and more test run data, GPS plots show pretty substantial position errors, even when the GPS has a very good fix (HDOP of 1.2 or less).

I've been planning all along to supplement GPS fix information with dead reckoning computations and I've finally gotten the software bugs worked out. Here are the plots I collected last night showing errors in GPS and dead reckoning position estimation.

The Plots


In each test run I'm starting at the exact same geographic location: the intersection of a concrete seam and the asphalt at the end of my driveway. I've plotted the point in Google Earth, and I've initialized the dead reckoning code with those coordinates as starting points.

In general, all the dead reckoning plots have the right shape, but seem to get the distances a bit wrong and they appear rotated counter-clockwise by several degrees. The GPS plots at best have the right shape but are off by around 50' in various directions. At worst, the fix data is nearly unusuable.


I'm taking distance and heading measurements every 200ms and the GPS sends fix information just as often. But the GPS data is obviously much noisier, hence the jagged lines as in the plot above and below.




So what does it all mean?  

  • At slower speeds, the wheel encoders effectively have less resolution, increasing error
  • Distance calculation error is propagating throughout the run
  • The compass appears to have an offset of several degrees
  • The GPS may be updating too quickly to get accurate results for the slow speeds traveled
  • Google Earth undoubtedly has some positional error
And what do I do about it?

I could optimize the tradeoff between calculation frequency and encoder resolution. The main distance problem is likely wheel circumference error propagating. More on long paths than short ones.

Last night I drove the robot in a straight line for a known distance and captured the total number of encoder ticks. The original circumference measurement was 3% too large.

I'll calibrate the compass with the onboard calibration and using a compass. I can calibrate it to a known straight feature in Google Earth, too.

To improve GPS readings, I'll try setting the update rate to 1Hz and see if that improves accuracy. I'll reinstall the iGPS-500 and gather data for both units and compare.

Google Earth introduces some error that I'll have to address next.

Beyond Individual Sensors

Ultimately there's a limit to each sensor's accuracy and precision and to calibration methods. Using statistical methods to fuse sensor input should improve accuracy.

I really have no idea if it is possible to get down to sub-meter accuracy navigating a 240m path while driving around barrels and colliding with other robots. I hope so. I better find out pretty darn quickly.

Friday, March 18, 2011

AVC Bot: Kill Switch

Dramatic, automated, high speed crashes, robotic parts flying, babies wailing in the background, gnashing of teeth... now that's what I call fun times!  And it describes perfectly what happened during the Maiden Voyages of Data Bus.

I had a remote kill switch installed. Turn on the RC remote and the robot would drop out of its main loop, turn off the throttle and steering... and crash anyway.

Remote kill switches are a good idea but if I could've taken control of the robot remotely I could've avoided crashes and saved having to chase after the wayward robot on foot. I could've driven it back to me.

Time to implement a combination kill switch / remote takeover circuit. Turn on the RC transmitter and immediately take control of the robot, steering it to safety, applying the brakes, etc.

I started with this website and circuit design.

WARNING: I'm not making any expressed or implied guarantees about the reliability or performance of this circuit. It's your responsibility to determine the best method of implementing safety measures for your situation.

Nevertheless, I hope this discussion is helpful and, perhaps, encourages other roboticists (and particularly AVC competitors) to implement remote kill switches and even 'take control' devices on their autonomous robots.

In subscribing to the Open Source Hardware ideal, the Eagle files for this and other Data Bus electronics can be found here --- Warning: the Rev 0.1 board has a couple bugs!

Detect Servo Pulses

First trick: a circuit to detect servo pulses. The circuit on the website above does this.

It implements a high pass filter, buffers the signal with an op amp, and rectifies it to build up a voltage in a capacitor. The output is high when the transmitter is on, low when it is off.

I modified the rest of the circuit for my own purposes. I wanted to build something quickly with parts on hand so I can get back to testing and refining the robot.

The "Switch"

I selected a 74*244 tri-state octal bus driver* as I had several on hand and it was an easily implemented solution. The 74*244 has two sections consisting of 4 inputs and 4 outputs (see picture).

Each section has an active-low enable that connects the section's inputs to their respective outputs. My circuit needs to switch between MCU servo signals and Radio servo signals so here's how I wired it up.


Certainly, a number of analog switches with smaller form factors than DIP-20 are available.

The Switch Driver

Note that each "servo" output and each "esc" output are tied together above. Only one of the sections of the *244 will be enabled at any given time, so between the detection circuit and the switch circuit, some "logic" driver circuitry was needed.

I breadboarded the heck out of the circuit to be sure it'd work. I had to try various configurations and designs before arriving at one that seemed to work reliably and which provided TTL/CMOS compatible high and low logic voltages.


The voltage signal from the detection circuit (left, middle line above) is amplified through the other half of the dual op amp.

Why? Servo pulses occur only about every 50ms and last only 1-2ms, and the pulses out of the filter are even shorter, so there's not a lot of current going into that 4.7uF capacitor. Its voltage is pretty low, too.

The amplifier has high input impedance so it doesn't draw down the capacitor voltage. When the transmitter is on, the circuit amplifies the signal to peg it near the supply rail, comfortably above the *244's threshold voltage. That way there's enough voltage and current to drive the *244 enable pin.

To drive the opposite enable pin a small signal transistor (2N2222A in this case) in common emitter configuration inverts the detect signal, drawing a tiny current out of the 4.7uF capacitor through a current limiting resistor and driving the opposite pin low (about 0.2V, well below the *244's threshold voltage) when the transmitter is on.

When the transmitter is off, the capacitor signal is at 0V. Thus, no base current is available to drive the NPN transistor, so only a minimal voltage drop occurs from current drawn through the collector resistor. Its output voltage is very near Vcc.

Recycling Components

I wanted to build the circuit with parts on hand, minimize board size, and avoid drilling holes. I'm sick of drilling holes.

Well, I didn't have any 74*244s or LM258 op amps in SOIC packages. But I did have some surface mount components that I could reclaim from some boards I salvaged out of PCs, CD and DVD players, and other audio equipment.

The board has a mix of size 1206 and 0603 resistors and capacitors. It also uses a tiny, salvaged 4mm, through-hole, 4.7uF electrolytic cap.

Beggars can't be choosers so I was stuck with some odd component values that I had to test on the breadboard before I could use them on the PCB. Fortunately the circuit seems relatively tolerant to variations in most of the components.

I also borrowed a (tiny!) SOT-23 2N2222A's from another project of mine that's on hold.

Fabrication

I've been honing my PCB fab skills over the last several months and have some new-to-me techniques to share.

I used the toner transfer method I've been practicing to fabricate the board with 16 mil traces. I etched it in Ferric Chloride in a warm water bath, a new technique that significantly speeds up etching time. The first attempt was over-etched because I left the board in too long.

I drilled holes with the rotary tool in a drill press as usual, then tossed the SMDs on after tinning and coating the board with flux paste to hold the parts in place.

I did the reflow on my reflow skillet. Then I used toner transfer method to "silkscreen" the board and, another new technique, sprayed the top of the board with clear gloss acrylic paint which I think makes the board look more professional. In fact, all the Data Bus boards are sprayed this way.

Note the two brown wire jumpers...
I soldered the through-hole parts on, and this time tried polishing the copper side with the rotary tool and a brass wire wheel, and then sprayed the bottom with acrylic. Looks nice. That should help prevent corrosion. I may go back and do this on the other Data Bus boards.


Mistakes

Filed under "colossal goof-ups" are the following:

I realized only after I'd plugged in everything that the robot's new ESC outputs 6VDC not 5VDC. Oops. What'd I fry? Possibly the original 74LS244 I selected.

But, by some absolute miracle, it turns out all the other 5V devices on the robot were tolerant to 6V! I seriously dodged a bullet there.

I switched the *244 for a 6V-tolerant 74HC244 and wired in a Pololu 5V regulator to power the mbed and attached 5V devices.

Next, I discovered that I had reversed the enable signals to each of the 'switches' on the *244. Argh! The quickest solution was to use jumper wires. I pulled the 244, bent pins 1 and 19 horizontally so they would no longer engage in the socket, soldered on wires, and plugged the wires into the appropriate socket holes. It worked!

Oh, and the input/output connectors are mislabeled. Oops. I hope that doesn't bite me on race day. (I hope I didn't just jinx myself)

Future

I incorporated some changes into the Rev 0.2 version of the board in case I need to re-do it at some point, probably in preparation for 2012. I fixed the enable wiring bug and I made space for a SOT-223-sized, 5V, 1117 LDO regulator.

Ideally I'd probably switch over to a dedicated, DPDT analog switch IC. I'd likely keep the DIP-8 op amp as it makes single layer layout much easier.

But, I can make this board work. I need to focus my remaining time and energy on object avoidance and improving the accuracy and precision of the robot's navigation.

---
* So now Data Bus has a bus driver on board...