rerun-data-model

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Rerun data model

Rerun数据模型

The hard part of ingesting a dataset is the modeling decision, not the API call. Get the model right and any mechanism works; get it wrong and queries, views, and training all break. This skill is just the decisions. For mechanism details see
rerun-chunk-processing
(pipeline mechanics) and the importer skills it routes to:
rerun-mcap
,
rerun-urdf
,
rerun-parquet
,
rerun-mp4
,
rerun-lerobot
. For exact signatures, the docs at
rerun.io/docs/concepts/logging-and-ingestion
.
Before writing conversion code, fill in the mapping table below. It is the design, and a human can review it in seconds.
导入数据集的难点在于建模决策,而非API调用。模型正确,任何机制都能正常工作;模型错误,查询、视图和训练都会失效。本文仅阐述决策内容。有关机制细节,请参阅
rerun-chunk-processing
(流水线机制)及其指向的导入工具技能:
rerun-mcap
rerun-urdf
rerun-parquet
rerun-mp4
rerun-lerobot
。如需确切的签名信息,请查看文档
rerun.io/docs/concepts/logging-and-ingestion
在编写转换代码之前,请填写下方的映射表。这是设计方案,人工审核只需几秒。

Pick the mechanism before you model the bytes

先选择机制,再建模字节数据

Modeling decides what each datum becomes; this decides how it gets there — and the default is a reader + lenses, not hand-built chunks:
  • Does a reader exist for this source? MCAP→
    McapReader
    , URDF→
    UrdfTree
    , parquet→
    ParquetReader
    , RRD→
    RrdReader
    , LeRobot dir→
    log_file_from_path
    . Yes →
    reader.stream()
    + lenses; the reader produces the chunks, you do not.
  • No, and it is genuine external metadata (JSON calibration, offsets) or a specific custom use case that can't be covered by a generic reader**→**
    Chunk.from_columns
    .
  • Otherwise: consider if you are about to hand-build something a reader or lens should produce and ask for clarification.
For MCAP specifically: a Foxglove- or ROS-decodable file emits archetypes like
Transform3D
,
Pinhole
, and
VideoStream
for certain supported message schemas ready-made — pass those through, never re-derive them; only custom protobuf signal topics need lenses. The full decision tree and the anti-pattern list are in
rerun-chunk-processing
.
建模决定每个数据项的最终形态;而机制决定实现方式——默认方案是读取器+镜头,而非手动构建块
  • 该数据源是否已有对应的读取器? MCAP→
    McapReader
    ,URDF→
    UrdfTree
    ,parquet→
    ParquetReader
    ,RRD→
    RrdReader
    ,LeRobot目录→
    log_file_from_path
    是 → 使用
    reader.stream()
    +镜头;读取器会生成块,无需手动构建。
  • 否,且属于真实的外部元数据(JSON校准数据、偏移量)或无法通过通用读取器覆盖的特定自定义场景**→** 使用
    Chunk.from_columns
  • 其他情况:考虑是否要手动构建读取器或镜头本应生成的内容,并请求澄清。
针对MCAP的特殊说明:可被Foxglove或ROS解码的文件会为某些受支持的消息模式直接生成
Transform3D
Pinhole
VideoStream
等原型——直接传递这些内容即可,切勿重新推导;仅自定义protobuf信号主题需要使用镜头。完整的决策树和反模式列表请参阅
rerun-chunk-processing

The model

数据模型

Dataset → Segment → Layer → Recording → Entity → Component → Chunk
  • Entity = a thing, named by a path (
    /robot/arm/camera
    ). Component = one typed field on it (positions, image, a scalar). Archetype = a standard bundle of components that log and render together (
    Points3D
    ,
    Image
    ,
    Transform3D
    ).
  • Every value you log sits on two axes: where (entity path + component) and when (which timeline, or static = all time).
  • Segment = one episode; on registration its
    recording_id
    becomes the
    segment_id
    . Layer = an extra
    .rrd
    on top of a segment. It attaches by matching the segment's
    recording_id
    and nothing else: that shared id is the whole layering mechanism.
Dataset → Segment → Layer → Recording → Entity → Component → Chunk
  • Entity(实体) = 一个事物,由路径命名(如
    /robot/arm/camera
    )。 Component(组件) = 实体上的一个类型字段(位置、图像、标量)。 Archetype(原型) = 一组可协同记录和渲染的标准组件集合(如
    Points3D
    Image
    Transform3D
    )。
  • 你记录的每个值都位于两个维度上:位置(实体路径+组件)和时间(所属时间线,或_static_=全时段)。
  • Segment(片段) = 一个片段;注册时其
    recording_id
    会成为
    segment_id
    Layer(层) = 附加在片段之上的额外.rrd文件。它通过匹配片段的
    recording_id
    进行关联:共享ID是唯一的分层机制。

The decisions

决策规则

Entity vs component on an existing entity New entity if it has its own spatial frame (
Transform3D
/
Pinhole
), its own annotation context, or should be shown/cleared/shared independently (each robot link, each camera, each sensor). Same entity + extra component for auxiliary data at the same instances (per-point confidence). Use
AnyValues
for non-standard fields.
Property vs component vs layer (the most common confusion)
  • Component: per-timestamp signal on the timeline (joint angle, image).
  • Segment property: one-per-episode metadata for catalog filter/search (operator, robot, site, task, date). Not per timestamp.
  • Layer: a whole derived
    .rrd
    over a base segment (FK transforms, point clouds, gripper state, labels, quality scores). Queryable as if part of base.
Static vs temporal Static belongs to all timelines and shadows any temporal value of the same component on the same entity. Use it for invariants (calibration, coordinate frames, robot meshes, annotation context, a video asset). Never make per-frame data static.
Which timeline A
timestamp
timeline (ns since epoch) for cross-sensor clock alignment, a
sequence
timeline for frame/ordinal alignment; stamp on both when useful. Do not resample to a common rate. Latest-at reconciles multi-rate streams at query time by holding each component's last sample (no interpolation).
Base vs layer Base = faithful conversion of the raw streams, nothing computed. Layer = anything derived (FK from URDF + joint states, clouds from depth + intrinsics). Keep them separate
.rrd
s.
实体 vs 现有实体上的组件 如果新对象拥有自己的空间坐标系(
Transform3D
/
Pinhole
)、自己的标注上下文,或需要独立显示/清除/共享(每个机器人连杆、每个摄像头、每个传感器),则创建新实体。若为同一实例的辅助数据(如逐点置信度),则使用同一实体+额外组件。非标准字段使用
AnyValues
属性 vs 组件 vs 层(最易混淆的点)
  • 组件:时间线上的每时间戳信号(关节角度、图像)。
  • 片段属性:每个片段的元数据,用于目录过滤/搜索(操作员、机器人、场地、任务、日期)。不属于每时间戳数据。
  • :基于基础片段生成的完整衍生.rrd文件(FK变换、点云、夹具状态、标签、质量分数)。可像基础片段的一部分一样被查询。
静态 vs 时间相关 静态数据属于所有时间线,会覆盖同一实体上同一组件的任何时间相关值。用于不变数据(校准信息、坐标系、机器人网格、标注上下文、视频资产)。切勿将每帧数据设为静态。
选择哪个时间线 使用
timestamp
时间线(纪元以来的纳秒数)实现跨传感器时钟对齐,使用
sequence
时间线实现帧/序号对齐;必要时可同时使用两个时间线。 不要重采样到统一速率。查询时,Latest-at机制会通过保留每个组件的最新样本(无插值)来协调多速率流。
基础 vs 层 基础 = 原始流的忠实转换,无任何计算内容。 层 = 任何衍生内容(URDF+关节状态的FK变换、深度图+内参生成的点云)。 将它们保存为独立的.rrd文件。

The mapping table (produce before coding)

映射表(编码前填写)

Source (topic/column/key)Entity pathArchetypeComponent(s)TimelineStatic/temporalBase/layerProperty?
mcap
/joint_states
/robot/<joint>
Scalars
scalars
sensor_time
temporalbaseno
cam0/color.mp4
/camera/cam0/video
VideoStream
codec+sample
video_time
codec static, samples temporalbaseno
calibration.json
/camera/cam0
Pinhole
(+
Transform3D
extrinsics)
image_from_camera
staticbaseno
URDF + joints (computed)
/robot/<link>
Transform3D
translation/rotation
sensor_time
temporallayerno
episode.json
operator
segmentyes
来源(主题/列/键)实体路径原型组件时间线静态/时间相关基础/层是否为属性
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 + 关节(计算生成)
/robot/<link>
Transform3D
translation/rotation
sensor_time
时间相关
episode.json
operator
segment

Patterns worth knowing

值得了解的模式

  • Transforms / FK trees: log a
    Transform3D
    per link entity; it relates to the parent path and composes down the tree. (Named
    CoordinateFrame
    +
    child_frame
    /
    parent_frame
    only when topology must be a flexible graph.)
  • Cameras: extrinsics (
    Transform3D
    ) + intrinsics (
    Pinhole
    ) on the camera entity, image/depth as children so they inherit the projection.
  • Video:
    VideoStream
    for compressed samples — the default for an mp4 (
    rerun-mp4
    ) and what the Foxglove decoder already hands you.
    AssetVideo
    +
    VideoFrameReference
    is the fallback for a codec
    VideoStream
    cannot represent.
  • Columnar ingest: for an existing file, use the matching reader (
    rerun-mcap
    /
    -parquet
    /
    -mp4
    /
    -lerobot
    ), which produces chunks directly — do not hand-assemble
    send_columns
    from a custom parser. When you do log columns directly (live logging),
    send_columns
    adds no automatic timelines, so pass every timeline you want.
  • 变换/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
    不会自动添加时间线,因此需要传入所有所需的时间线。

Gotchas that cause real failures

会导致实际故障的陷阱

  1. Component columns come back as
    ListArray
    in queries: index
    [0]
    /
    [0][0]
    (0-based DataFrame, 1-based SQL). See
    rerun-catalog-queries
    .
  2. A layer must share the segment's
    recording_id
    , or it won't attach.
    application_id
    is discarded on registration.
  3. send_columns
    /
    send_chunks
    add no
    log_time
    /
    log_tick
    ; only the timelines you pass exist.
  4. Static shadows all temporal data of that component for all time; static is overwritten in the viewer but every write stays on disk until
    rerun rrd optimize
    .
  5. One
    Transform3D
    /
    Pinhole
    relation per frame pair; logging the same relation on a second entity is rejected.
  6. Entity paths are not file paths (
    ..
    is meaningless,
    __
    is reserved).
  7. A catalog layer written with a default
    RecordingStream
    injects a
    /__properties
    (
    RecordingInfo
    ) chunk that can collide with the base segment's properties when the catalog merges layers by
    recording_id
    ; the dataset's default blueprint then stops applying on open. Construct the layer's stream with
    send_properties=False
    .
  1. 查询中组件列会以
    ListArray
    形式返回:使用索引
    [0]
    /
    [0][0]
    (DataFrame为0索引,SQL为1索引)。请参阅
    rerun-catalog-queries
  2. 层必须与片段共享
    recording_id
    ,否则无法关联。注册时
    application_id
    会被丢弃。
  3. send_columns
    /
    send_chunks
    不会添加
    log_time
    /
    log_tick
    ;仅存在你传入的时间线。
  4. 静态数据会覆盖该组件所有时间的时间相关数据;静态数据在查看器中可被覆盖,但所有写入内容会保留在磁盘上,直到执行
    rerun rrd optimize
  5. 每对帧仅能记录一个
    Transform3D
    /
    Pinhole
    关系;在第二个实体上记录同一关系会被拒绝。
  6. 实体路径不是文件路径(
    ..
    无意义,
    __
    为保留字符)。
  7. 使用默认
    RecordingStream
    编写的目录会注入一个
    /__properties
    RecordingInfo
    )块,当目录按
    recording_id
    合并层时,该块可能与基础片段的属性冲突;此时数据集的默认蓝图在打开时将不再生效。请使用
    send_properties=False
    构建层的流。