关于 rerun-data-model
面向 Rerun 数据导入设计的技能,帮助开发者在编写转换代码前确定实体、组件、时间线及数据分层方式。通过映射表和决策规则,强调优先使用读取器与 lens,而非手工构造数据块。
主要功能
- 01实体、组件与 Archetype 建模
- 02属性、组件与 Layer 的区分
- 03静态数据与时间数据选择
- 04时间线及多速率数据处理
- 05导入映射表与常见错误提示
适用场景
- 01规划传感器数据到实体路径的映射
- 02确定数据应作为组件、属性还是 Layer
- 03在转换前判断采用读取器还是手工数据块
- 04设计静态标定数据与时间序列的记录方式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ rerun-io/ rerun --skill rerun-data-model安装后在 Claude Code 中输入/rerun-data-model确认已加载。
详细介绍
Rerun 数据模型
摄取数据集的难点在于建模决策,而不是 API 调用。
模型选对了,任何机制都行;模型选错了,查询、视图和训练都会出问题。
这项技能只讲决策。
机制细节请参阅 rerun-chunk-processing(流水线机制)及其指向的导入器技能:rerun-mcap、rerun-urdf、rerun-parquet、rerun-mp4、rerun-lerobot。
准确的函数签名请参阅 rerun.io/docs/concepts/logging-and-ingestion 中的文档。
编写转换代码前,请先填写下方的映射表。 这就是设计,而且人工只需几秒钟就能审阅。
建模前先选择机制
建模决定每条数据会变成_什么_;机制决定它_如何_实现——默认选择是读取器 + 透镜,而不是手工构建分块:
- 此数据源有读取器吗? MCAP→
McapReader、URDF→UrdfTree、parquet→ParquetReader、HDF5→Hdf5Reader、RRD→RrdReader、LeRobot 目录→log_file_from_path。有 → 使用reader.stream()+ 透镜;读取器会生成分块,不需要你来生成。 - 没有,而且它是真正的外部元数据(JSON 标定数据、偏移量),或是通用读取器无法涵盖的特定自定义用例**→**使用
Chunk.from_columns。 - 否则:考虑一下你是否正要手工构建本应由读取器或透镜生成的内容,并请求澄清。
具体来说,对于 MCAP:可由 Foxglove 或 ROS 解码的文件会为某些受支持的消息架构直接生成 Transform3D、Pinhole 和 VideoStream 等原型——请直接传递这些内容,切勿重新推导;只有自定义 protobuf 信号主题才需要透镜。完整的决策树和反模式列表请参阅 rerun-chunk-processing。
模型
Dataset → Segment → Layer → Recording → Entity → Component → Chunk
- 实体 = 由路径命名的一项事物(
/robot/arm/camera)。 组件 = 实体上的一个类型化字段(位置、图像、标量)。 原型 = 一组可一起记录和渲染的标准组件(Points3D、Image、Transform3D)。 - 你记录的每个值都处在两个维度上:位置(实体路径 + 组件)和时间(所属时间轴,或 静态 = 所有时间)。
- 片段 = 一段情节;注册时,其
recording_id会成为segment_id。图层 = 叠加在片段之上的额外.rrd。图层通过匹配片段的recording_id来关联,不依赖其他信息:这个共享 ID 就是整个分层机制。
决策
在现有实体上使用实体还是组件
如果某项数据有自己的空间坐标系(Transform3D/Pinhole)、自己的标注上下文,或应独立显示、清除或共享(每个机器人连杆、每个相机、每个传感器),则新建实体。对于同一批实例上的辅助数据(每个点的置信度),则使用同一实体并添加额外组件。
非标准字段使用 AnyValues。
属性、组件还是图层(最常见的困惑)
- 组件:时间线上的逐时间戳信号(关节角度、图像)。
- 片段属性:每个片段一份的元数据,用于目录筛选和搜索(操作员、机器人、站点、任务、日期)。不是逐时间戳数据。
- 图层:基于基础片段派生出的完整
.rrd(FK 变换、点云、夹爪状态、标签、质量评分)。可像基础片段的一部分一样查询。
静态还是时间序列 静态数据适用于所有时间线,并会覆盖同一实体上同一组件的任何时间序列值。将其用于不变数据(标定、坐标系、机器人网格、标注上下文、视频资源)。绝不要将逐帧数据设为静态。
使用哪种时间线
使用 timestamp 时间线(自 epoch 起的纳秒)进行跨传感器时钟对齐;使用 sequence 时间线进行帧/序号对齐;适用时可同时标注两者。
不要重采样到统一速率。 Latest-at 会在查询时协调多速率数据流,方法是保留每个组件的最后一个样本(不插值)。
基础数据还是图层
基础数据 = 对原始数据流的忠实转换,不包含任何计算结果。
图层 = 任何派生数据(根据 URDF 和关节状态计算的 FK、根据深度和内参生成的点云)。
将它们保存在不同的 .rrd 中。
映射表(编码前先生成)
| 来源(topic/列/键) | 实体路径 | 原型 | 组件 | 时间线 | 静态/时间序列 | 基础数据/图层 | 属性? |
|---|---|---|---|---|---|---|---|
mcap /joint_states | /robot/<joint> | Scalars | scalars | sensor_time | 时间序列 | 基础数据 | 否 |
cam0/color.mp4 | /camera/cam0/video | VideoStream | codec+sample | video_time | codec 静态,样本为时间序列 | 基础数据 | 否 |
calibration.json | /camera/cam0 | Pinhole(+Transform3D 外参) | image_from_camera | — | 静态 | 基础数据 | 否 |
| URDF + joints(计算所得) | /robot/<link> | Transform3D | translation/rotation | sensor_time | 时间序列 | 图层 | 否 |
episode.json 操作员 | segment | — | — | — | — | — | 是 |
值得了解的模式
- 变换 / FK 树:为每个链接实体记录一个
Transform3D;它与父路径关联,并沿树向下组合。(仅当拓扑必须是灵活图结构时,才使用名为CoordinateFrame的组件以及child_frame/parent_frame。) - 相机:在相机实体上设置外参(
Transform3D)和内参(Pinhole),将图像/深度数据作为子项,使其继承投影。 - 视频:压缩样本使用
VideoStream——这是 mp4 的默认方式(rerun-mp4),也是 Foxglove 解码器直接提供的数据。对于VideoStream无法表示的编解码器,使用AssetVideo+VideoFrameReference作为备用方案。 - 列式导入:对于现有的 文件,使用相应的读取器(
rerun-mcap/-parquet/-mp4/-lerobot),它会直接生成数据块——不要用自定义解析器手动组装send_columns。直接记录列数据时(实时记录),send_columns不会自动添加时间线,因此请传入所需的所有时间线。 - 自定义数据:不要将不受支持的数据强行塞进无关的原型中。可以考虑使用
DynamicArchetype或AnyValues。DynamicArchetype适用于有意义的一组自定义组件;AnyValues适用于无法组成可识别对象或源类型的杂项值。
可能导致实际故障的问题
- 查询中组件列会以
ListArray的形式返回:使用[0]/[0][0]索引(DataFrame 从 0 开始,SQL 从 1 开始)。参见rerun-catalog-queries。 - 图层必须与数据段共享
recording_id,否则无法附加。注册时会丢弃application_id。 send_columns/send_chunks不会添加log_time/log_tick;只会存在你传入的时间线。- 静态数据会在所有时间范围内覆盖该组件的所有时序数据;在查看器中,静态数据会被覆盖,但每次写入都会保留在磁盘上,直到运行
rerun rrd optimize。 - 每对帧之间只能有一个
Transform3D/Pinhole关系;如果在第二个实体上记录相同关系,会被拒绝。 - 实体路径不是文件路径(
..无实际意义,__为保留值)。 - 使用默认
RecordingStream写入的目录图层会注入一个/__properties(RecordingInfo)数据块;当目录按recording_id合并图层时,它可能与基础数据段的属性冲突,导致数据集的默认蓝图在打开时不再生效。创建图层的流时,请设置send_properties=False。