Problems Using PID for Velocity

We have a PID control loop to control velocity of a motor. We have the tooth counter giving us our current velocity, and an OI analog input giving us our target. The code is written such that the motor can never go backwards. (The tooth counters are giving us a speed of about 0-18, we’re hoping to increase that range a little.)

The problem is that, when using only a P loop, it oscillates violently at mid- to low-speeds. Meaning that it revs up, then stops, revs up then stops, etc. (Victor set to coast.)

Anyone seen this before in their own code? Any recomendations on using PID for velocity->velocity control loops?

We saw exactly that behavior last year with a simpleminded attempt at closed-loop speed control. Adding the D term is absolutely the most reasonable way to resolve the oscillation.

It can be resolved with a much quicker control loop, but you’ll definitely have issues measuring the speed if you try it that way.

Yea, I agree. PD is pretty much the most common way to go about velocity control.

  • Set Kd to 0.
  • Increase Kp slowly until the robot starts to oscillate around its setpoint. Watch the oscillations, are they dying down, or staying consistent?
      • If yes, then set Kp to about 30% of its current value.
      • If no, then Kp is set way too high, for some reason. Reduce it by 60%, and watch for the oscillations again. When the oscillations are reasonable (staying about constant, or dying away, and aren’t too violent), then move to the next step.
  • Increase Kd slowly until the robot “snaps” to its setpoint.
  • If the robot “snaps” eventually, but there is some error between where it snaps, and the desired setpoint (and you can’t live with this error), then you have to add in a bit of Ki.
  • Ki is usally ends up being 1/Kd. I don’t like Ki for velocity control purposes, but you can fiddle with it if you want.

Ok. Good to know. (TODO: Comment out inetegral-handling code.)

After reading through the ambiguity in #2 there, I found that changing my constants from Kp = 1, Ki = Kd = 0, divisor =1 to divisor = 3 cleared the problem right up, and (under no load), it now works great!

Ahaha. Ambiguity follows me around, it seems. Glad its up and working.

We are using the PID code as it was originally provided. As the velocity approaches the target value, the error approaches zero and the corresponding pwm value will also go to zero. This seems to hold the velocity at about half of the commanded value, which makes sense. Have other teams had this problem and how have you gotten around it? Also in the tuning example from Joel J., what do you do with DIV_V?

Increase the I term to eliminate steady-state error.