Imad-Eddine NACIRI
← Back to Projects

SLAM-Based Autonomous Navigation in ROS 2

Built a complete autonomous navigation stack in ROS 2 — from URDF modeling and ros2_control, through Grid-Based FastSLAM and AMCL localization, to the full Nav2 stack — validated in Gazebo and deployed on a real differential-drive robot.

6/1/2025
ROS2SLAMAMCLNav2LiDARGazeboURDFAutonomous NavigationRobotics
Differential-drive mobile robot performing SLAM-based navigation

Overview

This project delivers an end-to-end autonomous navigation system for a differential-drive mobile robot, designed around the ROS 2 ecosystem. We start from the physical model (URDF + Blender), move through sensor integration (LiDAR + rotary encoders), set up the simulation (Gazebo + RViz2), and culminate in Grid-Based FastSLAM, AMCL localization, and the Nav2 stack for static and dynamic obstacle avoidance — all validated in simulation and on a real robot.

“A complete autonomous navigation stack: perceive, map, localize, plan, and act — coherently, in ROS 2.”

Problem Statement

Reliable autonomous navigation for differential-drive robots requires precise localization, accurate mapping, and robust path planning — and existing approaches often integrate these components poorly. The result is brittle behavior: drift, collisions, replanning loops, and failure in dynamic environments.

This work bridges that gap by integrating Grid-Based FastSLAM with AMCL inside ROS 2, anchored on a clean URDF-based robot model and validated in both Gazebo and the real world.

Objectives

  1. Design a URDF-based differential-drive robot with realistic kinematics and sensors.
  2. Generate accurate occupancy maps using Grid-Based FastSLAM.
  3. Maintain a globally consistent pose with AMCL correcting odometry drift.
  4. Plan and execute trajectories using Nav2 with reactive obstacle avoidance.
  5. Validate the stack in Gazebo simulation and on a physical robot.

System Architecture

The full stack is layered as follows — perception feeds mapping, mapping feeds localization, localization feeds the planner, the planner feeds the controller, and the controller drives the robot.

LiDAR + Encoders /scan, /odom URDF / TF Tree robot_state_publisher SLAM Toolbox Grid-Based FastSLAM Occupancy Grid Map /map AMCL Particle Filter Nav2 Global Planner Dijkstra / A* Local Controller DWB + Costmap Differential Drive /cmd_vel odometry feedback loop

Differential-Drive Robot Design

The platform is a small cylinder-shaped chassis carrying two driven wheels in the middle and two caster wheels (front + back) for stability. The compute stack is a Raspberry Pi 5B (high-level) talking to an Arduino Nano (motor control), with a 2D LiDAR for perception and rotary encoders for odometry.

Real differential-drive robot used for the project

Kinematic model

The robot’s translation and rotation are governed by the standard differential-drive kinematics:

v = (vR + vL) / 2
ω = (vR − vL) / d

Forward odometry is integrated from encoder ticks:

Δx = (r/2) · (Δenc_R + Δenc_L)
Δθ = (r/d) · (Δenc_R − Δenc_L)

where r is the wheel radius and d is the track width.

URDF & TF tree

The robot is described modularly in URDF — chassis, wheels, sensors, and joint types are split into includes for maintainability. ROS 2’s robot_state_publisher then broadcasts the full world → odom → base_link → laser/wheel_link transform chain, following REP-105 conventions.

Sensor Integration

SensorRoleROS 2 Topic
2D LiDARRange-bearing scans for SLAM and obstacle avoidance/scan
Rotary encoders (×2)Wheel ticks → odometry pose/odom
cmd_vel actuationLinear & angular velocity commands/cmd_vel

LiDAR is the primary perception sensor — its distance + intensity returns drive both map construction and AMCL’s measurement update. Encoders provide the motion model prior, but they suffer from drift on uneven floors — which is exactly what AMCL is there to correct.

Gazebo Simulation & RViz2

Validation begins in Gazebo with a custom world (obstaclesworld) full of walls and obstacles. The libgazebo_ros_diff_drive plugin maps /cmd_vel to wheel velocities, publishes /odom, and broadcasts the TF chain — a near-perfect proxy for the real robot.

RViz2 is the visualization layer: live LiDAR cloud, the growing occupancy grid, AMCL particle cloud, the global plan, the local trajectory rollouts, and the robot footprint — all on one canvas.

System pipeline overview

Grid-Based FastSLAM

We use Grid-Based FastSLAM because it gives us:

  • Memory efficiency — the world is discretized into a grid of occupancy cells.
  • Robustness — particle filters handle non-linear motion and noisy observations gracefully.
  • Loop-closure friendliness — important for indoor environments with corridors and rooms.

The algorithm alternates prediction (motion model) and correction (sensor model) for each particle:

for each particle k:
    x_t[k]  = MotionUpdate(u_t, x_{t-1}[k])
    w_t[k]  = SensorUpdate(z_t, x_t[k])
    m_t[k]  = UpdateOccupancyGrid(z_t, x_t[k], m_{t-1}[k])

resample particles ∝ w_t

Tuning happened in mapper_params_online_asynchronous.yaml — sensor-fusion gains, dynamic-object handling, map adaptation rate, and resampling thresholds were all tuned for our LiDAR/encoder pair and our indoor environment.

AMCL — Adaptive Monte Carlo Localization

Once a map exists, AMCL keeps the robot’s pose locked to it. A particle filter spreads hypotheses across plausible poses and resamples them based on how well incoming LiDAR scans match the map. The loop is:

Predict motion model (odometry) Update sensor model (LiDAR vs map) Weight w = p(z|x,m) Resample ∝ w Pose /amcl_pose feedback for next prediction

The closed loop base_link → odom → map is what saves us from cumulative odometry error: each AMCL update silently corrects the map → odom offset, so the robot’s map-frame pose stays consistent over arbitrarily long runs.

The Nav2 stack sits on top of the map + AMCL pose and turns goals into motion. It splits the work into:

  • Global Planner (Dijkstra / A*) — computes a long-horizon path on the static costmap.
  • Local Controller (DWB) — refines that path in real time using the live LiDAR and the local costmap.
  • Recovery Behaviors — clear costmaps, spin in place, back up — automatic resilience when the robot gets stuck.

Static obstacles come from the SLAM map; dynamic ones (people, moving boxes) come straight from live LiDAR — both fuse into a single costmap that the local planner re-evaluates at every control tick.

Static Map SLAM occupancy grid Live LiDAR dynamic obstacles Costmap Generation global + local Global Planner A* / Dijkstra Local Controller DWB /cmd_vel

Tooling & Stack

  • ROS 2 Humble (with ros2_control for hardware interfaces)
  • SLAM Toolbox — async online mapping
  • Nav2 — full navigation stack (planners, controllers, behavior trees, recoveries)
  • AMCL — particle-filter localization
  • Gazebo — physics + sensor simulation
  • RViz2 — visualization
  • Blender — 3D mesh design for the URDF
  • Python / C++ — node implementations
  • Raspberry Pi 5B + Arduino Nano — the on-robot compute

Real-World Deployment

After validation in Gazebo, the same stack was deployed on the physical robot. The key real-world adjustments:

  • Encoder calibration — measured wheel circumference and track width were tuned until simulated and physical odometry agreed within ~2% over a 5 m straight test.
  • AMCL covariance tuning — bumping alpha1..alpha5 reflected real wheel slip on tile floors.
  • LiDAR mounting offset — the laser frame transform was measured precisely from the URDF model so map alignment stayed clean.

The result: the robot consistently completes navigation goals in real indoor environments, smoothly avoiding both furniture (static) and people walking through (dynamic).

Watch the Robot

Future Work

  • Multi-robot SLAM with map-merging across a fleet
  • Visual-LiDAR fusion for richer feature association in low-feature corridors
  • Semantic mapping — labeling rooms / doors / objects on top of the geometric map
  • 3D Nav2 for stair-climbing or uneven terrain platforms

Contributors

  • Imad-Eddine NACIRI
  • Oussama Errouji
  • Jade Bousliman

Supervisor: Pr. Mostafa Mrabti — National School of Applied Sciences, Fez, Morocco.

Takeaway

Autonomous navigation isn’t one algorithm — it’s a contract between perception, mapping, localization, and control. ROS 2 + SLAM Toolbox + AMCL + Nav2 is a stack that respects that contract, and this project shows what it takes to make it work end-to-end, from URDF to real-world deployment.