From 464e17ed43a6f94bff552247f9c419dc760013b4 Mon Sep 17 00:00:00 2001 From: Grant Date: Sun, 12 Jul 2026 17:27:59 +0200 Subject: [PATCH] fix(bringup): wire mode_profile_loader into rov_full.launch.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mode_profile_loader was built and committed 7 Jul 2026 (4e48dc2) but never added to any launch file, so /rov/mode/profile has had zero publishers at runtime on every startup since — confirmed 12 Jul 2026 on RPi5 via `ros2 node list` (no mode node) and `ros2 topic info /rov/mode/profile` (Publisher count: 0, 2 subscribers waiting). The entire operating-mode profile system has been dark since it was built; failsafe_monitor's health_role has been silently running on its gate default the whole time rather than the actual configured mode. Adds the Node action (package rov_mission, executable mode_profile_loader) alongside the other core nodes, before Perception, so failsafe_monitor and cockpit_bridge — both latched subscribers to its output — wait as little as possible on a publisher. respawn=True/respawn_delay=5.0 to match the other core nodes (c099c00, a5e1c99); not on the respawn exclusion list. mode_profile_loader.py and mode_profiles.yaml are untouched — this closes the wiring gap only. --- src/rov_bringup/launch/rov_full.launch.py | 39 +++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/rov_bringup/launch/rov_full.launch.py b/src/rov_bringup/launch/rov_full.launch.py index 850eeff..ae2c1c5 100644 --- a/src/rov_bringup/launch/rov_full.launch.py +++ b/src/rov_bringup/launch/rov_full.launch.py @@ -67,6 +67,45 @@ def generate_launch_description(): ), ), + # ------------------------------------------------------------------ + # Mode profile loader — loads mode_profiles.yaml and publishes the + # resolved operating-mode profile (ROV / AUV / saved hybrid) on + # /rov/mode/profile, latched (TRANSIENT_LOCAL). It is the single + # source of truth for health_role (gate/advisory) and every other + # mode-derived flag; failsafe_monitor (mode-dependent recovery, + # 2a3e577) and cockpit_bridge (external/rov-* data lake variables) + # both subscribe to it and have nothing correct to fall back on + # until it publishes — failsafe_monitor's health_role in particular + # defaults to the conservative "gate" assumption until the first + # message arrives, so the sooner this node is up, the sooner that + # default stops being a guess. Placed here (with the other core + # nodes, before Perception) rather than down in the Mission stack + # further below, specifically so it does not sit behind Perception + # startup on the way to publishing. + # + # GAP: this node was built and committed on 7 Jul 2026 (4e48dc2) but + # was never added to this launch file, so /rov/mode/profile had zero + # publishers at runtime on every startup since — confirmed 12 Jul + # 2026 via `ros2 node list` (no mode node present) and + # `ros2 topic info /rov/mode/profile` (Publisher count: 0, 2 + # subscribers waiting). This entry closes that gap. + # + # respawn=True/respawn_delay=5.0 for the same reason as the other + # core nodes (c099c00, a5e1c99): if this node dies, the entire mode + # system goes dark and health_role silently falls back to its gate + # default — exactly the silent-degradation case respawn policy + # exists to catch. Not on the respawn exclusion list (mavros_node, + # recording_manager, perception, foxglove_bridge). + # ------------------------------------------------------------------ + Node( + package='rov_mission', + executable='mode_profile_loader', + name='mode_profile_loader', + output='screen', + respawn=True, + respawn_delay=5.0, + ), + # Perception stack IncludeLaunchDescription( PythonLaunchDescriptionSource(