Smooth Acceleration/Deceleration

Are there any guidelines to follow for smooth acceleration/deceleration? Does anyone have a method they generally use so the robot doesn’t jerk or lurch?

I’m having my robot move away from an analog stimulus, so it’s top speed is dependent on the magnitude of the input. Right now, I “step up” to the top speed using three steps @100ms each, stay at the top speed for 500ms, then step back down.

Does anyone have any recommendations? I’ll probably just bump up the number of steps until I get it right, but if anyone has a recommendation based on experience, I would appreciate it.

Thanks.

Hello.

It’s generally not too difficult to implement some sort of smooth acceleration. One way to do this is to maintain some notion of a target speed and a current speed in conjunction with a limitation on how much the current speed is allowed to increase or decrease in a given speed update. You can then configure your main loop to frequently (e.g. every 10 ms) compare the current speed to the target speed and perform the appropriate adjustment if they are not equal. For example, consider the following main loop:

unsigned long prevTime = get_ms();
int currentSpeed = 0;
int targetSpeed = 0;

while (1)
{
  if (get_ms() - prevTime >= 10)
  {
    prevTime = get_ms();
    if (currentSpeed < targetSpeed)
    {
      currentSpeed += acceleration;
      if (currentSpeed > targetSpeed)
        currentSpeed = targetSpeed;
    }
    if (currentSpeed > targetSpeed)
    {
      currentSpeed -= deceleration;
      if (currentSpeed < targetSpeed)
        currentSpeed = targetSpeed;
    }
    set_motors(currentSpeed);
  }

  // rest of main loop goes here
}

The key to smooth acceleration is frequent updates. When using the approach above, instead of setting the motor speed, your program should set the target speed, and then the main loop automatically adjusts the motor speed over time to approach the target speed. The above code is a simple example (I haven’t tested it or even compiled it, so you should treat it as more of a general guideline than actual code) that can be improved upon significantly if you want to get something fancier. If you run into trouble or there’s something you don’t understand, please let me know.

- Ben

Great - thanks for the reply. I figured the three updates I was doing wasn’t enough, but hadn’t considered doing it the way you suggested.

Based on your experience, do you have a recommended value for the variables “acceleration” and “deceleration”, or a general recommendation as to how much time the robot needs to slow down (from full-on, for instance) without lurching forward and smacking the floor? Are there other considerations, like wearing out the motors from jumping from 0 to 255, or 255 to 0, or 255 to -255?

If not, I’ll just play around with it until I figure out some good numbers and post it here.

Thanks again!

Repeatedly going directly from full-speed forward to full-speed reverse (or vice versa) will put additional stress on the motors. I can’t quantify how that would affect the lifetime of the motors, however.

One way to pick values for acceleration and deceleration is to consider how long you think it should take the robot to go from speed 0 to speed 255. If you want that to take 100 ms, you should pick:

acceleration = 255 * (10 ms / 100 ms) = ~26

You’ll need to empirically figure out what deceleration to use to keep the robot from hitting the floor as it slows down. Note, however, that the lurching you describe isn’t necessarily bad for the 3pi, so the main reason to prevent it would be aesthetics. There are also mechanical ways to prevent lurching: you can add a standard T1-3/4 through-hole LED (their 8.6 mm height is almost a perfect fit) or bent jumper wire to the underside of the 3pi’s front prototyping space to act as a front caster, or you can add weight to the rear of the robot.

There are a few other things for you to consider when implementing acceleration, too:

  1. You might want to implement it separately for the left and right motors. The sample code I gave only works when the robot’s motors are both moving at the same speed, which is unlikely to be very useful in a general sense.

  2. You might want to make a separate case to handle reverse acceleration/deceleration. In my example, the deceleration argument covers the rate at which the robot slows down in the forward direction and the rate at which it speeds up in the reverse direction. I think this is probably not going to be the behavior you ultimately want.

I think the best approach is for you to just start playing around with it. Don’t forget to consider adjusting the interval at which you update the motor speed (e.g. maybe every 20 ms would work better for you) as you adjust the acceleration/deceleration parameters.

I’d love to see the code you end up with!

- Ben