Changelog#

All notable changes to the ENPM605 Spring 2026 course documentation are recorded here.

v1.6.8 – Final Project Reference API Page (2026-05-04)

Final Project (assignments/final_project/code.rst)

  • Added a new Reference Implementation: group0_final page under Final Project: Search and Rescue that publishes the API reference (class signatures, method signatures, attributes, and Google-style docstrings) for the group0_final example package. Provided as a style and structure reference: the depth of docstring detail expected for the final project, and how to organise a ROS 2 package that combines a py_trees behavior tree, Nav2 action clients, custom services, TF broadcasting, and YAML-driven parameters.

  • The page does not expose the source code: the reference implementation is built locally with autodoc and the rendered article body is committed as a static HTML fragment (_code_api.html) embedded by code.rst via .. raw:: html. sphinx.ext.viewcode is disabled to suppress [source] links and _modules/ source pages, and a READTHEDOCS env-var check in conf.py excludes the autodoc-driving _code_source.rst from RTD’s build so the published site never imports the missing source modules.

  • Added a left-sidebar contents tree (configured per-page via html_sidebars) that lists every module → class → method/attribute. Classes are collapsed by default with a caret toggle. A search box at the top of the sidebar substring-matches the FQN: matching symbols stay visible, parent classes auto-expand, and non-matching <dl> blocks hide in the body too. Clearing the query collapses every class back. Mirrors the inline filter pattern used in the glossary search.

  • New maintenance script tools/render_api.py walks the locally-built _code_source.html, extracts the article body (stripping the wrapper <section> and page-title <h1> so the embedded fragment doesn’t introduce a second H1), and emits both _code_api.html and the Jinja sidebar template _templates/api-toc-sidebar.html. Both artifacts are committed; the script is run locally before pushing whenever group0_final/ changes.

v1.7.0 – L14 Documentation Released, L12 Refactor (2026-05-03)

Lecture Notes (l14_lecture.rst)

  • Added “Prerequisites” section: workspace cleanup, rosdep install, --packages-up-to lecture14_meta build, and a Gazebo smoke-test launch.

  • Added “Lifecycle Nodes” section: motivation for managed nodes, the four primary states (Unconfigured, Inactive, Active, Finalized) with a what-the-node-does table, and a transition-command table (configure, activate, deactivate, cleanup, shutdown) mapping each command to its on_* callback. Includes a “Why use lifecycle nodes” rationale (controlled init order, resource management, runtime pause/resume, system coordination via Nav2’s lifecycle_manager).

  • Added “Implementing a Lifecycle Node” subsection: full sensor_publisher walkthrough – class declaration with rclpy_lifecycle.LifecycleNode, on_configure allocating a create_lifecycle_publisher, a SUCCESS / FAILURE / ERROR return-value table, and the four transition callbacks with super().on_activate(state) / super().on_deactivate(state) placement notes. Closes with a CLI demonstration table (ros2 lifecycle list / get / set) and an experiment prompt.

  • Added “Programmatic State Changes” subsection: scenario for self_cycling_node, the auto-advertised change_state service, ChangeState.Request payload structure, the async call_async + done-callback pattern (including a deadlock warning for blocking call), and a demonstration table of the 5-second cycle.

  • Added “ROS 2 Bags” section: motivation, common use cases (algorithm dev, debugging, regression testing, dataset creation, remote ops), SQLite3 vs.MCAP comparison table, MCAP plugin install command, --storage switching for record and convert, useful ros2 bag record flags table, and an end-to-end “Recording a Navigation Run” demo listing the six topics (/odometry/filtered, /scan, /cmd_vel, /tf, /tf_static, /map).

  • Added “Inspecting” and “Replaying” subsections: ros2 bag info walkthrough, ros2 bag play flag table (--rate, --start-offset, --loop, --topics, --remap, --clock), and a warning about live-system conflicts on /tf and /cmd_vel.

  • Added “Foxglove Studio” section: what/why, three install options (Debian, Snap, browser), loading the nav_run bag, and a layout-import note.

Index (l14_index.rst)

  • Overview, learning objectives, toctree, and next steps for L14 (final regular lecture; remaining classes are status check + office hours).

Exercises (l14_exercises.rst)

  • Exercise 1: implement a CLI-driven counter_publisher lifecycle node publishing "count=<n>" at 2 Hz only while Active, with a verification flow that confirms publish/pause/restart behavior across transitions.

  • Exercise 2: extend Exercise 1 with a programmatic self-cycle – 5 s timer, [CONFIGURE, ACTIVATE, DEACTIVATE, CLEANUP] index, async change_state call with done-callback logging, and a launch file that starts the node already cycling.

  • Exercise 3: record a Nav2 navigation run as an MCAP bag, verify all six topics + non-zero /tf_static count via ros2 bag info, and confirm the bag directory contains a metadata.yaml and .mcap file(s).

  • Exercise 4: open the bag in Foxglove Studio and build a three-panel layout (3D with /scan + /tf + /map, XY trajectory Plot, /cmd_vel Raw Messages), then export nav_run_layout.json.

Quiz (l14_quiz.rst)

  • 8 multiple choice questions covering initial state, activate semantics, FAILURE return effect, create_lifecycle_publisher rationale, the auto-advertised change_state service, MCAP recommendation, the --clock flag, and /tf_static recording.

  • 4 true/false questions: skipping configure, whether ros2 bag info needs the storage plugin, publish-before- super().on_activate(), and the Foxglove browser upload myth.

  • 3 short-answer questions: timer placement in on_activate vs.__init__, why call_async for self-driven transitions (single-threaded executor deadlock), and the missing-mesh-in-Foxglove diagnostic (robot_description + /tf_static).

References (l14_references.rst)

  • Lecture 14 card summarizing all topics covered.

  • Lifecycle Nodes: ROS 2 design article, rclpy lifecycle source, lifecycle_msgs API, Nav2 lifecycle manager.

  • ROS 2 Bags: Jazzy “Recording and Playing Back Data” tutorial, rosbag2 GitHub, MCAP file format, rosbag2_storage_mcap plugin source.

  • Foxglove Studio: project site, top-level docs, panel reference, desktop downloads, web app, pricing / academic-access page.

  • Recommended Reading: Mataric A Concise Introduction to Robot Programming with ROS2, Quigley Programming Robots with ROS.

Lecture 12 – Refactor (lifecycle moved out)

  • Renamed the lecture from “Namespaces, Remapping, Lifecycle Nodes, and Behavior Trees” to “Namespaces, Remapping, and Behavior Trees”. Lifecycle-node coverage was moved to the new L14 to give it room to grow alongside the new programmatic-transition + change_state material.

  • Updated l12_index.rst overview (“three topics” instead of four; dropped lifecycle_demo from the package list) and the schedule entry / blurb in lectures/index.rst.

  • l12_exercises.rst: deleted Exercise 2 (“Lifecycle Node with on_shutdown”), renumbered the remaining two so the page now contains three exercises, and dropped lifecycle_demo from the workspace-package list.

  • l12_quiz.rst: removed all five lifecycle questions (Q2/Q6/Q11/Q13/Q16) and renumbered the remaining 11. Updated the topic blurb to drop “Lifecycle Nodes.”

  • l12_references.rst: removed the entire Lifecycle Nodes dropdown (ROS 2 design article + “Managing a Robot” tutorial); both now appear in l14_references.rst. Updated the Lecture 12 summary card to drop the lifecycle bullet from the description.

Lectures Index (lectures/index.rst)

  • Added lecture14/l14_index to the toctree.

  • Updated the L12 schedule row title and key-concepts cell.

  • Added an L14 schedule row covering lifecycle nodes (state machine, transition commands, LifecycleNode, create_lifecycle_publisher, TransitionCallbackReturn, CLI / programmatic transitions) and ROS 2 bags (SQLite3 vs.MCAP, ros2 bag record/info/play, Foxglove visualization).

Glossary (glossary.rst)

  • 14 new terms tied to L12 (now that lifecycle has moved to L14): Action Node (BT), Composite Node (BT), Condition Node, Decorator Node (BT), Fallback (BT) / Selector (BT), Leaf Node (BT), Memory Flag (BT), Namespace (ROS 2), py_trees_ros, Remapping, Sequence Node, Tick (BT). The existing Behavior Tree entry was extended with a composite/leaf summary.

  • 17 new terms tied to L14: Bag (ROS 2) / ROS 2 Bag, change_state Service, create_lifecycle_publisher, Foxglove Studio, Lifecycle Manager, Lifecycle Node, Lifecycle Publisher, LifecycleNode, MCAP, on_activate, on_cleanup, on_configure, on_deactivate, on_shutdown, Primary State (Lifecycle), rosbag2, SQLite3 Storage, TransitionCallbackReturn.

v1.6.7 – Final Project NavigateToZone Clarifications (2026-05-01)

Final Project (assignments/final_project/implementation_guide.rst)

  • Jump to the affected sections: NavigateToZone: The Hardest Node and State flags: _done and _success.

  • Replaced the brief **Study:** paragraph and the .. important:: block at the top of NavigateToZone: The Hardest Node with a more explicit .. warning:: admonition contrasting Lecture 13’s BasicNavigator + blocking-loop pattern with the final project’s rclpy.action.ActionClient + async-polling pattern. The warning calls out that BasicNavigator.goToPose() must not be used inside a BT update() (it freezes the entire tree) and notes that BasicNavigator is still legitimately used at startup for the one-shot AMCL seed in Auto-Seeding AMCL with BasicNavigator. Closes a recurring student question about whether the L13 demo applies directly to the BT nodes.

  • Corrected the L13 reference path inside the new warning from the stale lecture13/mapping_navigation_demo/navigation_demo_interface.py to the actual workspace path lecture13/nav_demo/navigation_demo.py. Two other occurrences of the stale path remain in implementation_guide.rst (Auto-Seeding AMCL section) and requirements.rst (NavigateToZone table row); these are scheduled for a follow-up pass.

  • Added a new sub-subsection State flags: _done and _success under NavigateToZone: The Hardest Node explaining, in prose only, why two boolean attributes are needed and how they relate to the goal/result futures. Covers: what each flag means and why one boolean is insufficient (three valid runtime states must be distinguishable), why the verdict is latched rather than re-derived from the futures on every tick, the lifecycle of the flags across initialise / update / terminate, and the relationship between the transient futures and the persistent verdict. Also flags the most common student bug (forgetting to reset the flags in initialise) by its observable symptom – “only the first zone gets visited” – so students can recognise the mistake in their own code.

v1.6.6 – Final Project Walkthrough Videos (2026-04-29)

Final Project (assignments/final_project/)

  • Embedded structure_final_project.mp4 in requirements.rst (right after the Package Structure section): a file-by-file walkthrough of a working group<N>_final/ and group<N>_final_interfaces/ layout.

  • Embedded demo_final_project.mp4 in outputs.rst (top of “Nominal Run”): full mission recording showing Gazebo, RViz, the launch terminal, and a filtered ros2 topic echo /rosout of just the search_and_rescue logs.

  • Both videos use a native HTML5 <video> tag with controls and preload="metadata" – they do not autoplay (saves bandwidth and avoids surprise audio). Wrapped in collapsible .. admonition:: ... :class: dropdown tip blocks so they are visible-on-demand rather than always expanded.

  • Videos live under docs/source/_static/videos/final_project/ and are copied verbatim by Sphinx via html_static_path.

v1.6.5 – Final Project SurvivorFound memory flip (2026-04-29)

Final Project (assignments/final_project/)

  • Flipped SurvivorFound Sequence from memory=False to memory=True. The original justification (“all three children are synchronous, single-tick”) stopped being true once NotifyBase was refactored to the async-poll pattern in v1.6.2 – NotifyBase.update() now returns RUNNING for one or more ticks while waiting on the report_survivor future. With memory=False, each RUNNING tick re-evaluated the entire Sequence; re-ticking BroadcastSurvivorTF called zone_manager.next_survivor_id() and broadcast a fresh static TF frame, so a 2-survivor mission produced survivor_1 through survivor_4 (or more) entries in /tf_static.

  • Updated implementation_guide.rst “Memory Flag Choices” and rubric.rst “memory flags” criterion to match.

v1.6.4 – Final Project Idiom + Spec Reconciliation (2026-04-29)

Final Project (assignments/final_project/implementation_guide.rst)

  • Added new “Auto-Seeding AMCL with BasicNavigator” section under “Key Patterns and Pitfalls” with the full hardcoded (0, 0, yaw=0) setInitialPose + waitUntilNav2Active recipe and a cross-ref to the lecture-13 navigation_demo_interface reference.

  • Added new “Reading Auto-Declared YAML Parameters” section documenting the automatically_declare_parameters_from_overrides=True + has_parameter guard idiom. Without this, students hit ParameterAlreadyDeclaredException three times in a row (one per explicit declare_parameter call) and the BT script crashes silently before any logs print.

  • Both sections expose :ref: anchors (final-project-auto-seed-amcl and final-project-auto-declared-params).

Final Project (assignments/final_project/requirements.rst)

  • Added a numbered list to the “Behavior Tree” section spelling out the five things the entry point must do, including a mandatory auto-seed step that cross-refs the implementation guide.

  • Added a fourth row to the launch-file actions table: rviz2 gated on a rviz launch arg, with a note that auto-seeding makes RViz situational rather than required.

  • Added a final-project-parameter-file label so other pages can link to the schema.

Final Project (assignments/final_project/infrastructure.rst)

  • Replaced the launch-file code skeleton: fixed the wrong executable name (search_and_rescue -> search_and_rescue_exe), added the two service-server Node\ s that were previously missing, added the optional rviz2 Node gated on a launch arg, switched launch_arguments from dict.items() to a list of tuples (avoids the MyPy union-type complaint), and added output="screen" + emulate_tty=True everywhere.

  • Added a .. note:: after the “important” admonition pointing at Parameter File and Reading Auto-Declared YAML Parameters.

Final Project (assignments/final_project/final_project.rst)

  • Added a cross-ref from the overview’s “YAML parameter file” mention to Parameter File so students reading the project landing page know where to find the schema.

Final Project (assignments/final_project/outputs.rst)

  • Reordered the “Nominal Run” expected output so service-server ready logs appear before the BT loaded-zones logs (matches what students actually see now that the BT seed step blocks until Nav2 is active).

  • Inserted the basic_navigator seed/wait/ready logs between parameter loading and the first zone, plus a final “Mission complete.” line after “Reached base station.” to match the new OneShot-wrapped NavigateToBase flow.

Final Project (assignments/final_project/rubric.rst)

  • Updated the “AMCL localization against the saved map” item: no longer expects a manual 2D Pose Estimate click; instead grades that the BT entry point auto-seeds AMCL via setInitialPose and waits for waitUntilNav2Active before ticking the tree.

v1.6.3 – Final Project NavigateToBase OneShot (2026-04-29)

Final Project (assignments/final_project/requirements.rst)

  • Added an “Important” admonition to the Behavior Tree section explaining that NavigateToBase must be wrapped in py_trees.decorators.OneShot(policy=ON_COMPLETION). Without it, the reactive root Selector keeps re-ticking NavigateToBase after Patrol fails: initialise() re-sends a Nav2 goal each tick, the controller instantly reports “Reached the goal!” because the robot is already there, and the loop never settles.

Final Project (assignments/final_project/implementation_guide.rst)

  • Added a new subsection “Wrapping NavigateToBase in a OneShot” under “Memory Flag Choices” with the full code snippet showing how to compose the decorator with the root Selector.

  • Cross-referenced from the new admonition in requirements.rst so students reading the BT spec can jump straight to the working pattern.

v1.6.2 – Final Project Service-Call Pattern in BT (2026-04-29)

Final Project (assignments/final_project/implementation_guide.rst)

  • Replaced the “Service Calls in BT Nodes” snippet. The previous example used call_async + rclpy.spin_until_future_complete, which raises RuntimeError: Executor is already spinning when invoked from inside a py_trees_ros.trees.BehaviourTree tick callback (the BT’s executor is already spinning tree.node via rclpy.spin).

  • The new snippet teaches the canonical async-BT pattern: submit call_async once on first tick, yield RUNNING until future.done(), then process the response on the resolving tick.

  • Added an “Important” admonition explaining why spin_until_future_complete cannot be reused here.

  • Updated step 11 of the recommended order to point at the new pattern (added a :ref: cross-ref to the service-calls section).

  • Added a final-project-bt-service-calls label so other pages can link to the pattern.

v1.6.1 – Final Project Parameter File Format (2026-04-29)

Final Project (assignments/final_project/requirements.rst)

  • Replaced the zones: list-of-dicts YAML in the Parameter File section with a zone_order string array plus a nested zones.<id> mapping. ROS 2 YAML parameter files require every list element to share a primitive type, so the previous list-of-dicts form failed to load with Sequence should be of same type.

  • Added an “Important” admonition explaining why the schema is split into two collaborating fields.

  • Added a “Reading the parameters back” Python snippet showing how the entry point joins zone_order and zones.<id>.{x,y,yaw} into the list[dict] consumed by ZoneManager (the ZoneManager constructor signature is unchanged).

  • Updated the “selective scoping” example so the namespace-specific block references zone_order and zones instead of the old zones list.

v1.6.0 – L13 Documentation Released (2026-04-26)

Lecture Notes (l13_lecture.rst)

  • Added “Prerequisites” section: workspace cleanup, rosdep install, --packages-up-to lecture13_meta build, and a Gazebo smoke-test launch.

  • Added “Mapping” section: motivation for maps (planning, localization, semantics, multi-session), comparison of metric / topological / semantic representations with light/dark figure placeholders.

  • Added “Occupancy Grid Maps” section: grid parameters (resolution, width, height, origin), the three cell states with a values table, and light/dark figure placeholders. Bayesian / log-odds LiDAR update with worked example.

  • Added “The map Frame” section: full REP 105 chain table, publisher / drift / jump semantics, light/dark frame-chain figure placeholders, and a side-by-side map vs. odom comparison table.

  • Added “SLAM” section: slam_toolbox overview, scan matching (with figure placeholders), pose graph (with figure placeholders), loop closure (with figure placeholders), and a “How the Three Pieces Connect” subsection covering covariance and edge strength.

  • Added “Launching slam_toolbox” subsection: key parameter table (resolution, max_laser_range, minimum_travel_distance / heading, use_scan_matching, do_loop_closing), mapping-mode demonstration, and a “drive fast vs. slow” experiment with answer.

  • Added “Map Saving and Loading” subsection: map_saver_cli usage and the .pgm / .yaml format example.

  • Added “Navigation” section: the four navigation questions, end- to-end Nav2 demonstration table.

  • Added “Localization” subsection: AMCL overview, why “adaptive,” three ways to set the initial pose (RViz2, parameters, programmatically), and a SLAM vs. AMCL comparison table.

  • Added “Particle Filters” subsubsection: scoring a particle against the map, the predict / update / resample cycle, and light/dark figure placeholders for the cycle and for initialization vs. converged clouds.

  • Added “Costmaps” subsection: global vs. local costmap table, layered architecture (static, obstacle, inflation), and the robot footprint with inscribed and circumscribed radii (with light/dark figure placeholders).

  • Added “Planning and Control” subsection: global planner table (NavFn, Smac Hybrid A*, Theta*), local controller table (DWB, Regulated Pure Pursuit), with explanatory bullets on output topics and behavior-tree plugin selection.

  • Added “Behavior Trees and Recovery” subsection: Nav2 BT orchestration and recovery behaviors (Spin, Wait, Clear costmap, Back up).

  • Added “NavigateToPose Action API” subsection: goal / feedback / result, sending a goal from RViz2, sending a goal programmatically with BasicNavigator. Added key-method table for BasicNavigator and two worked examples (single goal, follow waypoints) with demonstration tables.

  • Added “Explore Mode” subsection: simultaneous SLAM + Nav2 with mode:=explore.

Index (l13_index.rst)

  • Overview, learning objectives, toctree, and next-steps for L13.

Exercises (l13_exercises.rst)

  • Exercise 1: build, save, and reload a map – map with slam_toolbox, save with map_saver_cli, and reload for AMCL navigation.

  • Exercise 2: inflation radius and path quality – sweep four inflation_radius values, capture screenshots, and reflect on why the planner fails through narrow doorways above a threshold.

  • Exercise 3: sequential goals with BasicNavigator – parameterized three-goal sequence using goToPose, with feedback printing and result logging.

  • Exercise 4: cancel-on-distance behavior – extend Exercise 3 with a “no-progress for 5 s” watchdog that calls cancelTask() and continues with the next goal.

Quiz (l13_quiz.rst)

  • 8 multiple choice questions covering occupancy-grid encoding, REP 105 jump semantics, loop closure, AMCL adaptivity, global vs. local costmaps, Smac vs. NavFn, the inflation layer, and NavigateToPose feedback.

  • 5 true/false questions covering AMCL initial pose parameters, inscribed vs. circumscribed radius, slam_toolbox localization mode, planner-call frequency, and the BasicNavigator waypoint follower.

  • 4 essay questions: SLAM pipeline (scan match / pose graph / loop closure), particle-filter cycle, global vs. local costmaps, and the action goal / feedback / result triplet.

Glossary (glossary.rst)

  • 23 new terms added: AMCL, BasicNavigator, Circumscribed Radius, Costmap, DWB Controller, Footprint, Inflation Layer, Inscribed Radius, Loop Closure, map Frame, Map Server, nav2_simple_commander, NavFn Planner, NavigateToPose, Occupancy Grid Map, Particle Filter, Pose Graph, Regulated Pure Pursuit, REP 105, Scan Matching, SLAM, slam_toolbox, Smac Planner.

  • Updated Behavior Tree and Nav2 entries with L13 cross-references and an expanded scope.

References (l13_references.rst)

  • Lecture 13 card summarizing all topics covered.

  • Mapping and SLAM: nav_msgs/OccupancyGrid, REP 105, Nav2 + slam_toolbox tutorial, slam_toolbox repository, Jazzy API.

  • Localization (AMCL): Nav2 AMCL configuration page and nav2_amcl API reference.

  • Nav2 Stack: top-level Nav2 docs, concepts overview, costmap configuration, NavFn / Smac planner configuration, DWB / RPP controller configuration, behavior trees, BehaviorTree.CPP.

  • NavigateToPose API: Simple Commander API, source code, nav2_msgs action interface.

  • Recommended Reading: Corke’s Robotics, Vision and Control Chapter 14 and Lynch & Park’s Modern Robotics Chapter 13.

Lectures Index (lectures/index.rst)

  • Added lecture13/l13_index to the toctree.

v1.5.1 – Lecture 12 (2026-04-22)

GP 2 (gp2_requirements.rst)

  • Moved the scripts folder in the python package for GP2

v1.5 – GP2 scripts folder (2026-04-21)

GP 2 (gp2_requirements.rst)

  • Moved the scripts folder in the python package for GP2

v1.4.1 – GP1 AI Policy Removed (2026-04-01)

GP 1 (gp1.rst)

  • Removed AI tools permission from the Collaboration field.

  • Removed AI_USAGE.md from the package structure, suggested timeline, pre-submission checklist, and submission requirements.

  • The AI and Academic Integrity Policy dropdown was already commented out in a prior update.

v1.4.0 – L9 Documentation Released (2026-03-28)

Lecture Notes (l9_lecture.rst)

  • Added “Prerequisites” section: workspace clone, shell setup, and build commands for all three demo packages (launch_files_demo, parameters_demo, executors_demo).

  • Added “Launch Files” section: why use launch files (six reasons), anatomy (imports, generate_launch_description, node configuration, naming convention, two equivalent patterns with code examples), and demonstration commands.

  • Added “Advanced Features” section: including other launch files (IncludeLaunchDescription, FindPackageShare, PathJoinSubstitution), conditional launching (IfCondition, DeclareLaunchArgument, LaunchConfiguration, --show-args), and node grouping (GroupAction, conditional group with example).

  • Added “Parameters” section: characteristics (supported types, node-local scope warning, CLI reference and quick inspection commands), and sensor node parameter tables (camera and LiDAR) with light/dark figure placeholders.

  • Added “Declaring Parameters” section: three approaches (basic declaration, declaration with ParameterDescriptor and IntegerRange, and declare_parameters for batch declaration) each with code examples.

  • Added “Retrieving Parameters” section: when and why to retrieve, retrieval API with typed field accessors.

  • Added “Using Parameters” section: camera_name in logs and camera_rate as timer period control, with note on bandwidth measurement and performance gap.

  • Added “Setting Parameters” section: six methods (CLI, launch file, YAML file, programmatic, ros2 param set with callback, and launch file arguments) each with code examples and demonstration commands. Includes full on-set-parameters callback implementation and timer frequency update pattern.

  • Added “Executors” section: overview of multi-task robotic requirements and concurrency vs. parallelism definition.

  • Added “Single-Threaded Executor” section: key concepts, execution timeline with light/dark figure placeholders, phase offset table, and rclpy.spin() vs. explicit executor comparison.

  • Added “Multi-Threaded Executor” section: overview, benefits (performance, scalability, responsiveness), challenges (race conditions, overhead), concurrency vs. parallelism with hot dog stand figures (light/dark), and the Python GIL explanation with impact on ROS 2 and conditions for true parallelism.

  • Added “Callback Groups” section: overview with summary figure (light/dark), mutually exclusive group (declaration, effect of num_threads, execution timeline with light/dark figures, and timestamp table), reentrant group (declaration, fast callback timeline, slow/blocked callback timeline with light/dark figures, multiple concurrent instances warning), and comparison table.

Index (l9_index.rst)

  • Overview, learning objectives, toctree, and next steps for L9.

Exercises (l9_exercises.rst)

  • Exercise 1: Configurable Publisher – parameter declaration, CLI override, Float64 publisher controlled by publish_rate and topic_name parameters.

  • Exercise 2: Parameter File Node – YAML config file, sensor node with on-set-parameters callback, and a launch file that loads the YAML.

  • Exercise 3: Mutex vs Single-Threaded Comparison – slow callback demo comparing rclpy.spin() against MultiThreadedExecutor(num_threads=4) with a MutuallyExclusiveCallbackGroup; observation questions as code comments.

  • Exercise 4: Reentrant Pipeline – two independent 5 Hz callbacks sharing a log list, deliberate race condition introduction and fix with threading.Lock, written reflection on CPython list safety.

Quiz (l9_quiz.rst)

  • 10 multiple choice questions covering launch file structure, FindPackageShare, parameter type inference, on-set callback behavior, parameter retrieval API, executor types, mutex group semantics, reentrant group timing, the GIL, and timer frequency update patterns.

  • 10 true/false questions covering --symlink-install and launch files, ParameterDescriptor immutability, multi-node YAML files, multi-node executors, GIL release during sleep, reentrant safety, IfCondition behavior, ros2 param set persistence, GroupAction conditions, and num_threads with a mutex group.

  • 4 essay questions: parameter lifecycle, single vs. multi-threaded executor comparison, the Python GIL, and mutually exclusive vs. reentrant callback group comparison with concrete robotic examples.

Glossary (glossary.rst)

  • 12 new terms added: Callback Group, ColCon Symlink Install, Conditional Launch, DeclareLaunchArgument, generate_launch_description, Global Interpreter Lock (GIL), GroupAction, IfCondition, LaunchConfiguration, Mutually Exclusive Callback Group, Parameter Descriptor, Reentrant Callback Group.

References (l9_references.rst)

  • Lecture 9 card summarizing all topics covered.

  • ROS 2 Official Documentation: launch tutorials, parameters concept, parameters tutorial, ros2 param how-to, executors concept, callback groups how-to.

  • Launch File API: launch package API, launch_ros package API, YAML.org specification, launch file formats comparison.

  • Python Threading and the GIL: threading module, Real Python GIL article, multiprocessing module.

  • External Tutorials: Articulated Robotics, The Construct.

  • Recommended Reading: Koubaa ROS 2 series, Programming Robots with ROS 2, Silberschatz OS Concepts, David Beazley GIL talk.

v1.3.0 – L8 Documentation Released (2026-03-21)

Lecture Notes (l8_lecture.rst)

  • Added “What Is ROS?” section: overview, where ROS is used (transportation, manufacturing, specialized domains, emerging areas), and ROS 1 vs. ROS 2 comparison table.

  • Added “ROS 2 Architecture” section: process definition, monolithic vs. distributed design (with figures), core components (nodes, topics, services, actions, when to use each), pick-up-a-part task example with figure, DDS overview (application domains, key properties, resources), and QoS overview (four core policies, supported vendors, runtime inspection commands).

  • Added “Publish/Subscribe Model” section: node/topic/message definitions, four pub/sub rules, four communication patterns (one-to-many, many-to-one, multi-topic, bidirectional) each with a figure, introspection tools reference, and ros2 run vs. ros2 launch comparison table.

  • Added “ROS 2 Setup” section: workspace layout and setup commands, colcon build flags, Python package creation workflow, package layout with directory descriptions, package.xml fields and dependency tags, and setup.py entry points and data files.

  • Added “Writing Nodes” section: interfaces (three kinds, standard message packages, .msg to code pipeline, primitive types vs. std_msgs, introspection commands, composite message example), minimal procedural node, OOP node with separate class and entry point, spinning (thread definition with figure, main thread and executor figure, why spinning is required, try/except/finally pattern, spinning alternatives), timers and callbacks, publishers (create, message instantiation options, publish in timer callback, run and inspect), QoS (four policies, default vs. explicit profile, predefined profiles, compatibility rules, diagnostics), and subscribers (create, named vs. lambda callbacks, complete node).

  • Added “Communication Scenarios” section: three scenarios (no subscriber, fast subscriber, slow subscriber) each with a detailed timing table, plus a summary comparison table and diagnostic commands.

Index (l8_index.rst)

  • Overview, learning objectives, toctree, and next steps for L8.

Exercises (l8_exercises.rst)

  • Exercise 1: Periodic Logger – OOP node with timer callback and ROS 2 clock.

  • Exercise 2: String Publisher – publisher with std_msgs/String and introspection verification.

  • Exercise 3: String Subscriber – named callback subscriber, end-to-end verification with Exercise 2.

  • Exercise 4: QoS Mismatch Investigation – BEST_EFFORT publisher vs. RELIABLE subscriber, silent failure diagnosis, fix and written reflection.

Quiz (l8_quiz.rst)

  • 10 multiple choice questions covering DDS, colcon, node lifecycle, QoS policies, spinning, message types, and timing scenarios.

  • 10 true/false questions covering spin placement, publisher behavior, package.xml/setup.py consistency, TRANSIENT_LOCAL, symlink-install, print vs. logger, silent failures, and ros2 run.

  • 4 essay questions: monolithic vs. distributed architecture, QoS policies with examples, spinning and the executor, and the three communication timing scenarios.

Glossary (l8_glossary.rst)

  • 30 terms defined across 14 letter sections: Action, ament_python, Callback, colcon, DDS, Durability, Entry Point, Executor, Interface, Launch File, Message, Middleware, Node, package.xml, Process, Publisher, QoS, Queue Depth, rclpy, Reliability, ROS 2 Workspace, rosdep, RTPS, Service, Spinning, Subscriber, setup.py, Thread, Timer, Topic, Workspace Overlay.

References (l8_references.rst)

  • Lecture 8 card summarizing all topics covered.

  • ROS 2 Official Documentation: Jazzy docs, beginner tutorials, rclpy API, QoS concepts, logging, colcon docs.

  • DDS and Middleware: OMG DDS Portal, DDS Foundation, Fast DDS, ROS 2 DDS vendor guide.

  • External Tutorials: Articulated Robotics, The Construct, Real Python OOP review.

  • Style and Best Practices: ROS 2 Python style guide, PEP 8.

  • Recommended Reading: Koubaa ROS 2 series, Programming Robots with ROS 2, Silberschatz OS Concepts, OMG DDS Specification.

v1.2.0 – L6 Lecture, Exercises, and Quiz Updated (2026-03-02)

Lecture Notes (l6_lecture.rst)

  • Added “How Do We Achieve Abstraction?” dropdown with three levels (Documentation, Public Interface, Abstract Classes as L7 preview)

  • Added “How to Achieve Encapsulation” summary dropdown

  • Split @property dropdown into four separate sections: intro, Defining a Getter, Defining a Setter with Validation, and Using Properties

  • Added “Encapsulation Summary” dropdown after Read-Only Properties

  • Updated Class Attributes dropdown: removed max_reach for clarity, added shadowing warning (self vs class name)

  • Added full Appendix: Exception Handling section with 12 dropdowns covering: runtime errors, common built-in exceptions, try/except, accessing the exception object, handling multiple exception types, else clause, finally clause, full try statement, raise statement, why raise matters for OOP, and return NotImplemented vs raise NotImplementedError

Exercises (l6_exercises.rst)

  • Exercises 1, 2, and 3: added full if __name__ == "__main__" blocks from L6_exercises.py

  • Updated expected output for all three exercises to match the provided main blocks

Quiz (l6_quiz.rst)

  • Updated quiz description to reference the exception handling appendix

  • Added 3 new questions (Q31–Q33) in a new “Exception Handling (Appendix)” section covering try/except output, else clause purpose, and ValueError vs TypeError

Slides (ENPM605-L6-v1_0.tex)

  • Bumped version to v1.2

  • Restructured lecture into Design Phase and Implementation Phase sections

  • Added “Before We Start” slide referencing the appendix

  • Added Class Attributes slide with shadowing warning

  • Added “How Do We Achieve Abstraction?” slide (3 levels)

  • Added “How to Achieve Encapsulation” summary slide

  • Split @property content across separate slides (Pythonic Way, Getter, Setter, Using, Read-Only, Summary)

  • Added Exercise 1, 2, and 3 slides with specifications

  • Added full Appendix: Exception Handling section (overview, try/except, else, finally, full try, raise, raise for OOP, NotImplemented vs NotImplementedError)

v1.1.0 – RWA 2 Released (2026-03-01)

RWA 2: Search and Rescue Mission Planner (new)

Assignment Overview

  • New assignment covering Object-Oriented Programming (Lectures 6 and 7)

  • Two-phase structure: Phase 1 (Design) and Phase 2 (Implementation)

  • Use case: Disaster Response Operation with aerial drones and ground crawlers searching a disaster zone divided into sectors

  • Total: 50 points (Design: 6 pts, Implementation: 44 pts)

  • Due: March 25, 2026

Phase 1: Design Document (6 pts)

  • Deliverable: single UML class diagram in PDF format (design_document.pdf)

  • Design phase intentionally lightened to allow students to focus on implementation

  • Sequence diagram removed from requirements to reduce design workload

Phase 2: Implementation (44 pts)

  • 7 classes across 6 modules: SensorPayload, Robot (abstract), AerialDrone, GroundCrawler, Sector, Mission, DisasterZone

  • OOP concepts exercised: abstraction (abc.ABC), encapsulation (@property), inheritance (2 subclasses), polymorphism (search()/can_search() overrides), composition (Robot owns SensorPayload), aggregation (DisasterZone manages robots/sectors), association (Mission links robot to sector)

  • Dunder methods required: __str__, __repr__, __eq__, __lt__, __len__, __contains__

  • Main program (9 pts) demonstrates polymorphism, sorting, __contains__, and report generation

AI Policy

  • Explicit policy added: AI tools (Copilot, ChatGPT, Claude, etc.) are NOT permitted for code or design

  • Students instructed to disable GitHub Copilot and other AI extensions in VS Code before starting

  • Exception: AI may be used to generate docstring documentation after code is written by the student

Other Details

  • Project naming convention: firstname_lastname_rwa2/

  • Suggested 3-week timeline included with day-by-day breakdown

  • All major sections wrapped in .. dropdown:: directives for collapsible navigation

  • Use case separated into subsections using .. rubric:: directives (Robots, Common Robot Characteristics, Sensor Payload, Sectors, Missions, Disaster Zone)

v1.0.0 – Initial Release (2026-01-27)

Initial release of the ENPM605 Spring 2026 course documentation.

Course Structure

  • Lectures 1 through 6 published with lecture notes, exercises, quizzes, glossaries, and references

  • Each lecture organized as a self-contained folder with RST files following a consistent structure

RWA 1: Robot Fleet Monitor

  • First assignment covering Lectures 1 through 4 (variables, data types, control flow, functions)

  • 30 points, 6 parts across 5 Python modules

  • Due: February 25, 2026