DPRG
DPRG List  



[DPRG] Odometry and backlash

Subject: [DPRG] Odometry and backlash
From: David Anderson davida at smu.edu
Date: Tue Feb 3 10:35:46 CST 2015

Markus,

Great work!  Been down that road more than once... :)

Short answer to your question is: Yes.  Get PID working next.

However, the UMBMark takes into account the error of the navigation 
versus the error of the odometry.   So you can accurately calibrate the 
odometry even if the navigation is way off.   The way this works is 
that, at the end of the run, you record the robot's position error in X 
and Y, and you also record the robot's own odometry sense of where it is 
in X and Y, and subtract that off.

So for example, if your robot overshot the origin by 5 feet in X and Y 
at the end of the run, but the odometry now says that the robot is 5 
feet in X and Y away from the origin, then the robot X and Y error of 5' 
- the robot's calculated X and Y position of 5' = 0,0, and the odometry 
is in fact correctly calibrated.

So you can actually just drive the robot around the squares manually, or 
by R/C, or whatever.  Doesn't really even have to be a very good 
square.  All that's required is that the robot keep track of it's own 
location, and a way to compare that to it's actual location.

Onward!
dpa




On 02/03/2015 12:39 AM, Markus Lampert wrote:
> Hi David,
>
> I got everything stable now. In other words, I pass the "make sure your encoders work correctly" (for those who're interested there's a little report about the journey below - which turned out a bit long winded - sorry).
>
> Now I'm looking at the run in squares test, the UMBmark calibration as you pointed out. You mention that for the first estimate a "roughly straight" line is good enough. The point I'm not clear about is that in order for this procedure to work in the end I pretty much need a well tuned PID (or PD) controller working - right?
>
> AFAICT the performance of the motion controller has a direct impact on the quality of the test. I'm not just testing and calibrating the wheel encoders but also my ability to drive both motors at the same speed at all times (according to the encoder values).
>
> So I was wondering if I should first spend some quality time tuning motion control and making sure I can drive in a straight line?
>
> Thanks,
> Markus
>
>
> What happened inbetween:
>
> I built dark covers as Doug suggested for the wheel encoders and verified that they don't reflect the IR. They made the output signals a lot nicer on the oscilloscope but the overall symptoms didn't change. I still lost about the same amount of ticks.
>
> One of our club members reported that he had similar problems and the way the quad encoder is mounted they are pretty close to the robots base. He discovered that the reflectance of the robot base caused him, or better the quad encoders, grief. By putting black electrical tape between the quad encoder and the robot base he was able to solve his issues. As I proved later the combination of the two does the trick. However, at this point I was pretty paranoid and set on actually testing correctness.
>
> Going down further on Doug's suggestions I built schmitt triggers (with TLV272) and conditioned the quad encoder output signals with them.
>
> I whipped up another distance sensor and glued it in front of the wheels, which luckily have 3 distinct spokes, and used that to count the revolutions. Given the gearbox 100:1, 3 spokes and 3 flaps on the wheel encoders the tick ratio between the external wheel sensors and the quad encoders should be 100:1.
>
> I hooked the external distance sensors to a pin change interrupt and tried different approaches like only reading the quad encoder inputs during the interrupt routine. Unfortunately I was not able to measure conclusive results and things become a bit fuzzy.
>
> I started losing faith in physics so I covered the wheels with black electrical tape and put a single white sticker on it. Repeating the tests still didn't match up with expectations and got more confusing since I now had extra ticks from the quad-encoders. As it turns out the gearbox on my motors are not 100:1 but 100.37:1 which is clearly (bold) indicated on the actual product page, but not on the motor, the overview page, .... my brain.
>
> Once I figured that out the numbers started to match up. I had reduced the CPU & LS7366 clock frequency to 5MHz and was running all tests with 5V on the motors. Once this became stable and predictable I started using the 7.4V battery again and ramping the clock frequency back to 20MHz. Still everything worked. Last experiment I took the schmitt triggers out again and voila, we're all happy.
>
> This exercise has taken me a month, ruined my battery (I forgot to turn the robot off one day) and I can still hear the high pitched whine of the spinning motors - although I stopped testing more than 48h ago. But hey, I learned a lot and it was well worth it.
>
> Thanks for all the help!
> Markus
>
>
> On Tue, 6 Jan 2015 19:33:49 -0600
> David Anderson <davida at smu.edu> wrote:
>
>> Hi Markus,
>>
>> Bummer.   Good thing you caught this early on. :)
>>
>> So either the encoder is dropping ticks and incorrectly reporting the
>> behavior of the motor, or the encoder is working properly and correctly
>> reporting an issue with the motor speed.
>>
>> Considering that both motors work the same forward, the good motor
>> performs about the same forward and reverse and does not itself appear
>> to be dropping any ticks, and the motors together sound very different
>> in forward and reverse, I bet the encoder is working correctly, and it
>> is a problem with the motor, perhaps a control or friction issue.
>>
>> You might try the following:
>>
>> 1.  Run one motor at a time (i.e., needing only half the number of
>> encoder ticks and half the power from the motor controller) and see if
>> you get the same behavior.
>>
>> 2.  Unload the motors (i.e., remove the wheels et al) and see if you see
>> the same behavior when the motors are free running.
>>
>> 3.  If possible, swap the encoder cables and see if the problem stays
>> with the motor or moves with the cable.
>>
>> 4.  If possible, swap the motor power cables and see if the problem
>> stays with the motor or moves with the cables.
>>
>> If you have access to a dual trace 'scope you might disconnect the motor
>> power cables from the motors and look at the two as PWM signals on the
>> 'scope,  and verify that the two channels look the same (i.e., have the
>> same pulse length) for the same control signal, forwards and backwards.
>>
>> You might also code up a tachometer for each encoder: an endless loop
>> that reads and saves the encoders values and then zeros the encoders,
>> once per second.  A display of those two values will give you the wheel
>> velocity in encoder ticks per second.  Run the two motors at 1/2 speed,
>> full speed, 1/2 reverse, and full reverse, and compare the velocity
>> readings.  This might tell you something.
>>
>> You might also want to take note of the maximum ticks per second
>> velocity value, when the robot is running full speed forward. This
>> number is useful for constraining some things later on, like the timing
>> of the motor control loop, etc.
>>
>> onward!
>> dpa
>>
>>
>>
>> On 01/06/2015 12:16 AM, Markus Lampert wrote:
>>> Hi David,
>>>
>>> thanks for writing this up. It seems each time you do you add more details which are a tremendous help!
>>>
>>> Unfortunately I didn't get very far today. Actually I got stuck at 1. "Be sure the encoders are working properly"
>>>
>>> I did a) and b), the manual back and forth of both wheels for 10 turns and the wheels get to 3012 and 3013 counts respectively, which is also close to what it should be, 3 counts per motor revolution and a 100:1 gearbox. I put the 12/13 over-counts to my eyesight ;). Turning them back both end up at 1. So far so good.
>>>
>>> For c) I let the motors spin until the quad encoders were about to roll over (I configured them for 16bits since that is what my processor is using). Spinning both forward I end up with:
>>>    right:  63943
>>>     left:  62182
>>> I assume that is "close enough"?
>>>
>>> However, running backwards I end up with
>>>    right: 63556
>>>     left: 42986
>>> There's definitely something off. Running in reverse the motors sound differently too, more like 2 motors (whereas running forward sounds more like "more of the same"). So I sat the robot on the ground and repeated the exercise. Unfortunately I can't let it run for very long before it finds an obstacle (old house syndrome again). It does seem to do a slight arch when running either way, each way a different motor "leading" - although I did not find a significant difference in the arch radius going forward vs. backward. I guess the motors do have a //preferred// direction and since one always has to go against that it is a bit slower than the other.
>>>
>>> Anyway, it seems I am losing counts on the left motor when going backwards. That is a rather surprising result considering the quad decoding is done by a dedicated chip with signal conditioning for each wheel (LS7366). I'll have a look at the output from the wheel encoders tomorrow and see what's going on there.
>>>
>>> Thanks a bunch!
>>> Markus
>>>
>>>
>>> On Mon, 5 Jan 2015 15:30:48 -0600
>>> David Anderson <davida at smu.edu> wrote:
>>>
>>>> Markus,
>>>>
>>>> My SR04 robot, which has very good odometery, also has a laser pointer
>>>> and can be wiggled back and forth within the backlash of the gear train,
>>>> about +- 1 degree.  It's not a show stopper, and may not be the cause of
>>>> the errors you are seeing.
>>>>
>>>> I'm a little suspicious of the measurement method.  Seems like it
>>>> assumes the robot is pivoting perfectly around the un-driven wheel,
>>>> which may not be the case, and that's a bit hard to control for.
>>>>
>>>> In my experience odometery can be made to work very well but it takes a
>>>> lot of tuning of the robot.   For what it's worth, here's the method
>>>> that works for me for a differentially steered robot:
>>>>
>>>> 1.    Be sure the encoders are working properly.
>>>>
>>>> That is, not dropping any ticks, and working correctly forwards and
>>>> backwards.  Care taken that the encoder hardware and software are
>>>> working correctly and robustly will save lots of headaches later on.
>>>>
>>>>        a.  Make a mark on the wheel(s) that lines up with something on the
>>>> robot, set the encoder count to 0, and turn the wheel forward by hand 10
>>>> turns.  Write down the number of encoder counts, then turn the wheel
>>>> backward by hand 10 turns.  Be sure you get back close to 0.  Zero
>>>> itself can be hard to get depending on the resolution of the encoders,
>>>> but this is so you will know you are not dropping ticks forward or reverse.
>>>>
>>>>        b.  Do the same with the other wheel, and verify that the numbers
>>>> are about the same for both wheels.
>>>>
>>>>        c.  Run the motors forward at full speed for a time and be sure
>>>> that both encoders show about the same number of total counts.  They
>>>> won't be identical because the motors are not really running at the same
>>>> speed, open-loop.  But they should be close. Do the same in reverse.
>>>> This helps determine if you are dropping any ticks at high speed.
>>>>
>>>>
>>>> 2. Calibrate ticks-per-inch.  (or mm or whatever)
>>>>
>>>> Set the encoders to 0 and run both motors forward at a medium speed, in
>>>> more-or-less a straight line, for 10 feet, and stop. Write down the
>>>> total number of counts for each encoder.  Then the robot's
>>>> ticks-per-inch constant is:
>>>>
>>>> #define TICKS_PER_INCH = ((left_encoder+right_encoder)/2)/120.
>>>>
>>>> You can layout 10 feet with a tape measure on any convenient surface,
>>>> kitchen floor, sidewalk, etc.    Alternately, lots of buildings have
>>>> handy 1 foot square tile floors and a hallway makes a nice piece of
>>>> built-in graph paper for encoder calibration.
>>>>
>>>>
>>>> 3.  Manually measure the robot's wheel base.
>>>>
>>>> For a differential two wheel drive robot, lay a ruler across the bottom
>>>> of the robot from wheel to wheel, and record the distance from the
>>>> center of one wheel to the center of the other.   This is the starting
>>>> point for calibration of accurate turning and angles.
>>>>
>>>> #define WHEEL_BASE = hand measurement.
>>>>
>>>>
>>>> 4.  Run a series of left and right hand squares.
>>>>
>>>> This is really the only way to separate out the various sources of
>>>> errors.  It doesn't have to be 10 feet square, just use whatever room
>>>> you have available.  The larger the square, the more apparent the
>>>> errors.  But a smaller square works fine.  Also on carpet, if that's all
>>>> you have available.
>>>>
>>>> The procedure is to drive around a square and stop, and mark the
>>>> distance in X and Y from the stopping point to the starting point.   Do
>>>> it several times in one direction, say clock-wise, and average together
>>>> the errors.   A little like sighting in a rifle scope.  Then do the same
>>>> thing in the opposite direction, counter-clockwise in this case, and
>>>> average together those errors.
>>>>
>>>> The left and right hand squares will reveal two sources of errors.
>>>> Borenstein's UMBmark paper goes into the math in detail.  But more
>>>> basically the errors will be symmetrical and asymmetrical.    If the
>>>> clockwise and counter-clockwise position errors are symmetrical, it
>>>> means the robot is turning either too far or not far enough in the
>>>> corners.  That's a wheel base error.
>>>>
>>>> The larger the wheel base value, the fewer degrees the robot will turn
>>>> for the same number of encoder ticks, and vice-versa.  So if the robot
>>>> arrives short of the goal in both directions, it is not turning enough,
>>>> and the wheel base value needs to be reduced.  If it overshoots the
>>>> origin in both directions, it is turning too much, and the wheelbase
>>>> value needs to be increased.
>>>>
>>>> On the other hand, if the errors are not symmetrical around the origin
>>>> (they won't be) then the robot has two wheels that are not exactly the
>>>> same size.  This is common.   The correction is to add a small value to
>>>> the TICKS_PER_INCH for one wheel, and subtract it from the other wheel.
>>>>
>>>> #define LEFT_TICKS_PER_INCH = TICKS_PER_INCH + WHEEL_SIZE_ERROR
>>>> #define RIGHT_TICKS_PER)INCH = TICKS_PER_INCH - WHEEL_SIZE_ERROR
>>>>
>>>> This corrects the odometery for the error in wheel size without
>>>> effecting the previously measure ticks per inch.
>>>>
>>>> 5.  Now adjust the WHEEL_SIZE_ERROR.
>>>>
>>>> Rerun the clockwise and counter-clockwise squares, adjusting the
>>>> WHEEL_SIZE_ERROR until the position errors become symmetrical. You'll
>>>> probably have to do this a few times.  This will cancel out the wheel
>>>> size errors.
>>>>
>>>> 6.  Finally adjust the WHEEL_BASE value.
>>>>
>>>> Increase or reduce the WHEEL_BASE constant until the position errors,
>>>> now symmetrical, cluster around 0, for both clockwise and
>>>> counter-clockwise runs.   This is the fine tuning of the WHEEL_BASE,
>>>> which is in turn the accuracy of the robot's angles. Once all the errors
>>>> are clustered symmetrically around the origin at 0,0, then that's about
>>>> as good as it's going to get.
>>>>
>>>> Just as a reference, the odometery code that uses these constants looks
>>>> like this:
>>>>
>>>> void odometery()
>>>> {
>>>>
>>>>        /* calculate elapsed encoder counts and distance since last cycle */
>>>>
>>>>        left_inches = (float)left_velocity / LEFT_TICKS_PER_INCH;
>>>>        right_inches = (float)right_velocity / RIGHT_TICKS_PER_INCH;
>>>>        inches = (left_inches + right_inches) / 2.0;
>>>>
>>>>        /* calculate angle of rotation since last cycle */
>>>>
>>>>        theta += (left_inches - right_inches) / WHEEL_BASE;
>>>>
>>>>        /* And wrap theta at two pi */
>>>>
>>>>        theta -= (float)((int)(theta/TWOPI))*TWOPI;
>>>>
>>>>        /* calculate robot's current position in X and Y */
>>>>
>>>>        X_pos += inches *  sin(theta);
>>>>        Y_pos += inches *  cos(theta);
>>>> }
>>>>
>>>> This code runs at 25 Hz and maintains three global values: X, Y, and
>>>> theta, which are the robot's current pose and location.  Those values
>>>> are read by the navigation code that drives the robot to a target way
>>>> point location.
>>>>
>>>> Whoa, little windier than I intended, interesting how "simple" things
>>>> are sometimes more complex than is apparent.
>>>>
>>>> Anyway, hope this is helpful,
>>>> dpa
>>>>
>>>>
>>>>
>>>> On 01/05/2015 12:12 PM, Markus Lampert wrote:
>>>>> Hey Rud, Steve,
>>>>> eventually I will want to incorporate visual processing. For now though I want to keep things as simple as possible and see how far they go.
>>>>>
>>>>> Hi David,
>>>>>
>>>>> those are good questions.
>>>>>
>>>>> First off, I am currently not using UMBMark, mainly because I don't have access to a level and smooth 10' square - the virtues of living in an old house and our office building is all carpet.
>>>>>
>>>>> What I did was I mounted a laser pointer on my robot and mark the spot on the wall where it hits. I then turn on a single wheel to the lowest PWM signal that still makes the robot move reliably. I count the encoder ticks until I should have completed a full circle and measure where the laser pointer ends up in relation to where it started off. The intent was to do that in both directions and thereby get the accurate ratios of right wheel radius to wheel base and left wheel radius to wheel base. Which I then can use to calculate theta (or phi)....
>>>>>
>>>>> What happens though is that with the same settings I get differences of almost 3 degrees. The observed relation is that I should get about 4.7 encoder ticks per degree (if only one wheel is turning). In other words, with exactly the same number of encoder ticks the resulting turn is between 360 and 362.8 degrees.
>>>>>
>>>>> I have repeated the tests with different turning angles. The number of turns doesn't seem to make a difference. If I turn 10 times around I end up with the same variance as I do for a single turn. So the steady state seems to be working OK and the error is solely introduced by starting and stopping.
>>>>>
>>>>> By placing the robot on the floor, again turning on the laser pointer I can 'wiggle' the robot by ~1 degree before the gearbox engages and I get the first encoder tick (2cm laser pointer travel when the wall is 150cm away). Note that this is 1 degree in total, not 1 degree in each direction.
>>>>>
>>>>> After sending my email yesterday I spent the rest of the day rebuilt my robot to get the battery pack (currently by far the heaviest piece of the robot) closer to the wheels. Will redo my tests tonight and see if it makes a difference. I also thought of repeating the tests without battery in order to eliminate slippage and inertia as much as possible (although that might help me understand what is going on it will not help the robot).
>>>>>
>>>>> Any help appreciated, thanks,
>>>>> Markus
>>>>>
>>>>>
>>>>> On Mon, 5 Jan 2015 00:11:24 -0600
>>>>> David Anderson<davida at smu.edu>  wrote:
>>>>>
>>>>>> Hi Markus,
>>>>>>
>>>>>> It would be good to know exactly where the problem lies.   How have
>>>>>> you determined the rather large variance in calibration runs?  Was
>>>>>> this done using the UMBMark?   Large left-hand and right-hand squares?
>>>>>>
>>>>>> Is the large variance observed in  the stopping point of a series of
>>>>>> similar, say, left-hand runs?   Or is it between the left-hand and
>>>>>> right-hand runs?  Those are different problems.
>>>>>>
>>>>>> ~1 degree slop in the gear train is probably manageable, depending on
>>>>>> how you are doing the navigation.   If it is a single calculation at
>>>>>> the start of a run or line segment, then ~1 degree theta error at the
>>>>>> start will throw the robot way off in X,Y at the end.   If instead
>>>>>> the odometry navigation is a continuously running calculation as the
>>>>>> robot travels, then ~1 degree of error becomes less and less
>>>>>> significant as the robot approaches its target, and basically
>>>>>> insignificant when the robot is at the target.
>>>>>>
>>>>>>
>>>>>> Don't give up on your drive-train yet. :)
>>>>>>
>>>>>> dpa
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 01/04/2015 02:21 PM, Markus Lampert wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> I am adding odometry to one of my robots and found a rather large
>>>>>>> variance in my calibration runs. As it turns out my gear motor has
>>>>>>> some backlash resulting in ~1 degree of heading "wiggle room". The
>>>>>>> quad encoder sits on the motor shaft, not on the wheel itself which
>>>>>>> means they don't pick up on the backlash at all.
>>>>>>>
>>>>>>> I could not find any methods for backlash compensation other than
>>>>>>> for CNC machines, which doesn't seem to translate to mobile robots.
>>>>>>>
>>>>>>> Is there a method to compensate for it or am I in the business of
>>>>>>> finding a 'better' drive train for my robot?
>>>>>>>
>>>>>>> Thanks in advance,
>>>>>>> Markus
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> DPRGlist mailing list
>>>>>>> DPRGlist at dprg.org
>>>>>>> http://list.dprg.org/mailman/listinfo/dprglist
>>>>>> _______________________________________________
>>>>>> DPRGlist mailing list
>>>>>> DPRGlist at dprg.org
>>>>>> http://list.dprg.org/mailman/listinfo/dprglist

More information about the DPRG mailing list