PID Control
Posted: 27 Feb 2012, 19:03
Hello,
I've build an nxt robot which uses pid to follow a line.
It is quite slow due to the motors (nxt motors without external gears), so i didn't use the Derivative.
I did use the Proportional part. (of course !)
My Question is: Do I need the Integral for a line follower ? What are the benefits of (not) using it ?
I tought it would be quite jerky with the integral so i added a "forgetrate", which is: integral = integral*forgetRate + error;
My code: (it's only the important part)
I've build an nxt robot which uses pid to follow a line.
It is quite slow due to the motors (nxt motors without external gears), so i didn't use the Derivative.
I did use the Proportional part. (of course !)
My Question is: Do I need the Integral for a line follower ? What are the benefits of (not) using it ?
I tought it would be quite jerky with the integral so i added a "forgetrate", which is: integral = integral*forgetRate + error;
My code: (it's only the important part)
Code: Select all
#define Kp 1.5
#define Ki 0.2
#define Kd 0.0
#define FORGETRATE 0.5
#define SPEED 1.5
task main(){
light_l = limit( scale(SENSOR_L/1.0, minl, maxl, 0.0, 100.0) , 0.0, 100.0); // read and scale (calibrate) sensors
light_r = limit( scale(SENSOR_R/1.0, minr, maxr, 0.0, 100.0) , 0.0, 100.0);
error = (100-light_l) - (100-light_r); //difference between left and right sensor is the error
integral = integral*FORGETRATE + error;
derivative = error - lastError;
direction = Kp*error + Ki*integral + Kd*derivative;
OnFwd(OUT_B, limit( (50 - direction)*SPEED , -100, 100));
OnFwd(OUT_C, limit( (50 +direction)*SPEED , -100, 100));
lastError = error;
}
float scale(float value, float valueMin, float valueMax, float desiredMin, float desiredMax){
return (desiredMax - desiredMin) * (value - valueMin) / (valueMax - valueMin) + desiredMin;
}
float limit(float value, float valueMin, float valueMax){
if(value <= valueMin)
return valueMin;
else if(value >= valueMax)
return valueMax;
else
return value;
}