View Single Post
  #13   Spotlight this post!  
Unread 08-12-2016, 01:03
calcmogul's Avatar
calcmogul calcmogul is offline
WPILib Developer
AKA: Tyler Veness
FRC #3512 (Spartatroniks)
Team Role: Mentor
 
Join Date: Nov 2011
Rookie Year: 2012
Location: Santa Maria, CA
Posts: 51
calcmogul is just really nicecalcmogul is just really nicecalcmogul is just really nicecalcmogul is just really nice
Re: Velocity PID(F) Best Practices - To Integrate, or Not To Integrate?

I'm the person who implemented the velocity PID controller in WPILib last summer. If I understand correctly, an integrator is necessary and sufficient to eliminate steady-state error in controlling a DC motor with a velocity PID controller in all cases. Here's some math:

I'll be using the model for a DC motor from http://ctms.engin.umich.edu/CTMS/ind...stemModelin g, which has the following transfer function from voltage (V) to angular velocity (theta_dot):

P(s) = theta_dot(s)/V(s)=K/((Js+b)(Ls+R)+K^2)

First, we'll try controlling it with a P controller defined as:

C(s) = Kp

When these are in unity feedback, the transfer function from the input voltage to the error is:

E(s)/V(s) = 1/(1+C(s)P(s))
E(s) = 1/(1+C(s)P(s))*V(s)
= 1/(1+Kp*K/((Js+b)(Ls+R)+K^2))*V(s)

(See http://ctms.engin.umich.edu/CTMS/Con...motorBlock.png for a diagram. I'm assuming that theta_dot_ref maps to the input voltage with a constant gain and that the measured signal is used as-is in the error calculation, so H(s) = 1).

In this case, we'll apply a step input, so V(s) = 1/s.

E(s) = 1/(1+Kp*K/((Js+b)(Ls+R)+K^2))*1/s

To find the steady-state value of a transfer function, we can apply the formula:

e_ss = lim_s->0 s*E(s)

e_ss = lim_s->0 s*1/(1+Kp*K/((Js+b)(Ls+R)+K^2))*1/s
= lim_s->0 1/(1+Kp*K/((Js+b)(Ls+R)+K^2))
= 1/(1+Kp*K/((0+b)(0+R)+K^2))
= 1/(1+Kp*K/(bR+K^2))

Notice that the steady-state error is non-zero. To fix this, an integrator must be included in the controller:

C(s) = Kp+Ki/s

Same steady-state calculations as before with the new controller:

E(s) = 1/(1+C(s)P(s))*V(s)
= 1/(1+(Kp+Ki/s)*K/((Js+b)(Ls+R)+K^2))*1/s

e_ss = lim_s->0 s(1/(1+(Kp+Ki/s)*K/((Js+b)(Ls+R)+K^2))*1/s)
= lim_s->0 1/(1+(Kp+Ki/s)*K/((Js+b)(Ls+R)+K^2))

multiplying by s/s:

= lim_s->0 s/(s+(Kp*s+Ki)*K/((Js+b)(Ls+R)+K^2))
= 0/(0+(0+Ki)*K/((0+b)(0+R)+K^2))
= 0/(Ki*K/(bR+K^2))

the denominator is non-zero, so e_ss = 0.

So mathematically speaking, an integrator is required to eliminate steady-state error in all cases for this model. If you don't want to use one, a feedforward can eliminate most if not all of the error if chosen carefully. Given that, there is always uncertainty, hence why feedback control exists.

Oblarg is correct that the behavior of the velocity PID tuning constants doesn't match the displacement PID. I tried to get something with close enough dynamics that teams could use a similar tuning procedure for both (except in the velocity case, there's no steady-state error so I made Ki not do anything).
Reply With Quote