What is a PID controller?

So I have been trying to understand the concept of what PID is and how it works? I don’t really understand how to implement it pros and cons, and the differences between P and PD loops. Any help would be greatly appreciated.

3 Likes

This should help. A lot.

2 Likes

Thanks a lot for this guide. I am still a little confused on how to implement this into a turn function. If you could help with that, it would be greatly appreciated.

The p part is proportional, or what we nickname “error”. error = desiredValue - currentValue. This is a position, or delta x

So if you get the derivative of error (which error is a position, or delta x), you will get speed (error - previousError). So, you can use the this to help correct if the robot is moving too fast or too slow due to external sources like additional unknown friction or battery crapping out.

How the derivative is applied in code is by error(current error at the moment) - previousError(error a couple of miliseconds ago, usually 20 miliseconds ago)

So if you get the integral of position you would get absement, which is meter seconds of position is in meters.
Absement is

integral is first initiated outside of a loop set to 0. Whenever you find the integral of something and google it, you will find an equation + C. C is the starting position at time = 0, similar to y = mx+ b where b is the y intercept. That is why you have to initialize integral’s starting position, and since everything starts out with no motion you should always set it to 0.

Inside of the while loop, integral is created by
integral = integral + error (we sometimes call this totalError)

If we want to apply this to code (this is ROBOTC code I made a while ago, but can be easily converted to vexcode or any other code):

task usercontrol(){
int target = 0;
int previousError = 0;
int totalError = 0;

//Tune here
double kP = 0.054;
double kI = 0.043;
double kD = 0.42;

while(1==1){

if(vexRT[Btn6U] == 1){
target = 300;
}
else{
target = 0;
}

int error = SensorValue[Ecoder] - target;
totalError += error;
int derivative = error - previousError;

int motorPower = (error * kP + totalError * kI + derivative * kD); //Add values up
motor[Wrist] = motorPower; //Apply values to motor

//Since code is read from top to bottom, this will be read, 
//then 20 miliseconds will pass before the next loop causing this value
//To become a value 20 miliseconds ago
previousError = error; 
wait1msec(20);
}

}

Edit//: code fix

11 Likes

I was wondering how I would change the “desiredValue” and “desiredTurnValue” from ticks to degrees in the autonomous?

Note: I’m assuming you turned this into VEXcode so my response will be based on VEXCode

//These should be global, outside of while loops and whatever.
double degrees_to_ticks_conversion = 1/5; //gear ratio

void move_to_angle(double degrees){
desiredValue = degrees *  degrees_to_ticks_conversion ;
}

then call with:

move_to_angle(15);
1 Like

Hey Connor,

I was watching the PID video and instead of setting the position to 0, would using resetposition() also work?

If your setting the position to zero while at zero nothing should happen, same with resetposition(). But if your current position is 20 and you set the position to 0, the robot will move to zero. From there resetposition will not move the robot position to 0, rather make 20 0. Im really good at explaining things as you can tell…

1 Like

I get what you mean.
So should I set position to 0 like how Connor does in the video or should I use the resetposition function to set the encoder value to 0 and not move the robot

Depends on what you want to do

Hey Connor, I was watching your PID video and set everything up, but how would you set up the function to have the robot move to the desired encoder value, and then call that function in autonomous? An example code would be extremely helpful. Thanks so much.