Skip to the content
FixTheRobot Explore Robotics / UAV / Module 8 / M8-T13

UAV Systems Engineering · Module 8

M8-T13: IMU failure handling

The IMU is the one sensor everything depends on. Detect its failure quickly, isolate it, and have a plan for when it is the only one.

  • Lesson 13 of 18
  • Safety, Verification and Flight Testing
  • Established engineering
  • About 6 minutes to read

When a GPS fix is lost the vehicle can still fly; when the IMU is wrong the vehicle is in trouble within a second. IMU failures are rare but severe, and several are silent: a stuck output looks calm, a bias step looks like a manoeuvre. Detection needs either redundancy and cross-checks or a model-based residual against other sensors.

Learning objectives

After this lesson, you should be able to:

  • Classify IMU failure modes and their signatures in gyro and accelerometer data.
  • Implement cross-check voting for triple redundancy and explain why dual redundancy cannot isolate.
  • Use model-based residuals (gyro vs attitude change, accelerometer vs gravity) for single-IMU detection.
  • State detection time and what the vehicle does on a confirmed failure.

Conceptual explanation

Established Redundancy management by voting and cross-checks is standard in avionics. Many autopilots use several IMUs and a selection logic; check what yours does and how it is configured. Thresholds in the example are placeholders and must be derived from the sensor noise specification and validated.

Failure modes and their signatures:

undefined
FailureSignatureHow to detect
Stuck / frozen outputIdentical successive samples, zero noiseVariance below the noise floor; repeated values
Bias step or driftConstant offset on one axisDisagreement with other IMUs; residual against attitude change
Noise increaseHigh-frequency variance up (bearing damage, loose mounting)Variance ratio against its own history and against the other IMUs
Saturation / clippingSamples at full scaleRange check; clipping flag
Dropout / timingMissing or late samplesSample counter and timestamp gaps
Scale-factor or axis errorWrong magnitude or swapped axis after a faultDisagreement scaling with motion; gravity magnitude check at rest

Detection approaches:

  • Cross-check between units: with n≥3n\ge 3 the median of redundant measurements isolates one faulty unit; with 2, only a disagreement is seen.
  • Model-based residuals: integrate the gyro and compare with the attitude change from another source (magnetometer, vision, GNSS velocity); compare the accelerometer’s mean at rest with gravity; compare the estimator’s innovations with their expected size.
  • Built-in tests and data quality: sensor status flags, sample counters, temperature, vibration metrics.
IMU redundancy and votingSeveral IMUs feed a voter. Cross-checks detect which unit disagrees with the others; the voter isolates it and the estimator continues with the healthy units. With only two units a fault can be detected but not isolated without other information.IMU Agyro, accelIMU Bgyro, accelIMU Cgyro, accelVotermedian, cross-checkEstimatorhealthy setThree units isolate one fault; two units only detect it; one unit needs model-based checks.
Voting needs three units to isolate; fewer need model-based support.
Animation of a three-IMU voter. All three gyros measure the same slow rotation rate; at about the middle of the record one of them freezes at a constant value. The deviation of each from the median is shown; the one that exceeds the threshold for a set time is isolated. The mean of the three outputs is dragged away from the truth after the failure while the voted output, the median, stays on it and the error trace of the two is compared.
The median of three is robust to one arbitrary failure and gives a free residual for detection; a mean averages the fault into the output. With two sensors only, a disagreement cannot say which is wrong. Frozen output (stuck-at) is detected by the deviation from the median once the true signal moves. Synthetic signals, noise 0.02 rad/s. (Looping, about 6 seconds; drawn and computed for this course with illustrative values.)

Engineering intuition

Three clocks on a wall: if one disagrees, you believe the other two. Two clocks that disagree tell you something is wrong, not which one. IMUs work the same way, except vibration makes “disagree” fuzzy: two units at different mounting positions legitimately see slightly different signals during manoeuvres (lever arm, mounting flexure), so the thresholds must exceed the normal disagreement while staying below the level that matters to the estimator.

Isolation is only half the answer. After removing a faulty IMU the system has less redundancy; the next failure may be unrecoverable. The response ladder is: continue with warning on the first fault if two healthy units remain; land promptly if one remains; and treat a failure with no healthy unit as an emergency (controlled descent from a model-based estimate if the autopilot has one, otherwise termination).

Mathematical formulation

For three units measuring the same quantity with independent noise σ\sigma and no fault, the pairwise differences have standard deviation σ2\sigma \sqrt{2}; a fault is declared when a unit’s disagreement with the median of the three persists. For unit ii with measurement ziz_{i} and the median mm of the three, the residual ri=zi−mr_{i}=z_{i}-m is a noise-like quantity whose standard deviation is below σ\sigma for an unfaulted unit, so a threshold of several σ\sigma is conservative:

Cross-check threshold with a mounting-disagreement term
unit i faulty if ∣zi−m∣>γ=k σeff for N consecutive samples\text{unit } i \text{ faulty if } \lvert z_i - m\rvert > \gamma = k\,\sigma_{\text{eff}} \text{ for } N \text{ consecutive samples}
σeff=σ2+σmount2(t)\sigma_{\text{eff}} = \sqrt{\sigma^{2} + \sigma_{\text{mount}}^{2}(t)}

where σmount\sigma _{\text{mount}} accounts for legitimate disagreement from lever arms (for angular rate ω\omega and a lever-arm acceleration, a·rr) and k≈5–6k\approx 5\text{–}6 keeps the false-alarm probability per sample at about 10−610^{-6} to 10−910^{-9} for Gaussian noise. The detection delay for a bias step of size Δ\Delta with NN required samples at rate ff is N/f provided Δ≫γ\Delta \gg \gamma ; for Δ\Delta near γ\gamma detection takes longer and a CUSUM test improves sensitivity: Sk=max⁡(0, Sk−1+∣rk∣−ν)S_{k}=\max (0,\,S_{k-1}+|r_{k}|-\nu ), alarm when Sk>hS_{k}>h. A gyro bias of Δ\Delta rad/s gives an attitude error Δ t\Delta \,t, so a 0.05 rad/s bias reaches 2.9∘2.9^{\circ} in 1 s: detection within tens of milliseconds is needed for a fast vehicle.

σ\sigma , σmount\sigma _{\text{mount}}
sensor noise and legitimate inter-unit disagreement.
kk, NN
threshold multiplier and consecutive-sample count.
ν\nu , hh
CUSUM allowance and alarm level.

Architecture and data flow

IMU AA, BB, CC (SPI, each with its own sample counter and timestamp) → sensor drivers → sensors module (voter and selection) → estimator input (selected unit, or the combination of healthy units) with flags in the status message. The vehicle status reports the selected IMU and failure flags; the commander applies the failure response. The log records every unit’s raw data and the voter decisions so that a fault can be reconstructed. (In PX4 the sensors module and EKF2 handle multi-IMU selection and use innovation checks; consult the documentation of your version for the parameters and behaviour.)

Real-world UAV applications

  • Triple-IMU flight controllers with automatic failover.
  • Single-IMU vehicles using model-based residuals and a conservative failsafe.
  • Vibration and mounting diagnostics during development.
  • Verification of fault detection by injecting faults in recorded data.

Implementation example

This runs as shown. A triple-IMU gyro voter with three injected faults on different units (stuck output, bias step, noise increase), detection by median cross-check with NN consecutive samples and a CUSUM for small biases. It reports detection delays and false alarms, and shows that two units alone detect but cannot isolate.

import numpy as np
rng = np.random.default_rng(51)
fs, T = 250, 60.0; n = int(fs * T); t = np.arange(n) / fs
sigma = 0.004                                                                         # gyro noise (rad/s) per sample, placeholder
truth = 0.8 * np.sin(2 * np.pi * 0.5 * t) + 0.3 * np.sin(2 * np.pi * 1.7 * t)           # true body rate about one axis
def triple(fault=None, unit=0, t_fault=20.0):
    z = np.stack([truth + sigma * rng.standard_normal(n) for _ in range(3)]); k = int(t_fault * fs)
    if fault == 'stuck': z[unit, k:] = z[unit, k]
    if fault == 'bias': z[unit, k:] += 0.03                                           # about 7.5 sigma
    if fault == 'noise': z[unit, k:] += 0.05 * rng.standard_normal(n - k)             # about 12 sigma
    return z
def voter(z, k=6.0, N=5, nu=1.5 * sigma, h=12 * sigma, window=125):
    # median cross-check of three units; returns the time at which each unit is first flagged (None if never)
    alarm = [None] * 3; S = np.zeros(3); cnt = np.zeros(3, int)
    for j in range(z.shape[1]):
        m = np.median(z[:, j]); r = np.abs(z[:, j] - m)
        cnt = np.where(r > k * sigma, cnt + 1, 0); S = np.maximum(0.0, S + r - nu)          # consecutive-exceedance counter and a CUSUM
        if j > window:
            w = z[:, j - window:j]; frozen = np.ptp(w, axis=1) < 1e-9                       # no change at all for 0.5 s
            d = np.std(np.diff(w, axis=1), axis=1); noisy = d > 3 * np.median(d)            # much noisier than the median unit
        else: frozen = noisy = np.zeros(3, bool)
        for i in range(3):
            if alarm[i] is None and (cnt[i] >= N or S[i] > h or frozen[i] or noisy[i]): alarm[i] = t[j]
    return alarm
for fault, unit in (('stuck', 0), ('bias', 1), ('noise', 2)):
    a = voter(triple(fault, unit)); delay = a[unit] - 20.0
    print(f"{fault:>5} fault on unit {unit}: flagged at {a[unit]:.3f} s (delay {delay:.3f} s); other units flagged: {[x for i, x in enumerate(a) if i != unit and x is not None]}")
    assert 0 <= delay < 0.8 and all(x is None for i, x in enumerate(a) if i != unit)
fa = sum(x is not None for x in voter(triple())); print("false alarms on 60 s of fault-free data (3 units):", fa); assert fa == 0
z = triple('bias', 1); two = z[[0, 1]]; dis = np.abs(two[0] - two[1])[int(20 * fs):]
print(f"with two units only: disagreement after the fault is {dis.mean():.3f} rad/s ({dis.mean() / sigma:.0f} sigma) on average, but which of the two is wrong is undetermined")
assert dis.mean() > 5 * sigma
print(f"attitude error from the bias if not isolated: {np.degrees(0.03 * 1.0):.2f} deg after 1 s")
A triple-IMU voter with median cross-check, consecutive-sample logic, a CUSUM and a stuck/noise check; faults are injected on different units. Thresholds are placeholders.

Common engineering mistakes

Voting with two IMUs and pretending to isolate

Two units detect disagreement only; use a third unit or a model-based tie-breaker.

Thresholds ignoring legitimate disagreement

Lever arms and flexure cause disagreement in manoeuvres: include it, or false alarms occur in flight.

Same fault source for all IMUs

Common vibration, power or temperature faults hit all units: redundancy does not help.

No detection of stuck outputs

A frozen IMU looks calm; check for zero variance.

No response ladder

Decide in advance what to do after the first, second and last unit fail.

Failure modes

Failure modes, symptoms and causes
Failure modeHow it shows upLikely cause
Silent bias stepAttitude slowly wrongSingle IMU with no model-based residual
False failover in flightUnit rejected during aggressive manoeuvreThreshold below legitimate disagreement
Common-mode vibrationAll IMUs corruptedMount resonance or prop imbalance; redundancy defeated
Late detectionLarge attitude error before isolationToo many required samples or too high a threshold for the bias size

Debugging approach

  1. Log raw data of all IMUs and the voter state; plot pairwise differences.
  2. Measure normal disagreement in flight to set thresholds above it.
  3. Inject frozen, biased and noisy data into a recorded flight and replay.
  4. Check vibration spectra at the IMU mounts for resonances.

Practical exercises

  1. Compute the detection delay for a 0.02 rad/s bias with the example CUSUM parameters.
  2. Add the accelerometer and a gravity check at rest to the monitor.
  3. Estimate σmount\sigma _{\text{mount}} for a 0.1 m lever arm at 5 rad/s25\,\mathrm{rad}/\mathrm{s}^{2} angular acceleration.
  4. Define the response ladder for your vehicle (three, two, one IMU).

Interview questions

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

Question 1

Why can two IMUs not isolate a fault by voting?

Model answer

A disagreement is symmetric: either unit could be wrong. A third unit provides a majority, or a model-based residual provides a tie-breaker.

Question 2

How can a single IMU’s failure be detected?

Model answer

With model-based residuals: compare integrated gyro with attitude change from a magnetometer, vision or GNSS velocity, check that the accelerometer norm at rest equals gravity, and monitor estimator innovations and sensor variance.

Question 3

What is a common-mode failure?

Model answer

A single cause that affects all redundant units at once (shared power, vibration, temperature, software), which defeats voting and has to be handled by design, isolation and separate mounting.

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

M8-T14: Communication loss and failsafes

Configure communication-loss and other failsafes, choose actions and timeouts, and verify them.