Exercises#
This page contains four take-home exercises that reinforce the concepts from Lecture 14. 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 (lifecycle_demo,
bag_demo, or your own extension package).
Exercise 1 – Implement a CLI-Driven Lifecycle Node
Goal
Implement a Python lifecycle node that publishes a counter
string at 2 Hz, but only while in the Active state. Drive
the transitions externally with ros2 lifecycle set.
Specification
Create a node
counter_publisherextendingLifecycleNodefromrclpy_lifecycle.Allocate the publisher in
on_configureusingcreate_lifecycle_publisherforstd_msgs/Stringon the topic/counter.Create the timer in
on_activate(and callsuper().on_activate(state)first). Cancel it inon_deactivate.In
on_cleanup, drop the publisher reference and reset the counter to0.Publish a string of the form
"count=<n>"where<n>is an incrementing integer.
Verification
ros2 lifecycle get /counter_publishershowsunconfiguredat startup.After
configurethenactivate,ros2 topic echo /counterprintsdata: 'count=0',count=1, … at 2 Hz.After
deactivate,/counterstops publishing without the node exiting.After
cleanupthenconfigurethenactivate, the counter restarts at0.
Exercise 2 – Add a Programmatic Self-Cycle
Goal
Extend Exercise 1 so the node can drive its own state
transitions by calling its own change_state service.
Specification
Add a regular timer (not lifecycle-managed) that fires every
5.0seconds.Maintain an index that walks through the cycle
[CONFIGURE, ACTIVATE, DEACTIVATE, CLEANUP]fromlifecycle_msgs.msg.Transition.In the timer callback, call the
/counter_publisher/change_stateservice asynchronously (call_async) with the next transition id.Register a done callback on the future that logs whether
result.successisTrue.Provide a launch file that starts the node already in self-cycling mode (no external
ros2 lifecycle setcalls needed).
Verification
Running
ros2 lifecycle get /counter_publisherrepeatedly shows the state advancing through Unconfigured \(\to\) Inactive \(\to\) Active \(\to\) Inactive \(\to\) Unconfigured every 5 s.ros2 topic echo /countershows messages appearing only during the Active windows.The done callback log line confirms each transition succeeded.
Exercise 3 – Record and Inspect a Navigation Bag
Goal
Record a short Nav2 navigation run as an MCAP bag, inspect it
with ros2 bag info, and replay it with the live simulation
closed.
Specification
Make sure the MCAP plugin is installed:
sudo apt install ros-jazzy-rosbag2-storage-mcapIn one terminal, launch the simulation:
ros2 launch rosbot_gazebo husarion_world.launch.py rviz:=FalseIn a second terminal, start recording:
ros2 bag record -o nav_run --storage mcap \ /odometry/filtered /scan /cmd_vel /tf /tf_static /map
In a third terminal, launch Nav2 and send a goal:
ros2 launch nav_demo map_nav.launch.py mode:=navigationAfter the robot reaches the goal, stop recording with
Ctrl+C.Inspect the resulting bag:
ros2 bag info nav_run
Verification
All six topics appear in the
ros2 bag infooutput./tf_statichas at least one message.The bag duration matches the wall-clock duration of the run (within 1 s).
The
nav_rundirectory contains ametadata.yamland one or more.mcapfiles.
Exercise 4 – Visualize the Bag in Foxglove Studio
Goal
Open the recorded MCAP bag in Foxglove Studio and build a multi-panel layout that shows the LiDAR scan, the trajectory, and the velocity commands together.
Specification
Install Foxglove Studio (Debian package, snap, or browser).
Open
nav_run_0.mcap(the file inside the bag directory, not the directory itself).Build a layout with at least three panels:
3D panel: display frame
map; enable/scan,/tf, and/mapso the robot, its laser hits, and the static map appear together.Plot panel: plot
/odometry/filtered.pose.pose.position.xagainst...yto draw the parametric trajectory.Raw Messages panel: subscribe to
/cmd_velso you can scrub through individualTwistStampedmessages.
Export the layout via Layouts \(\to\) Export layout to file and save it as
nav_run_layout.jsoninside yourbag_demopackage.
Verification
All three panels stay synchronized to the playhead while the bag plays.
The 3D scene shows the robot moving across the saved map and the laser hits update with each
/scanmessage.The plot draws a smooth XY trajectory matching the path the robot actually drove.
The exported layout reopens correctly from a fresh Foxglove session.