Full autonomous navigation stack for a differential-drive mobile robot. SLAM mapping, Nav2 path planning, and custom embedded control — running on real hardware.
This project implements a production-grade autonomous navigation pipeline on a differential-drive mobile robot built with a Raspberry Pi 5 and ESP32 microcontroller. The system covers the complete autonomy stack:
RPLiDAR A1M8 → SLAM Mapping → Nav2 Planning → Motor Control → ESP32 Actuators
- 🗺️ Real-time SLAM mapping with
slam_toolbox - 🧭 Full Nav2 stack: AMCL localization → NavFn global planner → DWB local planner
- ⚡ Custom hardware interface: Multi-threaded ROS2 node translating
/cmd_velinto ESP32 motor commands via binary UART protocol with XOR checksum validation - 📐 Differential-drive odometry: Encoder-based dead reckoning publishing
/odomand TF transforms - 🛡️ Collision monitoring: Layered costmaps (static + inflation + obstacle layers)
- 🐳 Docker containerized for reproducible deployment
flowchart TB
%% Premium ROS2 Styling
classDef hardware fill:#1e293b,stroke:#475569,stroke-width:1px,color:#e2e8f0,rx:4px
classDef rosnode fill:#0369a1,stroke:#0284c7,stroke-width:1px,color:#f0f9ff,rx:4px
classDef topic fill:#064e3b,stroke:#047857,stroke-width:1px,color:#a7f3d0,rx:16px
subgraph Pi["🚀 Raspberry Pi 5 (ROS 2 Jazzy)"]
direction TB
%% Hardware & Nodes
LIDAR["RPLiDAR A1M8"]:::hardware
SLAM["SLAM Toolbox"]:::rosnode
Nav2["Nav2 Stack<br/>(AMCL, DWB, BT, Costmaps)"]:::rosnode
Odom["Kinematics & TF Broadcaster"]:::rosnode
Bridge["UART Hardware Bridge"]:::rosnode
%% Topics (Pub/Sub Hubs)
T_Scan(("/scan")):::topic
T_Map(("/map")):::topic
T_Odom(("/odom & /tf")):::topic
T_Cmd(("/cmd_vel")):::topic
%% Data Flow
LIDAR --> T_Scan
T_Scan --> SLAM
T_Scan --> Nav2
SLAM --> T_Map
T_Map --> Nav2
Odom --> T_Odom
T_Odom --> Nav2
Nav2 --> T_Cmd
T_Cmd --> Bridge
end
subgraph MCU["⚡ ESP32 Microcontroller (C++)"]
direction TB
Firmware["Serial Packet Parser<br/>(XOR Checksum)"]:::hardware
Motor["L298N / Motor Drivers"]:::hardware
Enc["Magnetic Encoders"]:::hardware
Firmware --> Motor
Enc --> Firmware
end
%% Physical Hardware Boundary
Bridge <==" UART (115200 bps) "==> Firmware
map → odom → base_footprint → base_link → [laser_frame, left_wheel, right_wheel]
| Component | Specification |
|---|---|
| Compute | Raspberry Pi 5 (16GB RAM) |
| Microcontroller | ESP32 (motor control + encoder reading) |
| LiDAR | RPLiDAR A1M8 (360° scan, 12m range) |
| Drive | Differential-drive (track width: 0.116m, wheel radius: 0.0335m) |
| Communication | Custom binary UART protocol with XOR checksum validation |
- Ubuntu 22.04 (ARM64 for RPi5)
- ROS2 Jazzy
- Docker (optional)
docker compose up# Terminal 1: Hardware interface + sensors
ros2 launch amr_bringup hardware.launch.py
# Terminal 2: SLAM mapping (first run)
ros2 launch amr_bringup slam.launch.py
# Terminal 3: Navigation (after map is saved)
ros2 launch amr_bringup navigation.launch.py map:=./maps/my_map.yamlDiagnosed and resolved a cascading Nav2 lifecycle bringup failure affecting all 9 managed nodes. Root cause chain:
- Misconfigured docking server parameters
- Missing AMCL initial pose publication
- Incorrect
base_framein behavior-server config - Busy-wait loop starving the controller server's executor
Resolution required deep understanding of ROS2 lifecycle node management and the Nav2 managed node activation sequence. Documented the full debugging process in the wiki.
- ✅ Successful real-time SLAM mapping of indoor environment
- ✅ Autonomous point-to-point navigation with obstacle avoidance
- ✅ Validated on physical hardware using Foxglove Studio
- ✅ Clean lifecycle activation across all 9 Nav2 managed nodes
amr-nav-stack/
├── amr_bringup/ # Launch files and configs
│ ├── launch/
│ ├── config/ # Nav2, AMCL, SLAM parameters
│ └── maps/ # Saved occupancy grid maps
├── amr_hardware/ # Custom hardware interface
│ ├── uart_bridge.py # UART protocol with XOR checksum
│ └── diff_drive.py # Odometry computation
├── amr_description/ # URDF/Xacro robot model
├── docker/ # Dockerfiles and compose
└── docs/ # Architecture diagrams
- Add IMU fusion via
robot_localizationEKF - Implement multi-waypoint navigation
- Add simulated Gazebo environment for testing
- CI/CD with GitHub Actions
MIT License — see LICENSE for details.