Hey guys! I’ve avoided programming PIDs for a while because they have always seemed intimidating and difficult to get right, but this year is the year, I finally decided to use a PID to control our robot in autonomous.
Actually, it’s turned out to be a little easier than I initially thought it might be. The proportional part totally makes sense and seems relatively easy to tune, (I just tune it so that it slightly undershoots, right?) but it’s the I and the D that are getting me.
From what I understand, it’s not usually necessary to use a true PID controller, but only a PI, so I’ve simply avoided the D part up to this point. So, here’s what I did:
First, tuned the P variable so that the robot slightly undershot. From what I understand, the I should take care of the undershoot. Second, I tried to tune the I to correct for the undershoot but I simply could not find a number that would get the results I want. If the I value was to high, the robot would overshoot significantly, and after a good amount of time (like 10 seconds), correct itself. If it was too low, it would still undershoot and never reach the target value. I did eventually find a number for the I that worked pretty well, but as soon as I would change the target distance, the exact same problems resurfaced.
So is my tuning process incorrect? Am I missing something? Please let me know. Here’s my code:
resetMotorEncoder(left);
resetMotorEncoder(right);
int errorLeft;
int errorRight;
float kP = 0.177;
//float kI = 0.000000005;
float kI = 0.0000001;
int integralLeft = 0;
int integralRight = 0;
int PIDDriveLeft;
int PIDDriveRight;
while(true) {
errorLeft = PIDTargetValueLeft - getMotorEncoder(left);
errorRight = PIDTargetValueRight - getMotorEncoder(right);
integralLeft += errorLeft;
integralRight += errorRight;
PIDDriveLeft = kP*errorLeft + kI*integralLeft;
PIDDriveRight = kP*errorRight + kI*integralRight;
motor[left] = PIDDriveLeft;
motor[right] = PIDDriveRight;
}
Only final thought:
ROBOTC has a built in PID tuning function, but I had some trouble getting that to work since you cannot disable each individual controller to tune one variable at a time, you must use all three variables. I’m wondering if there is a way to turn each off that I’m just missing, and if there is, could that controller potentially be superior to the one that I created? Our team was hoping to use a gyro sensor for turns, but there isn’t a PID programmer built into ROBOTC for the gyro, correct? Or could simply using the integrated PID controller in ROBOTC with just the integrated encoders be more effective than using the gyro?
Please let me know. Thanks, guys!