Multicopter is an unstable machine. It requires constant corrections to keep is stable in the air. This is done with PID control loop. When quadcopter does not fly like you hoped, you will hear: “Tune your PIDs“. Nice. But what exactly is PID? If you did not studied control theory, and you do not want to start, you read internet. And internet tries to explain PID in various ways. Some are better, some are worse, and there is always room for a new one. So here we go.
Officially, PID goes for Proportional, Integral, Derivative. Wikipedia provides enough of long and boring theory. If it’s TL;DR, here is a short summary:
- PID controller measures error of current output and desired output,
- This error is processed separately by P, I and D modules,
- Then, output of each module is multiplied by it’s coefficient (Kp, Ki, Kd) and added all together as an controllers output,
- Controller can be tuned by changing Kp, Ki and Kd values,
- In a multicopter, there is separate controller for each axis (roll, pitch, yaw) working based on rotation speed provided by gyros. This is called and “inner loop”.
- Some flight modes adds “outer loop” with separate PID controller that is translating user input into values used by “inner loop”. Outer loop is much less important than inner loop and usually there is not need to tune it,
- Flight modes like Attitude, Angle, Horizon (all with self leveling) are using both outer and inner loop,
- Flight modes like Rate, Acro and using only inner loop,
- When speaking on PID tuning, in 99% of cases we will be talking about tuning the “inner loop”,
- Inner loop tuning should be done only in Rate/Acro flight modes (no self leveling) and avoid complex outer-inner loop interactions.
Now, the only thing that is missing, is an explanation why there are 3 PID modules and what they are responsible for.
- Proportional (P) is working on current error. This is simple: “input says that we should not rotate, but gyro tells me we are rotating left. That means, that motors on the left are not giving enough thrust and we should increase their rotation speed. To do this, I will multiply input error by Ki and I am done.”.
- Integral (I) is working on past errors. “Gyro says we are rotating left, but I do not care very much about that. My memory says that until now we were mostly rotating right. Probably because right side is heavier, or motors are weaker. And according to my knowledge motors on the right should still have more rotation speed than those on the left.”. This is very important to remember: I is responsible for things like uneven weight distribution, wind compensation, slow drift. Not current stick input.
- Derivative (D) is working on future error. “Gyro says we are rotating left with a speed of 10 deg per second. Last time we checked we were not rotating at all. That means, that comparing to last check, our rotation speed increased by 10 deg/s. Next time, we will be rotating 20 deg/s and we should not be rotating. That requires a big correction”. But D is very imprecise. Predicting future is not easy. That means, that D is wrong very very often and Kd should be kept low not to implement too much error and noise to the output. But because it can predict future, it is very useful in the finishing sequence on movement. It can look like this: “Gyro says we should be rotating right with a speed of 20 deg/s. Right now we are rotating with a speed of 17 deg/s and previously with a speed of 9 deg/s. That gives us acceleration of 8 deg/s and in the next iteration we will be doing 25 deg/s. That will be too fast, we should start breaking right now, even that we did not reached our target.”. In other words: D adds smoothness. Without it movement would be robotic and shaky. But too much D would also make everything shakes because of noise.
PID tuning is all about finding optimal balance between Kp, Ki and Kd. Too much, or not enough of one of them and whole machine will be either “drunk” or too snappy and shaking like crazy. To make that harder, there is no single “good” PID tune. Slightly different weight distribution or center of weight shifted back can require a little different PIDs. Right now let’s take a look at this screen taken from Cleanflight’s Blackbox log of my Reptile 500 quadcopter.
In this example I wanted to roll right. As you can see, P and D output values are correlated with gyro’s readout. They start to rise a moment before movement begins. Then, when rotation speed is closing to target, they go to 0, but D is going down before P, to make transition smoother. And when I finally want to stop rotating (more less 2/3 of a graph) P and D goes down to stop rotation. And once again D is trying to stop the movement even before target is reached. And what I does? Not much. It is rather not reacting to stick movements. It is almost flat. It’s job is to compensate for long term errors, but stick movements. One final thought about this particular Blackbox graph: in this example both P and D are probably too high. It is not visible on a screen, but there is a constant roll axis oscillation and D is introducing too much noise. I seems to be fine.