Skip to main content
Version: 10

Tune Mobile Base Localization

MoveIt Pro localizes a mobile base in two stages:

  • A state estimator, Fuse, combines wheel odometry and IMU data into a smooth odometry estimate.
  • beluga_amcl matches lidar scans against a map and publishes the map → odom correction on top of that estimate.

This guide shows how to get that stack working on your robot, how to check that it is working, and what to change when it is not. Mobile Navigation (Nav2) describes how the stack is wired together.

The hangar_sim robot configuration package in the example workspace is a working reference. Its settings are in two files:

1. Check odometry first​

AMCL corrects odometry; it cannot make up for odometry that is wrong. Before tuning AMCL, drive the base a known distance and rotate it a known angle, and compare with the wheel odometry your drive controller publishes. In hangar_sim, that is /platform_velocity_controller_nav2/odom during navigation; /odom there is the simulator's ground truth, so it cannot show a wheel calibration error. If they differ, fix the drive controller's kinematic parameters, such as wheel radius and wheel separation.

2. Set the basic AMCL parameters​

Start from the hangar_sim amcl block and change these to match your robot:

ParameterWhat to set
robot_model_typenav2_amcl::OmniMotionModel for a holonomic base such as a mecanum drive; nav2_amcl::DifferentialMotionModel for a differential drive.
scan_topicThe lidar scan topic.
base_frame_id, odom_frame_id, global_frame_idYour robot's base, odometry, and map frames.
max_beamsClose to the number of rays in one scan. beluga picks evenly spaced rays before it discards invalid returns, so a low value can leave very few usable measurements.
laser_max_range, laser_min_rangeYour lidar's usable range.
laser_model_typeStart with likelihood_field. It is the cheapest model and copes well with many small or moving objects, such as chair legs. Switch to beam, which traces each ray along its whole path, only if likelihood_field cannot hold the estimate and you have CPU to spare. Do not use likelihood_field_prob: the beluga authors recommend it only together with beam skipping, which beluga does not implement.

Leave the other parameters at the hangar_sim values until you see a problem.

3. Check that localization is working​

  1. In the MoveIt Pro Desktop App, open the View menu and enable Particle Filter - topic under Navigation, for example Particle Filter - /particle_cloud. The particles appear as magenta arrows. See Particle filter overlay.
  2. Drive the robot around. The particles should stay in a tight group around the robot, and the lidar scan should line up with the walls in the map.
  3. Watch the robot, not the odom frame. A small heading correction moves the odom origin a long way when the robot is far from it, even though the robot itself barely moves. Judge localization by how well the robot and its scan line up with the map.

4. Fix common problems​

SymptomWhat to change
The robot's pose jumps when people, carts, or other objects that are not in the map are nearby.Increase sigma_hit in small steps. Also increase z_rand and decrease z_hit by the same amount.
The pose drifts between corrections, then snaps back.Decrease update_min_d and update_min_a so AMCL corrects more often. Try this before changing the alpha values. If the particles then thin out or collapse, increase resample_interval. Check that odometry is accurate (step 1).
The robot loses its position in long corridors or open areas.Increase the alpha1 … alpha5 motion noise values in small steps. This keeps the particles spread out until the robot sees distinctive features again.
The heading flips to a wrong direction during turns in place.Increase alpha1, the rotation noise caused by rotation, in small steps.
The robot loses its position near walls or obstacles on a hand-drawn map.Check that beluga's only_obstacle_boundaries option is true, its default; it reduces filled obstacles in the map to thin outlines. If it is disabled, redraw filled walls as thin outlines. Maps from SLAM already have thin outlines.
The map lags behind the robot during turns.Lower the velocity smoother's angular limit, max_velocity[2]. Changing MPPI's wz_max has no effect if it is above that limit.
The particles spread out and never come back together.Check odometry (step 1), then check that max_beams is close to the scan's ray count.
The robot is completely lost.Publish the robot's correct pose on /initialpose, for example with the 2D Pose Estimate tool in RViz. Keep recovery_alpha_slow and recovery_alpha_fast enabled, as in hangar_sim, so AMCL can recover on its own. Both default to 0.0, which disables recovery.
Localization is worse in simulation or when the computer is busy.Close other heavy programs, such as builds. In simulation, keep the real-time factor close to 1.0.

Change one parameter at a time, and drive the same route before and after each change so you can compare.

Parameters that have no effect

beluga does not implement beam skipping. You can remove do_beamskip, beam_skip_distance, beam_skip_error_threshold, and beam_skip_threshold from your configuration.

5. Tune Fuse​

These are the Fuse settings most robots need to change from the hangar_sim example:

  • throttle_period on each sensor. If an input arrives much faster than optimization_frequency, the optimizer falls behind, logs Optimization exceeded the configured duration, and keeps publishing an old estimate. Check each input's rate with ros2 topic hz and set throttle_period to bring it close to the optimizer's rate. If the optimizer still falls behind, shorten lag_duration, the smoother's time window, so each optimization has less to solve.
  • Which sensor provides heading. If your IMU heading is more accurate than wheel odometry, remove orientation_dimensions and angular_velocity_dimensions from the wheel odometry sensors so the IMU provides yaw.
warning

To stop a sensor from providing a measurement, delete the key entirely, such as orientation_dimensions. Do not set it to an empty list ([]): Fuse fails to start with the error parameter_value_from failed ... No parameter value set.

Compare settings systematically​

Driving the robot and watching is enough to get started. When you need to compare several settings reliably:

  • Record a representative route once as a ROS bag, then replay the same bag through AMCL with each setting, so every run sees the same data.
  • Compare the result with a reference: ground truth in simulation, or motion capture or surveyed markers on hardware.
  • Look at the error while the robot is stopped and the error while it is moving separately. They have different causes, so a change can improve one and not the other. Error while stopped decides whether the robot reaches its goals.
  • Repeat each setting several times, because results vary from run to run.

LAMBKIN, from the authors of beluga, automates this: it runs parameter sweeps over repeated iterations, manages the ROS processes, and collects the results for analysis.