View Single Post
  #16   Spotlight this post!  
Unread 08-12-2016, 02:02
Oblarg Oblarg is offline
Registered User
AKA: Eli Barnett
FRC #0449 (The Blair Robot Project)
Team Role: Mentor
 
Join Date: Mar 2009
Rookie Year: 2008
Location: Philadelphia, PA
Posts: 1,047
Oblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond repute
Re: Velocity PID(F) Best Practices - To Integrate, or Not To Integrate?

Quote:
Originally Posted by calcmogul View Post
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).
This is basically what I had figured after reading up on control theory over the past few days. The WPILib implementation certainly works (it is essentially what my team did for our drive last year); however, I don't know if anyone has any good data on how it performs c.f. the other method.

I'd like, when I find the time, to run some actual tests and find out what the practical difference in performance is between the two approaches in FRC contexts.

I know the WPILib implementation runs in its own thread and the loop frequency can be set manually - do you know what the fastest speed it can run is?
__________________
"Mmmmm, chain grease and aluminum shavings..."
"The breakfast of champions!"

Member, FRC Team 449: 2007-2010
Drive Mechanics Lead, FRC Team 449: 2009-2010
Alumnus/Technical Mentor, FRC Team 449: 2010-Present
Lead Technical Mentor, FRC Team 4464: 2012-2015
Technical Mentor, FRC Team 5830: 2015-2016

Last edited by Oblarg : 08-12-2016 at 02:04.
Reply With Quote