Flight Controller / Fundamentals

FC2 — UAV Control Architecture

Hierarchical Structure of Attitude Control, Position Control, and Mission Layers
Contents

    In our previous post, we provided an overview of flight controllers (FCs). In this article, we will dig deeper into how control is hierarchized inside the FC. Rather than a single PID loop, a UAV's control architecture relies on a hierarchical structure of nested control loops. Understanding this structure is a prerequisite for FC design, tuning, and debugging.

    The architecture is fundamentally a three-layer structure consisting of the Attitude Control Loop, Position Control Loop, and Mission Layer. The control bandwidth decreases as you move from the inside (fastest) to the outside (slowest).

    Why Hierarchical Control is Necessary

    If you were to attempt to achieve "reaching a destination" using a single PID loop, that single controller would have to handle sensor noise, external disturbances, motor latency, and the aircraft's non-linear dynamics all at once. This is impractical in terms of both computational load and stability.

    In hierarchical control, each layer treats the layer immediately inside it as an "ideally operating virtual actuator." The attitude control layer is designed assuming that "the ESCs and motors will output torque exactly as commanded," while the position control layer is designed assuming that "the attitude control will instantly achieve the target attitude." This abstraction allows each layer to be designed and tuned independently.

    Bandwidth separation is the key to stability. The inner loops are designed to be fast (high bandwidth), while the outer loops are slow (low bandwidth). If the bandwidth of the inner loop is at least 3 to 5 times higher than that of the outer loop, inter-layer interference becomes negligible.

    Layer 1: Attitude Control Loop (Innermost & Fastest)
    The attitude control loop is the fastest and most critical control loop within the FC. It controls the angles and angular velocities across the three axes: roll, pitch, and yaw.

    In both ArduPilot and PX4, attitude control is implemented as a dual-loop structure:

    ・Angular Rate Loop (Rate Loop - Inner): Minimizes the error between the target angular velocity and the measured angular velocity using PID control. In ArduPilot, ATC_RAT_RLL_P/I/D and ATC_RAT_PIT_P/I/D correspond to these PID gains. It typically runs at 400 Hz to 1 kHz.

    ・Angle Loop (Outer): Generates target angular velocities based on the error between the target angle and the estimated angle, then passes them to the rate loop. It usually employs P-control only, mapped to parameters like ATC_ANG_RLL_P in ArduPilot. It typically runs at around 400 Hz.

    The D-gain of the rate loop uses the derivative of the gyro value to increase responsiveness to changes in angular velocity. However, because it amplifies gyro noise, balancing it with notch filters and low-pass filters is crucial. This is why the noise mitigation measures explained in our IMU vibration isolation series directly impact attitude control performance.

    Thrust control is also handled within the attitude control layer. To achieve four degrees of freedom (roll, pitch, yaw, and thrust), the output distribution to the four motors is calculated using a Motor Mixer Matrix. For a quadcopter in an X-configuration, the individual motor outputs are calculated using the following mixing equations before being commanded to the ESCs:

    $$\text{Motor 1 (Front Right)} = \text{Thrust} - \text{Roll} + \text{Pitch} - \text{Yaw}
    $$$$\text{Motor 2 (Rear Left)} = \text{Thrust} - \text{Roll} - \text{Pitch} + \text{Yaw}
    $$$$\text{Motor 3 (Front Left)} = \text{Thrust} + \text{Roll} + \text{Pitch} + \text{Yaw}
    $$$$\text{Motor 4 (Rear Right)} = \text{Thrust} + \text{Roll} - \text{Pitch} - \text{Yaw}$$

    Layer 2: Position & Velocity Control Loop
    The position and velocity control loop sits outside (and runs slower than) the attitude control loop, managing the aircraft's horizontal and vertical position and velocity.

    Velocity Loop: Generates target roll and pitch angles based on the error between the target velocity and the measured velocity. Horizontal velocity control is achieved by tilting the aircraft, and this tilt angle command is passed down to the attitude control layer.

    Position Loop: Generates target velocities based on the error between the target position (obtained from GNSS, optical flow, etc.) and the current position, then passes them to the velocity loop.

    The execution frequency for position and velocity control is generally around 50 to 100 Hz. While the GNSS update rate (10 to 20 Hz) sets the lower bound, having a sufficient bandwidth gap between this layer and the attitude control bandwidth (400 Hz+) is a strict condition for stability.

    Altitude control is often handled as an independent sub-loop. Since vertical GNSS accuracy is lower than horizontal accuracy, sensor fusion with a barometric pressure sensor is essential. In ArduPilot, the EKF fuses the barometer, GNSS altitude, and the vertical component of the accelerometer to estimate altitude, which the altitude control loop then utilizes.

    During position hold while hovering (e.g., PosHold mode), if the aircraft drifts from its target position, the PID controller generates tilt commands to counteract the drift. Against wind disturbances, the I-term accumulates the integral error, bringing the steady-state error to zero.

    Layer 3: Navigation & Mission Layer (Outermost & Slowest)The navigation layer enables autonomous flight via waypoints. It sequentially processes a waypoint list provided by the Ground Control Station (GCS) and feeds the next target position to the position control layer.

    For path planning between waypoints, a trapezoidal velocity profile is generated, taking into account the aircraft's speed and acceleration limits. This avoids abrupt velocity changes and ensures smooth path tracking.

    Beyond waypoint flight, the mission layer handles takeoff, landing, RTL (Return to Launch), and failsafe processing. A failsafe is a safety procedure executed automatically during anomalies, such as a loss of GCS communication or a low battery—for example, a logic rule like "if GCS communication is lost for more than 3 seconds, initiate RTL.

    "In ArduPilot, this layer is implemented as a mode system, where flight modes like STABILIZE, ALT_HOLD, LOITER, AUTO, and GUIDED represent different combinations of these layers:

    STABILIZE:Uses only the attitude control layer; the pilot directly commands the tilt angles.

    ALT_HOLD: Uses attitude control + altitude control to automatically maintain altitude.

    LOITER: Uses attitude control + position control to automatically maintain the current 2D position.

    AUTO: Uses all layers to fly autonomously according to the mission plan.

    Architecture Positioning of the EKF
    While each control layer utilizes estimated states (attitude, velocity, position), it is the EKF (Extended Kalman Filter) that handles this state estimation. The EKF fuses data from multiple sensors—including the IMU, GNSS, barometer, compass, optical flow, and beacons—to continuously output the best possible estimates.

    The EKF is not part of the control loops themselves; instead, it functions independently as a platform that supplies state quantities to all control layers. If the EKF is unhealthy (due to poor GNSS signals, IMU saturation, etc.), the performance of all control layers degrades. Therefore, monitoring EKF status is one of the most critical aspects of system design.

    ArduPilot maintains multiple EKF instances (EKF3 is standard) to ensure redundancy by cross-monitoring instances and automatically switching to a healthy one. We will cover the EKF in detail in our upcoming Sensor Fusion series.

    Control Loop Implementation and Timing

    In ArduPilot, the execution timing of each control loop is managed by a task scheduler. The hierarchy prioritizes tasks, with attitude control at the highest priority (400 Hz or higher), position control at 50 to 100 Hz, and mission processing at around 10 Hz.

    When developing a custom FC, the standard approach is to synchronize the periodic reading of IMU data with the execution of the attitude control loop using STM32 timers and DMA. A common architecture triggers the attitude control loop using the IMU's Data Ready interrupt (DRDY) as a baseline, while running the remaining tasks via a round-robin scheduler.

    SummaryThe UAV control architecture relies on a three-layer nested structure: Attitude Control (kHz order), Position/Velocity Control (tens to hundreds of Hz), and Navigation/Mission (single to tens of Hz). The core principle of stability is that inner loops are fast and simple, while outer loops are slower and highly functional. The bandwidth separation between layers and the health of the EKF connecting them ultimately determine the reliability of the entire system.

    In our next post, FC3, we will discuss MCU selection for implementing this control architecture—specifically focusing on applying the STM32 family to flight controllers.

    Explore Our Technologies

    KURAGE GCS

    Browser-Based Ground Control System

    KURAGE Vision

    AI Vision & Security Platform

    KURAGE FC

    Custom STM32H743 Flight Controller

    KURAGE Mission Computer

    Autonomy Engine for UAVs and Robotics