feat(bringup): add foxglove_bridge and MCAP recording

This commit is contained in:
Grant 2026-05-07 08:26:26 +00:00
parent 6aea0c24a6
commit 559f60dfd8
3 changed files with 82 additions and 0 deletions

View File

@ -0,0 +1,74 @@
"""
foxglove_mcap.launch.py
Launches foxglove_bridge (WebSocket :8765) and MCAP bag recording.
Included automatically by rov_full.launch.py.
Standalone:
ros2 launch rov_bringup foxglove_mcap.launch.py
ros2 launch rov_bringup foxglove_mcap.launch.py record:=false
Foxglove connection from Edge PC:
Foxglove Studio -> Open Connection -> Foxglove WebSocket -> ws://rov-brain.local:8765
Storage:
Bags written to /data/bags/ on NVMe. Create before first launch:
sudo mkdir -p /data/bags && sudo chown ubuntu:ubuntu /data/bags
"""
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, ExecuteProcess, LogInfo
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
def generate_launch_description():
bag_output_arg = DeclareLaunchArgument(
'bag_output_dir',
default_value='/data/bags/dive',
description='Base path for MCAP bag. Timestamp appended automatically.',
)
record_arg = DeclareLaunchArgument(
'record',
default_value='true',
description='Set false to run foxglove_bridge without recording.',
)
# Exposes all ROS2 topics over WebSocket
# Edge PC connects via Foxglove Studio -> ws://rov-brain.local:8765
foxglove_bridge_node = Node(
package='foxglove_bridge',
executable='foxglove_bridge',
name='foxglove_bridge',
parameters=[{
'port': 8765,
'address': '0.0.0.0', # all interfaces — required for tether access
'tls': False,
'send_buffer_limit': 10000000, # 10MB — headroom for image topics
'max_update_ms': 100, # 10Hz cap — prevents WebSocket flooding
}],
output='screen',
)
# Records all topics to NVMe in MCAP format (Foxglove native)
# Output dir is auto-timestamped, e.g.: /data/bags/dive_2026_05_07-14_22_05/
mcap_recorder = ExecuteProcess(
cmd=[
'ros2', 'bag', 'record',
'--all',
'--storage', 'mcap',
'--output', LaunchConfiguration('bag_output_dir'),
'--max-bag-size', '0', # no size limit — one bag per dive
],
output='screen',
condition=IfCondition(LaunchConfiguration('record')),
)
return LaunchDescription([
bag_output_arg,
record_arg,
LogInfo(msg='foxglove_bridge: connect Foxglove Studio to ws://<RPi5-IP>:8765'),
foxglove_bridge_node,
mcap_recorder,
])

View File

@ -79,4 +79,11 @@ def generate_launch_description():
os.path.join(mission_pkg, 'launch', 'mission.launch.py')
),
),
# Foxglove bridge + MCAP recording (Prong 2 + 3)
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(bringup_pkg, 'launch', 'foxglove_mcap.launch.py')
),
),
])

View File

@ -14,4 +14,5 @@
<export>
<build_type>ament_cmake</build_type>
</export>
<exec_depend>foxglove_bridge</exec_depend>
</package>