View Single Post
  #5   Spotlight this post!  
Unread 29-12-2012, 08:59
apalrd's Avatar
apalrd apalrd is offline
More Torque!
AKA: Andrew Palardy (Most people call me Palardy)
VRC #3333
Team Role: College Student
 
Join Date: Mar 2009
Rookie Year: 2009
Location: Auburn Hills, MI
Posts: 1,347
apalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond reputeapalrd has a reputation beyond repute
Re: PID: what is it exactly?

A PID controller is a form of feedback controller. In general, a feedback controller takes sensor data and command data and sends commands to an actuator to control the system.

A PID controller does this using two inputs: 'setpoint' and 'sensor'. Setpoint is where you want to be, sensor is the measured position (or velocity for velocity PID) of where you are. The PID controller outputs a motor control, but the output is of arbitrary scale. In fact, all of the units used are of arbitrary scale, the only requirement is that setpoint and sensor be of the same units.

The PID controller is named as such because it has three terms: P, I, and D.
The PID controller first calculates the 'error' as the difference between the setpoint and sensor (a single subtract operation). This number is how far you are from where you want to be.

P is the Proportional term. It is named because it sets the output proportional to the error. The proportion is controlled by kP, the proportional gain. As the system approaches the setpoint, the proportional term will reduce power to slow down, hopefully getting close or stopping at the right place. Unfortunately, if it overshoots or undershoots a little, it usually can't do anything about it, because the power output is so low. In many FRC cases, this is the only term you need.

I and D are calculus terms. It helps but is not required to know calculus to understand them.

I is the Integral term. You first integrate the error over time, and the I terms contribution to the output is then proportional to this integrated error, by kI. This will cause the integral term to 'wind up' as the system takes a long time to move, so if it gets close to the target and sits still for a long time, the integrator will start to wind up and push it to the target. The math is:
I += (error * dt * kI);
-You need to know dt, the loop time. If you think of integration as a bar graph, with the X axis as time and the Y axis as the error * gain at that time, with all of the bars touching, dt is the width of the bars. If it's always the same, you can not care about dt, but in FRC with the cRio, the timing usually sucks a lot.

D is the Derivative term. This term works against the other two to slow down motion when the system is moving too fast and approaching the target. At high errors it is drowned out by the P term, since the P term will well exceed the maximum motor, and you limit the entire controller as a whole after adding the terms. IF you'd have calculus, it's literally just (de/dt) * kD, de is calculated as error - error_last, and dt is the loop time. kD is the derivative gain. This term cares a LOT about noise, so it really needs dt. Think of this method of calculating the drivative of the secant line between this time step (error now) and the last time step (error_last).

When each term is done, you add them all together, limit it to the range of the motor, and you are done. I usually write the controller from scratch for every subsystem that needs it, because I like to add code to control the I term, and the implementation of this varies by subsystem. Simply setting a bounds (+-43 worked well for 8-bit Vex robots, that's about 1/3 max motor power), sometimes it's more complicated (e.g. the shooter controller this year used a linear interpolation to find the limit, as error increased, the maximum error term dropped off to 0 as error was 200rpm).

I see far too many people try to stuff the stock PID class into every case, and treat it like a gold box. To prove that it's so simple it dosen't need a class of it's own, I will write it in 7 non-framework lines of c code:
Code:
double error,p,i,d,motor,error_last,setpoint,sensor;
sensor = ger_analog_value();
setpoint = 20;
#define kP 0.3
#define Ki 0.4
#define Kd 4
//Begin actual code
error = setpoint - sensor;
p = error * kP;
i += (error * kI);
d = ((error - error_last) / dt) * kD;
motor = p + i + d;
motor = limit(motor,127,-127);
error_last = error;
//See? 7 lines

Note: Also, cruise control is usually more complicated than just PID, or possibly does not even use PID at all. The system I worked with used a LUT on the error to determine acceleration, which it then converted to torque. In addition, cruise control must also control other things like shifting (for automatic cars), and in some cases even brakes (adaptive cruise systems are especially fond of brake intervention).
__________________
Kettering University - Computer Engineering
Kettering Motorsports
Williams International - Commercial Engines - Controls and Accessories
FRC 33 - The Killer Bees - 2009-2012 Student, 2013-2014 Advisor
VEX IQ 3333 - The Bumble Bees - 2014+ Mentor

"Sometimes, the elegant implementation is a function. Not a method. Not a class. Not a framework. Just a function." ~ John Carmack