UAV Systems Engineering · Module 1
M1-T6: Roll, pitch, yaw and thrust generation
Four motors, four numbers: derive the mixer that turns thrust and torques into motor commands, and see what breaks when a motor runs out of range.
The controller thinks in thrust and torques; the motors only know thrust. The mixer is the small linear map between the two, and it is also where saturation, the most common cause of lost control authority, first shows up.
Learning objectives
After this lesson, you should be able to:
- Explain how each of thrust, roll, pitch and yaw is produced by differential motor thrust.
- Derive the X-quadrotor mixer and its inverse from the geometry.
- Compute motor commands for a requested wrench and detect infeasible requests.
- Describe a priority scheme for handling saturation.
Conceptual explanation
All four motors point up. If they produce equal thrust, the vehicle only climbs or descends. Roll comes from more thrust on one side than the other, pitch from more thrust at the front than at the rear, and yaw from the reaction torque of the propellers: two spin clockwise and two counter-clockwise, and speeding up one pair produces a net torque about because each propeller’s drag torque pushes back on the airframe.

The mapping from motor thrusts to the generalised force is linear. The mixer is its inverse: given the wrench the controller asks for, it returns the four thrusts.
Engineering intuition
Roll and pitch are cheap: they use leverage, a thrust difference acting at the arm length. Yaw is expensive: it uses the propeller drag torque, which is a small fraction of the thrust times a lever arm, so a yaw command needs a large thrust difference for a small torque. That is why yaw is slow on a quadrotor and why, when motors saturate, yaw is sacrificed first: losing yaw control is far less dangerous than losing roll or pitch.
Mathematical formulation
Body frame forward, left, up. Motors sit at (±, ±, 0) with for a motor-to-motor distance . Each motor produces thrust along +z and a drag torque about , opposing its rotation.
- total thrust (N).
- , ,
- roll, pitch and yaw torque about the body axes (·).
- perpendicular lever arm of each motor, .
- ratio of propeller drag torque to thrust (m); depends on the propeller.
Writing this as , the four rows are orthogonal, so A is invertible and:
Saturation
Each must satisfy . If a requested wrench violates this, the mixer cannot deliver it. A common priority scheme: first reduce the yaw torque to zero; if still infeasible, shift thrust so no motor is below zero (sacrificing altitude hold); finally scale the roll and pitch torques. Autopilots implement variants of this; consult your autopilot’s control-allocation documentation for what it does.
Architecture and data flow
The mixer sits between the rate controller and the ESCs: rate controller → → mixer → normalised motor outputs → ESC → motors. Anything the mixer cannot satisfy is a saturation event that the controller should know about, so that its integrators stop winding up (anti-windup).
Real-world UAV applications
- Control allocation for quadrotors, hexarotors and octorotors (the matrix A has more columns; the inverse becomes a pseudo-inverse).
- Motor-out fault tolerance: remove a column and re-allocate with reduced yaw authority.
- Sizing: the maximum roll torque with all other axes at hover tells you the attitude bandwidth the airframe can deliver.
- Diagnosing a vehicle that flips at takeoff (a swapped motor or reversed propeller).
Implementation example
This runs as shown. It builds A from the geometry, inverts it, mixes a request, and checks that a feasible request round-trips while an extreme yaw request saturates.
import numpy as np
L, k, fmax = 0.25, 0.016, 12.0 # arm (m), drag/thrust ratio (m), max thrust per motor (N): illustrative
d = L / np.sqrt(2)
# f1 FR f2 RL f3 FL f4 RR rows: T, tau_x, tau_y, tau_z
A = np.array([[1, 1, 1, 1],
[-d, d, d, -d],
[-d, d, -d, d],
[-k, -k, k, k]])
Ainv = np.linalg.inv(A)
def mix(T, tx, ty, tz):
return Ainv @ np.array([T, tx, ty, tz])
def mix_with_priority(T, tx, ty, tz):
f = mix(T, tx, ty, tz)
if f.min() < 0 or f.max() > fmax: # 1) give up yaw first
f = mix(T, tx, ty, 0.0)
if f.min() < 0 or f.max() > fmax: # 2) shift collective thrust into range if the spread allows it
spread = f.max() - f.min()
if spread <= fmax:
f = f + max(0.0, -f.min()) - max(0.0, f.max() + max(0.0, -f.min()) - fmax)
else: # 3) scale the roll/pitch request down
f = f.mean() + (f - f.mean()) * fmax / spread
return np.clip(f, 0, fmax)
f = mix(14.7, 0.2, -0.1, 0.05)
assert np.allclose(A @ f, [14.7, 0.2, -0.1, 0.05]) # round trip
print("motors:", np.round(f, 2))
f_raw = mix(14.7, 0.0, 0.0, 1.0) # a large yaw request
print("raw yaw request:", np.round(f_raw, 1), "-> infeasible" if (f_raw.min() < 0 or f_raw.max() > fmax) else "")
assert f_raw.min() < 0 or f_raw.max() > fmax
f_ok = mix_with_priority(14.7, 0.0, 0.0, 1.0)
print("with priority:", np.round(f_ok, 2))
assert f_ok.min() >= 0 and f_ok.max() <= fmax and abs(f_ok.sum() - 14.7) < 1e-9Common engineering mistakes
Wrong spin direction or motor numbering
A reversed propeller flips the sign of and of the thrust it produces. Verify with a props-off motor test on every build.
Assuming the mixer is perfectly linear in throttle
Thrust is roughly proportional to the square of rotor speed; real systems linearise thrust-to-command with a calibrated curve.
Ignoring saturation in the controller
Integrators wind up while the mixer clips, then the vehicle overshoots wildly on recovery. Feed saturation back to anti-windup.
Equal weights for yaw and roll/pitch
Yaw must be the first thing sacrificed, not the last.
Failure modes
| Failure mode | How it shows up | Likely cause |
|---|---|---|
| Takeoff flip | Vehicle rolls or pitches violently when thrust is applied | Swapped motor wires, reversed propeller, or wrong mixer sign |
| Yaw drift in hover | Constant slow rotation | Motor or propeller mismatch, mis-trimmed yaw torque |
| Loss of attitude control under aggressive commands | Oscillation that grows when the command is large | Motor saturation without anti-windup or priority |
| Low-throttle instability | Wobble at minimum throttle | Motors clipped at their lower limit so negative thrust corrections cannot be applied |
Debugging approach
- With propellers removed, command each axis in turn and check which motors speed up (and in which direction they spin).
- Plot motor outputs and mark saturation in the log: they should not touch limits in normal flight.
- Verify numerically for the airframe geometry you actually built.
- Compare vehicle response to a small roll step with the model; a wrong sign or a gain error shows up immediately.
Practical exercises
- Derive the mixer for a plus (+) configuration with motors on the axes at distance L/2.
- Compute the largest yaw torque possible at hover thrust for , , , .
- Extend the mixer to a hexarotor and compute the pseudo-inverse.
- Remove motor 1 (failure) from the quadrotor mixer and show which axes can still be controlled.
Interview questions
Write an answer in your own words, then reveal the model answer. Nothing is sent anywhere.
Question 1
Why do two motors spin each way?
Model answer
Each propeller exerts a reaction torque on the airframe about the vertical axis. Equal numbers of clockwise and counter-clockwise propellers cancel these at equal speeds, and speeding up one pair gives a controlled yaw torque.
Question 2
Which axis is sacrificed first on saturation, and why?
Model answer
Yaw. It is the weakest and slowest axis and its loss is the least dangerous, whereas losing roll or pitch authority leads to a crash.
Question 3
What does the mixer do mathematically?
Model answer
It inverts the linear map from four motor thrusts to total thrust and three torques. With four motors the map is square and invertible; with more motors it is solved with a pseudo-inverse or an optimisation.
References and further reading
Primary papers, official documentation and standards. Each claim above that is specific to a tool or version points here.
- R. Mahony, V. Kumar, P. Corke, IEEE RAM 2012 (multirotor modelling and control allocation)
- PX4: Control allocation
- PX4: Airframe reference (motor numbering and geometry)