Hi,
I'd apprecieate some guidence on using a PID ontroller in a two wheeled balancing robot. I'm trying to learn a new skill but I think I'm missing something.
Would I be correct in saying that in a PID algorithm, if the error persisted over a period, the output should also continue to try and correct the error?
Put another way, I'm using an MCU605 to calculate the angle of my robot, which seems to be working. MY PID set-point is 0. When I change the angle of the MPU 6050 to say 20 deg (a error of 20), the PID algorithm breifly supplies a output to correct the error, then the output drops back to 0, even though the error is still 20.
I have set my arduino loop to sample every 100 millis, and I believe the PID algorithm is set accordingly.
So my question is should the PID output continue to be greater than 0 if my error continues to be greater than zero?
I probably need to go back to basics.
In the code below, I use a updateMovingAverage() method and strucure to remove some of the noise in the data. I've run that with a plotter and it seems solid.
For the PID algorithm I'm using br3ttb/PID @ ^1.2.1.
void setup() {
Serial.begin(115200);
while (!Serial)
delay(10); // will pause Zero, Leonardo, etc until serial console opens
// Try to initialize!
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
Serial.println("MPU6050 Found!");
mpu.setAccelerometerRange(MPU6050_RANGE_2_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
maAngle = createMovingAverage(WINDOW_SIZE);
//turn the PID on
myPID.SetMode(AUTOMATIC);
myPID.SetSampleTime(delaySize);
}
void loop() {
currentTime = millis();
if(currentTime - previousTime > delaySize){
previousTime = currentTime;
/* Get new sensor events with the readings */
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
float accYDrift=0;
float accZDrift=0;
float accY = a.acceleration.y + accYDrift;
float accX = a.acceleration.x;
float accZ = a.acceleration.z + accZDrift;
//float gyroX = g.gyro.x + gyroXdrift;
float gyroX = g.gyro.roll;
currentAngle = atan2(accY, accZ)*RAD_TO_DEG + ANGLE_OFFSET;
float currentAngleAvg = updateMovingAverage(maAngle, currentAngle);
Input = currentAngleAvg;
myPID.Compute();
Serial.print(" accY:");
Serial.print(accY);
Serial.print(" ,accZ:");
Serial.print(accZ);
Serial.print(" ,currentAngle:");
Serial.print(currentAngle);
Serial.print(" ,currentAngleAvg:");
Serial.print(currentAngleAvg);
Serial.print(" ,Input:");
Serial.print(Input);
Serial.print(" ,Output:");
Serial.println(Output);
}
}