Skip to the content
FixTheRobot Explore Robotics / UAV / Module 7 / M7-T6

UAV Systems Engineering · Module 7

M7-T6: End-to-end latency

Latency is a budget, jitter is a risk, and both are measured from the moment the world was sensed, not from the moment the message arrived.

  • Lesson 6 of 19
  • Embedded Systems, Timing and System Integration
  • Implementation-specific
  • About 6 minutes to read

Every stage of the pipeline from camera to motors adds delay. A 100 ms delay at 8 m/s is 0.8 m of position error before any algorithm makes a mistake, and a controller that ignores it can oscillate. This lesson makes latency a quantity you budget, measure and test.

Learning objectives

After this lesson, you should be able to:

  • Decompose end-to-end latency into stages and write a latency budget.
  • Convert delay into position error and into a control-stability concern.
  • Measure latency and jitter from timestamps and report percentiles.
  • Explain queueing, executors and buffering as sources of tail latency in ROS 2.

Conceptual explanation

Implementation-specific Typical stage values depend on the sensor, drivers, middleware settings and hardware. Measure your own system: the numbers in the example are illustrative.

Latency is the time from a physical event to the system’s response to it. Define it from the measurement’s timestamp (when the sensor sampled the world), through every stage, to the actuation or the published command. Jitter is the variation of latency from one sample to the next. A fixed delay can be modelled and compensated; variable delay cannot be, which is why jitter is more dangerous than a constant delay of the same mean.

Latency budgetA horizontal chain from exposure to actuation: exposure and readout, transport, perception, estimation, planning, flight controller and motor response. Each stage has a budget, and the total must stay within the control loop requirement.Exposure + readoutcameraTransportdriver / busPerceptionVO / LIOEstimatorfusionPlannerMPCFlight ctrlPX4MotorsESC + prop end-to-end latency L = Σ stage latencies (+ queueing); jitter is the variation of Lmeasure from the exposure timestamp, not from message arrival
A latency chain. Each stage consumes budget.
Animation of how a latency distribution builds up stage by stage. Starting from sensor exposure, each stage in turn is added to the pipeline, driver transfer, visual odometry, the link and the estimator, and the histogram of the total latency shifts right and develops a long tail. Markers for the median and the 99th percentile move with each stage, and the printed numbers show the 99th percentile growing much faster than the median.
Total latency = Σ\Sigma stage latencies; each stage is a distribution with a tail (queueing, scheduling, contention), and tails add. Control and estimation must be designed for a high percentile (p99), not the mean; the budget is allocated per stage. Simulated gamma-distributed stage times with illustrative parameters; 100 000 samples. (Looping, about 6 seconds; drawn and computed for this course with illustrative values.)

Engineering intuition

Two consequences matter. First, delay becomes position error: the vehicle has moved vv·LL by the time you act on what you saw. Second, delay costs stability margin: a pure delay adds phase lag that grows with frequency, so a controller tuned for no delay can ring or oscillate when a 100 ms vision loop sits inside it. The cure is a mix of reducing delay (faster stages, less queueing), compensating a known delay (predict the state forward with the IMU), and keeping control loops that must be fast off the slow path: the attitude loop runs on the flight controller and never waits for vision.

Mathematical formulation

Position error from an uncompensated delay at speed vv:

Delay to position error
e≈v Le \approx v\,L
L is the end-to-end latency.
Example
8 m/s×0.12 s=0.96 m8\ \mathrm{m/s}\times 0.12\ \mathrm{s} = 0.96\ \mathrm{m}

A pure delay LL contributes phase lag −ωL\omega L (radians) at frequency ω\omega . A loop with crossover frequency ωc\omega _{c} loses a phase margin of about ωcL\omega _{c}L: a 1 Hz crossover with 100 ms of delay loses 0.1×2π≈0.63 rad≈36∘0.1\times 2\pi \approx 0.63\,\mathrm{rad}\approx 36^{\circ}, a large fraction of a typical 45–60∘45\text{–}60^{\circ} margin.

Phase margin lost to delay
Δ(phase margin)≈−ωc L(rad)\Delta(\text{phase margin}) \approx -\omega_c\,L \quad(\text{rad})
Keep the latency below
L<PMavailableωcL < \frac{\text{PM}_{\text{available}}}{\omega_c}

Percentiles, not means

Report the median, the 95th, 99th and maximum latency. A pipeline with a mean of 40 ms and a 99th percentile of 180 ms behaves like a 180 ms system when the worst case happens during a fast manoeuvre. Deadline-miss rate (fraction of samples over a threshold) is the number that connects to safety.

Queueing

If a stage takes longer on average than the interval between inputs (utilisation ≥ 1), its queue grows without bound and latency grows with it. Even below 1, bursts make latency variable. Use bounded queues of depth 1 for sensor streams so that stale data are dropped instead of processed late.

Architecture and data flow

Timestamps flow with the data: each message carries the sensor’s acquisition time, and every stage forwards it (it does not re-stamp with the processing time). A monitor at the end computes now − stamp per output. Stage latencies come from spans logged between stages or from the ROS 2 tracing tools (for example ros2_tracing); the sum of the stage medians should match the end-to-end median, and a gap means you are missing a stage (often a queue or a driver buffer).

Real-world UAV applications

  • Choosing between a 30 Hz and a 60 Hz camera: higher rate lowers latency as well as raising update rate.
  • Setting EKF2’s external-vision delay or sample timestamps (lesson M6-T10).
  • Deciding whether an MPC with a 15 ms worst-case solve fits in a 50 Hz loop.
  • Deciding what must stay on the flight controller and what can run on the companion.

Implementation example

This runs as shown: it analyses a synthetic log of stage timestamps. It reports percentiles, the deadline-miss rate, the position error implied by the 99th percentile, and finds the stage that contributes the tail.

import numpy as np
rng = np.random.default_rng(8)
n = 5000
# Synthetic per-frame stage latencies in milliseconds (illustrative distributions, not measurements of any device)
stages = {
    "exposure+readout": 12 + 2 * rng.random(n),
    "driver/transport": 6 + 3 * rng.random(n),
    "perception (VIO)": 18 + rng.gamma(2.0, 2.0, n),
    "estimator":        4 + rng.gamma(2.0, 0.5, n),
    "planner (MPC)":    5 + rng.gamma(1.5, 1.0, n) + (rng.random(n) < 0.01) * 40,      # 1% of solves overrun
    "flight ctrl + motors": 20 + 2 * rng.random(n),
}
total = sum(stages.values())
p50, p95, p99, pmax = np.percentile(total, [50, 95, 99, 100])
print(f"end-to-end: p50 {p50:.0f} ms, p95 {p95:.0f} ms, p99 {p99:.0f} ms, max {pmax:.0f} ms")
deadline = 100.0                                                    # requirement: 100 ms
miss = np.mean(total > deadline)
print(f"deadline misses (> {deadline:.0f} ms): {100 * miss:.2f}%   position error at 8 m/s, p99: {8 * p99 / 1000:.2f} m")
# which stage contributes the tail? compare each stage's contribution on the worst 1% of frames with its overall mean
worst = total >= p99
for name, v in stages.items():
    print(f"  {name:22s} mean {v.mean():5.1f} ms | in worst 1%: {v[worst].mean():5.1f} ms")
tail_stage = max(stages, key=lambda k: stages[k][worst].mean() - stages[k].mean())
print("largest tail contributor:", tail_stage)
assert tail_stage.startswith("planner") and p99 > p50 + 10 and abs(sum(v.mean() for v in stages.values()) - total.mean()) < 1e-9
Latency percentiles and tail attribution from per-stage timestamps (synthetic data).

Common engineering mistakes

Reporting average latency only

Safety depends on the tail. Always report p95, p99 and maximum, and the deadline-miss rate.

Measuring from message arrival

Latency starts at sensor exposure. Arrival time hides driver and transport delay.

Unbounded queues on sensor streams

Overload turns into growing latency instead of dropped frames. Use depth-1 queues.

Re-stamping messages with processing time

It destroys the information needed for delay compensation and fusion.

Assuming the network and middleware add nothing

Serialisation, copies, DDS discovery and QoS settings all contribute: measure with the real QoS.

Failure modes

Failure modes, symptoms and causes
Failure modeHow it shows upLikely cause
Position lag in motionMap and pose trail the vehicle at speedLarge constant latency not compensated
Intermittent glitchesOccasional jumps while average latency looks fineTail latency from a GC pause, an overrunning solver or a bursty driver
Growing latencyDelay rises over minutesStage slower than its input rate and an unbounded queue
Control oscillationSlow oscillation when vision is in the loopPhase lag from delay inside a feedback path

Debugging approach

  1. Add acquisition timestamps at the source and log now − stamp at each stage and at the output.
  2. Run with tracing enabled (ros2_tracing, perf) and attribute the tail to a stage.
  3. Test under realistic load (all sensors, logging on, thermal throttling) because latency depends on load.
  4. Set CPU governor and power mode explicitly: frequency scaling changes timing.

Practical exercises

  1. Compute the phase lag in degrees of 80 ms delay at 2 Hz.
  2. Modify the code so the planner’s overrun rate is 5% and find the p99 position error at 10 m/s.
  3. Design a budget for a 100 ms end-to-end requirement and assign each stage a limit.
  4. Explain why a depth-1 queue plus “drop oldest” is the right default for a camera stream.

Interview questions

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

Question 1

Why report latency percentiles?

Model answer

Means hide the tail, and failures happen in the tail: a rare 200 ms delay during a manoeuvre matters more than a 40 ms average.

Question 2

How does delay affect a control loop?

Model answer

A delay LL adds phase lag ωL\omega L at frequency ω\omega , reducing phase margin; vision-in-the-loop controllers can oscillate unless the delay is small, compensated, or kept out of the fast loop.

Question 3

Where should latency be measured from?

Model answer

From the sensor exposure timestamp, through every stage, to the output; arrival time omits driver and transport delay.

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.

Practice this lesson

M7-L1: Measure ROS 2 end-to-end latency

Measure latency across a pipeline.

Next lesson

M7-T7: Jitter and deadline monitoring

Measure periodic-task jitter, detect deadline misses and set watchdog thresholds that match the control requirement.