I have a differential drive robot that works fine (good PD parameters) driving at say 1 m/s. Now, if it speeds up (to 1.2 m/s) it starts wobbling again. What would be a good strategy for a controller that is able to cope with the whole speed range of 0 - 4 m/s?

edit 14th of April:

The robot is a line follow robot but I do not see how this would be related to my question since a robot following a trajectory would have the same problem.

I recently talked to other developers of differential drive robots and they are facing similar issues e.g. they told me that they need to adjust PID parameters once the battery is not fully charged hence the robot drives at a different speed.

I do not know if you guys are into youtube, but if your are really interested in my robot this link would be helpful: https://www.youtube.com/watch?v=vMedNPhXlEo

PID parameters are: P 0.31, D 0.59, I 0.00

PID controller programmed using C:

  // note: the inner wheel turns backwards for narrow curves
  // cte is -128..128 depending on the robots position
  // relative to a trajectory / black line 
  /** Execute the PID controller and update motor speeds */
  void PID()
    int32_t steer;
    int32_t cte;
    cte = 128 - get_segment_center(0);
    // Compute PID equation
    steer = (int)(
      -P * (float)cte 
      -D * (float)(cte - diff_cte) / (float)PERIOD_MS
      -I * (float)int_cte
    if (steer < -5)
      // turn left
      turn = -1;
      uXbot_move(MAX_SPEED + steer, MAX_SPEED);
    else if (steer > 5)
      // turn right
      turn = 1;
      uXbot_move(MAX_SPEED, MAX_SPEED - steer);
      // go straight
      turn = 0;
      uXbot_move(MAX_SPEED, MAX_SPEED);
    diff_cte = cte;
    int_cte += cte;
  • $\begingroup$ Why the +5/-5 threshold? What happens if you remove that? You should not need to introduce this sort of non-linearity. Try D=0, I=0 and ramp up P gradually. $\endgroup$ – Guy Sirton Apr 14 '14 at 18:32
  • $\begingroup$ +5/-5 is from another feature. To disable the feature I can set it to 0 and I tried this already. I tried different PID values for the last two days (I have a simulator for this that tired thousands of different values over the last weeks). $\endgroup$ – mark Apr 14 '14 at 19:17

You aren't properly mapping your steering value to the wheel speeds. In fact, I don't think you're applying the PID correctly at all.

From your code, my guess is that you're using get_segment_center to determine the adjustment that you need to make. My assumption is that this describes a distance measurement of how far the line sensor is off of the center of the line. If that's the case, you are lacking the necessary calculations.

The output of a PID takes an error and gives you a correction, so if your error is in inches then your correction will be in inches; if the error is in degrees, your correction will be in degrees, and so on. You need to pick either of those and stick with it. As written, you're taking a distance error and plugging it directly into a speed correction – no wonder it only works at one speed!

My recommendation would be to calculate the steering error as an angle, which you can get by measuring (1) the distance over which your sensor can pick up the line and (2) the distance between the axle and the sensor. With the tangent function, you can map sensor readings to angle error. Then, you can implement the function I wrote about in this post to convert the steering angle to wheel velocities.

  • $\begingroup$ great! That is a really interesting observation. The approach taken in my code is similar to code I studied in other peoples line followers and I never really questioned it like you did. I thought the P factor would take care of the conversion. But this would only work if the conversion is linear. I will study this further during the Easter break and report back. If you do not mind I will keep the question open until then. $\endgroup$ – mark Apr 14 '14 at 19:20
  • $\begingroup$ I followed your advice and factored in (1) and (2) cte = 104.0 * atan((float)(128 - get_segment_center(0)) * 0.003); the reference to to the other post (nice visualizations) was not so helpful since it has some features I do not need (turning on the spot etc.). It also does NOT work with velocities as advertised. My new PID (using the above formula) works a little bit better but it still does not solve the problem. I currently can not send robot telemetry (I miss a tiny sprintf library). But as soon as this is resolved I will provide some data and graphs. $\endgroup$ – mark Apr 21 '14 at 7:21
  • $\begingroup$ How are you mapping your desired vehicle steering angle (+ velocity) to individual wheel velocities? What problems did you run into when you say that the other algorithm "does not work with velocities as advertised"? $\endgroup$ – Ian Apr 21 '14 at 15:38
  • $\begingroup$ Your post works on "joystick-position" instead of velocity. I am not able to see wheel-velocity you are talking about:( $\endgroup$ – mark Apr 22 '14 at 5:25
  • $\begingroup$ Aah, in that post it was assumed that the left-right joystick position would be used to indicate the desired steering angle (-90 to +90), and the up-down joystick position would indicate the desired vehicle speed (-100% to +100%). What does your abbreviation "cte" stand for? $\endgroup$ – Ian Apr 22 '14 at 13:12

Nice robot.

The +/- 5 threshold in your code is a red flag to me. This introduces a non-linearity/discontinuity which shouldn't be needed. What is the rationale for that?

If you have enough memory to capture some real-time data try logging your cte and steer and then review them as you tune.

Speed is going to have an impact because of the way you've set up your steering and the vehicle dynamics. As the speed increases your steering command is going to cause a different turning radius. Also as speed increases it becomes hard to steer the vehicle. This isn't a trivial system. When your battery voltage goes down and assuming that voltage is your motor power tail and that you're not actually closing a velocity loop the effect of the lower voltage would be lower speed and therefore the effect of your PID coefficients will be reduced linearly to that. Note that going at a lower speed with a full battery and going at a low speed due to a low battery will behave differently (the impact of your steer command will be different).

Here's what I would suggest as a first go:

  1. Get rid of that +5/-5 threshold.
  2. Add some data logging in and review while tuning.
  3. Start with I=0, D=0 and pick a fixed velocity. Start on the slow end.
  4. Ramp up P, keep doubling it until the system becomes unstable. Back off (e.g. take half or 1/4 of the unstable P.)
  5. Experiment with adding a little I or D and see if they improve performance. If not leave at 0.
  6. Repeat tuning at a few speeds and plot your tuned variables vs. speed.
  7. Try fitting linear or 2nd order segments to that graph to determine the coefficients at different speeds if needed.
  • $\begingroup$ I could explain what a "differential drive" robot is but I assumed that people here would know. I think my problem is very common to these kind of robots e.g. needing to change PID parameters when the battery power goes down... $\endgroup$ – mark Apr 14 '14 at 5:36
  • $\begingroup$ @mark: in your question you talk about speed, in this comment you talk about battery power. We can't read your mind. You could get more and better answers if you take the time to provide all the necessary information. It's up to you. You don't need to explain what a differential drive is but you do need to give details about your specific setup which is having your specific issues. $\endgroup$ – Guy Sirton Apr 14 '14 at 6:15

After thinking about this problem a little more I had an important insight:

For the robots differential drive PID controller to be operational at different speeds, the turning angle R used for steering must be consistent over the whole speed range.

This post inspired my thinking and explains the turning angle of a differential drive robot: Calculate position of differential drive robot

Thanks to Guy Sirton and Ian for discussing my PID controller and providing useful debugging tips.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.