16Apr/1210

## PID success!!

After many days ironing out a ridiculous amount of careless bugs plus a major break in the frame I have finally managed to get the PID algorithm keeping the quad level ðŸ˜€ At this point I *think* it would hover if released from its supports, but for now I would rather improve the code further to get it more responsive still.

The main change I am about to make is switching the output compare modules from PWM mode to single shot. This is because at the moment it takes a full PWM cycle before a new duty cycle can be loaded, adding a 2.5ms delay between the motors and the sensors. By locking the update rate to 400Hz, I should be able to trigger a new pulse as soon as the new duty cycle is calculated, completely removing this delay.

WyllyApril 25th, 2012 - 07:59

Nice! I’ve prepared a “similar” testing bench but I’ve got some doubts about PID settings. Which values did you use for the constants? I was thinking by starting with 5, 0.2 & 0.2 but I’m not sure if I’m way too far from useful values and I don’t want to chop my head off ðŸ™‚

Thanks!!

adminApril 25th, 2012 - 11:57

I’m currently using P=35, I=85, and D=30. I think I might drop KD down to around 25 to improve the command tracking a bit, and it’s important to note I calculate the integral term as I+=I*dt instead of just summing the error, meaning if you are just summing like most quads seem to you would need to use KI=85/400=0.21 (400Hz is my update rate). I also use a pretty tight wind up limit, meaning the integral term doesn’t really have a massive effect on the output, it’s just there to correct the small steady state error.

However as for tuning, I would say the best method would be to disregard any values I or anyone else has used, as they seem to vary a lot depending on the quad dimensions and the code behind it. I obtained mine by starting every constant at 0 and the throttle at 1/3, then used the serial connection to increment them individually until I achieved a response I liked, starting with P D then I.

Just make sure you have a kill switch, especially when first implementing the integral term ðŸ˜›

WyllyApril 25th, 2012 - 13:19

Thanks for the explanation. I’ll give it a try as you mention. This PID tuning seems to be the most obscure process for quads as almost everybody skips explaining it. I understand PID tuning is some “magic” process but I think it is actually the most interesting!

JohnMay 13th, 2012 - 14:55

Hi!, I’m traying to take the mathematic model of my quadcopter, but I have some problems with it. Â¿How did you do to obtain the values of PID terms? Â¿Had you used a Ziegler-Nichols method or something like that?

adminMay 13th, 2012 - 20:24

I tuned it by hand by increasing KD and KP until I achieved a response I liked, then slightly increased KI to eliminate the steady state error. However, on the next version I’ll be redesigning the loop, as at the moment the command tracking is very poor. I’ll probably do this by adding some sort of feed forward control, but I haven’t had the time to research this properly yet.

BenjaminJune 3rd, 2013 - 17:57

Hi,

I was looking at you code and it looks very nice and simple to understand. I am interested in the PID control part, and there is one thing that I don’t finish to understand though. How did you jump from here:

PID_XOUTPUT = XERROR*KP + XDIFFERENTIAL*KD + XINTEGRAL*KI;

PID_YOUTPUT = YERROR*KP + YDIFFERENTIAL*KD + YINTEGRAL*KI;

PID_ZOUTPUT = ZERROR*ZKP; + ZDIFFERENTIAL*ZKD;

to here:

OC1_output = 0.7071*PID_XOUTPUT + -0.7071*PID_YOUTPUT + PID_ZOUTPUT + MOTOR_MIN + MOTOR_RANGE*throttle;

OC2_output = 0.7071*PID_XOUTPUT + 0.7071*PID_YOUTPUT – PID_ZOUTPUT + MOTOR_MIN + MOTOR_RANGE*throttle;

OC3_output = -0.7071*PID_XOUTPUT + 0.7071*PID_YOUTPUT + PID_ZOUTPUT + MOTOR_MIN + MOTOR_RANGE*throttle;

OC4_output = -0.7071*PID_XOUTPUT + -0.7071*PID_YOUTPUT – PID_ZOUTPUT + MOTOR_MIN + MOTOR_RANGE*throttle;

I hope you can help me here a little bit. Where did you find, or how did you know this PID stratige to use. I mean I understande the PID, but from the PID result to the motor ouputs I don’t get it.

adminJune 3rd, 2013 - 18:03

The PID values represent the change required in each axis. In reality, this quad is in an X configuration, so each motor is affected by both the x and y PID outputs, meaning they must be ‘mixed’. This is what you see here. This mixed value is then added on top of the minimum motor speed along with the base throttle required.

BenjaminJune 3rd, 2013 - 18:25

wow, thanks for the fast answer :). yeah I unterstend the logic, I actually tought that it was a X configuration. But I don’t get why 1/sqrt(2)Pid_X -1/sqrt(2)Pid_Y + 1*Pid_Z … etc. Are you kind of normalizing the ouput? like a vector? How did you get to that mixed configuration.

I am programming a + configuration. So if I understand your logic, for me it whould be something like

Motor1 = Pid_xOuput + Pid_zOuput + Motor_Min + MotorRange*Throttle

Motor2 = Pid_yOuput + Pid_zOuput + Motor_Min + MotorRange*Throttle

Motor3 = -Pid_xOuput – Pid_zOuput + Motor_Min + MotorRange*Throttle

Motor4 = -Pid_yOuput – Pid_zOuput + Motor_Min + MotorRange*Throttle

BenjaminJune 3rd, 2013 - 18:45

I think the zOutput is wrong, it should be like this right?

Motor1 = Pid_xOuput + Pid_zOuput + Motor_Min + MotorRange*Throttle

Motor2 = Pid_yOuput – Pid_zOuput + Motor_Min + MotorRange*Throttle

Motor3 = -Pid_xOuput + Pid_zOuput + Motor_Min + MotorRange*Throttle

Motor4 = -Pid_yOuput â€“ Pid_zOuput + Motor_Min + MotorRange*Throttle

andrewJuly 8th, 2013 - 03:57

Where can I find the code for this?