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

Engineering Guides · Module 09

Configuring a SLAM package

Most SLAM problems from a new setup are inconsistencies between the configuration and the robot: frames, ranges and rates.

  • Intermediate
  • Module 09: SLAM Selection, Configuration & Troubleshooting
  • 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

A SLAM package runs with defaults and gives poor results when the defaults do not match the robot: a wrong base frame, a range above the sensor’s maximum, thresholds that never trigger. A short consistency check catches these before any mapping run.

2. When is this needed?

  • First launch of a SLAM package on a new robot.
  • When maps are poor and the sensor is fine.
  • When changing the LiDAR.

3. Selection and design decisions

The slam_toolbox example configuration (jazzy branch, read 2026-11-06) sets, among others: odom_frame: odom, map_frame: map, base_frame: base_footprint, scan_topic: /scan, mode: mapping (or localization), resolution: 0.05, max_laser_range: 20.0, minimum_time_interval: 0.5, minimum_travel_distance: 0.5, minimum_travel_heading: 0.5, do_loop_closing: true, loop_search_maximum_distance: 3.0 and link_scan_maximum_distance: 1.5. The package supports synchronous and asynchronous mapping and a lifelong mode on a serialized pose graph.

Overview
ParameterMeaningCheck against
odom_frame, map_frame, base_frametf frames usedThe robot’s tf tree (view_frames)
scan_topicInput scansThe actual topic name and frame
max_laser_rangeLongest range used from each scanThe sensor’s real maximum range
resolutionMap cell size (m)The finest feature and compute budget
minimum_travel_distance / headingMotion between processed scansSpeed and scan rate
minimum_time_intervalMinimum time between processed scansScan period
do_loop_closing, loop_*Loop closure behaviourEnvironment size and similarity

4. Advantages and disadvantages

  • Finer resolution gives detail and costs memory and compute.
  • Smaller travel thresholds add scans and compute; larger ones reduce accuracy.
  • Loop closure on corrects drift and can produce false closures in repetitive places.

5. Requirements and constraints

  • Frames in the configuration exist in tf and form a connected tree.
  • Ranges and rates match the sensor.
  • Odometry is smooth and its time stamps are consistent with the scans.

6. Architecture

/scan + odom ─▶ slam_toolbox (config) ─▶ map ─▶ map→odom transform ─▶ localisation / planning

7. Implementation

  1. Open the configuration and list frames, topic, ranges and thresholds.
  2. Check them against the robot and sensor (below).
  3. Run in mapping mode in a known place and inspect the map.
  4. Check the map→odom transform in tf.
  5. Save the pose graph and test localisation mode.
cfg = {"odom_frame": "odom", "map_frame": "map", "base_frame": "base_footprint", "scan_topic": "/scan", "resolution": 0.05,
       "max_laser_range": 20.0, "minimum_travel_distance": 0.5, "minimum_travel_heading": 0.5, "minimum_time_interval": 0.5,
       "do_loop_closing": True, "loop_search_maximum_distance": 3.0, "link_scan_maximum_distance": 1.5, "mode": "mapping"}
sensor = {"max_range": 12.0, "rate_hz": 10.0, "base_frame_in_tf": "base_link"}
issues = []
if cfg["max_laser_range"] > sensor["max_range"]:
    issues.append(f"max_laser_range {cfg['max_laser_range']} m exceeds the sensor range {sensor['max_range']} m")
if cfg["base_frame"] != sensor["base_frame_in_tf"]:
    issues.append(f"base_frame '{cfg['base_frame']}' is not the robot's tf base frame '{sensor['base_frame_in_tf']}'")
if cfg["minimum_time_interval"] < 1 / sensor["rate_hz"]:
    issues.append("minimum_time_interval is below the scan period: it never limits processing")
if cfg["loop_search_maximum_distance"] < cfg["link_scan_maximum_distance"]:
    issues.append("loop search distance is smaller than the link distance")
print("\n".join(issues) or "no issues")

Printed (checked by the site’s tests):

max_laser_range 20.0 m exceeds the sensor range 12.0 m
base_frame 'base_footprint' is not the robot's tf base frame 'base_link'

Reading it: the checker reports that the configured 20 m range exceeds the 12 m the sensor provides and that the configured base frame differs from the one in tf; the other checks pass. The sensor values are illustrative.

8. Real examples

  • Nav2 with slam_toolbox: the Nav2 documentation has a tutorial on running Nav2 with SLAM (docs.nav2.org).

9. Failure scenarios

  • A base frame that does not exist, so no scan can be transformed.
  • Odometry with time stamps in the future, which stalls the scan queue.
  • A 2D scan with a wrong frame_id that is tilted relative to the floor.

10. Troubleshooting

  1. If the map does not update, check frames and the scan topic.
  2. If it smears when turning, check odometry quality and time stamps.
  3. If loop closures are wrong, tighten the loop parameters.

11. Validation

  • The checker prints the lines shown (executed by the site tests).
  • A test map of a known place has the right dimensions.

12. Engineering checklist

13. Further references

Related on FixTheRobot