How the Quadrotor Model Works
This page explains how QuadrotorModel turns four
rotor speed commands into the motion of a rigid body. It builds the model up
one idea at a time: rotor, then thrust and torque, motor lag, attitude, and
translation. A last section shows a rigid-body effect that has nothing to do
with the rotors.
Every animation plays a trace recorded from the model’s own C++ (the scenario is linked under each player). Nothing on this page computes dynamics in the browser. The controls, the keys, and the conventions are described on the Trace Player page.
The vehicle
Section titled “The vehicle”The model is a rigid body with four rotors in the PX4 Quad X layout. The world frame has z up. The body frame has x forward, y left, and z up.
| Rotor | Position | Spin, seen from above |
|---|---|---|
| 0 | front right | counter-clockwise |
| 1 | rear left | counter-clockwise |
| 2 | front left | clockwise |
| 3 | rear right | clockwise |
The default parameters are RP-1’s: 1 kg, an arm of 0.11 m, and a hover speed of about 1660 rad/s per rotor. Each rotor can make up to 12 N, which it does at ω_max ≈ 3672 rad/s.
1. Each rotor pushes and twists
Section titled “1. Each rotor pushes and twists”A rotor spinning at ω makes a thrust along body z. Since the rotor sits off the centre of mass, the thrust also makes a torque about body x and y. Spinning the air one way pushes the body the other way about z. A counter-clockwise rotor makes a yaw torque of .
Before you play: rotor 0 is front right. When it spins alone, which way does the vehicle want to roll, and which way to pitch?
The 3-D view needs WebGL, which this browser does not provide. The plots and the description below show the same trace.
Keys (with the player focused): Space play/pause · ← → one sample (Shift: ten) · Home/End · [ ] speed
The vehicle sits on the ground with its rotors stopped. Each rotor in turn spins up to 90 % of the hover speed, alone, for 0.4 s. One rotor makes about 2 N, a fifth of the weight, so the vehicle never lifts off and stays still. The torque plot shows what each rotor would do to an airborne vehicle. Rotor 0 (front right) makes negative roll and negative pitch: it lifts the right side and the nose. Rotor 1 (rear left) makes the opposite. Each makes 0.15 N·m about x and y. The yaw torque is five times smaller, and its sign follows the spin: negative for the counter-clockwise rotors 0 and 1, positive for 2 and 3. With all four running, the torques cancel and the thrust is 81 % of the weight.
- rotor 0 (front right, CCW) alone
- rotor 1 (rear left, CCW) alone
- rotor 2 (front left, CW) alone
- rotor 3 (rear right, CW) alone
- all four: the torques cancel; thrust 81 % of the weight
- all rotors commanded to stop
The torque is the model’s own. The scenario reads it from derivative()
as J·ω̇ while the body rates are zero, so the gyroscopic term vanishes. A
grounded vehicle stays put while its vertical thrust is at most its weight,
which is why the vehicle does not move here. The
ground contact animation on the V&V
page shows that rule at take-off and landing.
The four rotors give four independent controls: total thrust, and torque about x, y, and z. The mixer inverts this map.
2. Rotors lag their commands
Section titled “2. Rotors lag their commands”A rotor cannot change speed at once. The model treats each motor as a first-order lag with time constant τ = 20 ms: , with the command u clamped to .
Before you play: the command jumps by 10 %. How long until the thrust has made most of that change?
Predict, then try it: make τ slower, say 60 ms. Does the vehicle gain as much upward speed by 0.25 s, when the command drops? Then make τ 5 ms, and look at the check.
The 3-D view needs WebGL, which this browser does not provide. The plots and the description below show the same trace.
Keys (with the player focused): Space play/pause · ← → one sample (Shift: ten) · Home/End · [ ] speed
The vehicle hovers at 1 m. At 0.05 s every rotor is commanded 10 % faster. The rotor speed follows along an exponential: 63 % of the step after one time constant (20 ms, at 0.07 s), and 95 % after three. The thrust grows with the square of the speed, so it rises by about 21 %, and the vehicle accelerates upward at about 2 m/s². At 0.25 s the command returns to the hover speed, and the rotors slow down along the same curve. The vehicle keeps the upward speed it gained, because nothing brakes it.
- command +10 % on every rotor
- one time constant later: 63 % of the step
- command back to the hover speed
- ✓ passBB-V1 rotor_speed_error_vs_closed_form_max = 3.32e-6 rad/s (<= 1.00e-4), computed by the scenario harness
The sliders rerun the scenario’s C++, compiled to WebAssembly, in your
browser. With a slow motor the thrust arrives late and leaves late. At
τ = 60 ms the vehicle has gained 0.29 m/s by 0.25 s instead of 0.37 m/s,
and it makes up most of the difference after the command drops. At τ = 5 ms the check fails. The
motor is fine, but the 1 ms integration step is now a fifth of τ, and the
integrator’s error passes the check’s limit. A step size must stay small
against the fastest time constant, which is why step() requires dt ≤ τ.
The check under the player compares the recorded rotor speed with the closed-form step response at every sample. An exact solution like this is how the V&V plan verifies each term of the equations (BB-V1).
For a controller, the lag is the first thing it has to live with. A torque commanded now arrives over the next few tens of milliseconds.
3. Torque turns the body, and tilted thrust moves it
Section titled “3. Torque turns the body, and tilted thrust moves it”Rotation and translation are coupled only through the direction of the thrust. A roll torque does not move the vehicle sideways by itself. It tilts the thrust vector, and the horizontal part of the tilted thrust accelerates the vehicle.
Before you play: the left rotors speed up and the right rotors slow down, then the reverse. Where does the vehicle end up, and does it stay level afterwards?
The 3-D view needs WebGL, which this browser does not provide. The plots and the description below show the same trace.
Keys (with the player focused): Space play/pause · ← → one sample (Shift: ten) · Home/End · [ ] speed
The vehicle hovers at 1 m. At 0.1 s the left rotors (1 and 2) are commanded 40 rad/s faster and the right rotors (0 and 3) 40 rad/s slower. The rotors follow with their 20 ms lag, and the vehicle starts to roll right side down. At 0.22 s the commands reverse, which brakes the roll. At 0.34 s every rotor is commanded back to the hover speed. The vehicle is left rolled by about 0.18 rad (10°). Nothing levels it, because there is no controller. The tilted thrust pushes the vehicle to the right (−y), and since only part of the thrust now points up, it slowly sinks: about 1.4 m sideways and 0.11 m down by 1.5 s.
- left rotors +40 rad/s, right rotors -40 rad/s: roll torque
- reversed: braking torque
- hover command: the vehicle stays rolled about 10°
- ✓ passBB-V3 attitude_norm_error_max = 4.44e-16 (<= 1.78e-15), computed by the scenario harness
The order of effects is the chain a controller works through in reverse: rotor speed, then torque, roll rate, roll angle, and only then sideways acceleration. A position controller therefore commands an attitude, and an attitude controller commands rates, which is the cascade structure.
4. A free body that flips
Section titled “4. A free body that flips”The rate equation has a second term that does not come from the rotors. It is the gyroscopic term of a rigid body, and it matters even with no torque at all. A body with three different moments of inertia spins steadily about its largest and its smallest axis. About the middle axis, any small disturbance grows, and the body flips end over end (the intermediate-axis theorem, or Dzhanibekov effect).
RP-1’s inertia is (3, 3, 5)·10⁻³ kg·m². Its x and y moments are equal, so it has no middle axis. This scenario uses (2, 4, 6)·10⁻³ kg·m² instead.
Before you play: the vehicle spins at 6 rad/s about body y, the middle axis, and nothing pushes on it. Does the spin stay about y?
Predict, then try it: the spin is about body y. Make J_y the largest of the three moments, or the smallest. Does the vehicle still flip?
The 3-D view needs WebGL, which this browser does not provide. The plots and the description below show the same trace.
Keys (with the player focused): Space play/pause · ← → one sample (Shift: ten) · Home/End · [ ] speed
The rotors are off, so there is no torque. The vehicle spins at 6 rad/s about body y, with a 0.1 rad/s disturbance about x and z. Gravity is set to 10⁻⁶ m/s² to keep the vehicle in view: gravity acts at the centre of mass and exerts no torque, so the rotation is the same as in free fall. For about 1.5 s the spin stays about y while the disturbance grows. Then the body flips: the y rate passes through zero and reverses, while the x and z rates surge and fall back. It flips back at about 4.6 s. Through all of this, the kinetic energy and the angular momentum vector in the world frame stay flat. The body rates change because the body turns, not because anything acts on it.
- ✓ passBB-V3 energy_and_momentum_relative_drift_max = 2.18e-11 (<= 1.00e-6), computed by the scenario harness
With the sliders, make y the largest or the smallest axis: the spin then stays about y, and only wobbles. Only the middle axis is unstable.
The two flat plots are a check on the integrator as much as a fact of physics. Classical RK4 does not conserve energy or momentum exactly. At dt = 1 ms the drift over 5 s stays near 10⁻¹¹ of the initial values, which the check under the player bounds (BB-V3). The motion is also sensitive to roundoff near the flip. A 10⁻¹⁵ rad/s change in the initial rate moves the trace by about 10⁻¹¹ rad/s, which is still well inside the tolerance the docs CI uses to compare a regenerated trace with this one.
Where to go next
Section titled “Where to go next”- The developer guide has the equations, the invariants, and the API.
- The V&V plan shows how the model is verified, with animations of the mirror symmetry, the convergence with step size, and ground contact.
- The deployment guide covers what an integrator needs: parameters, timing, the validity envelope, and behaviour at the limits.