I am using Pololu’s Zumo chassis to implement a dead-reckoning NavBot with the Arduino. However, I’m discovering some issues with the Zumo for this kind of application, and at this point I’m not sure if they are solvable.
Dead reckoning is very simple. We can measure, accurately, how much each wheel of the bot turns. From this we can calculate our change in location based on simple physics. [A good explanation is given in A Tutorial and Elementary Trajectory Model for the Differential Steering System of Robot Wheel Actuators by G.W. Lucas.]
The Achilles’ heel of dead reckoning is error and, worse yet, the ultimate accumulation of this error resulting in less and less reliable positioning the more we move.
The first injection of error is the dead reckoning calculations themselves. Regardless how detailed they get they will never match perfectly what is going on in the real world.
For example, NavBot is using the simplified equations given in section  of the above G.W. Lucas paper. I created a diagram showing how those calculations work:
Point A is where the bot has actually moved to. (x, y) is the new position calculated using the traditional equations. (x’, y’) is an optimized calculation (where θ is divided by 2) that is a better approximation but still an approximation of A. It should be noted that the diagram is a gross exaggeration. The calculations would be performed at much smaller intervals and thus the error will be much smaller.
The next source of errors are called “systematic” errors. These are due to physical characteristics of the bot that effect the way it moves. An example is when wheels are not the exact same diameter. One wheel will travel further per revolution than the other:
The nice thing about systematic errors is we can compensate for them in our dead reckoning calculations, assuming we can identify and model them mathematically. A good explanation of this is given in: Measurement and Correction of Systematic Odometry Errors in Mobile Robots by Borenstein, et al.
The final source of errors are “non-systematic” errors, i.e. anything that is not a systematic error. The key one here is “slippage”, i.e. loss of traction between the tires and the ground. Any slippage, regardless how small, means the robot did not move as much as indicated by our calculations.
Another example is uneven terrain. If one wheel was to go over a bump it will not have travelled horizontally as far as the other wheel and that will change the bot’s overall orientation.
Effectively it’s as if one wheel slowed down for a moment.
Non-systematic errors are a lot harder to compensate for as you need some way to detect that they happened in the first place.
For the NavBot project I’m only dealing with small bots using differential steering on flat, even and uniform surfaces. This simplifies things greatly but, as we’ll see, the devil is in the details.
Detecting Systematic Errors
One of the simplest tests for systematic errors is to get the bot to drive in a straight line. I’ve already posted about doing this in “PID Tuning for Zumo”
For this test we use a PID controller to adjust the relative speeds of both wheels so they turn the same amount over time. Once we ensure the PID controller is working properly we know, regardless of anything else, that both wheels are turning equally. In my particular case the wheels where never more than 9/1204ths of a revolution out of sync at any given point in time.
The result should be that the bot travels in a perfectly straight line but it doesn’t:
The deviation from center line is due mainly to systematic errors, though non-systematic errors do play a part as we’ll see later on.
In the post I added a simple “system bias” to compensate for the error, and ended up with a bot that did drive straight, but this simple bias breaks down when doing more complex maneuvers. I’ve had to step back and try to understand exactly what the systematic errors are so that I can either eliminate them or compensate for them correctly.
So I set up the bot for straight line driving again, without the system bias, and did some tests.
With no changes to the bot, it averaged about 54cm deviation to the left. Each run was within +-3cm of each other.
One possible cause for the error might be due to some imbalance between the left and right drive wheels. It could be the wheel diameters are slightly different or the drive axle coming out of the gear box are aligned differently or the gear ratio is slightly different.
I already know from pass encoder tests that the gear ratios are near identical. Using a caliper I could not detect any noticeable difference in the wheel diameters or unevenness in the circumference of either. But the real test is to swap the left and right sides and see if there is any change in how the bot drives.
So that’s what I did and there was no noticeable change. We can conclude that the wheels and gearbox are not contributing significant systematic errors.
All that seemed left to do was to look into the wheel/track alignment. I knew going into this that a track based bot was probably not the best choice for a NavBot and my tests bore that out.
I also won’t bore you the details of all the testing and adjustments that were made. I will highlight some of the ways I was able to adjust the alignments.
The first, and most difficult, was to adjust the drive wheel positions on their motor shafts. Pololu’s wheels fit extremely tightly to the shafts. In fact, I worried I was going to damage the motors or their gearboxes when I first put the wheels on. I ended up using a nail punch tool to move the wheel up the shaft a little:
There’s no way to be precise with this technique and you have to dismantle the bot in the process.
Another method is to reverse the idlers:
This brings the wheel closer to the chassis. It’s a pretty extreme adjustment but if your drive wheels are pushed in a lot then it might help.
The most significant adjustment I found was adding a thin washer to the idlers:
It servers two purposes: It reduces the amount of play in the wheel itself – the idlers are pretty loose – and it can be used to shift the alignment of the wheel slight in or out on its axel depending if you put the washer on the outside or inside of the wheel.
Using all of these techniques I was able to get the Zumo to travel reasonably straight.
However, part of my test was to also have the bot drive backwards. I wanted to see if the systematic errors where symmetric. To my surprise they were not but later when I thought about what was happening it’s not surprising at all.
Here is a montage of some of the final test runs:
In one or two of them you can see that the error on the drive backwards was significantly different than the drive forwards, however I did manage in the end to minimize both errors to something reasonable.
The misalignment of the tracks is a systematic error. We can model it simply:
Like having wheels that are not the same diameter, having the tracks unaligned results in one track not traveling the same distance as the other though they both turn the same amount.
However, the problem is more serious. In the diagram the left track wants to travel in a slightly different direction than the right. Physically that is not possible so something has to give and what gives is traction. The tracks will experience some amount of slippage and the problem with slippage is that it is a non-systematic property, i.e. we can’t really account for how the tracks are going to slip – it will depend on surface conditions and the tracks themselves.
I think the problem is further compounded by those loose idlers. It probably means that even the alignment will vary depending on the forces at play on the tracks, and that most likely explains the different behavior I was seeing between forward and backward motion.
All in all it’s not looking too hopeful that Zumo will cut it as a NavBot but then it does serve as a good test case to stress-test the Navigator and Pilot implementations.
I can already see a future project to design the optimum NavBot. I think that would be a lot of fun.
But that brings up the question of whether or not accurate dead reckoning is a worthwhile endeavor at all? Even if we were to create the ideal NavBot there will still be errors and the bot will only be able to travel so far before it requires some kind of external reference to correct its position. Maybe it’s better to focus solely on external navigation.
But then again, dead reckoning is a lot of fun and it’s not like I have a practical application for any of this.
You gota love hobbies.