Drone Flight Dynamics

A quadcopter generates thrust from four motors to achieve 6-DOF motion (3 translation + 3 rotation). Control is achieved through differential thrust — varying individual motor speeds to create forces and torques. The flight controller runs nested PID loops at high rates to maintain stable flight.

Why It Matters

Quadcopters are inherently unstable — without active control, they tumble immediately. Understanding the dynamics — how motor thrust creates forces and torques, how body frame relates to world frame, and how cascaded PID achieves stable flight — is essential for building or tuning any multirotor.

Quadcopter Layout

      M1 (CW)        M2 (CCW)
         ╲            ╱
          ╲          ╱
           ╲        ╱
            ┌──────┐
            │ body │  ← IMU at center of mass
            └──────┘
           ╱        ╲
          ╱          ╲
         ╱            ╲
      M3 (CCW)       M4 (CW)

Adjacent motors spin opposite directions to cancel net yaw torque.

Body frame: x = forward, y = right/left, z = down (NED convention varies).

Forces and Torques

Each motor produces:

  • Thrust T = Ct · ρ · n² · D⁴ (upward force)
  • Torque τ = Cq · ρ · n² · D⁵ (reaction torque about motor axis)

Where Ct = thrust coefficient, Cq = torque coefficient, ρ = air density, n = rev/sec, D = prop diameter.

Control Axes

MotionMotor ActionResulting Force/Torque
Throttle (altitude)All motors ↑ or ↓Net vertical force
Roll (left/right tilt)Left pair ↑, right pair ↓Torque about x-axis
Pitch (forward/back tilt)Front pair ↑, back pair ↓Torque about y-axis
Yaw (rotate)CW motors ↑, CCW motors ↓Net torque about z-axis

Mixer Matrix

Converts desired thrust and torques into individual motor commands:

[T1]     [1  -1  -1   1] [throttle]
[T2]  =  [1   1  -1  -1] [roll    ]
[T3]     [1   1   1   1] [pitch   ]
[T4]     [1  -1   1  -1] [yaw     ]
import numpy as np
 
def mix(throttle, roll, pitch, yaw):
    """Convert desired forces to motor commands (X-configuration)."""
    mixer = np.array([
        [1, -1, -1,  1],   # front-left (CW)
        [1,  1, -1, -1],   # front-right (CCW)
        [1,  1,  1,  1],   # rear-right (CW)
        [1, -1,  1, -1],   # rear-left (CCW)
    ])
    commands = mixer @ np.array([throttle, roll, pitch, yaw])
    return np.clip(commands, 0, 1)  # clamp to valid range

Newton-Euler Equations of Motion

The rigid body dynamics in the body frame:

Force:   m · a = R · [0, 0, -mg]ᵀ + [0, 0, ΣTi]ᵀ
Torque:  I · α + ω × (I · ω) = τ

m = mass
I = 3×3 inertia matrix
R = rotation matrix (body → world)
ω = angular velocity in body frame
τ = [torque_roll, torque_pitch, torque_yaw]

Simplified for small angles (hovering):

x'' ≈ g · θ        (pitch → forward acceleration)
y'' ≈ -g · φ       (roll → lateral acceleration)
z'' ≈ (ΣT/m) - g   (thrust → vertical acceleration)

This shows why quadcopters must tilt to move horizontally — there’s no other way to create lateral force.

Body Frame vs World Frame

World (NED):                 Body:
  N (north) ↑                 x (forward) ↑
  E (east) →                  y (right) →
  D (down) ⊙                  z (down) ⊙

Rotation: R(φ,θ,ψ) converts body → world
  φ = roll, θ = pitch, ψ = yaw

The IMU fusion estimates this rotation. The flight controller works in the body frame (controls motor torques) but navigates in the world frame (GPS waypoints).

Cascaded PID Control

Three nested loops, each faster than the previous:

Position PID (10 Hz) → desired_angle
  └→ Angle PID (100-250 Hz) → desired_rate
       └→ Rate PID (500-1000 Hz) → motor_commands
# Simplified single-axis (pitch) cascade
# Outer loop: position → desired pitch angle
pitch_error = target_x - current_x
desired_pitch = pid_position.update(pitch_error)
 
# Middle loop: angle → desired pitch rate
angle_error = desired_pitch - measured_pitch
desired_pitch_rate = pid_angle.update(angle_error)
 
# Inner loop: rate → motor command
rate_error = desired_pitch_rate - gyro_pitch_rate
pitch_command = pid_rate.update(rate_error)

The inner loop (rate PID) is the most critical — it runs fastest and directly damps oscillation. The outer loops can be tuned more aggressively once the inner loop is stable.

Key Flight Parameters

ParameterTypical ValueAffects
Thrust-to-weight ratio2:1 minimum (3:1 for acrobatic)Max acceleration, wind resistance
Control loop rate500-1000 Hz (rate), 250 Hz (angle)Stability, responsiveness
IMU update rate1-8 kHzControl precision
Battery voltageDrops during flightThrust changes — need compensation