ROS 2 Navigation project assignment for a simulated autonomous mobile robot in a hospital environment.
The goal of this project is to build and demonstrate a ROS 2 navigation stack for a differential-drive robot in Gazebo Sim. The robot must be able to operate in a hospital-like world, publish simulated sensor data, localize itself with a saved SLAM Toolbox map, and navigate to target poses using Nav2.
- Custom mobile robot URDF with four wheels, lidar, IMU, and camera frames.
- Gazebo Sim integration with differential-drive, lidar, IMU, camera, and joint state plugins.
- Hospital simulation environment using local AWS RoboMaker model assets.
- ROS-Gazebo bridges for velocity commands, odometry, laser scan, camera, IMU, joint states, and simulation clock.
- EKF-based odometry fusion with
robot_localization. - SLAM Toolbox configuration for mapping and localization.
- Nav2 configuration for planning, control, costmaps, behavior recovery, and waypoint following.
- Saved map and pose graph assets for hospital localization.
- RViz configurations for URDF checking, mapping, and navigation.
- Optional Python waypoint navigator node that sends
NavigateToPosegoals. - Real time reaction to people moving in the robots environment
navi_stack_hw/
|-- launch/
| |-- check_urdf.launch.py
| |-- world.launch.py
| |-- spawn_robot.launch.py
| `-- navigation_with_slam.launch.py
|-- config/
| |-- ekf.yaml
| |-- navigation.yaml
| |-- slam_toolbox_mapping.yaml
| `-- slam_toolbox_localization.yaml
|-- urdf/
| |-- nav_bot.urdf
| |-- nav_bot.gazebo
| `-- materials.xacro
|-- meshes/
| |-- base.dae
| |-- lidar.dae
| `-- wheel.dae
|-- worlds/
| |-- hospital.sdf
| |-- hospital_easy.sdf
| |-- hospital_half_easy.sdf
| `-- world.sdf
|-- models/
| `-- local Gazebo model assets used by the hospital worlds
|-- maps/
| |-- hospital_map.yaml
| |-- hospital_map.pgm
| |-- kesz.posegraph
| `-- kesz.data
|-- rviz/
| |-- urdf.rviz
| |-- rviz.rviz
| |-- mapping.rviz
| `-- navigation.rviz
`-- navi_stack_hw_py/
`-- Python waypoint navigation helper package
This project was prepared for ROS 2 Jazzy on Ubuntu.
Install the main required packages:
sudo apt update
sudo apt install \
ros-jazzy-navigation2 \
ros-jazzy-nav2-bringup \
ros-jazzy-slam-toolbox \
ros-jazzy-robot-localization \
ros-jazzy-ros-gz-sim \
ros-jazzy-ros-gz-bridge \
ros-jazzy-ros-gz-image \
ros-jazzy-robot-state-publisher \
ros-jazzy-joint-state-publisher-gui \
ros-jazzy-urdf-launch \
ros-jazzy-xacro \
ros-jazzy-topic-tools \
ros-jazzy-rviz2From the ROS 2 workspace root:
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select navi_stack_hw
source install/setup.bashThe helper package navi_stack_hw_py is currently inside the main project
folder. If the waypoint navigator is needed, build it explicitly:
cd ~/ros2_ws
colcon build --base-paths src/navi_stack_hw/navi_stack_hw_py
source install/setup.bashThis opens the robot URDF in RViz:
ros2 launch navi_stack_hw check_urdf.launch.pyThis starts Gazebo Sim with the default hospital world:
ros2 launch navi_stack_hw world.launch.pyThe default world is:
hospital_easy.sdf
Other available worlds:
ros2 launch navi_stack_hw world.launch.py world:=hospital_half_easy.sdf
ros2 launch navi_stack_hw world.launch.py world:=hospital.sdf
ros2 launch navi_stack_hw world.launch.py world:=world.sdfThis starts the world, spawns the robot, starts the ROS-Gazebo bridges, and starts the EKF node:
ros2 launch navi_stack_hw spawn_robot.launch.pyThe robot spawn pose can be changed:
ros2 launch navi_stack_hw spawn_robot.launch.py x:=0.0 y:=1.0 yaw:=0.0Open a second terminal after the robot has been spawned:
cd ~/ros2_ws
source install/setup.bash
ros2 launch navi_stack_hw navigation_with_slam.launch.pyThis launch starts:
- SLAM Toolbox in localization mode.
- Nav2 navigation stack.
- RViz with the navigation configuration.
In RViz, use the Nav2goal tool to send navigation goals.
The Python helper node sends a sequence of hard-coded Nav2 goals:
ros2 run navi_stack_hw_py hospital_navigatorThe waypoint list can be edited in:
navi_stack_hw_py/navi_stack_hw_py/hospital_navigator.py
The simulation and bridge setup provide the main ROS 2 topics used by Nav2:
/clock
/cmd_vel
/odom
/joint_states
/scan
/scan/points
/camera/image
/camera/camera_info
/camera/image/camera_info
imu
config/ekf.yaml: EKF configuration for fusing odometry and IMU data.config/navigation.yaml: Nav2 parameters for planner, controller, costmaps, behaviors, velocity smoother, and waypoint follower.config/slam_toolbox_mapping.yaml: SLAM Toolbox mapping configuration.config/slam_toolbox_localization.yaml: SLAM Toolbox localization configuration using the saved pose graph inmaps/.maps/hospital_map.yaml: saved occupancy grid map metadata.
The robot is a four-wheel differential-drive mobile base.
Main simulated sensors:
- 2D GPU lidar on
/scan. - IMU on
imu. - RGB camera on
/camera/image. - Wheel joint states on
/joint_states. - Odometry on
/odom.
Main dimensions and limits:
- Base collision size: approximately
0.7 x 0.4 x 0.3 m. - Wheel separation:
0.52 m. - Wheel radius:
0.1 m. - Maximum linear velocity:
0.5 m/s. - Maximum angular velocity:
1.0 rad/s.
config/slam_toolbox_localization.yamlcurrently contains an absolute path to the saved pose graph:
/home/pali/ros2_ws/src/navi_stack_hw/maps/kesz
If the project is moved to another workspace, this path must be updated.
- The repository contains some
:Zone.Identifierfiles. These are metadata files created during file transfer and are not required by ROS 2. - The optional
interactive_marker_twist_servernode is present in the launch file but currently commented out.
For evaluation, the expected demonstration sequence is:
- Build the package successfully with
colcon build. - Launch and inspect the robot model in RViz.
- Launch the hospital Gazebo world.
- Spawn the robot and verify
/scan,/odom,/tf, and/clock. - Start SLAM Toolbox localization and Nav2.
- Send a
Nav2goalin RViz and verify that the robot plans and moves toward the selected goal.