View Single Post
  Spotlight this post!  
Unread 02-02-2008, 16:34
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,070
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 for velocity control

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

(Yes, I know there are other ways to write the PID equation - I usually use the recursive discrete form so I don't need to keep track of an error sum, but I digress...).

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)

So that's how you'd make a velocity controller. Note that the constants will be different than from the positional case (obviously).

One other thing - most of the time, people only care about closed loop velocity control in a robot in order to GO STRAIGHT. Having two separate PID controllers (one for each side) is one way to do this. But what if I bump the robot off course? The two sides will independently stabilize near the setpoint after the disturbance, but the entire robot may be pointed in a new direction.

Without giving everything away, what if your error term was not (desired - actual), but rather (left_actual - right_actual)? With some changes to the above equation, and a nonzero Ki, the robot will correct its course as it drives, effectively slowing down one motor when the other gets slowed down because of the environment.