Good day,
I would like to ask why is it that when I add the Yaw control to my PID controller for each motor. The quadcopter refuses to take off or maintain its altitude. I am curently using a Cascaded PID controller for attitude hold using an Accelerometer, a Magnetometer and a Gyroscope, and a 40Hz Ultrasonic Sensor for Altitude Hold. Since the scope is indoor I have done away with the barometer due to its +-12m error.
Resulting Response
Without Yaw Control, the plot below shows the response of the quadrotor.
With Yaw Control, the plot below shows the response of the quadrotor.
Debugging
I found out that each of the outputs from each PID's give a too high of a value such that when summed together goes way over the PWM limit of 205 or Full Throttle.
Without yawPID contribution The limiter kicks in without damaging the desired response of the system thus is still able to fly albeit with oscillatory motion along the z axis or height
- With yawPID contribution
The added yaw components increases the sum of the PID's way above the limit thus the limiter compesates the excess too much resulting in an over all lower PWM output for all motors thus the quad never leaves the ground.
//Motor Front Left (1) float motorPwm1 = pitchPID + rollPID + yawPID + baseThrottle + baseCompensation;
//Motor Front Right (2) float motorPwm2 = pitchPID - rollPID - yawPID + baseThrottle + baseCompensation;
//Motor Back Left (3) float motorPwm3 = -pitchPID + rollPID - yawPID + baseThrottle + baseCompensation;
//Motor Back Right (4) float motorPwm4 = -pitchPID - rollPID + yawPID + baseThrottle + baseCompensation;
- With yawPID contribution
The added yaw components increases the sum of the PID's way above the limit thus the limiter compesates the excess too much resulting in an over all lower PWM output for all motors thus the quad never leaves the ground.
Background
The PID parameters for the Pitch, Yaw and Roll were tuned individually meaning, the base throttle was set to a minimum value required for the quadcopter to be able to lift itself.
The PID parameters for the Altitude Sensor is tuned with the other controllers active (Pitch and Roll).
Possible Problem
- Limiter algorithm
A possible problem is that the algorithm I used to limit the maximum and the minimum throttle value may have caused the problem. The following code is used to maintain the ratio of the motor values instead of limiting them. The code is used as a two stage limiter. In the 1st stage, if one motorPWM is less than the set baseThrottle, the algorithm increases each motor PWM value until none of them are below that. In the 2nd stage, if one motorPWM is more than the set maxThrottle, the algorithm decreases each motor PWM value until none of them are above that.
//Check if PWM is Saturating - This method is used to fill then trim the outputs of the pwm that gets fed into the gpioPWM() function to avoid exceeding the earlier set maximum throttle while maintaining the ratios of the 4 motor throttles.
float motorPWM[4] = {motorPwm1, motorPwm2, motorPwm3, motorPwm4};
float minPWM = motorPWM[0];
int i;
for(i=0; i<4; i++){ // Get minimum PWM for filling
if(motorPWM[i]<minPWM){
minPWM=motorPWM[i];
}
}
cout << " MinPWM = " << minPWM << endl;
if(minPWM<baseThrottle){
float fillPwm=baseThrottle-minPWM; //Get deficiency and use this to fill all 4 motors
cout << " Fill = " << fillPwm << endl;
motorPwm1=motorPwm1+fillPwm;
motorPwm2=motorPwm2+fillPwm;
motorPwm3=motorPwm3+fillPwm;
motorPwm4=motorPwm4+fillPwm;
}
float motorPWM2[4] = {motorPwm1, motorPwm2, motorPwm3, motorPwm4};
float maxPWM = motorPWM2[0];
for(i=0; i<4; i++){ // Get max PWM for trimming
if(motorPWM2[i]>maxPWM){
maxPWM=motorPWM2[i];
}
}
cout << " MaxPWM = " << maxPWM << endl;
if(maxPWM>maxThrottle){
float trimPwm=maxPWM-maxThrottle; //Get excess and use this to trim all 4 motors
cout << " Trim = " << trimPwm << endl;
motorPwm1=motorPwm1-trimPwm;
motorPwm2=motorPwm2-trimPwm;
motorPwm3=motorPwm3-trimPwm;
motorPwm4=motorPwm4-trimPwm;
}
This was obtained from pixhawk. However the difference is that they employ only upper bound compensation limiting, while mine also performs lower bound compensation limiting which may cause more saturation once it reaches the second stage.
From:https://pixhawk.org/dev/mixing
- Gains are set too high.
It is also possible that I've set my P gains too high thus exceeding the max RPM limit of the motors causing the Limiter algorithm to overcompensate.
Current PID Settings:
The minimum motor value for the quad to lift itself is 160 while the maximum limit is 200 from the PWM time high of 2000ms
- Pitch (Cascaded P-PID controller) Rate P = 0.07 Rate I = 0.03 Rate D = 0.0001 Stabilize P = 2
- Roll (Cascaded P-PID controller) Rate P = 0.09 Rate I = 0.03 Rate D = 0.0001 Stabilize P = 2
- Yaw (Cascaded P-PID controller) Rate P = 0.09 Rate I = 0.03 Rate D = 0.0001 Stabilize P = 2
- Hover (Single loop PD controller) P = 0.7 D = 35
Possible Solution
I think I have set the PID parameters particularly the P or D gain too high that the computed sum of the outputs of the controller is beyond the limit. Maybe retuning them would help.
I would just like to ask if anyone has encountered this problem or if you have any suggestions. Thank you :)
EDIT
I have added the plots of the response when the control loop is fast (500Hz) and Slow (300Hz)