← Back
Home › Systems › Robotics

flight-controller

Keeps a multirotor or fixed-wing aircraft flying by reading sensors, estimating attitude and position, and commanding motors and servos on a fixed clock.

PX4, Betaflight

Open the flight-controller pageflight-controller SPSC ring bufferdata-structures: Bounded wait-free queue for exactly one producer and one consumer thread, built from an array and two indices with acquire/release ordering.›Dma transfersembedded: DMA controllers: descriptors, circular buffers, cache coherence for zero-CPU data movementFixed-rate control loopembedded: Run a controller at an exact period using absolute deadlines and a fixed dt, so jitter never accumulates and the math stays valid.›Preemptive priority schedulingembedded: Always run the highest-priority ready task, switching the instant a higher one becomes ready; selection is O(1) with one FIFO per priority and a bitmap.›PWM generationembedded: A timer's counter, period and compare registers draw the pulse train; preload, dead time and DMA make duty changes glitch-free, shoot-through-free and cheap.›Spi i2c bus driversembedded: SPI/I2C/UART peripheral drivers with interrupts, DMA and bus error recoveryCRC32C checksumshardware-os: The Castagnoli CRC-32 with dedicated instructions on x86 (SSE4.2) and ARMv8. It is the standard fast integrity check for storage blocks, logs and network frames.›Interrupt handlinghardware-os: How a device signal reaches a CPU handler through an interrupt controller and vector table, and how top/bottom halves, polling switch-over and coalescing keep load bounded.›Fast Fourier transformnumerics: Computes the DFT in O(n log n) by recursively splitting into even and odd halves; the basis of fast convolution and spectral methods.›Complementary filterrobotics: Blend high-passed gyro integration with low-passed accelerometer/magnetometer attitude (Mahony/Madgwick)Control allocation mixingrobotics: Map desired thrust and torques to actuator commands via mixer matrices with saturation handlingExtended Kalman filterrobotics: Kalman filter for nonlinear motion and measurement models: linearize f and h with Jacobians at the current estimate each step. The default estimator in robot navigation.›PID controllerrobotics: Drive a measured value to a setpoint with three terms on the error: proportional, integral, derivative. The default feedback loop for motors, heaters, drones and gimbals.›Pure pursuit path trackingrobotics: Geometric path following by steering to a look-ahead point (pure pursuit, L1, Stanley)Rigid-body transforms (SE(3)poses)robotics: Represent, compose, invert, integrate and interpolate 3D poses as unit quaternion plus translation, with exp/log maps for small motions and uncertainty.›Sensor fusionrobotics: Combining IMU, GNSS, camera, lidar and radar estimates with Kalman-type filters and time alignmentBiquad filterssignal-processing: Second-order IIR sections (RBJ cookbook): low/high pass, peaking EQ; stable cascadesHierarchical state machinesystems: Nest states so a substate inherits its parent's reactions and only overrides what differs, with ordered entry and exit actions along the path.›False sharingconcurrency: Independent variables written by different cores on one cache line force the line to bounce between cores; pad or regroup hot data to fix it.›Memory orderingconcurrency: What Relaxed, Acquire, Release and SeqCst atomics actually guarantee, what they cost on x86 and ARM, and which one each pattern needs.›SIMD programminghardware-os: Process 4-16 lanes per instruction with AVX2, AVX-512 or NEON via Rust std::arch, with runtime dispatch and a portable fallback.›Finite differencesnumerics: Replace derivatives with weighted differences of grid values; simple stencils plus a stability condition (CFL) turn PDEs like heat, advection and waves into array loops.›LU and Cholesky factorizationnumerics: Factor A = PLU (any square matrix, partial pivoting) or A = LLᵀ (SPD) once in O(n³), then solve each right-hand side in O(n²).›Kalman filterrobotics: Optimal recursive estimator for a linear system with Gaussian noise: fuses a motion model with noisy measurements into a state estimate plus its covariance.›Homogeneous transformsgeometry: 4x4 affine and projective matrices, homogeneous coordinates, view and projection, normal matricesQuaternion rotationsgeometry: Unit quaternions as 3D rotations: 4 floats, cheap composition, no gimbal lock, plus the conversions, interpolation choices and numerical care needed in practice.›Transform treerobotics: Time-indexed tree of coordinate frames with interpolated lookups between any two framesCPU caches and the memoryhierarchyhardware-os: Sizes, line widths and latencies of L1/L2/L3/DRAM on modern x86 and Apple M-series, and the data-layout rules that follow from them.›Explicit Eulernumerics: Step an ODE forward by its current slope, y += h·f(t, y); first-order, one evaluation per step, the baseline every other integrator is measured against.›Thomas tridiagonal solvernumerics: O(n) tridiagonal linear solve used in implicit finite-difference and spline schemesLowest common ancestorgraphs: LCA/merge-base computation in trees and DAGsSpline interpolationnumerics: Linear, bilinear/trilinear and cubic spline interpolation on grids and tables

How it is built

Architecture overview

A flight controller is the small computer that keeps a civilian multirotor or fixed-wing aircraft in the air. It reads inertial and other sensors at a high rate, estimates the aircraft's attitude, velocity and position, compares that estimate with what the pilot or the mission wants, and writes motor and servo commands, all on a fixed clock that does not skip. A multirotor cannot be flown open loop for even a second, so the control loops are the aircraft's stability, not an add-on to it.

The software is a cascade. An outer loop turns a position or velocity target into a desired tilt and thrust; a middle loop turns attitude error into a desired body rotation rate; an inner loop turns rate error into torque demands; a mixer turns thrust and torque demands into one command per motor. Each inner loop runs faster than the one outside it, so the outer loop sees an inner loop that has already settled. Next to the cascade sit the state estimator, the sensor drivers, a mode and failsafe state machine, a logger, and a link to the ground station. PX4 and ArduPilot are the open full-featured stacks; Betaflight is the open stack tuned for racing and freestyle multirotors with a very fast inner loop.

Parts:

 gyro/accel ──SPI+DMA──► drivers ──► notch/low-pass filters ──┐
 baro, mag, GNSS ──I²C/UART──► drivers ───────────────┐       │
                                                      ▼       ▼
                                    state estimator (EKF or complementary filter)
                                                      │ attitude, velocity, position
 pilot / mission ─► mode logic ─► position ─► velocity ─► attitude ─► rate (PID) ─► mixer ─► PWM / digital ESC
      (state machine)   loop       loop        loop        loop                                  │
                                                                                                 ▼
                                                                                              motors
 all stages ──► message queues ──► logger (CRC-protected blocks) and ground link

There are two profiles of the same design. A racing or freestyle profile pushes the rate loop and the gyro sampling as fast as the chip allows and does little else. A navigation profile (survey, inspection, delivery, manned light aircraft autopilots) adds position estimation with GNSS, waypoint missions and failsafes, and runs the slower outer loops on the same cycle structure.

How the parts fit together

Sensor drivers

The inertial measurement unit (IMU) is the heartbeat. A typical board reads the gyro and accelerometer over SPI, which is fast enough for sampling in the kilohertz range, and slower sensors (barometer, magnetometer, GNSS) over I²C or UART. Sampling must be regular: the IMU raises a data-ready signal, an interrupt runs a short handler that only stamps the time and wakes a driver task, and bulk transfers are handed to DMA so the CPU is not blocked while the bytes arrive (dma-transfers, no page yet). The driver tags every sample with the timestamp of the data-ready event, not the time the CPU got round to reading it. A timestamp error of a millisecond is a significant angle error during a fast rotation, and the estimator cannot recover it afterwards. Bus errors are counted and a sensor that stops answering is marked failed, which is what lets the failsafe logic act.

State estimator

The estimator turns raw, drifting measurements into a usable state. Attitude comes mainly from the gyro, which is accurate over short times but drifts, corrected slowly by the accelerometer (which measures gravity when the vehicle is not accelerating) and the magnetometer (heading). The cheap and robust form is a complementary filter (no page yet): integrate the gyro, and pull the result towards the accelerometer and magnetometer attitude with a small gain. Mahony and Madgwick are the best-known formulations, and Mahony et al. give a stability proof for the nonlinear filter on the rotation group. Attitude is held as a quaternion because it composes cheaply and has no gimbal lock; rigid-body transforms relate the body frame to the navigation frame.

For position and velocity the standard is an extended Kalman filter. The state holds attitude, velocity, position and the sensor biases; prediction integrates the IMU at its full rate, and corrections arrive when GNSS, barometer, magnetometer, optical flow or airspeed data come in, each with a noise model and a consistency test that rejects an innovation that is too large. This is the sensor-fusion (no page yet) pattern. PX4's estimator is called EKF2; ArduPilot's is EKF3. Because the measurements arrive late and at different rates, the filter keeps a short buffer of its own past states and applies each measurement at the time it was taken.

Signal filtering

Propellers and motors shake the airframe, and the gyro measures that shaking at the motor frequency and its harmonics. Feeding it into the derivative term of a PID or into the estimator saturates the motors and heats them. Filtering is the answer, and it is a trade-off: every filter adds delay, and delay in a feedback loop reduces the margin of stability. The building block is the second-order recursive filter (biquad-filters, no page yet) in cascades: low-pass filters to remove broadband noise and notch filters to remove narrow peaks. The peaks are found by spectral analysis with the fast Fourier transform on logged or live gyro data, and in flight a dynamic notch follows the peak as throttle changes; in racing firmware the frequency can come from telemetry of the motor speed. The filter design directly sets how aggressive the PID gains can be.

Controllers

The inner loop is a PID controller per axis on body rate. The proportional term reacts to the present error, the integral term removes steady offsets such as an unbalanced battery, and the derivative term (computed on the measurement, not the error, to avoid kicks on set-point steps) damps the response. Anti-windup is mandatory, because the integral must stop growing when the motors are already saturated. A feed-forward term from the stick or the trajectory reduces lag. The attitude loop outside it is typically a proportional controller on the attitude error, giving a rate command; the velocity and position loops continue the cascade.

For fixed-wing and for waypoint following, a path has to be tracked rather than a point. Geometric methods such as pure pursuit (pure-pursuit-path-tracking, no page yet) aim at a look-ahead point on the path and steer towards it; the nonlinear guidance logic used in fixed-wing autopilots (the "L1" family) is the same idea written as a lateral acceleration command. Longer look-ahead gives smooth but corner-cutting paths; shorter gives tight but oscillating paths.

Mixer and output

The controllers decide a total thrust and three torques. control-allocation-mixing (no page yet) maps them to one command per actuator through a matrix that depends on the airframe geometry: for a quadcopter in X configuration, each motor gets the thrust plus a signed share of roll, pitch and yaw. The mixer has to handle saturation. If one motor would be driven above its maximum, naive clipping changes the attitude torque the vehicle receives; good mixers scale down the lower-priority demands (typically yaw first) or shift the whole thrust so that roll and pitch authority is kept. PX4 documents its control allocation, with an effectiveness matrix per vehicle type, as a replacement for fixed mixers, and it also handles vehicles with tilting rotors and surfaces.

The result goes to the speed controllers (ESCs). Classic hobby ESCs take a PWM pulse whose width carries the command; a timer's period and compare registers draw the pulse train, with DMA to avoid CPU involvement at high rates. Digital protocols such as DShot send the command as a digital word with a checksum and avoid the analogue calibration problem; PX4 documents DShot support, and bidirectional DShot carries motor speed back, which is what feeds the dynamic notch.

Scheduler

Everything above has to run on a clock that never skips. The fixed-rate control loop discipline applies: the rate loop executes at an exact period, computed against absolute deadlines, with a fixed dt used in the integrators and filters instead of whatever interval was measured. Tasks run at different rates (rate loop at the fastest, attitude and estimator slower, navigation and logging slowest) under preemptive priority scheduling: the highest-priority ready task runs, and a short control task preempts a long logging task at once. PX4 runs on the NuttX real-time operating system (and Linux on some targets) with a work-queue structure; ArduPilot uses ChibiOS. A watchdog resets the processor if the main loop stops, and, as a design rule, the control path must not wait on storage or on the radio.

Mode and failsafe logic

Which loop is active, and what its targets are, depends on the flight mode: manual and acrobatic rate control, stabilised attitude, altitude hold, position hold, mission, return-to-launch, land. A hierarchical state machine fits well, because many reactions are shared by all sub-modes (disarm on a crash, return on low battery, land on loss of the estimator), and sub-modes inherit them instead of copying them. Arming has pre-conditions (sensors healthy, calibration good, estimator converged, battery sufficient), and failsafes are a prioritised list of triggers (radio link lost, data link lost, battery critical, geofence breach, estimator failure) and responses. The state machine must also be safe to re-enter: after a momentary radio loss the vehicle should not oscillate between "return" and "manual".

Internal messaging and logging

Tasks exchange data through typed queues: PX4's uORB is a publish-subscribe layer inside the process, with the latest value always available to a late subscriber. Where one task produces and one consumes, a single-producer single-consumer ring buffer gives a wait-free hand-off without locks, which is what you want between the IMU task and the logger. The logger writes selected topics to an SD card or flash; because power can be cut by a crash, the log is written in blocks with a CRC-32C so a damaged tail is detected and skipped on read. The same checksum protects stored parameters. Telemetry to the ground station uses MAVLink, a compact framed protocol with its own checksum and sequence number.

Data and control flow

One control cycle (multirotor, navigation profile):

  1. The IMU data-ready interrupt fires; the driver reads the sample by DMA, stamps it, and publishes it.
  2. The filters process the sample; the estimator predicts with it and applies any measurements that are due.
  3. At the position-loop rate the position and velocity controllers turn the mission or stick target into a tilt and thrust request.
  4. At the attitude rate the attitude error becomes a rate setpoint.
  5. At the rate-loop rate the PID loop turns the rate error into torque demands; the mixer allocates motor commands; the outputs update (PWM or DShot).
  6. Logging and telemetry consume the same samples at a lower rate.

A failsafe event: the radio link is lost; the mode logic checks the configured response, switches to return-to-launch, the position loops fly the path home, and land logic takes over near the target. If the estimator reports a lost position, the state machine drops to a mode that does not need position (for instance descent under attitude control).

Scaling

Limits, in the order they bite:

  1. Loop latency from sensor to motor: sampling, filtering and the output protocol add delay. Levers: higher gyro sampling rates, lighter filters, faster output protocols, DMA.
  2. CPU and memory on a microcontroller. The estimator and the logger compete with the rate loop. Levers: a chip with a floating-point unit, moving heavy work to a companion computer, bounded queues.
  3. Vibration and noise limit usable gains more than CPU does. Levers: mechanical damping, notch filters, balanced propellers, rate-limited derivative terms.
  4. Vehicle configurations: a stack that supports many frames needs a configurable mixer and a parameter system, not hand-written code per airframe. Levers: geometry-driven control allocation.
  5. Aircraft size and certification context: for larger civilian aircraft, redundant sensors and processors with cross-checking become necessary; this design does not claim to provide it on its own.

Failure modes

FailureSymptomCauseFix
Vibration noisemotors hot, twitching in hover, derivative term noisyframe resonance, unbalanced props, gyro aliasingsoft-mount the IMU, notch and low-pass filters, higher sample rate
Timing jitteroscillation that tuning does not fixloop not periodic, variable dt, long interruptabsolute deadlines, fixed dt, short interrupt handlers, priorities
Integrator windupovershoot after saturation, slow recoveryintegral grows while motors are clippedanti-windup, saturation-aware mixer
Bad heading or positionflyaway or toilet-bowl circlesmagnetometer disturbed by motor current, wrong frame conventioncompass calibration and motor compensation, estimator innovation checks
Mixer saturationuncontrolled yaw or flip at full throttleone motor clipped, torque authority lostpriority-aware allocation, thrust limits, headroom
Sensor bus failuresudden stop of IMU databus error, bad cable, interrupt stormerror counters, failover to a second IMU, failsafe to a safe mode
Corrupted log or parametersboot with default or wrong parameterspower loss during writechecksummed blocks, double-buffered writes
Mode oscillationrepeated switching between return and manualthreshold chatter on link or batteryhysteresis and latching in the state machine

Real implementations

namewhat it isrepolicencenotes
PX4 Autopilotopen flight stack for multirotors, planes and VTOL; uORB, EKF2, control allocationPX4/PX4-AutopilotBSD-3-Clausedocs at docs.px4.io
ArduPilotopen autopilot for copters, planes, rovers and boatsArduPilot/ardupilotGPL-3.0EKF3 estimator
Betaflightopen firmware for racing and freestyle multirotorsbetaflight/betaflightGPL-3.0fast gyro loop, dynamic notch
MAVLinkthe telemetry and command protocol used by PX4 and ArduPilotmavlink.iosee repomessage definitions and framing

The alternative: a flight controller can be a single loop on a microcontroller without an operating system (a cyclic executive), which is simpler to reason about for a small, fixed airframe. A companion-computer architecture puts the navigation and vision tasks on a Linux board that talks to the flight controller over MAVLink, leaving the hard real-time loops on the microcontroller. Pick the RTOS-based stack when the vehicle needs several flight modes and several tasks at different rates; pick the companion-computer split when perception is heavy.

Sources

Similar systems

Share the most building blocks with this one.