Module 1/5 · Weeks 1–3 · 27 h

Indoor positioning

UAT 366 Indoor Autonomous and Multi-Unmanned Aircraft Systems

About 80 minDraft, awaiting reviewLast updated 27 September 2026

Lesson

By the end of this module you will be able to

  1. Combine position errors from several sources into a root-sum-square error budget
  2. Explain VIO drift and how known-position reference tags correct it
  3. Explain the external position chain into EKF2, its latency and its update rate
  4. Define a building coordinate frame and choose tag spacing from the acceptable error

Prerequisites: UAT 322 (automation integration and sensor fusion) and UAT 363 Module 3 (warehouse positioning)

Why this matters

Inside a warehouse there is no GNSS signal, so the drone must know its position from other sensors. UAT 363 introduced indoor positioning methods and UWB position fixes. This course asks the next question: is the position good enough to fly between racks only a few metres apart? Error comes from several sources at once. Unless the team adds them all up, it may fly closer to the racks than it realises.

The whole course uses one hypothetical case: a parts factory with a 60 × 30 m high-bay rack warehouse that uses three drones to count stock at night. All numbers are made up for practice. The Python code for every module can be downloaded from /downloads/uat-366/.

The position data chain

Five stages from left to right: UWB, MoCap or VIO; the companion computer running ROS 2; the MAVLink ODOMETRY message; EKF2 with delay compensation; and position control. Below, a note says external position is sent at 30 to 50 Hz
Figure 1 The external position chain into EKF2

The PX4 guide to vision and motion-capture positioning says external position should be sent at 30–50 Hz; if the rate is too low, EKF2 will not fuse the data. The parameter EKF2_EV_CTRL selects whether horizontal position, vertical position, velocity or yaw is used, and EKF2_EV_DELAY sets the delay of the vision data relative to the IMU, which the guide says must be tuned experimentally. Uncompensated latency means the position being used is a past position, off by the speed multiplied by the delay.

The error budget

Independent errors from several sources combine as a root sum square (RSS). The largest source dominates, so shrinking small sources helps little.

Example 1 Position error budget in the warehouse

Assumed values (standard deviation in m); the drone flies between racks at 1.5 m/s with 40 ms of uncompensated latency.

import math

SPEED, LATENCY = 1.5, 0.040
sources = {
    "UWB position": 0.10,
    "anchor survey": 0.05,
    "uncompensated latency": SPEED * LATENCY,
    "map-to-tag offset": 0.03,
}
total = math.sqrt(sum(v ** 2 for v in sources.values()))
for name, v in sources.items():
    print(f"{name:<22} {v:.3f} m  ({v ** 2 / total ** 2:.0%} of variance)")
print(f"total (RSS) {total:.3f} m")
fixed = math.sqrt(total ** 2 - sources["uncompensated latency"] ** 2)
print(f"after compensating latency with EKF2_EV_DELAY: {fixed:.3f} m")
UWB position           0.100 m  (59% of variance)
anchor survey          0.050 m  (15% of variance)
uncompensated latency  0.060 m  (21% of variance)
map-to-tag offset      0.030 m  (5% of variance)
total (RSS) 0.130 m
after compensating latency with EKF2_EV_DELAY: 0.116 m

UWB is the largest source, more than half of the variance. Compensating the latency reduces the total error by about 1.4 cm. If the aisle is 2.5 m wide and the drone is 0.8 m wide, the margin on each side is about 0.85 m, which must be compared against several standard deviations, not a single one.

VIO drift

VIO (visual-inertial odometry) estimates motion from a camera and an IMU without installing anything in the building, but its error grows with distance travelled. AprilTag markers (Olson, 2011) placed at known positions reset the error whenever the camera sees one, so the error follows a sawtooth.

Graph of error against flight distance. A pink dashed line without tags keeps rising in a straight line. A solid blue line with tags every 30 metres rises and drops back to 0.03 metres every 30 metres, forming a sawtooth
Figure 2 VIO drift and correction with tags

Example 2 Required tag spacing

Assume VIO drifts by 1% of distance travelled and a tag resets the error to 0.03 m.

DRIFT, TAG_ERR, ROUTE_M = 0.01, 0.03, 120

for spacing in (60, 30, 15):
    worst = TAG_ERR + DRIFT * spacing
    print(f"tags every {spacing:>2} m: worst error {worst:.2f} m")
print(f"no tags over {ROUTE_M} m: {TAG_ERR + DRIFT * ROUTE_M:.2f} m")
for limit in (0.20, 0.10):
    print(f"to stay below {limit:.2f} m, place tags at most every {(limit - TAG_ERR) / DRIFT:.0f} m")
tags every 60 m: worst error 0.63 m
tags every 30 m: worst error 0.33 m
tags every 15 m: worst error 0.18 m
no tags over 120 m: 1.23 m
to stay below 0.20 m, place tags at most every 17 m
to stay below 0.10 m, place tags at most every 7 m

Keeping the error below 10 cm would need a tag every 7 m, which is too many. The answer is to combine sources, such as UWB with VIO, as in Module 2.

The building coordinate frame

Every source must refer to the same frame. Define the room’s origin and axis directions (for example, the south-west corner with x along the aisles), survey the UWB anchors and tags with instruments several times more accurate than the requirement, and convert to the frame PX4 uses (NED), as covered in the ENU and NED conversion in UAT 322.

Module lab

Lab: an error budget in the lab

  1. Define the flight room’s coordinate frame and survey the UWB anchors or motion-capture cameras and the AprilTags.
  2. Send external position into PX4 following the guide, check the rate and set EKF2_EV_CTRL.
  3. Try three values of EKF2_EV_DELAY and compare the error while flying back and forth at a constant speed.
  4. Measure the error of each source and use the code from Example 1 to build an error budget.
  5. Fly a long straight line on VIO alone, measure the drift and use the code from Example 2 to choose the tag spacing.

Common mistakes

Watch out

  • Looking only at UWB accuracy without adding the other sources.
  • Not compensating the latency of external data.
  • Sending position more slowly than EKF2 needs.
  • Mixing ENU and NED frames.
  • Trusting VIO for a long time with no reference to correct its drift.

Summary

  • Errors from several sources combine by RSS, and the largest source dominates the total.
  • Uncompensated latency produces an error of v·Δt; set EKF2_EV_DELAY and send data at 30–50 Hz.
  • VIO drifts; reference tags reset it, and tag spacing follows from the acceptable error.
  • Every source must share one precisely surveyed coordinate frame.

Check your understanding

  1. What is the RSS of error sources of 0.06 m and 0.08 m?
  2. Flying at 2 m/s with 50 ms of uncompensated latency, how large is the error?
  3. VIO drifts 2% of distance, a tag resets the error to 0.02 m, and the limit is 0.2 m. What is the maximum tag spacing?
  4. At what rate does PX4 recommend sending external position?
  5. Why does reducing the smallest error source help so little?
Answers
  1. m
  2. m
  3. m
  4. 30–50 Hz
  5. RSS depends on the square of each source, so a small source contributes very little to the total.

Key formulas

Root-sum-square error budget
Error from uncompensated latency
Maximum tag spacing

Key references

  1. PX4 Autopilot. Using vision or motion capture systems for position estimation. PX4 guide (main). link
  2. Olson, E. (2011). AprilTag: A robust and flexible visual fiducial system. In 2011 IEEE International Conference on Robotics and Automation (pp. 3400–3407). IEEE. link
  3. IEEE. (2020). IEEE standard for low-rate wireless networks — Amendment 1: Enhanced ultra wideband (UWB) physical layers (PHYs) and associated ranging techniques (IEEE Std 802.15.4z-2020). link
  4. Alarifi, A., Al-Salman, A., Alsaleh, M., Alnafessah, A., Al-Hadhrami, S., Al-Ammar, M. A., & Al-Khalifa, H. S. (2016). Ultra wideband indoor positioning technologies: Analysis and recent advances. Sensors, 16(5), 707. link
  5. Groves, P. D. (2013). Principles of GNSS, inertial, and multisensor integrated navigation systems (2nd ed.). Artech House. link
  6. Siegwart, R., Nourbakhsh, I. R., & Scaramuzza, D. (2011). Introduction to autonomous mobile robots (2nd ed.). MIT Press. link

Further reading

Study the assigned knowledge units in advance, review media and take the module quiz

In class / field

Intensive lab and field practice recorded in a lab notebook

Learning evidence: Lab notebook signed by the instructor

Module quiz

This is a formative self-check, not a graded exam

Knowledge domain: Delivery, indoor operations and warehousing · Control, autopilot and navigation