MCAP Recording¶
This example records simulated robot data to MCAP files for replay and analysis in Foxglove Studio.
After starting the application, the developer panel offers start/stop buttons and a topic selection, and the recordings can be listed and downloaded at http://localhost:8080/recordings.
#!/usr/bin/env python3
from nicegui import ui
from rosys.analysis import recording
from rosys.analysis.recording import McapRecorder, RecordingsPage
from rosys.driving import Odometer, Steerer, keyboard_control, robot_object
from rosys.geometry import Prism
from rosys.hardware import RobotSimulation, WheelsSimulation
shape = Prism.default_robot_shape()
wheels = WheelsSimulation()
robot = RobotSimulation([wheels])
odometer = Odometer(wheels)
steerer = Steerer(wheels)
recorder = McapRecorder(auto_start=False)
recording.add_event_topic(recorder, '/wheels', event=wheels.VELOCITY_MEASURED, unpack=True)
recording.add_pose_topic(recorder, '/odometry/pose', event=odometer.POSE_UPDATED, child='odometry')
RecordingsPage(recorder, header=lambda: ui.link('steering', '/'))
@ui.page('/')
def index() -> None:
keyboard_control(steerer)
with ui.scene():
robot_object(shape, odometer)
recorder.developer_ui()
ui.run(title='MCAP Recording')
- Recorder
- The
McapRecorderwrites every registered topic to rotating MCAP files under~/.rosys/mcap. Withauto_start=Falseit stays idle until you press the record button indeveloper_ui. - Topics
add_event_topicandadd_pose_topicbind a topic to a RoSys event; the matching Foxglove converter is picked from the payload type automatically. The subscription is only active while a recording is open.- Image quality
- Camera topics dominate a recording's size.
Keyword arguments are forwarded to the converter, so
add_event_topic(recorder, '/camera/front/image', event=camera.NEW_IMAGE, quality=75)records JPEGs at quality 75 instead of the default 90, roughly halving the bytes per frame. - Recordings page
RecordingsPagemounts a page for listing, renaming, reindexing and downloading recordings, plus a download endpoint at/api/recordings/{name}. The optionalheadercallback renders shared navigation at the top of the page.