View Single Post
  #15   Spotlight this post!  
Unread 26-01-2011, 14:49
Jared Russell's Avatar
Jared Russell Jared Russell is offline
Taking a year (mostly) off
FRC #0254 (The Cheesy Poofs), FRC #0341 (Miss Daisy)
Team Role: Engineer
 
Join Date: Nov 2002
Rookie Year: 2001
Location: San Francisco, CA
Posts: 3,078
Jared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond repute
Re: PID Loop Question

The topic of doing speed control via PID has come up several times in recent weeks. I have referred people to this thread: http://www.chiefdelphi.com/forums/sh...&highlight=PID

To quote myself:

Quote:
A couple things to keep in mind here:

The standard POSITION PID loop might look something like this:

output = Kp*e_pos + Ki*e_pos_sum + Kd*e_pos_delta;

Where output is the output.
e_pos is the error in position = desired_pos - actual_pos
e_pos_sum is the sum of the position errors = e_pos_sum + e_pos
e_pos_delta is the derivative of the error = e_pos - e_pos_last

This loop, if well tuned, should provide pretty good position control. But what about VELOCITY? Speed is the first derivative of position - so we could differentiate the position loop with respect to time to obtain a velocity controller.

I will use the D() operator to represent taking the time derivative.

D(output) = Kp*D(e_pos) + Ki*D(e_pos_sum) + Kd*D(e_pos_delta);

So far so good. What's the derivative of the output? Well, that's the change in output over time, so D(output) = output - output_last.

Whats the derivative of e_pos? Remember that e_pos itself is (desired_pos - actual_pos). It's derivative would simply replace "pos" with "vel".

e_vel = D(e_pos) = desired_vel - actual_vel.
e_vel_sum = D(e_pos_sum) = e_vel_sum + e_vel.
e_vel_delta = D(e_pos_delta) = e_vel - e_vel_last.

Putting it all together, you get:

output - output_last = Kp*e_vel + Ki*e_vel_sum + Kd*e_vel_delta;

Let's rearrange...

output = output_last + Kp*e_vel + Ki*e_vel_sum + Kd*e_vel_delta;

or...

output += Kp*e_vel + Ki*e_vel_sum + Kd*e_vel_delta;
(assuming output is global or static and persists between loop iterations)
The key is the "+=" in the final equation. E.g. your PID loop output should be the DELTA to the motor PWM. If you use the output directly, you essentially only took the time derivative of one side of the (well understood) position PID equation. You can still tune it to work, but Kp, Ki, and Kd no longer represent what you thought they did.

In simpler terms, position PID uses motor PWM (~= speed, the time derivative of position) as the quantity being output. Thus, velocity PID uses motor acceleration (the time derivative, or DELTA in motor PWM) as the quantity being output.

Last edited by Jared Russell : 26-01-2011 at 14:51.