news 2026/9/16 18:34:30

Rerun RecordingInfo 详解:记录级属性的定义、字段语义与多语言写入方式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Rerun RecordingInfo 详解:记录级属性的定义、字段语义与多语言写入方式

Rerun RecordingInfo 详解:记录级属性的定义、字段语义与多语言写入方式

【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun

RecordingInfo是 Rerun 类型系统中一个状态为 stable 的 Archetype,用于描述一条 recording(录制/采集会话)自身的元属性,包含可选的start_timename两个字段。在 Rerun 的 properties 机制中,它作为内建属性被自动存入保留实体路径/__properties,并可作为 segment 表的列用于过滤、排序与数据表查询。读完本篇,你将能够理解该 archetype 的字段定义与生成机制,掌握 Rust / Python / C++ 三种 SDK 下写入录制名称、覆盖起始时间、附加自定义属性的完整写法,并从源码层面看清send_recording_name等便捷 API 是如何落到RecordingInfo的 partial 更新上的。

RecordingInfo 是什么:archetype 定义与字段语义

根据类型定义源文件 recording_info.def.rs,RecordingInfo的注释原文是 "A list of properties associated with a recording.",并带有如下关键标注:

  • #[rerun(state = "stable")]:API 已稳定,可用于生产数据管线;
  • #[rerun(visualizer_none)]:它不是可视化数据,不参与任何 visualizer 的渲染,仅作为数据/元数据存在;
  • 两个字段均为#[rerun(optional)],即没有任何必填组件。

字段语义如下:

字段组件类型必填性说明
start_timeTimestamp可选录制开始时间。应当是绝对时间,即相对于 Unix Epoch 的时间戳(纳秒级)
nameName可选用户自定义的录制名称,用于区分不同 episode/会话

从 recording_info.rs 的生成代码可以确认组件构成:NUM_COMPONENTS: usize = 2,其中 0 个必填、0 个推荐、2 个可选;archetype 全名为rerun.archetypes.RecordingInfo,两个组件描述符分别为RecordingInfo:start_time(组件类型rerun.components.Timestamp)与RecordingInfo:name(组件类型rerun.components.Name)。由于全部字段可选,RecordingInfo::new()返回的两个字段均为None,这意味着它既可以整体记录,也可以通过 partial 更新只写其中一个字段——这正是 SDK 便捷 API 的工作方式,后文会展开。

写入录制属性:Rust / Python / C++ 完整示例

官方示例concepts/recording_properties展示了三种语言下设置录制属性的完整流程,核心模式一致:设置名称、覆盖起始时间、附加基于现有 archetype 的自定义属性、附加基于任意数据的自定义属性,最后演示属性(含名称)可被随时覆盖。

Rust

来源:recording_properties.rs

fn main() -> Result<(), Box<dyn std::error::Error>> { let rec = rerun::RecordingStreamBuilder::new( "rerun_example_recording_properties", ) .spawn()?; // 录制可以有可选名称 rec.send_recording_name("My recording")?; // 起始时间会被自动设置,但随时可以覆盖 rec.send_recording_start_time(1742539110661000000)?; // 使用现有 Rerun 类型,为录制添加用户自定义属性 rec.send_property( "camera_left", &rerun::archetypes::Points3D::new([[1.0, 0.1, 1.0]]), )?; let other = rerun::AnyValues::default() .with_component_from_data( "confidences", Arc::new(arrow::array::Float64Array::from(vec![0.3, 0.4, 0.5, 0.6])), ) .with_component_from_data( "traffic", Arc::new(arrow::array::StringArray::from(vec!["low"])), ) .with_component_from_data( "weather", Arc::new(arrow::array::StringArray::from(vec!["sunny"])), ); // 再添加一个属性,这次是用户自定义数据 rec.send_property("situation", &other)?; // 属性(包括名称)随时可以被覆盖 rec.send_recording_name("My episode")?; Ok(()) }

要点说明:

  • send_recording_start_time接收impl Into<Timestamp>,示例中的1742539110661000000是纳秒级绝对时间戳;
  • send_property(name, value)value可以是任意实现了AsComponents的类型(archetype、AnyValues等),因此属性值不受限于RecordingInfo的两个内建字段;
  • 名称可以多次发送,后发覆盖先发,示例末尾把 "My recording" 改成了 "My episode"。

Python

来源:recording_properties.py

import rerun as rr rec = rr.RecordingStream("rerun_example_recording_properties") rec.spawn() # 覆盖上方设置的名称 rec.send_recording_name("My recording") # 起始时间会被自动设置,但随时可以覆盖 rec.send_recording_start_time_nanos(1742539110661000000) # 使用现有 Rerun 类型,为录制添加用户自定义属性 rec.send_property( "camera_left", rr.archetypes.Points3D([[1.0, 0.1, 1.0]]), ) # 再添加一个属性,这次是用户自定义数据 rec.send_property( "situation", rr.AnyValues( confidences=[0.3, 0.4, 0.5, 0.6], traffic="low", weather="sunny", ), ) # 属性(包括名称)随时可以被覆盖 rec.send_recording_name("My episode")

注意 Python 的起始时间 API 显式命名为send_recording_start_time_nanos,单位语义(纳秒)直接体现在函数名中。

C++

来源:recording_properties.cpp。C++ 侧没有AnyValues风格的便捷封装,自定义数据需通过 Arrow 构造ComponentBatch后传入send_property

const auto rec = rerun::RecordingStream("rerun_example_recording_properties"); rec.spawn().exit_on_failure(); rec.send_recording_name("My recording"); rec.send_recording_start_time_nanos(1742539110661000000); auto points = rerun::Points3D({{1.0f, 0.1f, 1.0f}}); rec.send_property("camera_left", points); // 自定义数据:用 Arrow builder 构造组件数组 arrow::DoubleBuilder confidences_builder; ARROW_RETURN_NOT_OK(confidences_builder.AppendValues({0.3, 0.4, 0.5, 0.6})); ARROW_RETURN_NOT_OK(confidences_builder.Finish(&arrow_array)); auto confidences = rerun::ComponentBatch::from_arrow_array( std::move(arrow_array), "confidences"); // ... traffic / weather 同理构造后: rec.send_property("situation", confidences, traffic, weather); rec.send_recording_name("My episode");

源码剖析:send_recording_name 如何落到 RecordingInfo

Rust SDK 中三个便捷 API 的实现位于 recording_stream.rs:

/// Sends a property to the recording. pub fn send_property<AS: ?Sized + AsComponents>( &self, name: impl Into<String>, values: &AS, ) -> RecordingStreamResult<()> { let sub_path = EntityPath::from(name.into()); self.log_static(EntityPath::properties().join(&sub_path), values) } /// Sends the name of the recording. pub fn send_recording_name(&self, name: impl Into<String>) -> RecordingStreamResult<()> { let update = RecordingInfo::update_fields().with_name(name.into()); self.log_static(EntityPath::properties(), &update) } /// Sends the start time of the recording. pub fn send_recording_start_time( &self, timestamp: impl Into<Timestamp>, ) -> RecordingStreamResult<()> { let update = RecordingInfo::update_fields().with_start_time(timestamp.into()); self.log_static(EntityPath::properties(), &update) }

从源码结构可以读出三层信息:

  1. 静态(static)语义:三个 API 都走log_static,即数据不关联时间轴。这与 properties 的语义一致——属性描述整条录制而非某个时刻,相关概念文档见 properties-and-segments.md。
  2. partial 更新机制send_recording_name内部先调用RecordingInfo::update_fields()(返回所有字段为None的实例),再只with_name(...)。由于该 archetype 没有必填组件,这条行只会携带RecordingInfo:name一个组件,不会把start_time清空。这也解释了为什么"名称与起始时间可以分别、反复覆盖而互不干扰"。
  3. 保留实体路径:内建属性直接记录在EntityPath::properties()(即/__properties)下,自定义属性则拼接为/__properties/<name>。文档同时明确不建议直接往该路径写数据,应通过send_property/send_recording_name等 API 完成。

另外,properties-and-segments.md 说明start_time会被 Rerun 自动填充——即不手动调用send_recording_start_time时该字段也有值,手动调用属于"覆盖"而非"首次设置"。

展示与查询:DataframeView 与 segment 表

按参考文档,RecordingInfo可以在 DataframeView 中展示。更实际的消费路径有两条:

  • 数据表(dataframe)查询:属性默认被排除在实体过滤之外,显式包含/__properties/**后即可查询,属性列名遵循property:$property_name:$Archetype:$field规则;内建属性省略$property_name段,因此RecordingInfo的两个字段呈现为property:RecordingInfo:nameproperty:RecordingInfo:start_time
  • catalog 的 segment 表:录制注册进数据集后,每个属性成为 segment 表的一列(每行一个录制)。由于 segment 表是 DataFusion DataFrame,可以直接用标准 DataFrame 操作按属性值过滤,例如按property:RecordingInfo:name筛选特定会话。从查询输出示例可见,列元数据中还带有archetype: RecordingInfocomponent: RecordingInfo:nameentity_path: /__properties等信息,与上文ComponentDescriptor的定义一一对应。

生成机制与类型定义

RecordingInfo属于 Rerun 类型系统的多语言绑定来源之一:定义文件 recording_info.def.rs 本身不可执行,由re_types_builder解析后生成 Rust(recording_info.rs 顶部即标注 "DO NOT EDIT! This file was auto-generated...")、Python 与 C++ 三侧绑定,参考文档页(即 recording_info.md)本身也是由 website.rs 自动生成。因此当你看到文档、API 与源码之间的字段说明时,它们都以同一个.def.rs为唯一事实来源;修改字段语义需要改定义文件并重新生成绑定,而不能手改生成物。

在 Rust 侧直接使用 archetype(而非便捷 API)时,生成的构造函数还提供:

  • RecordingInfo::new()/update_fields():全None的起点,适合只写单个字段;
  • with_start_time(impl Into<Timestamp>)/with_name(impl Into<Name>):链式设置单值;
  • with_many_start_time/with_many_name:一次打包多个值,配合columns()分片,适合列式批量写入;
  • clear_fields():用空 Arrow 数组显式清空各字段。

小结

  • RecordingInfo是一个 0 必填、2 可选组件的 stable archetype,字段start_time(绝对 Unix 纳秒时间戳)与name(用户命名)均为可选;
  • 写入入口为各语言 SDK 的send_recording_name/send_recording_start_time(_nanos),底层是"对/__properties下的RecordingInfo做 static 的 partial 更新";自定义属性走send_property,值可以是任意 archetype 或AnyValues自定义数据;
  • start_time由 Rerun 自动填充、可随时覆盖;所有属性在数据表查询与 catalog segment 表中以property:RecordingInfo:*列名暴露,可直接用于过滤与分析。

【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 18:34:18

公益培训报名小程序开发实战:uni-app+Spring Boot实现名额管理

简介&#xff1a;这是一份面向文化馆、图书馆、文体中心、青少年活动中心、少年宫等公益机构的微信小程序报名系统设计源码&#xff0c;用于发布公告通知、展示课堂风采、维护报名列表并完成在线报名登记&#xff0c;解决公益培训活动组织中的报名管理难题。压缩包共464个文件&…

作者头像 李华
网站建设 2026/9/16 18:33:37

AT24C02+1602LCD按键计数:从I2C时序到断电存储的完整方案

简介&#xff1a;一份基于89C51/89C52单片机的AT24C02读写应用资源&#xff0c;面向51单片机学习者和电子设计入门者&#xff0c;演示如何将按键次数写入AT24C02存储芯片&#xff0c;再读出并显示在1602LCD液晶屏上。工程基于Keil5编写C语言程序&#xff0c;配套Proteus 7.8仿真…

作者头像 李华
网站建设 2026/9/16 18:32:50

两层神经网络:深度学习最简完备认知单元

1. 项目概述&#xff1a;为什么从“两层神经网络”开始&#xff0c;是理解深度学习真正的起点如果你翻过任何一本《深度学习》教材&#xff0c;或者点开过吴恩达Deep Learning Specialization系列课程的第五课&#xff0c;第一眼看到“05 两层神经网络”这个标题&#xff0c;大…

作者头像 李华
网站建设 2026/9/16 18:31:09

从红包到AI补贴:互联网营销的技术演进与商业逻辑

1. 从红包大战到AI补贴&#xff1a;互联网营销的十年轮回2014年春节&#xff0c;微信红包横空出世&#xff0c;一夜之间绑卡量突破1亿&#xff0c;被马云称为"珍珠港偷袭"。这场红包大战彻底改变了中国互联网的营销玩法&#xff0c;也拉开了移动支付普及的大幕。十年…

作者头像 李华
网站建设 2026/9/16 18:30:56

鸿蒙开发者激励计划:技术扶持与商业变现全解析

1. 鸿蒙开发者激励计划全景解析作为华为生态建设的核心战略&#xff0c;鸿蒙开发者激励计划自推出以来就备受业界关注。这个计划绝不仅仅是简单的补贴政策&#xff0c;而是一套从技术赋能到商业闭环的完整解决方案。我接触过不少从Android转型鸿蒙的开发者&#xff0c;他们最关…

作者头像 李华
网站建设 2026/9/16 18:30:52

安卓地理围栏与传感器融合开发实战

简介&#xff1a;这是一份面向安卓开发初学者的实战学习项目&#xff0c;基于《一起来捉妖》游戏设计辅助定位与自动捉妖功能&#xff0c;聚焦移动应用逆向分析、自动化测试与虚拟定位技术实践。资源涵盖完整Android Studio工程&#xff0c;包含163张界面截图与图标资源&#x…

作者头像 李华