The quadcopter : control the orientation

We will use use these axes as reference

Quadcopter principle

The quadcopter orientation can be defined by three angles : Pitch, Roll, and Yaw. These angles determine orientation and therefore the direction the quadcopter will take. Basically, changing the pitch will make the quadcopter go forward/backward, the roll Β bend to the left/right, and finally the yaw will make it rotate around its vertical axis.

So, to fully control a quadcopter- i.e make it go where you want over your neighbors' garden to spy on them- you just need to control these 3 angles. Do you? Almost ;). You need a 4th parameter, the throttle of the rotors. Obviously, if the propellers are not spinning, it would be hard to take off, wouldn't it? πŸ˜‰ But let's forget about that and assume that the throttle is sufficient enough so the drone takes off.

Control individually pitch, roll and yaw angles

In order to change the pitch and roll angles , the main idea is to change each motors speed so the quadcopter starts bending in the desired direction. Let's formalize things a bit and define the motors "power" Β in Β C++ language style :

int motor1Power, motor3Power; // Motors on the X axis

//=>; changing their speeds will affect the pitch

int motor2Power, motor4Power; // Motors on the Y axis

//=>; changing their speeds will affect the roll

As I said in the previous paragraph, the motors power depends on the throttle you can give them with a remote control for example. A simple implementation of this in an Arduino-like sketch would look like this

void loop(){

motor1Power = throttle;

motor2Power = throttle;

motor3Power = throttle;

motor4Power = throttle;


What is done here is just simply redirecting the throttle input (coming from a remote control for example) to the motors, which will just concretely change the altitude/ vertical speed of the drone.

Now, let's think a bit about how to make the quadcopter move forward/ backward . This motion corresponds to the pitch angle. In order to change the pitch, we only need to change the speed of the two motors on the X axis. Indeed, affecting the speed of the motors 2 and 4 (on the Y axis) would just start a rotation around the X axis (therefore changing the roll angle).

But how to change the first and third motors speeds?

If you try adding the same value offset to the motors speed, it won't change anything because what you need in order to incline the aircraft is a difference in the motors speed. Imagine you attach two weights of one kg to the two opposite motors, what happens to the pitch? Nothing, you would need to attach different weights to incline the quadcopter. It's very intuitive and works exactly the same with the motors speed!

The best way to get different motors speed is to add the offset value one one motor output, and to subtract it on the other, so the "overall throttle " of the axis remains constant and therefore changing the pitch won't affect the quadcopter's "vertical speed"

 Throttle_{13} = \frac {(throttle + offset)+(throttle-offset)} 2 =throttle

By the same method, you can change the roll angle by changing motors speeds on the Y axis (in our example motors 2 and 4) and therefore control separately pitch and roll! Let's look at the updated pseudo-code introducing two new inputs pitchOffset and rollOffset

void loop(){

motor1Power = throttle + pitchOffset;

motor2Power = throttle + rollOffset;

motor3Power = throttle - pitchOffset;

motor4Power = throttle - rollOffset;


And that's it! This is how the pitch and roll are controlled.

Β The yaw..

Why is the yaw different? Because it's not a matter of inclination here, so changing two motors speed won't make it. But i forgot Β to tell you a little detail about quadcopters πŸ˜‰ Two propellers turn clockwise, the two others turn counterclockwise. And how does it help you? The answer is the torque . When an object rotates around an axis, it creates a torque, creating a rotation movement of the body holding the propeller, and that's why traditional helicopters have an anti torque rotor on their tail, keeping the rotorcraft from spinning until the pilot pukes (it is more likely he dies in an awful crash). With opposite rotations, the quadcopter doesn't need and anti-torque tail, one axis compensating the torque of the other.

Changing the torque and therefore the yaw seems now really simple,doesn't it? Just add a yawOffset to the speed of two motors on the same axis, while you subtract it from the speeds on the other axis (so the overall throttle doesn't change). The final code looks like this:

void loop(){

motor1Power = throttle + pitchOffset + yawOffset;

motor2Power = throttle + rollOffset  - yawOffsett;

motor3Power = throttle - pitchOffset + yawOffsett;

motor4Power = throttle - rollOffset  - yawOffsett;



And that's it for the basics of how to control a quadcopter, hope it was clear and detailed enough. If you want to take it to the next level and auto stabilize your quadcopter, it's right here πŸ˜‰

42 thoughts on “The quadcopter : control the orientation

  1. IΒ΄m working in a caudricopter but i can't understand very well about the control and i see the post and i am interesting in your code, can you send me to observe and analyze it.

    Thanks Alex

    1. Hi Azahel and thanks for your comment!
      We are not giving away any code here because we think this is pointless, the idea is to explain how to code a way to control the movements of your quadcopter. If something is not clear, you can ask your question here and we will try to answer it ! πŸ™‚

      1. Well, Can you give me your e-mail and I will send you my code ? I did a code to keep hover the cuadricopter, but I'm programming in android, can you help me?

        1. I need more information and i wanna ask you something question, can you give me your e-mail? is really important to me


  2. Hello. Very nicely explained.

    But I have two questions

    To change the pitch angle you have to change the speed relation between two motors. But when the desired pitch angle is reached, do the motors rotate at the equal speed again?

    And secondly, how is it possible to constrain the copters acceleration/G-force. For example, if the copter carries a fragile cargo that dont tolerate more than 5G's? Can this be done with the help of the accelerometer?


    1. Hi Rod, thanks for your comment ! πŸ™‚

      -Yes, you are right, the speed of the motors changes in order to make the quadcopter tilt . The motors are controlled by PIDs, which we talk about in other articles, but let me explain here quickly. With a level quadcopter (0 degrees pitch,roll), if you want it to tilt until the pitch angle is let's say 15 degrees, you can change the speed of the motors with a factor proportional (let's call it P) to the difference between the target angle (15) and the current angle(0), so the pitchOffset I talk about in the article gets like pitchOffset= (15-0)*P. What this means is that the further you are from your target angle, the more the speed difference between the two motors will be important. When you get closer to the target angle, the pitchOffset will slowly decrease and finally reach 0 when your target angle is reached ! If this pitchOffset is 0, then the two motors rotate at the same speed again, you are right ! I recommend you to read about PIDs, which are how the motors are controlled. We will perhaps write an article about it in the future πŸ™‚

      -About your second question, yes I think it's possible to constrain the acceleration the quadcopter's acceleration. A very simple and naive way would be to limit the maximum angles of pitch and roll, which will basically limit the speed/acceleration of the copter to a low value. For the vertical speed, you can do the same thing by reducing the available throttle on the copter. Your quadcopter will then be very slow to react, but if you want to limit acceleration, it's a simple way to do it. A more complex way would be to actually use the embedded accelerometer on the drone and check whether or not it's over your limit value (or getting closer to it). You could then in your controller program reduce the angles/throttle of the quadcopter in order to reduce its acceleration dynamically in-flight without limiting its speed!

  3. Hi Alex

    Well, I'm working with android, therefore I'm using a Phone to use the sensor that has it. Also I have a ioio-board to create a interface between the phone and the brushless motors. According to information collected if i want to keep hovering my quadcopter I have to put all the motors at the same power, therefore I did 4 PID control to stabilze the quadcopter.
    My question is if I have that, The quadricopter should fly?,I mean ascend.

    1. Hi Abraham

      I am working on the exact same thing you worked on, I mean a quadcopter + Android phone + IOIO + PID. Can you please provide me with your email? I have few questions.

      Many thanks in advance

  4. hi,
    We are currently doing a quadcopter based project and we have some doubts in the stabilization of the UAV.
    Is the throttle specified here the value in degrees given to control the pwm pulse to the motor's ESC?
    also what is the range of offset values used in program and how would you find them?
    thanks Alex.

    1. Hi Merin!
      About the specified throttle, it is not included in the PID algorithm to give the order to the quadcopter : the order given to the ESCs is : ESC_PWM= rawThrottlePWM + PIDOffset. rawThrottlePWM is the value given by the TX without any treatment It is therefore not affected at all by the inclination orders (pitch,roll and yaw). The offset range directly depends on your quadcopter configuration I think, and is directly connected to your PID values. I think the maximum value on our quadcopter is around 300Β΅S (for a PWM max cycle of 2ms). But you shouldn't take these numbers for granted and make your own tests. I know, it's hard. We crashed many, MANY times before finding the sweet spot. But my advice would be to start with really low values and increase them progressively. First P, then the D, and in most cases you won't even need the Integral factor. Hope i helped you ! πŸ™‚

      1. I would add that you must be absolutely certain of your PID polarities : triple check your constant signs, so the PID will give you the right order. For a better comprehension, think of the P value as a value that increase as your signal get further of your target, and the D value as a value that increase as your signal has a speed that makes it go further. Instinctively you want to put an P-value that will make your signal want to come back to the target, and a V-value that has an inverse direction of the "velocity" of your signal. This said, for clarity reasons, I recommand you to put all your signal values in a coherent way : + is CCW (or trigonometric) for all values, then all your PID coefs should be positive.

      2. But i wasnt planning to use a PID algorithmn. Was thinking of just doing normal coding .
        Actually i was asking you about the range of values for pitchOffset, rollOffset and yawOffset.
        I dont think i know about the PID concept.
        Any suggestion on this ???
        Thank you πŸ™‚

        1. What do you mean by "normal coding"? πŸ˜€ If you don't use PIDs or machine learning algorithms (which would be a LOT harder than PIDs...), I don't see how you could do. Can you explain how you would do? πŸ™‚

  5. Can you help me to explain the process of the installation of the program for a fully autonomous UAV....We are using APM 2.5 board. can i have your email id as well??


      1. Hi Alex,

        The problem is we need operate it without GPS system, so we need to use optical flow sensor to detect the path. We got one Arduino program, but once we installed the program the board is not responding......Can you help me if you know about the installation of the program??...


        1. I'm sorry but we don't own (yet) an APM, but we actually ordered one a few days ago ! Maybe we can help you out when we get it. We'll perhaps make an article about it πŸ™‚

  6. Hey,
    I have got X frame of the quadcopter. So, tilting copter at single side affects both roll and pitch at the same time..
    So, your code is not applicable here.
    Can you suggest me which method I should use.?

    1. Hi bhaumik!
      Indeed the code is slightly different for an X configuration, but the principle is the same. So instead of only affecting 2 motors at the same time when you want to change the pitch (for example), you will change the 4 motor speeds this way:
      If the motors 1 and 2 are the front motors

      motor1= throttle + pitchOffset/2;
      motor2= throttle + pitchOffset/2;
      motor3= throttle - pitchOffset/2;
      motor4= throttle - pitchOffset/2;

      The same thing goes for the roll!

  7. Hi im trying to build a quadcopter for my school project, so i have already built it and the thing is i dont want to add a pilot to it. I have an arduino and i want to make my own pilot, i also have a 9DOF sensor stick and i wanted to control motor speed according to the values given by the sensor (accel, gyro, magneto). I have managed to find pitch yaw and roll values, i just need the formulas to know the speed of the motors, In your formula i cant understand what offset represents. Can you please explain it to me? thanks

    1. Hi!
      Well it is what I explain in the post. The motors PWM will depend on two things: the throttle you apply with the remote, and the PID outputs (the offsets)!

  8. can you help me my project of quadcopter is without microcontroller and the rules tells us it must be by logic gates
    can u help me ???!!!

    1. You mean on an FPGA or really by transistors? That seems quite hard πŸ˜€ I really don't think I can help you but let us know if you succeed, that would be cool to see how you did this πŸ˜‰

  9. Hi Alex,

    I'm interested in building my own quad. I would like to make a small one, like 6"x 6" and self commanded. Do you think it's gonna be more difficult to stabilize it? (due to the size)
    The PID is always implemented on the code or there are some IC to do this?

    Thanks and congratulations for this beautiful project!


    1. Hi Rodolfo and thanks for your comment πŸ™‚

      The smaller the drone is, the more "nervous" it will be. But I don't think it will be harder to stabilize, if you get your PIDs right. Yes, the PID is always implemented on the code side (as far as I know),and using a microcontroller is the most efficient way to do it!

      Good luck with your project πŸ™‚

  10. Hi Alex! Thanks alot for the post.
    I am designing my own quad and stuck at the point of setting kp, ki and kd values of PID, if these values are obtained from the experiments then please guide me what values should i check during the experiment?? I have obtained the roll, pitch, yaw and now want to implement PID for stability, need your help:)
    Thanks and good Work:)

    1. Hi CIS, sorry for replying so late!
      There are many guides about how to fine tune the PID settings for your quadcopter on the internet, but the main rules are: start by tuning the P by increasing it slowly until your quadcopter starts to really level itself and even wobble a bit. Then increase the D to counter act the wobbling caused by the P factor. Then increase progressively I for stability (you don't need to use the I factor). But the most important thing you should remember is that if you can't get your copter level, even after having tried all the PID values you could, then the problem doesn't come from the PIDs. It shouldn't be such a big deal!
      Good luck ! πŸ˜€

  11. Hi

    Nice article ,I would like to know if there is a formula to calculate the speed of a quadcopter given the angle of pitch/roll and arm length motor thrust and other parameters. Please reply

  12. Hi!
    I'm building quadcopter, controlled by Raspberry Pi, with MPU9150 sensor for pitch, roll and yaw, I have X frame for my quadcopterand I' m confused πŸ™‚

    Here's picture of my motor setup.

    This replay to bhaumik:
    motor1= throttle + pitchOffset/2;
    motor2= throttle + pitchOffset/2;
    motor3= throttle - pitchOffset/2;
    motor4= throttle - pitchOffset/2;
    The same thing goes for the roll! - so the logic is:
    in the loop:
    motor1= throttle + pitchOffset/2;
    motor2= throttle + pitchOffset/2;
    motor3= throttle - pitchOffset/2;
    motor4= throttle - pitchOffset/2;
    motor1= throttle + rollOffset/2;
    motor2= throttle + rollOffset/2;
    motor3= throttle - rollOffset/2;
    motor4= throttle - rollOffset/2;

    right ?

    1. Hi!

      It's different for the roll! Here the motors 2 and 3 should push the same way in order to tilt the frame! So:
      motor1= throttle + pitchOffset/2 -rollOffset/2;
      motor2= throttle + pitchOffset/2+rollOffset/2;
      motor3= throttle - pitchOffset/2+rollOffset/2;
      motor4= throttle - pitchOffset/2_rollOffset/2;

  13. Hi!
    Thank you for answering my question, i updated my code and now, for roll (when i'm looking sensors data, it's ok), copter is auto leveling, but for pitch the opposite propellers are turning faster, than those which should.

    Thank you again for your time πŸ™‚

  14. Hi Alex,
    1/ You said "The best way to get different motors speed is to add the offset value one one motor output, and to subtract it on the other, so the "overall throttle " of the axis remains constant and therefore changing the pitch won't affect the quadcopter's "vertical speed""...when subtracting the offset speed from one motor and adding it to the opposite motor there will be a tilt (pitch or roll) now the total force on positive Z-axis is not equal to (<) the total original force, it's written in term of the cosine of the pitch angle or the roll angle, while the other component of the force will cause the quadcopter to move horizontally. I assume there will be a drop of the altitude of the quadcopter which means a change in the acceleration, thus an instantaneous change in the vertical speed. Please explain to me if I'm wrong.

    2/ Let's assume the quadcopter is on hover mode. Since the net force of all rotors is pointing to +ve Z direction, the quadcopter has to have a pitch or roll angle in order to move horizontally and accelerate and then once the quadcopter is back on X-Y plane the horizontal speed stays constant if we ignore friction and other disturbances until there is an opposite angle to slow down the horizontal speed and eventually can bring the copter to hover mode or further to accelerate on the opposite direction . Thank you

  15. Hey I'm still having difficulty understanding the "offset". I'm building everything from scratch, even the controller I use a RaspberryPI to code the USB HID inputs from a JoyStick(
    Then I have a Arduino Mini that uses 400mhz transceiver to get the Data sent from the raspberryPi. It all works properly and I'm about to do the throttle part of the quadcopter ( which is kind of an H form).
    So basically, my controller sends data between 0 - 255, then I convert that into nanoseconds for the PWM to tell the ESC which speed to set. That min-max range is from 1000us - 2000us. Roll and Pitch is -500 to 500, and Yaw is -180 to 180.
    So my major question is: How do I calculate the offset? My understanding is, if I have 1500us throttle on all motors and I start pitching to lets say +300 does that mean motor1 will have 1800us and motor3 will have 1200us? Please guide me!


  17. Hi!We have a quadcopter project control with android mobile phone and we use MPU6050 gyro cencor our X frame.Bu we confused how can get the gyro data and control motors ?

  18. Hi there! Quick question regarding controlling orientation. For our senior project, we are building a sky crane to be attached to a quadcopter. One of our constraints is to be stable when delivering the payload, which we have defined as remaining less than 30 degrees of roll and pitch. I see the MPU6050 allows you to read the roll and pitch angles, but is there any way to prohibit a quadcopter from exceeding a certain roll or pitch angle? Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *