rerun-mcap
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRerun MCAP ingestion
Rerun MCAP 导入
McapReaderrerun-chunk-processingMcapReaderrerun-chunk-processingThe API
API 说明
python
from rerun.experimental import McapReader
reader = McapReader(mcap_path) # see help(McapReader) for the full option set
stream = reader.stream()A URDF embedded in the MCAP can be ingested as well (then see ).
rerun-urdfpython
from rerun.experimental import McapReader
reader = McapReader(mcap_path) # 查看 help(McapReader) 获取完整选项列表
stream = reader.stream()MCAP 中嵌入的 URDF 文件也可被导入(相关内容请参考 )。
rerun-urdfWhat a topic becomes
主题的转换规则
With the default decoders (), the message schema name decides what a topic becomes — pass archetypes through, lens only the raw topics:
decoders=None:message| MCAP schema name | decodes to | what to do |
|---|---|---|
| | pass through; do not hand-build |
| | pass through |
| | pass through |
other | the matching archetype | pass through |
ros2 well-known types ( | archetype | pass through |
your own | one | attach semantics with a |
So a camera topic already arrives as , its video as , and a topic as — only custom messages (e.g. a custom joint states schema, a custom gripper status enum) come through reflection or raw only and need lenses.
PinholeVideoStreamframe_transformsTransform3DThe decoder does the schema→archetype mapping; because foxglove messages are protobuf-encoded it rides on the decoder, so keep (verified: alone leaves a raw ; adding makes it a ). Confirm on your file: , then read and a few before deciding anything is missing or needs rebuilding.
foxgloveprotobufdecoders=Nonedecoders=["protobuf"]foxglove.CameraCalibration:messagefoxglovePinholeMcapReader(path).stream()McapSchema:nameChunk.format()- Entity path = topic name (stays
/sensors/joint_states). Filter early:/sensors/joint_states.McapReader(path).stream().filter(content="/sensors/**") - A reflection-decoded message lands as one struct component named . Navigate it with
<fully.qualified.MessageName>:message(Selector) inside lenses; this is how custom messages get Rerun semantics attached (see the DeriveLens patterns inSelector(".joint_positions")).rerun-chunk-processing - Topic regexes use RE2 syntax and are not anchored: matches
camand/external/cam_low. Anchor explicitly (/camera_info) when it matters. Prefer reader-level topic filtering over^/external/camwhen you can, so excluded topics are never decoded at all..filter(...)
使用默认解码器()时,消息模式名称决定主题的转换结果——直接传递原型,仅对原始 主题应用透镜:
decoders=None:message| MCAP 模式名称 | 解码为 | 处理方式 |
|---|---|---|
| | 直接传递;请勿手动构建 |
| | 直接传递 |
| | 直接传递 |
其他 | 匹配的原型 | 直接传递 |
ros2 知名类型( | 原型 | 直接传递 |
自定义 | 单个 | 通过 |
因此,相机主题会直接转换为 ,视频主题转换为 , 主题转换为 ——只有自定义消息(如自定义关节状态模式、自定义夹爪状态枚举)会通过反射或仅以原始形式传递,需要使用透镜处理。
PinholeVideoStreamframe_transformsTransform3Dfoxgloveprotobufdecoders=Nonedecoders=["protobuf"]foxglove.CameraCalibration:messagefoxglovePinholeMcapReader(path).stream()McapSchema:nameChunk.format()- 实体路径 = 主题名称(保持为
/sensors/joint_states)。 尽早过滤:/sensors/joint_states。McapReader(path).stream().filter(content="/sensors/**") - 反射解码的消息会作为一个名为 的结构体组件存在。 使用透镜内的
<fully.qualified.MessageName>:message(如Selector)进行导航;这是为自定义消息添加 Rerun 语义的方式(请参考Selector(".joint_positions")中的 DeriveLens 模式)。rerun-chunk-processing - 主题正则表达式采用 RE2 语法,且未锚定:会匹配
cam和/external/cam_low。 必要时请显式锚定(如/camera_info)。如果可以,优先在阅读器层面进行主题过滤,而非使用^/external/cam,这样被排除的主题根本不会被解码。.filter(...)
When to use the low-level mcap
package instead
mcap何时改用底层 mcap
包
mcapMcapReadermcap.reader.make_readerMcapReadermcap.reader.make_readerGotchas
注意事项
- Empty stream, no error: a topic regex that matched nothing, or a channel
whose decoder produced no rows. Check on a few chunks of
Chunk.format()against a tiny test file, or compare topic names with thereader.stream().to_chunks()CLI / package first.mcap - Topic regexes are unanchored RE2; excludes run after includes.
- interprets MCAP log times as wall-clock ns since epoch. If the recording's clock is wrong, fix it at the reader with
timeline_type="timestamp"rather than mutating timestamps downstream.timestamp_offset_ns - Decoder subsets silently skip topics no decoder claims; when a topic is
missing, retry with to rule out decoder selection.
decoders=None - Example fix-lenses are dataset-specific. Before copying a like the
MutateLensswap from thePinhole:resolutionexample, read the raw component fromrobot_data_preprocessingand confirm the defect exists in your data — applied blindly it corrupts correct calibration (a correct 648×480 flipped to 480×648).McapReader(path).stream() - derives both the camera's
foxgloveand the video'sPinhole:child_framefrom each message'sCoordinateFrame:frame(plus an image-plane suffix), so they match when the calibration and video topics share a.frame_id. Only when those topics carry differentframe_ids does the video frame diverge and orphan the video from its image plane — re-home it then with a per-cameraframe_idonMutateLens.CoordinateFrame:frame
- 流为空但无错误:主题正则表达式未匹配到任何内容,或通道的解码器未生成任何行。请针对小型测试文件,检查 的部分块的
reader.stream().to_chunks(),或先通过Chunk.format()CLI / 包对比主题名称。mcap - 主题正则表达式是未锚定的 RE2;排除规则在包含规则之后执行。
- 将 MCAP 日志时间解释为自 epoch 以来的 wall-clock 纳秒。如果录制的时钟有误,请在阅读器层面使用
timeline_type="timestamp"修正,而非在下游修改时间戳。timestamp_offset_ns - 解码器子集会静默跳过无解码器认领的主题;当主题缺失时,请重试设置 ,以排除解码器选择的问题。
decoders=None - 示例修复透镜是特定于数据集的。在复制 示例中的
robot_data_preprocessing(如MutateLens交换)之前,请从Pinhole:resolution读取原始组件,确认你的数据中存在该问题——盲目应用会损坏正确的校准(如将正确的 648×480 翻转成 480×648)。McapReader(path).stream() - 从每条消息的
foxglove(加上图像平面后缀)派生相机的.frame_id和视频的Pinhole:child_frame,因此当校准和视频主题共享同一个CoordinateFrame:frame时,二者会匹配。只有当这些主题携带不同的frame_id时,视频帧才会偏离并与图像平面脱节——此时需要针对每个相机在frame_id上使用CoordinateFrame:frame重新关联。MutateLens
References
参考资料
- End-to-end MCAP pipeline:
https://github.com/rerun-io/rerun/tree/main/examples/python/robot_data_preprocessing - (stream/lens mechanics),
rerun-chunk-processing(FK from joint-state topics),rerun-urdf(modeling decisions)rerun-data-model
- 端到端 MCAP 流水线:
https://github.com/rerun-io/rerun/tree/main/examples/python/robot_data_preprocessing - (流/透镜机制)、
rerun-chunk-processing(关节状态主题的正向运动学)、rerun-urdf(建模规则)rerun-data-model