Skip to the content
FixTheRobot Explore Robotics / UAV / Module 6 / M6-T5

UAV Systems Engineering · Module 6

M6-T5: PX4 state estimation and EKF2

EKF2 decides what the vehicle believes. Know its sources, its gates and its health signals before blaming the controller.

  • Lesson 5 of 16
  • UAV Software and Flight-Controller Integration
  • Implementation-specific
  • About 6 minutes to read

Almost every “the drone flew badly” report is an estimation problem in disguise. PX4 runs an extended Kalman filter (EKF2) that fuses the IMU with several optional sources. Knowing which sources are active, how each is gated, and how to read its innovations is the single most useful debugging skill for this stack.

Learning objectives

After this lesson, you should be able to:

  • List the sources EKF2 can fuse and the parameters that enable them in your release.
  • Interpret innovation test ratios, status flags and resets in the log.
  • Explain how delays, noise and gating parameters affect behaviour.
  • Diagnose a bad estimate to its source: vibration, magnetometer, GNSS or external vision.

Conceptual explanation

Implementation-specific EKF2 parameter names and message names change between PX4 releases (for example the older EKF2_AID_MASK was replaced by per-source control parameters such as EKF2_GPS_CTRL and EKF2_EV_CTRL in newer versions). Read the “Using the ECL EKF” page of the documentation for the version you fly. Parameter names below are examples to look up, not a fixed contract.

EKF2 is an error-state extended Kalman filter derived from the ECL library: the IMU integrates the nominal state at high rate, and a covariance-propagating filter estimates the error state, correcting it with aiding measurements: GNSS position and velocity, barometric height, magnetometer heading or yaw, rangefinder, optical flow, airspeed (fixed wing) and external vision (position, velocity, yaw). It also estimates IMU biases and, optionally, wind and magnetic field states.

Each aiding source goes through the same process: the measurement is compared to the prediction, the innovation is normalised by its predicted covariance, and if the squared normalised value exceeds a gate (a number of standard deviations, set by a parameter) the measurement is rejected. Persistent rejection leads to a timeout, a reset of the estimate toward the measurement, or a failsafe. Several parameters control each source: its noise, its gate, its delay relative to the IMU, and whether it is used at all.

EKF2 sources and outputsEKF2 predicts with the IMU and corrects with GNSS, barometer, magnetometer, rangefinder, optical flow and external vision. Innovation checks gate each fusion; the outputs are local position, velocity, attitude, and status flags.IMUpredictionAiding sensorsGNSS, baro, mag, EVEKF2error-state EKFInnovation gatesaccept / rejectOutputspose, statusParameters select which sources are fused and how they are weighted and gated.
EKF2 at a glance. The innovation gate is the guard on every source.
Animation of innovation gating in a position estimator. A GNSS position measurement suddenly jumps by twelve metres. The innovation test ratio, the normalised innovation squared divided by its gate, rises above one and the measurements are rejected, so the estimate stays near the truth. If the inconsistency persisted beyond the timeout the filter would reset to the measurement. Three strips show the measurements and the estimate, the test ratio against its limit of one, and the accept or reject decision.
EKF2 compares each measurement with its prediction: test ratio = ν2/(γ2 S)\nu ^{2}/(\gamma ^{2}\,S) with the gate γ\gamma in standard deviations (3 here); above 1 the measurement is rejected, and persistent rejection leads to a reset or a failsafe. Scalar position filter with a 12 m glitch between t=12 st=12\,\mathrm{s} and 17.5 s; gate and timeout are illustrative parameters. (Looping, about 6 seconds; drawn and computed for this course with illustrative values.)

Engineering intuition

The filter is a weighted average of a model prediction and measurements, with the weights set by the covariances. Tell it a sensor is more accurate than it is (noise parameter too small) and it will believe it too much and be dragged around by errors; tell it the sensor is noisy and it will trust the IMU and drift. Gates are the safety net: a measurement that is wildly inconsistent is thrown away instead of accepted.

When the estimate is wrong, find the source of the inconsistency. High vibration clips the accelerometer and corrupts the prediction (look at the vibration metrics and the innovation test ratios of velocity and height). A magnetic disturbance appears in heading innovation. A bad GNSS fix appears as position and velocity innovations that grow. External vision with a wrong frame or time offset appears as a position innovation that correlates with vehicle motion.

Mathematical formulation

For a measurement zz with prediction z^\hat{z} and innovation covariance S=H P H⊤+RS=H\,P\,H^{\top}+R, the innovation and the test ratio are

Innovation test ratio (per measurement, gate γ in standard deviations)
ν=z−z^,ρ=ν⊤S−1νγ2\nu = z - \hat z, \qquad \rho = \frac{\nu^{\top}\mathbf S^{-1}\nu}{\gamma^{2}}
reject if ρ>1\text{reject if } \rho > 1

EKF2 reports these ratios as estimator_status test ratios (for example velocity, horizontal position, vertical position, magnetometer, height above ground); values below 1 mean the fusion is accepted, values persistently near or above 1 mean the filter and the source disagree. A measurement delay of Δ\Delta seconds relative to the IMU is handled by a buffer: the measurement is compared with the state at time t−Δt-\Delta , so a wrong delay parameter turns motion into apparent innovation:

Effect of a delay error
νerr≈v δΔ\nu_{\text{err}} \approx v\,\delta\Delta
Position error from a delay error δΔ at speed v.

At 5 m/s a 100 ms delay error already gives 0.5 m of spurious innovation, comparable to a good GNSS accuracy; that is why delay parameters (for example the external-vision delay) must be measured, not guessed.

ν\nu , SS
innovation and its covariance.
γ\gamma
gate in standard deviations (a parameter per source).
δΔ\delta \Delta
error in the assumed measurement delay (s).

Architecture and data flow

IMU (integrated through the IMU prediction) + aiding sources → ekf2 → vehicle_local_position, vehicle_global_position, vehicle_attitude, vehicle_odometry; health in estimator_status (and in newer releases the estimator_status_flags, estimator_innovations and related topics), failsafe-relevant flags in vehicle_status. The controllers and navigator consume the outputs; the commander reads the validity flags for mode checks and failsafes.

Real-world UAV applications

  • Choosing which sources a vehicle should fuse in a GNSS-denied test.
  • Diagnosing drift and glitches in position hold.
  • Setting up external vision with the right delay and noise.
  • Deciding when to declare the estimate unusable and trigger a failsafe.

Implementation example

This runs as shown. A reduced model of the mechanism: a 10 Hz position measurement of where the vehicle was 100 ms ago is compared with the filter’s own position estimate at the time the filter assumes the measurement was taken. The normalised innovation is at the noise level only when the assumed delay is right, which also gives a practical way to measure the delay: scan the assumed delay and take the minimum. It is a model of the mechanism, not EKF2 code.

import numpy as np
rng = np.random.default_rng(1)
dt, n = 0.01, 6000
t = np.arange(n) * dt
p_true = 10.0 * np.sin(0.8 * t)                                  # moving vehicle, peak speed 8 m/s
true_delay, sigma, sigma_est = 0.10, 0.20, 0.10
p_est = p_true + sigma_est * rng.standard_normal(n)              # the filter's own (undelayed) position estimate, accurate to about 0.1 m
k_meas = np.arange(300, n, 10)                                   # a 10 Hz position measurement of where the vehicle was true_delay ago
z = p_true[k_meas - int(round(true_delay / dt))] + sigma * rng.standard_normal(k_meas.size)

def mean_nis(assumed_delay):
    ka = k_meas - int(round(assumed_delay / dt))                 # compare with the estimate at the time we BELIEVE the measurement was taken
    nu = z - p_est[ka]; return float(np.mean(nu ** 2 / (sigma ** 2 + sigma_est ** 2)))
delays = np.arange(0.0, 0.31, 0.02)
nis = np.array([mean_nis(d) for d in delays])
best = delays[np.argmin(nis)]
print(f"mean NIS: delay right {mean_nis(0.10):.2f}, delay ignored {mean_nis(0.0):.2f}; delay scan minimum at {best:.2f} s")
assert mean_nis(0.0) > 2.0 * mean_nis(0.10) and abs(best - 0.10) < 0.021 and mean_nis(0.10) < 1.5
A wrong measurement delay inflates the normalised innovation, and scanning the assumed delay finds the true one. A model of the mechanism, not EKF2 code.

Common engineering mistakes

Leaving external-vision delay at the default

Measure it; a wrong delay looks like a noisy source.

Loosening gates to hide a problem

The filter then accepts bad data; fix the source.

Ignoring vibration

Accelerometer clipping corrupts everything that follows; check vibration metrics first.

Enabling several sources without a plan

Conflicting sources fight each other; decide the primary source per axis.

Not checking resets

Position and heading resets move the setpoint frame under the controller.

Failure modes

Failure modes, symptoms and causes
Failure modeHow it shows upLikely cause
Position drift in holdSlow wanderWeak aiding source, wrong noise parameters, bias not observable
Sudden jumpsPosition or yaw resetSource change, gate timeout, GNSS glitch, EV frame mismatch
Height oscillationVertical bobbingBarometer pressure error from airflow or vibration; rangefinder conflicts
Failsafe on estimator errorSwitches to land or holdTest ratios exceeded for the timeout period

Debugging approach

  1. Plot the innovation test ratios and status flags with the position error.
  2. Check vibration metrics and accelerometer clipping first.
  3. Compare each source against the estimate to find the offender.
  4. Log and review resets (counter changes) around the event time.

Practical exercises

  1. In a log, find the time EKF2 started fusing GNSS after takeoff and the flags that changed.
  2. Disable GNSS fusion in SITL (parameter for your version) and watch the estimate degrade.
  3. Compute the position error from a 60 ms delay error at 10 m/s.
  4. Plot the velocity innovation test ratio during an aggressive manoeuvre.

Interview questions

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

Question 1

What is an innovation test ratio?

Model answer

The squared normalised difference between a measurement and its prediction, divided by the gate; below 1 means the measurement is accepted, persistently high means the source and the filter disagree.

Question 2

Why does a wrong sensor delay show up as a noisy sensor?

Model answer

The filter compares the measurement with the state at the wrong time; the discrepancy scales with speed, so it looks like noise that grows with motion.

Question 3

How do you diagnose an EKF2 position glitch?

Model answer

Check resets and status flags at the time, plot innovation ratios of each source, check vibration and magnetometer health, and compare each aiding source with the estimate.

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.

Next lesson

M6-T6: Flight modes

Describe the main PX4 flight modes (manual, altitude, position, mission, offboard, return) and the sensors and failsafes each depends on.