As a bonus I'll explain the sensor that I used and how I used it to obtain a good result. On the one hand, the sensor fusion between the gyroscope and accelerometer is very useful to control the quadcopter horizontality, and on the other, the altitude of the quadcopter is also a good data to obtain, and is measured using the pressure sensor and the temperature sensor.

Sensor fusion

In order to maintain the horizontality of the device, we use two angles, pitch and roll. These two angles are measured using two sensors: accelerometer and gyroscope. Both have their advantages and disadvantages. The accelerometer can measure the force of the gravity, and with that information we can obtain the angle of the device. The problem of the accelerometer is that it can also measure the rest of the forces the device is subjected to, so it makes a lot of errors and noise. The gyroscope measures the angular velocity, so if we integrate this data we can obtain how much the angle is moved. The problem of this measure is that is not perfect and the integration has a deviation. That means that in a short span of time the measure is very good, but for longer spans the measure angle will deviate much from the real angle.

Combining both sensors can solve these problems. That’s called sensor fusion, and there are a lot of methods to combine them. In this project I have tried two of them: the Kalman Filter, and the complementary filter.

The Kalman filter is an algorithm very extended in robotics, and offers a good result with low computational cost. There is an Arduino's library that implements this method, but if you want to learn more about that method or implement it by yourself look at this page.

The Complementary filter is a combination of two or more filters that connect the information from different sources and gets an estimation of the real value. It can be implement in only one line of code. For more information visit this page.

angle = A * (angle + gyro * dt) + (1 - A) * accel;

where A is normally equals to 0.98.

First I tried to use a Kalman filter but I did not obtain good results. The angle was calculated with a little delay and it affected the control. The Kalman filter has three variables that you can change based on the parameters of your sensors, and by doing this you can obtain better results. I tried to change the values, but I did not get better results so I decided to implement the complementary filter. It happened to be much easier and had a lesser computational cost. The complementary filter worked fine for me.

Sea level height

In order to control the position of our quadcopter we need to know the altitude. This can be measured by the combination of a pressure sensor and a temperature sensor. It can be obtained only from the pressure data, using the following equation:

H = 44330 ( 1 - ( Pressure_measured / 101325 ) ^ ( 1 / 5.25588 ) )

i obtained the equation form the datasheet of the sensor I used (BMP085) This equation is based on the Barometric Formula using the data of the standard atmosphere That means that is not true in every case, but for non-precise applications is enough. For more precise applications we need to use temperature and pressure, using the next formula:

H = ( ( ( 101325 / P ) ^ ( 1 / 5.257 ) - 1) * ( T + 273.15 ) ) / 0.0065

I'm not sure if this formula is correct, but it seems to work. There is a page where you can calculate the altitude providing the pressure at sea level and the pressure and temperature at the point you want to calculate the altitude.

Note: In this two formulas the altitude is calculated relative to the sea level, so if you want to get the altitude relative to the ground you have to measure first the altitude at ground level and subtract it from the subsequent measures.