Differential Drive Service

Differential Drive Service

A differential drive is a  configuration where two motors are used to control the robots direction and movements.  Wheels or tracks are commonly used.

Each motor can have 3 states: Forward Backward Stopped

<<list 6 states>>


Driving very straight is problematic, because in the real world, motors rarely turn at the exact same speed.  This will cause the robot to drift slightly in one direction.


Some ways to remedy this is to use feedback.

PID Control

PID control is one method of correcting or maintaining the appropriate speed or heading.  Being new to PID I asked about details and potential problems in a LMR Post


Video Feedback



Feedback Lag


I was concerned at first, my initial idea of calibrating Bug Toy would mean not doing PID.  I thought PID control relied completely on feedback.  PID does rely on feedback, but there are many variable to "tune" the PID control.  I finally came to the realization, that calibrating was apply correct values to these variables.

To start with I'm interested in 2 calibration points.

  • actual lag time - the time it takes after issuing a control command for the feedback to return - i guessed 1500 ms but I should be able to determine this in the calibration phase.  Possibly, it would be worthwhile to calculate continuously as new feedback data arrives.
  • degrees of a turn per time at some constant power level - left and right motors are going to be different, but once these ratios are found they will help in creating a power profile to do an accurate turn.  The power level itself can vary too, and in the future it might be good to incorporate in our turning profile.  But, to keep things simple I am going to make it constant, and the time.  A low power level at a short time might not move Bug Toy at all, so I'm going to go with a rather high power level of 40%.


Code for test

    beginMotion = System.currentTimeMillis()

    float heading = getHeading()// blocks on feedback system

    endMotion = System.currentTimeMillis();
    LOG.error("hc? " + heading + " hc " + headingCurrent + " hl " + headingLast);
    LOG.error("lagTime " (endMotion - beginMotion));


Start Test

End Test

Logged values :


hc? 67.97696 hc 67.97696 hl 63.415077
lagTime 891
So Issuing a command to spin at 40% power, will incur a change of heading 891 ms later.  The change will be about 4 degrees (in guessing about 70ms).  The total amount of spin in 891 ms was 180 - 63 (starting position in 1st picture) 117 + 180 - 10 (position 2nd picture) = 287 degrees in 891 ms
lag time : 891 ms - actual time (70ms?) ~= 820 ms
speed of heading change : ~ 2.8 ms per degree  (this includes start and complete stop - so delay of start, momentum, drift are included)
Test 2
In this test will we take values from the previous experiment and estimate a 10 degree turn.   It should be about  ~28 ms all of this is from dead start to dead finish.

      beginMotion = System.currentTimeMillis()

      endMotion = System.currentTimeMillis();

      LOG.error("move time " (endMotion - beginMotion));


That was an abysmal failure... 



It looks like it went over 120 degrees.
I changed the time down to 10 ms - lower than that has very little meaning. It still went over 90 degrees.

Arggh... so it looks like power must be lowered.



What I've learned is so far differences with time under 340 ms make no difference - there is so much slop in command, feedback, motor start ramping, drift etc... that times under 340 ms are really more or less equivalent to 340 ms


Greater than 340 ms and rough changes happen - for example 9000ms @ 13% power will give you a 190 degree turn +/- 10 degrees

340 ms @ 13% will give you about a 2-3 degree +/- up to 3 degrees :P