I am a beginner in the realm of PID control loops, so if anybody is willing to help me point out any issues with my program that would be incredibly appreciated.
The issues are that our robots drivetrain will turn endlessly, and that It turns on the right side instead of turning in place.
Code Pasted below:
double kPAngle = 0.1;
double kIAngle = 0.0;
double kDAngle = 0.0;
double maxSpeed = 6;
void rotatePID(double angleTurn) {
double error = 0;
double lastError = 0;
double Derivative = 0;
double integral = 0;
double totalerror = 0;
while( fabs(Inertial.rotation() - angleTurn) > 0.5) {
error = angleTurn - Inertial.rotation(rotationUnits::deg);
derivative = error - lastError;
lastError = error;
if(fabs(error) < 5 && error != 0) {
integral += error;
}
else {
integral = 0;
}
if(abs(error) < integralBound) {
totalerror+=error;
}
else {
totalerror = 0;
}
//turntotalError += turnerror;
//This would cap the integral
turntotalError = abs(turntotalError) > maxTurnIntegral ? signnum_c(turntotalError) * maxTurnIntegral : turntotalError;
double powerDrive = error*kPAngle + Derivative*kDAngle + integral*kIAngle;
if(powerDrive > maxSpeed) {
powerDrive = maxSpeed;
}
else if(powerDrive < -maxSpeed) {
powerDrive = -maxSpeed;
}
//cout << "power: " << powerDrive << endl;
//cout << "angle: " << Inertial.rotation() << endl;
//cout << "error: " << error << endl;
// cout << "prevError: " << prevError << endl;
// cout << "derivative: " << derivative << endl;
// cout << "integral: " << integral*kIDrive << endl;
//cout << "////" << endl;
// turning = true;
// goalVoltage = powerDrive;
rightfront.spin(forward, powerDrive, voltageUnits::volt);
leftfront.spin(reverse, powerDrive, voltageUnits::volt);
rightback.spin(forward, powerDrive, voltageUnits::volt);
rightfront.spin(reverse, powerDrive, voltageUnits::volt);
this_thread::sleep_for(15);
}
// turning = false;
// goalVoltage = 0;
rightfront.stop(brakeType::brake);
leftfront.stop(brakeType::brake);
rightback.stop(brakeType::brake);
leftback.stop(brakeType::brake);
return;
}
/*---------------------------------------------------------------------------*/
/* */
/* Autonomous Task */
/* */
/* This task is used to control your robot during the autonomous phase of */
/* a VEX Competition. */
/* */
/* You must modify the code to add your own robot specific commands here. */
/*---------------------------------------------------------------------------*/
void autonomous(void) {
// ..........................................................................
// Insert autonomous user code here.
// ..........................................................................
vex::task initpid(drivePID);
Inertial.calibrate(2000);
this_thread::sleep_for(2000);
//cout << "Done calibrating" << endl;
Inertial.setRotation(270.00, rotationUnits::deg);
//cout << "rotation: " << Inertial.rotation() << endl;
rotatePID(180);
this_thread::sleep_for(1000);
rotatePID(90);
this_thread::sleep_for(1000);
rotatePID(0);
this_thread::sleep_for(1000);
rotatePID(-90);
this_thread::sleep_for(1000);
edit: code tags added by mods.