Exercises#
This page contains four take-home exercises that reinforce the concepts from Lecture 13. Each exercise asks you to write code from scratch based on a specification – no starter code is provided.
All files should be created inside your ~/enpm605_ws/src/
workspace in the appropriate packages (nav_demo or your own
extension package).
Exercise 1 – Build, Save, and Reload a Map
Goal
Build an occupancy grid of the Husarion world using
slam_toolbox, save it to disk, and reload it for AMCL-based
navigation.
Specification
Launch Gazebo and
slam_toolboxin mapping mode:# T1 ros2 launch rosbot_gazebo husarion_world.launch.py # T2 ros2 launch nav_demo map_nav.launch.py mode:=mapping
Drive the robot with teleop to cover the entire environment. Aim for at least one loop closure by returning to your starting area after exploring all rooms.
Save the map under
~/enpm605_ws/maps/my_mapusingnav2_map_server:ros2 run nav2_map_server map_saver_cli -f ~/enpm605_ws/maps/my_mapVerify the two files
my_map.pgmandmy_map.yamlexist and open the.pgmin an image viewer.Re-launch in navigation mode pointing to your saved map and confirm the robot localizes after a single 2D Pose Estimate click in RViz2.
Verification
White, black, and grey regions of the
.pgmcorrespond to free, occupied, and unknown space.In RViz2, the AMCL particle cloud converges to a tight cluster around the robot within a few seconds of motion.
A Nav2 Goal click successfully drives the robot to the requested pose.
Exercise 2 – Inflation Radius and Path Quality
Goal
Investigate how the inflation layer’s radius affects the planned path and the robot’s clearance from obstacles.
Specification
Locate the Nav2 parameter file used by
map_nav.launch.py(typicallynav_demo/config/nav2_params.yaml).Set the
inflation_layer.inflation_radiusof the global costmap to each of the following values, one at a time:0.100.300.550.80
For each value, launch navigation, send the same goal from RViz2, and:
Capture a screenshot of the planned path overlaid on the global costmap.
Note whether the path is feasible (the robot reaches the goal) or fails (no plan, recovery loop, or collision).
Write a short reflection (one paragraph) answering: at what radius does the planner start refusing to plan through narrow doorways, and why?
Verification
Four screenshots labelled with their inflation radius.
One paragraph of analysis tying the result to the robot’s circumscribed radius.
Exercise 3 – Sequential Goals with BasicNavigator
Goal
Write a Python node that drives the robot through a sequence of
three goals using the nav2_simple_commander API and reports
feedback while moving.
Specification
Create nav_demo/nav_demo/sequential_goals.py.
The node must:
Instantiate a
BasicNavigator.Set the initial pose from the latest
map->base_linkTF lookup (use a 2-second timeout).Call
waitUntilNav2Active()before sending goals.
Define three goal poses (read from ROS 2 parameters):
goal_1(default[2.0, 0.0, 0.0])goal_2(default[5.0, 1.0, 1.57])goal_3(default[-5.42, 11.22, 3.14])
Each parameter is a length-3
double_arrayof \((x, y, \text{yaw})\).Send the goals one at a time with
goToPose. Between goals:Print feedback every second: distance remaining and time elapsed.
When the goal completes, log the final
TaskResult(SUCCEEDED / CANCELED / FAILED).
After all three goals, exit cleanly with
rclpy.shutdown().
Verification
# T1
ros2 launch rosbot_gazebo husarion_world.launch.py rviz:=False
# T2
ros2 launch nav_demo map_nav.launch.py mode:=navigation
# T3
ros2 run nav_demo sequential_goals
The robot visits all three goals in order, and the terminal shows distance-remaining feedback for each leg.
Exercise 4 – Cancel-on-Distance Behavior
Goal
Extend the sequential-goals node from Exercise 3 with a safety behavior: if the robot has not made progress (distance remaining has not decreased) for five seconds, cancel the current goal and move on to the next one.
Specification
Inside the goal-monitoring loop, track
distance_remainingfrom each feedback message.Maintain a
last_progress_timetimestamp; update it wheneverdistance_remainingdecreases by at least0.05m.If
now - last_progress_time > 5.0seconds while the goal is still active:Call
self._navigator.cancelTask().Log
"No progress -- cancelling goal."at WARN level.Continue with the next goal in the sequence.
The node must always finish, even if some goals were cancelled, and print a final summary like:
goal_1: SUCCEEDED goal_2: CANCELED goal_3: SUCCEEDED
Verification
Place a wall in Gazebo (or pick a goal inside an obstacle) so that one of the goals becomes unreachable. The node should cancel that goal after five seconds of no progress and continue with the remaining goals without crashing.