Skip to the content
FixTheRobot Explore Robotics / UAV / Module 1 / M1-T5

UAV Systems Engineering · Module 1

M1-T5: Six-degree-of-freedom UAV dynamics

Twelve numbers describe where a rigid quadrotor is and how it is moving; two vector equations say how they change.

  • Lesson 5 of 12
  • UAV Fundamentals and System Architecture
  • Established engineering
  • About 8 minutes to read

A quadrotor is a rigid body pushed by four thrust forces. That single fact gives you the model every controller, estimator and simulator in this track is built on. This lesson writes it down, explains each term, and integrates it.

Learning objectives

After this lesson, you should be able to:

  • List the 12 states of a rigid-body UAV and their frames.
  • Write the translational and rotational equations of motion with thrust and torque as inputs.
  • Explain why a quadrotor is underactuated and how tilt produces horizontal acceleration.
  • Integrate the model numerically and verify hover and a free fall.

Conceptual explanation

A rigid body in space has six degrees of freedom: three of position and three of orientation. With their rates, the state has twelve numbers: position pp (3), velocity vv (3), attitude (roll, pitch, yaw or a quaternion) and body angular rate ω(3)\omega (3).

A quadrotor has only four inputs: the four motor thrusts, equivalently a total thrust TT and three body torques τx\tau _{x}, τy\tau _{y}, τz\tau _{z}. Six degrees of freedom driven by four inputs makes it underactuated: it cannot accelerate sideways directly. To move horizontally it must first tilt, so that part of the thrust points sideways.

Rigid-body quadrotor forcesA quadrotor with four thrust vectors along the body z axis, weight acting down in the world frame, and the body axes x forward, y left, z up. Tilting the body tilts the net thrust and produces horizontal acceleration. TT m g (world −z) body zbody x (forward) Translation:m a = R·[0,0,ΣT] − m g ẑ Rotation:J ω̇ = τ − ω × Jω
Thrust acts along the body zz axis. Orientation therefore decides the direction of the net force.
Animation of a quadrotor in three dimensions performing each of its six rigid-body motions in turn: surge, sway and heave (translation along the body x, y and z axes) and roll, pitch and yaw (rotation about those axes). A panel on the right lists the six degrees of freedom x, y, z, phi, theta, psi with live values and highlights the active one. A faint ghost shows the starting pose.
The six degrees of freedom, one at a time (looping, about eight seconds; a schematic drawn for this course). Body axes: xx forward (orange), yy left (green), zz up (blue). Three numbers locate the vehicle, three give its orientation; their rates bring the state to twelve numbers.
Animation of a planar quadrotor translating sideways. A torque pulse pair tilts the vehicle, the thrust vector leans, the horizontal component of thrust accelerates it, velocity builds and position increases; a reverse tilt then brakes it and a final pulse pair levels it. Six strip charts on the right show torque, angular rate, tilt, acceleration, velocity and position growing together, each one the integral of the previous.
Why a quadrotor must tilt to move sideways (looping, about six seconds). The curves are computed by integrating J θ¨=τJ\,\ddot{\theta }=\tau with the thrust held at m g/cos⁡ θm\,g/\cos \,\theta , so x¨=g tan⁡ θ\ddot{x}=g\,\tan \,\theta : each trace is an integral of the one above it. The drawing is a schematic made for this course.

Engineering intuition

Think of the vehicle as a thrust vector attached to a rotating platform. Translation is fast to understand: weight pulls down, thrust pushes along the body zz axis. Rotation is the slow, delicate part: torques from differential thrust change ω\omega , ω\omega changes orientation, orientation redirects thrust.

This chain, torque → angular rate → attitude → thrust direction → acceleration → velocity → position, is why controllers are cascaded. Each stage is an integrator or two away from the next. The inner (attitude) loop must be several times faster than the outer (position) loop, otherwise the outer loop sees a lagging plant and oscillates. You can see that in the Quadrotor Dynamics Simulator when the position gains are raised.

Mathematical formulation

Translation (world frame, z up)

Translational dynamics
p˙=v\dot{\mathbf p} = \mathbf v
m v˙=R(ϕ,θ,ψ)[00T]−m g[001]+Fdrag+Fwindm\,\dot{\mathbf v} = \mathbf R(\phi,\theta,\psi)\begin{bmatrix}0\\0\\T\end{bmatrix} - m\,g\begin{bmatrix}0\\0\\1\end{bmatrix} + \mathbf F_{\text{drag}} + \mathbf F_{\text{wind}}

Why is the weight term negative?

The weight is not negative: its size is the positive number mgmg (14.7 NN for a 1.5 kg vehicle). The sign gives its direction. Here the world frame has zz pointing up and z^=[0,0,1]⊤\hat{\mathbf{z}} = [0,0,1]^{\top} is the unit vector along it. Gravity pulls down, opposite to ẑ, so the weight force vector is

Weight as a vector (z up)
Fweight=− mg z^=[00−mg]\mathbf{F}_{\text{weight}} = -\,mg\,\hat{\mathbf{z}} = \begin{bmatrix} 0 \\ 0 \\ -mg \end{bmatrix}
The minus sign says “down”. Its magnitude is mg.

On the vertical axis, level thrust gives +T and weight gives −mg, so mv˙z=T−mgm\dot v_z = T - mg: the vehicle climbs if TT > mg, hovers if TT = mg and sinks if TT < mg. In a z-down frame such as NED, z^\hat{z} points down, so the same weight is written +mg z^\hat{z} and thrust −TT z^\hat{z}; the physics is identical and only the sign convention changes. The code below uses zz up, which is why it subtracts gg.

Rotation (body frame)

Rotational dynamics
J ω˙=τ−ω×(Jω)\mathbf J\,\dot{\boldsymbol\omega} = \boldsymbol\tau - \boldsymbol\omega\times(\mathbf J\boldsymbol\omega)
Euler-angle kinematics
Θ˙=W(ϕ,θ) ω\dot{\boldsymbol\Theta} = \mathbf W(\phi,\theta)\,\boldsymbol\omega
Or, with a quaternion, q̇ = ½ q ⊗ [0, ω].
pp, vv
position and velocity in the world frame (mm, m/s).
RR
rotation matrix from body to world (lesson M1-T4).
TT
total thrust, T=f1+f2+f3+f4(N)T=f_{1}+f_{2}+f_{3}+f_{4}(N).
JJ
inertia matrix, usually diagonal diag⁡(Jx, Jy, Jz)\operatorname{diag} (J_{x},\,J_{y},\,J_{z}) for a symmetric airframe (kg·m2m^{2}).
ω\omega
angular velocity of the body in the body frame (rad/s).
τ\tau
torques about the body axes (NN·mm), produced by differential motor thrust (lesson M1-T6).
ω\omega × Jω\omega
gyroscopic term: small for a symmetric vehicle at modest rates.

The Euler kinematics for the ZYX convention, with ω=(p, q, r)\omega =(p,\,q,\,r), are:

Euler-angle kinematics
ϕ˙=p+(qsin⁡ϕ+rcos⁡ϕ)tan⁡θθ˙=qcos⁡ϕ−rsin⁡ϕψ˙=qsin⁡ϕ+rcos⁡ϕcos⁡θ\begin{aligned} \dot\phi &= p + (q\sin\phi + r\cos\phi)\tan\theta\\ \dot\theta &= q\cos\phi - r\sin\phi\\ \dot\psi &= \frac{q\sin\phi + r\cos\phi}{\cos\theta} \end{aligned}

The term 1/cos⁡θ1/\cos \theta is the gimbal-lock singularity at θ=±90∘\theta =\pm 90^{\circ}; avoid Euler angles for integration in real flight code.

Hover and small-angle behaviour

At hover, v˙=0\dot{v}=0 and attitude is level, so T=m gT=m\,g. For small angles the horizontal accelerations are ax≈g θa_{x}\approx g\,\theta and ay≈−g ϕa_{y}\approx -g\,\phi (with xx forward, yy left, zz up), which is the link the position controller uses to turn a desired acceleration into a desired tilt.

Architecture and data flow

In a flight stack the model appears three times, each time with different fidelity:

  • Simulator: full nonlinear model with motor dynamics, drag and wind (this lesson).
  • Controller design: a linearisation about hover (lesson M5-T7 uses it for LQR) or a simplified point-mass for MPC (lesson M5-T8).
  • Estimator: the IMU is treated as measuring ω\omega and specific force, and the model is used for prediction (module 3).

Real-world UAV applications

  • Choosing motors and batteries: T=m gT=m\,g and the margin for manoeuvres follow from this model.
  • Simulation-first controller tuning before the first flight.
  • Predicting how payload mass and centre-of-mass offsets change hover trim.
  • Model-based estimation and model predictive control of aggressive flight.

Implementation example

This runs as shown: it integrates the translation and rotation equations from rest, checks that hover thrust T=m gT=m\,g keeps the vehicle still, and that zero thrust gives a free fall of ½ g t2g\,t^{2}.

import numpy as np
g = 9.81

def rot(phi, th, psi):
    cp, sp, ct, st, cy, sy = np.cos(phi), np.sin(phi), np.cos(th), np.sin(th), np.cos(psi), np.sin(psi)
    return np.array([[cy*ct, cy*st*sp - sy*cp, cy*st*cp + sy*sp],
                     [sy*ct, sy*st*sp + cy*cp, sy*st*cp - cy*sp],
                     [-st,   ct*sp,            ct*cp]])

def step(x, T, tau, m, J, dt):
    """x = [p(3), v(3), euler(3), omega(3)], z up. Semi-implicit Euler."""
    p, v, e, w = x[0:3], x[3:6], x[6:9], x[9:12]
    a = rot(*e) @ np.array([0, 0, T]) / m - np.array([0, 0, g])
    wdot = np.linalg.solve(J, tau - np.cross(w, J @ w))
    v = v + a * dt
    p = p + v * dt
    w = w + wdot * dt
    phi, th = e[0], e[1]
    W = np.array([[1, np.sin(phi) * np.tan(th), np.cos(phi) * np.tan(th)],
                  [0, np.cos(phi), -np.sin(phi)],
                  [0, np.sin(phi) / np.cos(th), np.cos(phi) / np.cos(th)]])
    e = e + (W @ w) * dt
    return np.concatenate([p, v, e, w])

m, J, dt = 1.5, np.diag([0.0096, 0.0096, 0.018]), 0.002
x = np.zeros(12)
for _ in range(1000):                       # hover for 2 s: T = m g, no torque
    x = step(x, m * g, np.zeros(3), m, J, dt)
assert np.allclose(x[0:3], 0, atol=1e-9)

x = np.zeros(12)
for _ in range(500):                        # free fall for 1 s
    x = step(x, 0.0, np.zeros(3), m, J, dt)
print("fell", round(-x[2], 3), "m; analytic 0.5*g*t^2 =", round(0.5 * g, 3))
assert abs(-x[2] - 0.5 * g) < 0.02

x = np.zeros(12); x[6] = 0.2                # 0.2 rad roll with hover thrust: it accelerates sideways
for _ in range(100):
    x = step(x, m * g, np.zeros(3), m, J, dt)
assert x[4] < 0                             # roll right-wing-down in z-up/y-left pushes toward -y
print("lateral velocity after 0.2 s:", round(x[4], 3), "m/s")
A complete 6-DoF integration with three sanity checks. J is an illustrative inertia, not a measured one.

Common engineering mistakes

Forgetting the thrust direction changes with attitude

Using TT along world zz. Thrust is along the body zz axis; only at level attitude is it vertical, and holding altitude while tilted needs T=m g/(cos⁡ϕ cos⁡θ)T=m\,g/(\cos \phi \,\cos \theta ).

Using degrees inside trig functions or rates

Equations assume radians everywhere; mixing degrees silently scales torques and angles.

Assuming a point mass is enough for control tuning

Attitude dynamics and motor lag set the achievable bandwidth. A point-mass model is only valid for an outer loop that is much slower than the inner one.

Integrating Euler angles near ±90° pitch

The 1/cos⁡θ1/\cos \theta term blows up; use quaternions.

Using inertia guessed from mass

Inertia scales with mass distribution, not mass. Measure it (bifilar pendulum) or take it from CAD before tuning.

Failure modes

Failure modes, symptoms and causes
Failure modeHow it shows upLikely cause
Model–vehicle mismatch in inertiaController gains that were stable in simulation oscillate on hardwareInertia, motor lag or thrust coefficient differ from the model
Missing motor dynamicsAggressive attitude commands overshoot on the real vehicle but not in the simulatorMotor/ESC lag adds phase delay that the model omitted
Euler-angle singularityAttitude estimate jumps near vertical flightGimbal lock in the Euler kinematics
Wrong sign of a torque axisRoll command pitches the vehicle or the vehicle flips on takeoffMixer or frame convention error (lesson M1-T4, M1-T6)

Debugging approach

  1. Test the model alone first: hover thrust must keep it still and zero thrust must fall at gg.
  2. Apply a small constant roll torque and check the sign and magnitude of the resulting angular acceleration against τ/Jx\tau /J_{x}.
  3. Compare simulated and logged step responses of attitude: the time constant and overshoot reveal missing lag.
  4. Check energy: with no thrust and no drag, kinetic plus potential energy must be conserved to integration accuracy.

Practical exercises

  1. Derive the thrust needed to hold altitude at 30∘30^{\circ} roll and explain why a vehicle with T/W=1.1T/W=1.1 cannot do it.
  2. Linearise the model about hover and show that z¨=(δT)/m\ddot{z}=(\delta T)/m, ϕ¨=τx/Jx\ddot{\phi }=\tau _{x}/J_{x}, and x¨=g θ\ddot{x}=g\,\theta .
  3. Add linear drag −cc vv to the code and find the terminal speed in free fall for c=0.3 kg/sc=0.3\,\mathrm{kg}/\mathrm{s}.
  4. Replace Euler angles by a quaternion integration and compare after a 90∘90^{\circ} pitch manoeuvre.

Interview questions

Write an answer in your own words, then reveal the model answer. Nothing is sent anywhere.

Question 1

Why is a quadrotor underactuated, and how does it translate horizontally?

Model answer

It has four inputs (total thrust and three torques) but six degrees of freedom. It cannot produce horizontal force directly; it tilts so the thrust vector has a horizontal component, which is why attitude control sits inside position control.

Question 2

What is the hover condition?

Model answer

Level attitude and total thrust equal to weight, T=m gT=m\,g, with zero angular rate. Tilted, the vertical component must still equal weight, so T=m g/(cos⁡ϕ cos⁡θ)T=m\,g/(\cos \phi \,\cos \theta ).

Question 3

Why must the attitude loop be faster than the position loop?

Model answer

The position loop commands tilt; if attitude responds slowly, the position loop sees a delayed plant and loses phase margin. A common rule of thumb is a several-times bandwidth separation.

References and further reading

Primary papers, official documentation and standards. Each claim above that is specific to a tool or version points here.

What’s next

Mark this lesson

Saved in this browser and synced to your account when you are signed in.

Practice this lesson

M1-L1: Build a simulated quadrotor model

Integrate the 6-DoF model, apply a mixer and hold hover with attitude PID.

Next lesson

M1-T6: Roll, pitch, yaw and thrust generation

Derive the motor mixer for an XX quadrotor and compute the commands for a desired thrust and torques.