|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
||||
|
||||
|
PID without the D
so I looked around a bit for this and I can't seem to find a way to do this on the multiple white papers that are posted. So my question is, how do I use the proportional and Integral parts of the theory with out the derivative part of it.
I know how to do them individually but have no idea on how to combine ay of these aspects to do anything meaningful. Thanks in advance for any help that can be provided |
|
#2
|
|||
|
|||
|
Re: PID without the D
Well if you have a full PID loop up and running, then just set the D gain to zero and you'll be running PI, you'll need to retune the loop though.
Otherwise, if you have them running individually but not together, just take the output of P and I and add them together for a simple PI loop, once again you'll have to retune it. Last edited by JonathanLKS : 22-01-2008 at 16:11. Reason: typo |
|
#3
|
||||||
|
||||||
|
Re: PID without the D
If you know how to calculate the P, I, and D errors, combining them is easy. Just use a different gain constant for each and add the outputs together.
For example output = Kgain * Kerror + Igain * Ierror + Dgain * Derror. Once you have code that does all three, an easy way to disable any of them is to set the gain to 0 for that one. |
|
#4
|
||||
|
||||
|
Re: PID without the D
on that note, the PID loop, how fast do I really need it. Is the normal 26ms loop fast enough? or does this need to be faster?
|
|
#5
|
||||
|
||||
|
Re: PID without the D - implementation of the I
When implementing the integral part, you can start by just adding or subtracting a constant value (start with one) and adding the integral part to the Proportional part. So, suppose you have a 5V analog potentiometer that is connected to an arm. The target or set point you want is 4V which corresponds to about 818 counts or units on the 10 bit A/D. If you are presently at 3V or about 614 counts or units, you want to move towards 818 counts. So, Error is 818 minus 614 = 204 counts. Multiply 204 by let's say 10 percent . To speed up calculation , use multiply by 26 and divide by 256 (26/256 is about 10 %).
So, (204 times 26)/256 is 20.7. With roundoff you will get 20 counts. Next, since PWM units are scaled 0 to 255, which is 1/4 range of 0-1023 a-d units, you will need to rescale (divide by 4) the 20 counts output by 4 to get 5 counts. This will be what you add to the present value you are already outputting to the PWM (which is scaled zero to 127 for one direction and 127 to 254 for the other direction). So if your present PWM output is 150 counts, you will add 5 counts for the proportional part of the 26.2 msec loop you are in. Next, since you are below your target, add 1 PWM output unit to the 150 counts for the integral portion of the PI gain. Remember this is all happening 38 times per second, so the numbers you add for the Proportional and Integral part can be small. Hope this sheds some insight into one way of making your PID work for you. ![]() Last edited by marccenter : 22-01-2008 at 16:28. Reason: Make page look better |
|
#6
|
||||
|
||||
|
Re: PID without the D
Quote:
b) Since you can't update the PWM outputs any faster[*] than every 26ms, I don't see how running your PID calculations any faster would be of help to you. Why do you want to do just a PI loop? I've heard of people using just P, or PD, but never PI. [*] Actually, you can update your PWM outputs faster, if you use PWMs 13-16 and your own pwm generation functions (or one from a non-IFI library) |
|
#7
|
||||
|
||||
|
Re: PID without the D
I would think that doing a PI would be really unstable. The D part has the effect usually of dampening the I since the I will always overshoot the goal. Of course the instability will dampen itself over time because of friction in the system but I would agree that I have never seen a PI loop. Plenty of P+D and P-D and just P loops but never a PI loop.
What exactly is your reason for not using the derivative part of the loop? |
|
#8
|
||||
|
||||
|
Re: PID without the D
Not meaning to side track here, but that is what I'm going to do.
P+D and P-D, which is correct? Or should I ask, how do I determine which to use? ![]() |
|
#9
|
||||
|
||||
|
Re: PID without the D
Quote:
Code:
//
//
// x-axis/pan tracking code
//
//
// save the current pan servo PWM value into a local
// integer variable so that we can detect and correct
// underflow and overflow conditions before we update
// the pan servo PWM value with a new value
temp_pan_servo = (int)pan_servo_position;
// calculate how many image pixels we're away from the
// vertical center line.
pan_error = (int)T_Packet_Data.mx - (int)Tracking_Config_Data.Pan_Target_Pixel;
// Are we too far to the left or right of the vertical
// center line? If so, calculate how far we should step
// the pan servo to reduce the error.
if(pan_error > (int)Tracking_Config_Data.Pan_Allowable_Error)
{
// calculate how far we need to step the pan servo
servo_step = pan_error / (int)Tracking_Config_Data.Pan_Gain;
// Due to rounding error in the division calculation above,
// the step may be calculated as zero, which will make it
// impossible to converge on the target when pan_error is
// smaller than Pan_Gain. To get around this problem, we just
// test for the zero case and set the step size to one.
if(servo_step == 0)
{
servo_step = 1;
}
}
elseif(pan_error <-1* (int)Tracking_Config_Data.Pan_Allowable_Error)
{
// calculate how far we need to step the pan servo
servo_step = pan_error / (int)Tracking_Config_Data.Pan_Gain;
// Due to rounding error in the division calculation above,
// the step may be calculated as zero, which will make it
// impossible to converge on the target when pan_error is
// smaller than Pan_Gain. To get around this problem, we just
// test for the zero case and set the step size to one.
if(servo_step == 0)
{
servo_step = -1;
}
}
else
{
// if we've fallen through to here, it means that we're
// neither too far to the left or too far to the right
// of the vertical center line of the image and don't
// need to move the servo
servo_step =0;
// signal that the pan servo is on target
Tracking_State += STATE_PAN_ON_TARGET;
}
// add the step to the current servo position, taking into
// account the direction set by the user in tracking.h
temp_pan_servo += ((int)Tracking_Config_Data.Pan_Rotation_Sign * servo_step);
// check the pan servo PWM value for under/overflow
if(temp_pan_servo < (int)Tracking_Config_Data.Pan_Min_PWM)
{
temp_pan_servo = (int)Tracking_Config_Data.Pan_Min_PWM;
}
elseif(temp_pan_servo > (int)Tracking_Config_Data.Pan_Max_PWM)
{
temp_pan_servo = (int)Tracking_Config_Data.Pan_Max_PWM;
}
pan_servo_position = (unsigned char)temp_pan_servo;
// update pan servo PWM value
Set_Pan_Servo_Position(pan_servo_position);
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Running the robot without a tether | Hiromi | Technical Discussion | 3 | 05-10-2007 08:37 |
| PID How to hold an arm in a fixed position without a locking gear box | Ian_Xodus | General Forum | 29 | 28-01-2007 08:50 |
| PID without a Ph.D. | Joe Johnson | Programming | 3 | 07-02-2006 17:37 |
| Emergency: PID with Wheels Off the Ground | Rick TYler | Programming | 9 | 07-02-2006 11:37 |
| Drive Straight C Code using Encoders without PID? | Chris_Elston | Programming | 17 | 15-02-2005 23:41 |