Log in

View Full Version : PID Loops


theNerd
12-03-2011, 12:41
Besides the name proportional, integral, and derivative (if that's how you spell it) what exactly is this special algorithm used for? I understand its used for fine tuning but when would I ever use it and also how do I use it. I followed the National Instruments tutorial however I still don't understand how it exactly works. Could anybody shed some light on the dirt on how and when PID loops are used?

Chris Hibner
12-03-2011, 13:43
Besides the name proportional, integral, and derivative (if that's how you spell it) what exactly is this special algorithm used for? I understand its used for fine tuning but when would I ever use it and also how do I use it. I followed the National Instruments tutorial however I still don't understand how it exactly works. Could anybody shed some light on the dirt on how and when PID loops are used?

A PID loop is used to make something go to and hold a value (position, speed, etc) automatically. For example, think of your cruise control on your car. You set a desired speed. A PID can be used to make your car go to and hold that speed automatically.

There are many ways to use this for your robot. Let's say you have an arm that you want to control. You can put a sensor on that arm that measures the angle of the arm (for example, a potentiometer or an encoder). Using a PID loop, you can tell your arm what angle to go to, and the PID will command the motor automatically to get to that angle. If you can measure the heading of your robot (using a gyro or two encoders) you can use a PID loop to automatically drive along a desired heading in autonomous. There are unlimited uses: if you can think of something you want the robot to do automatically, a PID loop can help you do it.

How does it work? It's actually fairly simple.

Let's say you're driving your car and you want to accelerate to 40 MPH and hold that speed. How much do you push the pedal while you accelerate? (think about that for a minute before going on). I'm willing to bet that when you are far away from 40 MPH you push the pedal a lot, and as you get closer to 40 MPH you gradually back off. In other words, the farther you are from your desired speed, the more you push the pedal.

Let's add some mathematics to this driving technique:

You can determine how far you are away from your desired speed with a simple subtraction:

How Far From Desired Speed = DesredSpeed - ActualSpeed

The jargon is to call the above subtraction the "error". In other words, the "error" is how far away you are from what you desire. Mathematically:

Error = Desired - Actual

For the cruise control: Error = DesiredSpeed - ActualSpeed.

Example: you want to be going 40 MPH (above example) and you are going 30 MPH. Then:

Error = 40 MPH - 30 MPH
Error = 10 MPH

As we said before, when you drive you push the pedal more when you're farther away from 40 MPH and back off as you get closer. We can restate this by saying that as the "Error" is larger, you push the pedal more. When the Error is smaller, you back off on the pedal. Mathematically, this is:

Pedal = K * Error

Where K is some constant to convert between the Error and how much you push the pedal.

The above equation (Pedal = K * Error) is exactly what is being done by the P part of the PID. P means proportional, and the above equation pushes the pedal in proportion to how much error you have.

The I and the D part are a little more complicated. If this all makes sense so far, let me know and we can continue on with the I and the D part.

WizenedEE
13-03-2011, 03:52
The I and the D part are a little more complicated. If this all makes sense so far, let me know and we can continue on with the I and the D part.

Please do. I know the basic theory and I've looked at the labview vi, but I'm a little hazy on the details. Is this how it works:

The integral adds up all the errors and then multiplies by a constant (one of the gains) to adjust the speed.

The derivative takes the current speed and somehow uses that to adjust the speed? How does it do that?

Also, looking at the labview vi again, I'm wondering why they use minutes instead of milliseconds. If I rewrite it (to learn about it) to use milliseconds, would I have to the input D by 60,000 for it to work?

Ether
13-03-2011, 09:04
The derivative takes the current speed and somehow uses that to adjust the speed? How does it do that?

The derivative subtracts the previous value of the process variable from the current value of the process variable and divides the result by the elapsed time between the two to get an approximation of the time rate of change of the process variable. This is then multiplied by a gain and added to the contributions from the P and I calculations.

Greg McKaskle
13-03-2011, 09:09
When looking at the LV VI, be a little careful that it doesn't add to the confusion. You know how there are multiple formulas for computing the slope of a line? Well there are multiple ways to write the formula for a PID.

The one most often used in robotics is called the parallel form or ideal form, and the terms are independent and the P, I, and D coefficients are all multiplied gains.

The LV VI implements the academic form or standard form, the one most often used for industrial plant control. The proportion gain affects the I and D results as well, and the I and D coefficients are time based and the I coefficient is a divisor instead of a gain. The time units are long because the processes often change slowly, and convention is to use seconds.

The wikipedia article (near the bottom) covers the conversions and some of the other implementation techniques in the LV one that make it more stable for industry.

By the way, we are considering including both forms and a number of additional control tools in the future. Any feedback or requests?

Greg McKaskle

HarveyAce
13-03-2011, 10:40
So you could make an arm hold a certain position without a mechanical lock? I've been wondering how to get an arm to drive and hold a position in the vertical without it falling down and without using the window motors. is that what a PID loop does?

Ether
13-03-2011, 11:08
So you could make an arm hold a certain position without a mechanical lock? I've been wondering how to get an arm to drive and hold a position in the vertical without it falling down and without using the window motors. is that what a PID loop does?

Yes. But if you don't have the right motor/gear combination and/or you have a large unbalanced torque load, you will burn up the motor.

HarveyAce
13-03-2011, 11:16
If we have approx 30-35 ft.lbs. of torque from the weight of the arm, fp would defiantly move it with ease, but it won't stay in a position. What would be needed with a PID to make it work?

Chris27
13-03-2011, 11:49
read this starting at page 23

http://www.cs.cmu.edu/afs/cs/academic/class/15494-s07/lectures/motion_by_friction.pdf


Basically, PID is a function that takes an input a target (set point) you want to achieve and your current error to this target and outputs the motor speed to get there.

P refers to a term that is proportional to the error. It is used to achieve the desired rise time to get to the set point. However having a high P will cause
the system to oscillate around the set point.

D refers to a term that is proportional to he derivative of the error. It is used to dampen the system to reduced the oscillations. If you overly dampen the system, you may rob it of the power it needs to actually reach the set point. This is called steady state error.

I refers to a term that is proportional to the integral of the error. It is used to address steady state error. Basically, as long as error persists, the system will try harder and harder to reduce the error. This may become dangerous because of wind up. E.g. say that you disable power to a motor
for a moment. The I term will cause the speed output to rise as the error is
not going away (the motor is disabled). When the motor is finally re enabled, it will go flying.

Sometimes you can get away with just using P especially if there is a lot of
friction in the system which would make it hard to shoot past the set point.

Hope that helps.

Ether
13-03-2011, 13:09
D refers to a term that is proportional to he derivative of the error.

In the LabVIEW PID vi, D is the derivative of the process variable... not the error.

Ether
13-03-2011, 13:11
If we have approx 30-35 ft.lbs. of torque from the weight of the arm, fp would defiantly move it with ease, but it won't stay in a position. What would be needed with a PID to make it work?

What is your total gear ratio from motor to arm (gearbox plus external gears or sprockets or pulleys etc).

theNerd
13-03-2011, 13:47
read this starting at page 23

D refers to a term that is proportional to he derivative of the error.

I refers to a term that is proportional to the integral of the error


I still don't understand to much about the details on how to find the derivative of the error (or the integral). I understand that the derivative of an equation is e.g.: instantaneous velocity, for instance F(x)' 4x^4 = 16x^3 (not pretending anything however I don't know the in depths of the derivatives all i know from second hand learning is the power rule). However my knowledge on integrals is null. How do you find the integral and derivative?

Ether
13-03-2011, 14:03
I still don't understand to much about the details on how to find the derivative of the error (or the integral). I understand that the derivative of an equation is e.g.: instantaneous velocity, for instance F(x)' 4x^4 = 16x^3 (not pretending anything however I don't know the in depths of the derivatives all i know from second hand learning is the power rule). However my knowledge on integrals is null. How do you find the integral and derivative?

If you are using PID functions that came with the language you are using, you don't have to. It is done within the provided library function.

All you need supply are:

the setpoint (the target value),

the process variable (the measured - with a sensor - value of what you are trying to control),

the 3 "gains" P, I, D

and any other optional inputs to the function such as output range


See attached screenshot of LabVIEW's PID

Chris27
13-03-2011, 14:20
Computing the derivative is easy as it is just change over time. Computing the integral is a bit more involved. You can use Fourth order Runge-Kutta to estimate the integral

http://mathworld.wolfram.com/Runge-KuttaMethod.html
http://doswa.com/blog/2009/01/02/fourth-order-runge-kutta-numerical-integration/

If you are using a PID function of some library, you probably don't need to worry about computing derivatives and integrals and will probably just need to pass it the desired set point and the current location/sensor reading (like in Labview)

Ether
13-03-2011, 14:40
Computing the integral is a bit more involved. You can use Fourth order Runge-Kutta to estimate the integral

"Euler's Method is the most common integration method for control systems . Control methods such as PID do not need exact integration to work well. This is because the purpose of the integral is usually to force the average error to zero to ensure that the controlled signal matches the command signal over long periods of time. Only rarely is there a need to control the integral of a signal. In those cases you may need a more accurate integration method."

Control System Design Guide
Second Edition
George Ellis
Page 82

Chris27
13-03-2011, 14:43
when PID loops are used?
An example of a use of PID is our autonomous mode. We want to be able to drive out exactly x inches to our rack in a perfectly straight line to put us in a position to score a tube on the high rack. This isn't so straightforward as a 150lb robot has a lot of momentum and it is easy to overshoot a target distance (and crash into the wall). We can record the distance the robot has traveled by putting an encoder on the right side of the drive train. Using PID, we set the set point to x and read the encoder to get the current position. With our gains set correctly, we arrive at distance x rather smoothly.

However, we also want to drive in a perfectly straight line. If, say there is more friction on one side of the drive train, this will cause the robot to drive in an arc. You can add a gyro to the bot, use PID on it with the set point of whatever heading is defined to be "straight". Add this correction to the speed of the left wheel motors and you are 80% of the way to having a perfect one tube autonomous mode.

PriyankP
13-03-2011, 15:21
I've been reading this thread and could someone please post an example code with P, I and D implemented to control something? I saw the LabView code, but I never learned labview, so could someone please post a C++/Java example?! :)

EDIT: I did implement P loop to control our arm this year, but only for presets. Is it possible to implement PID loop for manual control? If yes, how so?

archaopteryx
13-03-2011, 15:39
I'm not a mathematician, but couldn't Pedal = K * Error, where K is a constant, simply do without K? If pedal and error have a direct correlation, why can't you just say that pedal = error and leave it at that?

Chris27
13-03-2011, 15:44
I'm not a mathematician, but couldn't , where K is a constant, simply do without K? If pedal and error have a direct correlation, why can't you just say that pedal = error and leave it at that?


If you are trying to move your car at 50 mph and currently, the error from this target is +10 mph, does it make sense to push the pedal down at 10 mph? A correlation does not mean an equivalent 1 to 1 relation. Another example is if you are trying to drive your robot 5 feet forward and the current error is 4 inches. Does it make sense to tell the motors to drive at 4 inches? Built into the k value is unit conversion among other things.

Ether
13-03-2011, 15:44
EDIT: I did implement P loop to control our arm this year, but only for presets. Is it possible to implement PID loop for manual control? If yes, how so?

Instead of preset, make the setpoint manually adjustable (like the output of a joystick axis) .

PriyankP
13-03-2011, 15:53
Instead of preset, make the setpoint manually adjustable (like the output of a joystick axis) .




So it would be something like target = currentPotValue + (Yaxis * 5) right?

I'm multiplying by 5 because the Yaxis is only between -1 and 1 so one would want to have a target that is significantly different compared to the currentPotValue

Ether
13-03-2011, 15:54
I'm not a mathematician, but couldn't , where K is a constant, simply do without K? If pedal and error have a direct correlation, why can't you just say that pedal = error and leave it at that?

If you are trying to control position, then the error will be in inches (or feet or meters or whatever). In response to this error, you want to choose the appropriate command to your motors, which will be a voltage command... which roughly corresponds to a speed command. So the K is a scaling and gain factor to convert the error to an appropriate motor voltage (speed) command.

On the other hand, suppose you are trying to control motor speed. You want to go 2000 rpm and you are presently going 1900 rpm. So the error is 100 rpm. Would it make sense to give the motor a voltage command which is roughly equal to 100 rpm?

Chris27
13-03-2011, 15:55
EDIT: I did implement P loop to control our arm this year, but only for presets. Is it possible to implement PID loop for manual control? If yes, how so?

If a system of your robot has mechanical limits (e.g. an arm) you may want to use PID (or even just P) to not smash into those limits. I can also see PID used for speed control like in Chris's example.

Ether
13-03-2011, 16:02
So it would be something like target = currentPotValue + (Yaxis * 5) right?

Yaxis is your setpoint and (m*currentPotValue+b) is your process variable.

Adjust the gain "m" and the offset "b" so that your process variable corresponds to your Yaxis output.

Then,

error = setpoint - process_variable;

motor_voltage_command = Kp*error;

Kp is your proportional gain which you tune for the desired response.

PriyankP
13-03-2011, 16:14
Yaxis is your setpoint and (m*currentPotValue+b) is your process variable.

Adjust the gain "m" and the offset "b" so that your process variable corresponds to your Yaxis output.

Then,

error = setpoint - process_variable;

motor_voltage_command = Kp*error;

Kp is your proportional gain which you tune for the desired response.




So (m*(currentPotValue+b)) should have range of -1 to 1? or it doesn't matter because Kp takes care of that?

HarveyAce
13-03-2011, 16:28
What is your total gear ratio from motor to arm (gearbox plus external gears or sprockets or pulleys etc).




We are currently running two denso window motors in tandem to power the joint with a surgical tubing counter balance. I'm just curious because when we ram the fp, it was WAY too fast and couldn't hold the weight in one position, but I've seen teams do it with much success.

Ether
13-03-2011, 16:52
So (m*(currentPotValue+b)) should have range of -1 to 1? or it doesn't matter because Kp takes care of that?

Kp does not take care of that. Kp is the tuning constant, and is applied to the error. Take another look.

Ether
13-03-2011, 16:53
I'm just curious because when we ram the fp,

when you "ran the fp" how did you run it? i.e. what total gear ratio did you use?

Ether
13-03-2011, 16:55
We are currently running two denso window motors in tandem to power the joint with a surgical tubing counter balance.

In an earlier post (http://www.chiefdelphi.com/forums/showpost.php?p=1038494&postcount=8), you mentioned 30-35 ft-lbs of torque on the arm. Was that with or without the surgical tubing in place?

PriyankP
13-03-2011, 17:35
Kp does not take care of that. Kp is the tuning constant, and is applied to the error. Take another look.





So (m*currentPotValue+b) doesn't have to be within -1 to +1? And what exactly does it, the process variable, do?

Ether
13-03-2011, 17:43
So (m*currentPotValue+b) doesn't have to be within -1 to +1?

"m" and "b" are constants which you need to calculate and set so that the operating range of the process variable corresponds to the desired operating range of the joystick, be it -1 to +1 or 0 to +1 or whatever.


And what exactly does it, the process variable, do?

Read this post (http://www.chiefdelphi.com/forums/showpost.php?p=1038569&postcount=13), then ask if it's not clear.

PriyankP
13-03-2011, 17:59
"m" and "b" are constants which you need to calculate and set so that the operating range of the process variable corresponds to the desired operating range of the joystick, be it -1 to +1 or 0 to +1 or whatever.




Read this post (http://www.chiefdelphi.com/forums/showpost.php?p=1038569&postcount=13), then ask if it's not clear.




Am I correct about this:

JoyStickYaxis is +1 (operator input)
currentPotValue is 550 (min is 300 and max is 600)

(m*(currentPotValue+b)) = ( (1/150)*(550-450) )
m is 1/150 and b is -450 so that the number is always between -1 and 1

error = 1 - 0.6666;
MotorOutput = k * 0.3333 and say k is 0.75 then the output becomes 0.25
of course, k needs to be adjusted so the error is as close to 0 as possible and/or the arm doesn't oscillate

Good so far? Or did I make a mistake somewhere?

EDIT: I have a feeling I did something wrong

Ether
13-03-2011, 18:41
JoyStickYaxis is +1 (operator input)
currentPotValue is 550 (min is 300 and max is 600)

(m*(currentPotValue+b)) = ( (1/150)*(550-450) )

m is 1/150 and b is -450 so that the number is always between -1 and 1

That should work, although it's a little different from the standard slope/intercept form that I posted.

PriyankP
13-03-2011, 18:55
That should work, although it's a little different from the standard slope/intercept form that I posted.






I think there is something wrong with that pseudo code because if the Yaxis is not touched, a value of 0 is being outputted, the arm will still move. How can I fix that? Do I need to do something like 'if the Yaxis is between -0.05 and +0.05, stop the arm, else run the code' ?

Ether
13-03-2011, 19:04
I think there is something wrong with that pseudo code because if the Yaxis is not touched, a value of 0 is being outputted, the arm will still move. How can I fix that? Do I need to do something like 'if the Yaxis is between -0.05 and +0.05, stop the arm, else run the code' ?

The code is correct. Perhaps you misunderstand what a closed-loop position controller does.

What you have implemented is a closed-loop position controller. The arm will move to a position commanded by the joystick, and stay there as long as the joystick continues to command that position. If you let go of the joystick, the joystick will return to its rest position and will be commanding "go to position zero", which corresponds to a reading of 450 on your pot. So that is where the arm will go.

If that is not the behavior you want, then you need to articulate more clearly what you are trying to accomplish.

For example, if you want the controller to hold the arm in a given position once you have moved it to where you want it to be with the joystick, then you could do something like the following: change the code so that it uses the joystick value for the setpoint only if Button1 is pressed. When Button1 is released, the joystick is ignored and the last joystick value continues to be used for the setpoint. So the driver holds Button1 pressed while he is moving the joystick to put the arm in position, and once the arm is where he wants it, he releases Button1, and the controller will hold the arm at that position, and he can let go of the joystick. When he wants to change the arm position, he holds Button1 pressed and uses the joystick to move the arm to the new position, and then releases Button1.

Or perhaps there is a small set of pre-defined positions from among which you would like to be able to select. For example: floor, level1, level2, level3. You could program 4 buttons so that each button changes the setpoint to the necessary value. The closed-loop controller then moves the arm to that setpoint. In this case, you could dispense with the "m" and "b" constants, and just assign a pot-value setpoint to each of the buttons.

PriyankP
13-03-2011, 19:52
The code is correct. Perhaps you misunderstand what a closed-loop position controller does.

What you have implemented is a closed-loop position controller. The arm will move to a position commanded by the joystick, and stay there as long as the joystick continues to command that position. If you let go of the joystick, the joystick will return to its rest position and will be commanding "go to position zero", which corresponds to a reading of 450 on your pot. So that is where the arm will go.

If that is not the behavior you want, then you need to articulate more clearly what you are trying to accomplish.

For example, if you want the controller to hold the arm in a given position once you have moved it to where you want it to be with the joystick, then you could do something like the following: change the code so that it uses the joystick value for the setpoint only if Button1 is pressed. When Button1 is released, the joystick is ignored and the last joystick value continues to be used for the setpoint. So the driver holds Button1 pressed while he is moving the joystick to put the arm in position, and once the arm is where he wants it, he releases Button1, and the controller will hold the arm at that position, and he can let go of the joystick. When he wants to change the arm position, he holds Button1 pressed and uses the joystick to move the arm to the new position, and then releases Button1.

Or perhaps there is a small set of pre-defined positions from among which you would like to be able to select. For example: floor, level1, level2, level3. You could program 4 buttons so that each button changes the setpoint to the necessary value. The closed-loop controller then moves the arm to that setpoint. In this case, you could dispense with the "m" and "b" constants, and just assign a pot-value setpoint to each of the buttons.






Oh I see, regardless of the practical usefulness on the robot, it was worth learning something new. :)

I already have the four presets that the operator can use, but the only difference is that I'm only using a P loop to reach that target. It works beautifully and doesn't oscillate. The only drawback is that its only accurate to +-5 pot values. But I compensate by increasing the desired value by 5 pot increments that way it gets as close to the target as possible going one way... I didn't really implement I and D because for one, I didn't really know how to use them and secondly, I didn't really have enough time to learn and implement it on the robot to yield some positive results.

Thank you!

Alan Anderson
13-03-2011, 20:01
By the way, we are considering including both forms and a number of additional control tools in the future. Any feedback or requests?

Useful additions might be output limits and perhaps rate change limits.

Joe Ross
14-03-2011, 15:01
Useful additions might be output limits and perhaps rate change limits.

The advanced PID VI has output limits. There is also a rate limiter VI in the PID library.