Compass Trials and Tribulations

I finally got back to working on my 1st robotic vehicle, and it’s been 1 step forward, two steps back, with one of the back steps being self-inflicted.  My first go at a robotic vehicle used only wheel encoders for dead reckoning, working alright for measuring distance traveled, but suffering the well known lack of both precision and accuracy in heading.  So for determining heading, I decided to add an electronic compass, in particular the Devantech CMPS10 tilt-compensated compass.  I don’t really need the tilt compensation, since I’m running over flat ground and flooring, but I figured I may want to reuse the compass later on another project and it’s inexpensive for a tilt-compensated compass.

So, I add the compass and run a simple test program.  First issue is that there’s clearly interference from the metal, motors, and/or electronics.  So I’ve mounted in on an aluminum mast, and that seems to clear things up.  One problem down.

Next I modified my code and went into a several hour debugging nightmare.  As is often the case, the bug is obvious in hindsight, with the symptoms pointing to it.  My robot ran forward the set distance, then, when it should have turned left, it spun right in endless circles, bringing to mind the Tommy Roe song Dizzy for those of us of a certain age. In debugging, I notice that while the simple compass reading test program works fine, when I load the full robot code, the bearing jumps in large discrete increments of about 22 degrees.  Curious, obviously a clue, but I couldn’t figure out what it meant.  Only after a couple hours of staring at code and trying small incremental changes did I notice the problem. Where I should have typed: lowerByte = compass.read(), I had instead typed lowerByte – compass.read().  The higher precision result from the compass is sent in two bytes, and I was never actually setting the lowerByte value, resulting in the large discrete jumps.  One self-inflicted problem solved.

Why did the robot turn right instead of left? Either the code was erroneously jumping to the middle of the obstacle avoidance routine, where it try turning right to avoid obstacles, or something else.  This was relatively easy to isolate, as when the robot is hooked up to the PC with debugging serial.print statements on, it dumps its current state and parameters each time through the loop.  So I quickly saw it wasn’t a bad state change.  The problem was self-inflicted wound two: a sign error.   A clockwise turn is positive in the coordinate system, but it’s a negative turn in terms of compass bearing (e.g., turning right from heading 90 degrees to heading 0 degrees).  So, flip the sign and I’m in business.  An easy one.

Now it moves straight to the first waypoint, turns in the proper direction, but not to the correct heading.  There’s a lag in the compass reading that I need to account for.  At least that’s not a silly mistake, and I know the source of the problem.

Here’s a picture of my initial compass test (without the robot) , and then MARV-1 with the compass mounted on the mast:

Tilt Compensated Compass Test displaying bearing

 

MARV-1 robotic vehicle with electronic compass on mast