Hi all, i've been googling and reading up on plenty of projects and papers, but not much have been discussed about PID control and updating of PWM of quadrotor.

from my understanding, there are 2 ways of doing the quadrotor hover control..
1) brute force calibration, input = euler angles from IMU which most hobbyists do. set point=0 degree

front motor PWM = user_thrust + PIDpitch - PIDyaw
back motor PWM  = user_thrust -PIDpitch - PIDyaw
left motor PWM = user+thrust+PIDroll+PIDyaw
right motor PWM = user thrust -PIDroll + PIDyaw

wait, do we calibrate all PID parameters for pitch roll yaw at the same time or do we calibrate them separately like see-saw balancing? 

2) include dynamics, physics, consider moment of inertia.etcetc which research graduates do

Well i chose to use brute force calibration due to time constraints.
Here are some questions I have:
1) do we need to consider the Centre of Gravity in our PID control? My quadrotor's CG is more towards back motor.

2) What is the common frequency of PID control loop? Normally, the IMU data is updated then PID is updated right? The maximum I can go on my 16bit 33MHz MCU is 200Hz, and sending data wirelessly via XBee at 100Hz. Is it too slow?

3) I find my PID too slow because I can never find the Pgain(Igain=0 and Dgain=0) (i.e the pitch pole) that  does not oscillate.
We need some limit of the maximum and minimum PWM if we are flying autonomously. however, my PID always reaches the maximum and minimum limit and by the time the pole crosses 0degree, the pitch pole does not change direction even though the PID has caused the PWM to switch. Please see attached (problem.jpg) note that my pwm has been shifted down to see the effects with respect to error pitch.

4) What is the frequency of the PWM sent to the ESC? reverse engineering the common RF receivers, the pwm used should be 50Hz. If we're updating PID(200Hz) wouldn't the PWM be too slow?
However, i have found somebody doing a test that going beyond 50Hz PWM actually affects the motor's thrust, which does more harm than good. please see attached (wobbletest.jpg)

5) Using Pgain and Dgain together, the control has improved, but the pitch pole still oscillates up to +/-20degrees which is bad. Increasing Dgain any further causes the pole to be "stuck".

6) My prof had actually advised me to use PDsquare control but it doesn't help because Dsquare refers to d(error square)/dt= d/dt[d(error)/dt] right? if 1/dt = 200, then  will be multiplying the D term by 4000 which will hit the PWM limit even faster.

7) What is PID saturation, steady state error, integral windup, integral antiwindup? omg I'm noob with control theory.

/////My pid code in c/////

float inv_dt=200; // means 1/dt, pid loop at 200Hz
float error_pitch; //global variable
float fm,bm; //front motor and back motor pwm on cycle
float Kp_pitch,Ki_pitch,Kd_pitch; //set these values using my ground station when tuning

float PIDpitch(float Kp, float Ki, float Kd)
float previous_error;
previous_error= error_pitch;

error_pitch = 0 -    kalman_pitch; //set point = 0 degree

integral_pitch  += error_pitch*dt;

derivative_pitch = (error_pitch - previous_error)*inv_dt;         
return (Kp*error_pitch)+(Ki*integral_pitch)+(Kd*derivative_pitch);


void motorControl() //controls front and back motor's PWM
float pitch=0; int temp=0;
pitch = PIDpitch(Kp_pitch,Ki_pitch,Kd_pitch); //update PID loop


fm = 750 + pitch;                            //750=start off at 1.5ms
if(temp>1000)fm=1000;                    //max pwm limit 2ms 
else if(temp<600)fm=600;            //min pwm limit 1.2ms


bm = 750 - pitch;                            //750=start off at 1.5ms
if(temp>1000)bm=1000;                    //max pwm limit 2ms
else if(temp<600)bm=600;            //min pwm limit 1.2ms


Views: 13500


Reply to This

Replies to This Discussion

Hi Guiness, i am still analysing my control output, sensors output and is still stuck. do you have any progress?

i have been looking a many people's implementation. They said that we can first find a P gain(no D, no I) that does not make the pitch axis oscillate. but i just can't find it. i'm not sure if it is due to inertia. by the time IMU detects 0 degree pitch and the PWM changes sign, the inertia causes pitch axis to overshoot 0degrees.

hence the only way is to use PD controller. it works for me(+/- 5degrees) if i limit my PWM of opposite motors to a certain amount(i.e+-50 counts). but my professor said i should only limit it based using the maximum and minimum throttle(2ms and 1ms) if my pid control is working correctly.

i noticed my pitch derivative is very noisy. maybe it is because of that that i cannot reach a steady state. my pitch axis does not react fast to disturbance either. i'm not sure if it's because my P gain is too low.
Read this:
PID Explained

The Integral "I" term prevents overshoot.
thanks dean. but i never found the middle P in my case, it's always oscillating greatly from the set point:

quote from article
If you have too large a number for “P” then it over reacts and you get a rapidly oscillating out of control vehicle. If “P” is too small then it is too slow to react and by then the situation has changed and you get
a drunk vehicle. It’s important to slightly reach these conditions to
understand where the middle is"

I admittedly am not working on an actual quad-rotor, but have some control experience - I think one thing to think about is how the PWM signal relates to actually reducing the attitude error. The PWM signal will change motor RPM, which will change rotational acceleration. Since acceleration is the 2nd derivative of attitude, it may be difficult to to find a set of PID gains that work well. Another approach might be to close the PID loop on pitch rate, so P = pitch rate error, D = pitch acceleration, I = attitude. Then, you could calculate a 'pitch rate command' based on the error between the actual and desired attitudes: PID error = (pitch_rate_command - actual_pitch_rate) = ((desired_attitude - actual_attitude)*P_att - actual_pitch_rate). You may also want to limit the maximum pitch_rate_command that can be generated.
here's how the pitch response curve looks like when i adjust the P gain only, which in turn controls PWM supplied..
1) You can consider CG - but at a beginner level you can ignore it. Just be aware you'll probably need an I or Integral term

2) Different quads have different rates. 50 Hz is probably a bare minimum loop iteration rate. 200 Hz should be fine

4) Different ESCs can be communicated with at different rates. The Turnigy Plushes have been shown to handle 400 Hz rates

7) I think PDsquared refers to taking the second derivative of the error, not the square of the first derivative.

See if these links help at all:


Something seems wrong with your latest implementation. The front and rear PWM motor commands are moving apart, yet there is no pitch motion for quite some time, then the pitch response takes off, then it holds again until the PWM has built up again. Are you sure you have the PWM coded properly?

- Roy
The integral term reduces steady-state error. Too much I can actually cause overshoots. Typically the derivative or D term is what reduces overshoot.

- Roy
Im working on my quadrotors PID. Somehow I have some concerns about suppyling power from Li Po's. As you know brushless motors can supply different thrusts on different voltage levels supplied from Li Po's.
For example while using fully charged 12.6V 3S Lipo on 9000rpm with XX brand brushless, it can supply 900gr thrust. On the other hand, everything same but Lipo charged only 11.0V, it may supply like 820gr thrust.
Therefore, because of different voltage conditions, PID parameters will never match. It will be ok only if I have a voltage feedback from LiPo's and then change PID parameters for each voltage level. Adding voltage feedback on the control algorithm will solve the problem i guess. Anyone do this kind of feedback for their PID ? Thanks, have a nice one...

      I have found a solution to my previous question, but i have another now :) 

Quadrotor and brushless motors used in the Quad systems are not LINEAR. So PID control design shouldnt work well with it if you run your brushless motors in nonlinear region. However, brushless motors have some region which is almost linear, So PID is ok to use in that range as a control method. So system must be linearized, then PID method should be used, thats what its needed. Here is an example of  angular velocity versus pulse width. Its seen that there are nonlinear region.

  The question im asking is do you guys measure your brushless and use that linear range before you write control algorithm ?  Or just go for PID tuning and try to find parameters ?  AeroQuad or ArduCopter  codes are ready to use, so I guess most of the Quad users just go with PID tuning. Any comment will help, thanks...



Recall that the PID loops want the thrust response to be linear, not RPM. Thrust is actually proportional to RPM squared. Looking at this plot (thanks for the data, by the way), it may work out that the pulse width to thrust response might actually be linear. Other data I've seen suggests the same conclusion.


- Roy

Thanks Roy. I asked this because im reading and searching about design, not only interested building Arducopter. The data is from one of the guys master thesis. As I read from the theses he makes linearization like on the data, measures each brushless and plot pwm versus speed of them. Then draws regression line, finds transfer function ( brushless gains etc ) then finds system model, then finally find PID parameters accourding to design. Since i dont see these kind of stuff here between ArduCopter people, i felt just a little curious.

hey guys i found a serious bloody error in my pid highlighted in red.

Reply to Discussion


© 2019   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service