rov-autonomy/src/rov_bringup/launch/foxglove_mcap.launch.py
Grant du Toit 5d75a9d30d Phase 3 Stage 1: Recording Manager (DIR-9)
- Add recording_manager node: continuous rosbag2 MCAP recorder,
  zstd compression, 500MB bag splitting, 10GB retention policy,
  1Hz health monitoring and restart on subprocess exit
- Add /rov/recording/active no-go gate to mission_executor START handler
- Add rov-recording variable to cockpit_bridge (data lake visibility)
- Replace foxglove_mcap ExecuteProcess with recording_manager Node
- Register recording_manager entry point in setup.py
- Confirmed: data: true on /rov/recording/active in full stack
2026-07-04 07:42:09 +00:00

80 lines
2.9 KiB
Python

"""
foxglove_mcap.launch.py
Launches foxglove_bridge (WebSocket :8765) and the recording_manager node.
Included automatically by rov_full.launch.py.
Standalone:
ros2 launch rov_bringup foxglove_mcap.launch.py
Foxglove connection from Edge PC:
Foxglove Studio -> Open Connection -> Foxglove WebSocket -> ws://rov-brain.local:8765
Recording:
Managed by recording_manager node (rov_mission package).
Bags written to /data/bags/dive_<timestamp>/ on NVMe.
Create /data/bags before first launch if it does not exist:
sudo mkdir -p /data/bags && sudo chown ubuntu:ubuntu /data/bags
Recording behaviour (DIR-9):
- recording_manager starts ros2 bag record on node startup.
- Records continuously, independent of mission state.
- Publishes /rov/recording/active (Bool) — hard no-go gate for mission start.
- Retention: deletes oldest dive_* dirs when /data free space < 10 GB.
- MCAP format, zstd compression, 500 MB bag segments.
"""
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
# -----------------------------------------------------------------------
# Foxglove Bridge
# Exposes all ROS2 topics over a WebSocket for Foxglove Studio.
# Visualisation only — does NOT record MCAP (DIR-9).
# Connect Foxglove Studio to: ws://rov-brain.local:8765
# -----------------------------------------------------------------------
foxglove_bridge_node = Node(
package='foxglove_bridge',
executable='foxglove_bridge',
name='foxglove_bridge',
parameters=[{
# Listen on all interfaces — required when connecting over tether
'port': 8765,
'address': '0.0.0.0',
# TLS disabled for LAN/tether use; enable for public internet
'tls': False,
# 10 MB send buffer — headroom for compressed image topics
'send_buffer_limit': 10000000,
# 10 Hz cap on topic updates — prevents WebSocket flooding on
# high-rate topics (IMU, EKF at 50+ Hz) without dropping data
# for operator-relevant topics (mission status, depth at ≤10 Hz)
'max_update_ms': 100,
}],
output='screen',
)
# -----------------------------------------------------------------------
# Recording Manager
# Dedicated continuous recorder node (DIR-9).
# Manages ros2 bag record subprocess internally.
# Starts recording on node startup — before any mission can begin.
# Publishes /rov/recording/active as the mission start no-go gate.
# -----------------------------------------------------------------------
recording_manager_node = Node(
package='rov_mission',
executable='recording_manager',
name='recording_manager',
output='screen',
)
return LaunchDescription([
foxglove_bridge_node,
recording_manager_node,
])