FixTheRobot Explore Robotics / Systems Engineering / Engineering Guides / Module 12

Engineering Guides · Module 12

Relocalization and recovery

Lost localisation shows up as growing uncertainty. Detect it by threshold and duration, then recover in stages.

  • Intermediate
  • Module 12: Outdoor-to-Indoor Localization & GNSS-Denied Navigation
  • Written for ROS 2 Jazzy where ROS 2 is used
  • Sources checked 2026-11-06

Assumptions: Numbers in the examples are illustrative and the code is executed by the site’s tests. Facts taken from a cited source are marked; other statements are general engineering knowledge and must be confirmed on the datasheet of the part you use.

1. Engineering problem

After a reboot, a kidnapping or a long dropout, a map-based localiser can be wrong or very uncertain. The robot must notice, stop or slow down, and relocalise. A monitor with a hold time avoids reacting to a single bad update.

2. When is this needed?

  • Setting up AMCL or another map-based localiser.
  • After reboots or the robot being moved.
  • Designing fail-safe behaviour for localisation loss.

3. Selection and design decisions

The Nav2 AMCL package (README read 2026-11-06) is a probabilistic localisation module that estimates the pose of a robot in a known map using a 2D laser scanner; its default parameters include min_particles: 500, max_particles: 2000, update_min_d: 0.25, update_min_a: 0.2, laser_model_type: likelihood_field, save_pose_rate: 0.5 and the recovery parameters recovery_alpha_fast and recovery_alpha_slow both 0.0, that is, off by default. Particle spread (or the pose covariance) is the usual measure of confidence: a tight cloud means a confident estimate, a wide one means the robot is unsure.

Overview
StageTriggerAction
NormalSpread below the limitContinue
DegradedSpread above the limit for the hold timeSlow down, hold, rotate or move a little for more scan information
Relocalise near the last poseDegraded persistsSet an initial pose near the last known pose or a dock
Global relocalisationStill lostSpread particles over the map, move to gain information
Give upStill lost after a time limitStop and ask for help

4. Advantages and disadvantages

  • Short hold time reacts fast and triggers on noise; long is stable and slow.
  • Global relocalisation works anywhere and can pick a wrong place in symmetric maps.
  • Saving the last pose helps restart and can be stale after a move while off.

5. Requirements and constraints

  • A defined action at every stage, including stop.
  • A way to give an initial pose (operator, dock, marker).
  • Saved pose is only trusted if the robot was not moved while off.

6. Architecture

localiser ─▶ confidence (spread/covariance) ─▶ monitor (limit, hold) ─▶ recovery stages ─▶ stop/ask

7. Implementation

  1. Choose the confidence signal and its limit from healthy logs.
  2. Choose the hold time.
  3. Implement the monitor (below) and the stages.
  4. Test with the robot kidnapped and with a reboot at several places.
  5. Log every recovery with its cause and result.
import math
def spread(particles):
    n = len(particles); mx = sum(p[0] for p in particles) / n; my = sum(p[1] for p in particles) / n
    return math.sqrt(sum((p[0] - mx) ** 2 + (p[1] - my) ** 2 for p in particles) / n)
def monitor(history, limit=1.0, hold=3):
    bad = 0
    for t, s in enumerate(history):
        bad = bad + 1 if s > limit else 0
        if bad >= hold:
            return f"t={t}: spread {s:.2f} m above {limit} m for {hold} updates -> start recovery"
    return "healthy"
tight = [(0.1 * math.cos(a), 0.1 * math.sin(a)) for a in range(8)]
wide = [(2.0 * math.cos(a), 2.0 * math.sin(a)) for a in range(8)]
print("tight cloud spread %.2f m, wide cloud spread %.2f m" % (spread(tight), spread(wide)))
print(monitor([0.2, 0.3, 1.4, 1.6, 2.0, 2.2]))
print(monitor([0.2, 1.4, 0.3, 1.6, 0.4]))

Printed (checked by the site’s tests):

tight cloud spread 0.10 m, wide cloud spread 1.96 m
t=4: spread 2.00 m above 1.0 m for 3 updates -> start recovery
healthy

Reading it: a tight cloud of eight hypotheses has a spread of 0.10 m and a wide one 1.96 m. A history rising above the 1 m limit for three updates in a row triggers recovery at the fifth update; a history that spikes and returns never triggers. The limit and hold time are illustrative.

8. Real examples

  • Warehouse AMR after a battery swap: starts from the dock pose, confirms with a scan match, and falls back to global relocalisation if the match score is low.

9. Failure scenarios

  • Treating a single noisy update as loss.
  • Global relocalisation in a symmetric corridor choosing the wrong end.
  • No stop behaviour while lost.

10. Troubleshooting

  1. Plot spread over time against events.
  2. Check that the saved pose file is updated and loaded.
  3. Check the map matches the environment (changed layout).

11. Validation

  • The monitor example prints the lines shown (executed by the site tests).
  • Kidnapping and reboot tests end with a correct pose or a safe stop every time.

12. Engineering checklist

13. Further references

Related on FixTheRobot