PID altitude control of a Quadcopter

I’m a work experience student who was tasked with using a PID controller and a barometer to control the altitude of a Crazyflie quadcopter. Although I had active control of the upwards forces getting it to go upwards or the thrust, I had much less control for making the quadcopter come back down — gravity would be doing that for me.

What is a PID controller?

A PID controller is basically made up of three parts:

Proportional term. Produces an output value that is proportional to the current error value.

This means that when this value was too large the quadcopter seemed to be flying all over the place not correcting anything. But in reality it was over-compensating for the error that was there. For example, when I was just blindly messing around with the values at the start (thanks to Simon for the extreme patience) and I set the p value to 100, this meant that a 3 degree error would be corrected with a 300 degree force, which gave the impression of random flight. However, when this value was too small, the error took a long time to be corrected and the quadcopter crashed.

Integral term. This is the sum of the instantaneous error over time.

I didn’t really touch this value, but it basically takes into consideration the magnitude of the error as well as the duration. So the longer the error persists, the larger the magnitude of the force is applied.

Derivative term. This is found by determining the gradient of the of the error over time.

I didn’t touch this value either. However, I am told that it reduces the overshoot.

CrazyFlie 2.0 Quadcopter

The Crazyflie 2.0 is a small, lightweight quadcopter that can be programmed using Python. Although it may be very lightweight and manoeuvrable, this also makes it very easy to crash. This happened a lot, which may have had something to do with my programming inexperience, but making replacement parts meant that I got to witness the thing of beauty which was the 3D printer.

Python itself was a very useful tool as I was able to instantly check and test my scripts and values. This meant I had instant feedback when trying to find things like initial thrust values.

The task

As I said at the start, my task was just to get the quadcopter to hover at a controlled height. However, I struggled to get the quadcopter off the ground. This lead to the creation of a “rapidly wind up” command which allowed the quadcopter to achieve the thrust value and height before the PID controller kicked in.


Another challenge was understanding how the p gain worked. In an ideal world the force needed to correct the quadcopter when it’s below the “zero error” line would equal the force needed when it is above. However, in reality the force needed to correct the error above and below was different. This is because gravity is acting on the quadcopter. Therefore, two values for the PID controller for altitude (p and p_low) were needed. This was another example where instant feedback from the Python scripts was useful.

Another skill I learned was interpreting the results from the command window. This meant that when the quadcopter scripts did fail I was able to more quickly resolve issues. For example, knowing that attitude was too high and that it wasn’t thrust values causing the quadcopter to cut out.

One issue I did have was controlling the attitude, I.e. the pitch, roll and yaw. This could have been easily addressed by setting all the values to zero. However, the quadcopter, especially after being broken numerous times, couldn’t take off straight. So to counteract the uneven take-off, the initial pitch, roll and yaw were changed. Unfortunately, after take-off these values meant the quadcopter was not straight in the air, so often veered off-course. This is a good example where the PID controller would be very useful, as I could have set the initial parameters to get the quadcopter off the ground straight, but set the “zero error” mark on the PID controller for pitch, roll and yaw to zero. This way the quadcopter would have climbed using the initial pitch, roll and yaw values and then when it reached the preferred altitude it would switch to the “zero error” values allowing the PID to do all the work. This would have made accurately controlling the altitude a lot easier.


I have been thoroughly inspired to learn how to code using Python and enjoyed having got to play with a quadcopter for three days.

Quadcopter image source: