The best explanation I've found about quadcopter flight control is Gareth Owen's article called "How to build your own Quadcopter Autopilot / Flight Controller". Basically, you can control a quadcopter in two different ways:
- In "Acrobatic" or "Rate" mode: the user's input (i.e. moving the sticks on the transmitter) tells the controller at what rate/speed the aircraft should rotate on each axis (yaw, pitch and roll). In this mode the user is constantly adjusting the quadcopter rotational speed which is a bit tricky but allows acrobatic maneuvers, hence it's name! The "acro" controller is the easiest you can implement and it only requires a gyroscope in terms of hardware. The basic KK board I was using previously is an Acro controller.
- In "Stabilized" mode: this time the user's inputs indicate the angles on each axis that the aircraft should hold. This is far easier to pilot: for example: if you center the sticks, the aircraft levels. Technically, a stabilized flight controller internally uses an Acro flight controller. In terms of hardware, in addition to the gyroscope, this controller needs an accelerometer (to distinguish up from down), and optionally a magnetometer (to get an absolute reference frame).
So let's start at the very beginning: an Acro flight controller working on a single axis. Here's the kind of loop behind such a controller:
- Get the latest user's inputs:
- The desired rotation rate around the axis (in degrees per second)
- The throttle value (in my case, unit-less "motor-power" between 0 and 1)
- Get a reading from the gyroscope (a rotation rate in degrees per second)
- Determine the difference between the measured rotation rate and the desired one: this is the error (still in degrees per second)
- Use the PID magic on this error to calculate the amount of motor-power to apply to correct the error. This is the same unit as the throttle.
- Add this correction to the throttle value, and send the result to one motors. Subtract the correction from the throttle value and send the result to the second one (the [0..1] value is converted into a pulse-width in microseconds, i.e a PWM signal that the ESCs understand)
And repeat this loop as frequently as possible (for me: the flight control is done at 125Hz, the gyro reading at 250Hz, and the user's input reading at 50Hz). And this is what the result looks like:
- green: gyroscope reading
- blue: user's "desired" angular rate
- red: throttle value
Notice how the quadcopter rotates at constant speed when the desired angular rate stays at the same non-zero value.