L1 Control Logic
Executive Summary
The L1 Controller is ArduPilot's primary guidance algorithm for fixed-wing aircraft and rovers. Unlike a simple PID controller that reacts to cross-track error, L1 is a Nonlinear Guidance Logic that looks ahead on the path.
It computes a Lateral Acceleration Demand (_latAccDem) to curve the vehicle onto the desired path, similar to how a human driver looks down the road rather than at the hood ornament.
Theory & Concepts
1. The "L1" Distance
The core concept is the L1 Point: a virtual target point on the desired path at a specific distance ($L_1$) ahead of the vehicle.
- Physics: The vehicle attempts to fly a circular arc that intersects the L1 point.
- Effect:
- Long $L_1$: Stable, smooth path converging (Under-damped).
- Short $L_1$: Aggressive, fast convergence (Over-damped).
2. Centripetal Acceleration
The controller outputs a lateral acceleration command ($a_s$) based on the L1 distance and the angle $\eta$ (Nu) between the velocity vector and the L1 point.
$$ a_s = 2 \frac{V^2}{L_1} \sin \eta $$
Where:
- $V$ = Ground Speed
- $\eta$ = Angle to L1 point
- $L_1$ = Lookahead distance
3. Vector Fields
ArduPilot's implementation is actually a Vector Field. It calculates a desired velocity vector at every point in space. Even if the plane is flying away from the waypoint, the vector field "flows" back towards the track line.
Codebase Investigation
1. The Core Update Loop: update_waypoint()
Located in libraries/AP_L1_Control/AP_L1_Control.cpp.
-
Calculate L1 Distance:
_L1_dist = MAX(0.3183099f * _L1_damping * _L1_period * groundSpeed, dist_min);- The distance scales with Ground Speed. Faster planes look further ahead to stay stable.
NAVL1_PERIODdetermines the time constant.
-
Calculate Nu ($\eta$):
The code calculates the angle to the L1 point.- If far from track:
Nupoints directly at the line (Capture Mode). - If near track:
Nupoints along the track with an intercept angle (Track Mode).
- If far from track:
-
Compute Acceleration Demand:
_latAccDem = K_L1 * groundSpeed * groundSpeed / _L1_dist * sinf(Nu);This demand is fed into the roll controller (
nav_roll_cd).
2. Loiter Logic: update_loiter()
Loitering is treated as a continuous turn.
- Capture Phase: If outside the circle, it flies a tangent to the circle edge.
- Hold Phase: It balances Centripetal Acceleration (
latAccDemCircCtr) with PD control (latAccDemCircPD) to correct radius errors.
Key Parameters
| Parameter | Default | Description |
|---|---|---|
NAVL1_PERIOD |
20 | (Seconds) The aggressiveness of the turn. Lower = sharper turns. Higher = smoother navigation. |
NAVL1_DAMPING |
0.75 | Damping ratio. 0.7-0.8 is ideal. Higher values reduce overshoot but slow convergence. |
NAVL1_LIM_BANK |
0 | (Degrees) Limits the bank angle specifically for loiters. 0 = Use standard roll limit. |
Source Code Reference
- Implementation:
libraries/AP_L1_Control/AP_L1_Control.cpp - Header:
libraries/AP_L1_Control/AP_L1_Control.h
Practical Guide: Tuning L1 Navigation
Common symptom: "My plane weaves (snakes) around the waypoint line."
Step 1: Check NAVL1_PERIOD
This is the most common culprit.
- Symptom: Fast oscillation (weaving) around the track.
- Fix: Increase
NAVL1_PERIOD. Default is 20. Try 25.- Why? The plane is reacting too fast to small errors. Increasing the period forces it to "look further ahead," smoothing out the path.
Step 2: Check NAVL1_DAMPING
- Symptom: The plane turns onto the line but overshoots it, then corrects back and overshoots again (sloppy S-turns).
- Fix: Increase
NAVL1_DAMPINGby 0.05.- Why? It needs more damping to settle onto the line without overshoot.
Step 3: The "Too Slow" Turn
- Symptom: Plane takes forever to turn towards a waypoint, flying a huge lazy arc.
- Fix: Decrease
NAVL1_PERIOD. Try 15 or 12.- Warning: If you go too low (e.g., < 10), the plane may become unstable and induce roll oscillation.