ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Rerun Range1D 编码详解:一维区间(lower/upper bound)的 Arrow 表示与 SDK 实战

Rerun Range1D 编码详解:一维区间(lower/upper bound)的 Arrow 表示与 SDK 实战 Rerun Range1D 编码详解一维区间lower/upper bound的 Arrow 表示与 SDK 实战【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun导读Range1D是 Rerun 数据模型层级中位于最底层的**编码encoding**类型用于表示一个由下界与上界构成的一维数值区间。本文以 docs/content/reference/types/encodings/range1d.md 为主体结合仓库中的类型定义、SDK 生成代码与 Viewer 组件 UI 源码深入讲解它的 Arrow 内存布局、Rust/Python/C 三端使用方式以及它在标量轴范围ScalarAxis、二维包围盒Range2D、数值范围ValueRange等场景中的实际落地用法。一、Range1D 在 Rerun 数据模型中的位置Rerun 的数据模型是分层的encodings处于最底层Encoding编码可复用的基础数据类型被组件引用Component组件由编码组合而成携带具体语义Archetype原型面向用户的高层记录单元由若干组件构成。docs/content/reference/types/encodings.md中对这一层有明确说明Data types are the lowest layer of the data model hierarchy. They are re-usable types used by the components.数据类型是数据模型层级的最底层是组件复用的基础类型。Range1D正是其中之一其官方定义只有一句话A 1D range, specifying a lower and upper bound.即一个由下界lower bound和上界upper bound共同指定的一维区间。它本身不含任何语义不关心区间代表的是坐标范围还是数值范围语义由引用它的组件赋予。二、Arrow 内存布局FixedSizeList(2 x non-null Float64)Range1D在 Apache Arrow 层面采用如下数据类型FixedSizeList(2 x non-null Float64)这意味着数据存储为一个定长列表恰好包含 2 个元素每个元素是Float6464 位双精度浮点数元素不允许为 nullnon-null即区间两端点必须成对存在。在仓库的 Rust SDK 生成代码 crates/store/re_sdk_types/src/encodings/range1d.rs 中可以看到这一布局的直接对应实现#[derive(Clone, Debug, Default, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)] #[repr(C)] pub struct Range1D(pub [f64; 2usize]);其中arrow_data_type()返回DataType::FixedSizeList( std::sync::Arc::new(Field::new(item, DataType::Float64, false)), 2, )false即对应文档中的 non-null 语义。序列化ToArrow时内部[f64; 2]被拍平写入一个FixedSizeListArray反序列化FromArrow时则会校验value_length() 2不满足直接返回DatatypeMismatch错误从源码层面保证了区间的两个端点缺一不可。该类型定义并非手写而是由类型定义文件 crates/build/re_type_definitions/rerun/encodings/range1d.def.rs 经re_types_builder自动生成到 Rust、Python、C 三端绑定中。定义文件中的关键标注包括#[rerun::rerun_type] #[arrow(transparent)] #[python(aliases npt.NDArray[Any] | npt.ArrayLike | Sequence[float] | slice)] #[rust(tuple_struct)] #[rerun(state stable)] pub struct Range1D { pub range: [f64; 2], }#[arrow(transparent)]Arrow 表示直接透传内部字段不额外包裹 StructPython 别名标量场景下可直接传Sequence[float]或slice批量场景支持Sequence[Sequence[float]]与 NumPy 数组#[rerun(state stable)]该编码本身处于stable稳定状态二进制格式具备向后兼容性。三、Rust 端实用能力INFINITY 常量、abs_len 与 emath 互转在 crates/store/re_sdk_types/src/encodings/range1d_ext.rs 中Range1D还附带了一批手写扩展方法/// Range that expands from negative infinity to positive infinity. pub const INFINITY: Self Self([f64::NEG_INFINITY, f64::INFINITY]); /// Absolute length of the range. #[inline] pub fn abs_len(self) - f64 { (self.0[1] - self.0[0]).abs() }值得注意的细节Range1D::INFINITY表示从负无穷到正无穷的全程区间常用于未显式指定范围、交给系统自动计算的占位场景abs_len()取上界减下界的绝对值因此它不要求min max即便传入逆序区间也能得到正的区间长度实现了与emath::Rangef的双向转换Fromemath::Rangef for Range1D与反向转换后者是 egui 生态中表示一维范围的常用类型——这为 Viewer 内部将Range1D直接桥接到 UI 拖拽控件铺平了道路。同时生成的impl From[f64; 2usize] for Range1D与反向FromRange1D for [f64; 2usize]让用户在 Rust 中可以用最直观的数组字面量构造区间let range Range1D([0.0, 10.0]); let [min, max]: [f64; 2] range.into();四、谁在使用 Range1D组件与更高层类型的引用链原文档的 Used by 一节列出了三类使用者它们在仓库中均有对应定义1.components.Range1D组件transparent 包装文档页 表明该组件直接以Range1D编码作为其 Rerun 编码Arrow 类型与编码完全一致。其类型定义 crates/build/re_type_definitions/rerun/components/range1d.def.rs 中标注了#[rust(repr transparent)]即组件在内存布局上就是编码本身只是附带了这是一个组件的语义身份。2.encodings.Range2D二维包围盒由两个 Range1D 拼成Range2D 文档 定义其为 2D 空间的轴对齐包围盒AABB由最小角点与最大角点实现内部正是两个Range1Dpub struct Range2D { /// The range of the X-axis (usually left and right bounds). pub x_range: rerun::encodings::Range1D, /// The range of the Y-axis (usually top and bottom bounds). pub y_range: rerun::encodings::Range1D, }对应定义见 crates/build/re_type_definitions/rerun/encodings/range2d.def.rs。其 Arrow 类型也顺理成章地展开为两个FixedSizeList(2 x non-null Float64)字段组成的 Struct。3.components.ValueRange数值的有效/期望取值范围ValueRange 文档 描述为Range of expected or valid values期望或有效数值的范围同样以Range1D编码承载并被以下 archetype 引用DepthImage深度图像EncodedDepthImage编码深度图像Tensor张量VoxelGridMap体素栅格地图例如深度图像常常只在一个有限深度范围内包含有效数据ValueRange正是用来记录该范围便于 Viewer 据此做颜色映射与裁剪。注意该组件在文档中标注为unstable带 ⚠️ 警告未来可能在二进制层面发生不向后兼容的变更使用时需留意版本升级。五、实战场景ScalarAxis 蓝图中的 Y 轴范围配置Range1D最典型的落点之一是时间序列图plot的 Y 轴范围配置。在蓝图类型定义 crates/build/re_type_definitions/rerun/blueprint/archetypes/scalar_axis.def.rs 中pub struct ScalarAxis { /// The range of the axis. /// If unset, the range will be automatically determined based on the queried data. #[rerun(optional)] pub range: Optionrerun::components::Range1D, /// If enabled, the Y axis range will remain locked to the specified range when zooming. #[rerun(optional)] pub zoom_lock: Optionrerun::blueprint::components::LockRangeDuringZoom, }两个关键点range是可选项不设置时 Viewer 根据查询到的数据自动计算 Y 轴范围设置后则由你显式指定[min, max]zoom_lock决定缩放时是否将 Y 轴锁定在指定范围内。对应地Viewer 侧的 UI 编辑逻辑位于 crates/viewer_support/re_component_ui/src/encoding_uis/range1d.rs它把Range1D渲染为两个egui::DragValue分别编辑 min 与 max中间以-连接let range (*max - *min).abs(); let speed (range * 0.01).at_least(0.001); let response_min ui.add( egui::DragValue::new(min) .clamp_existing_to_range(false) .range(f64::NEG_INFINITY..*max) .speed(speed), ); ui.label(-); let response_max ui.add( egui::DragValue::new(max) .clamp_existing_to_range(false) .range(*min..f64::INFINITY) .speed(speed), );从这段代码可以推断出 Viewer 在 UI 层对区间施加的约束min 始终 ≤ maxmin 的拖拽上界被钳制在 maxmax 的拖拽下界被钳制在 min且拖拽步长speed按区间长度的 1%最小 0.001自适应区间越小步长越精细。这解释了为什么底层abs_len()允许逆序区间但交互层仍会引导用户维护有序端点。六、多语言 API 快速上手Range1D在三种官方 SDK 中均可直接构造Python依据 crates/build/re_type_definitions/rerun/encodings/range1d.def.rs 中的别名标注from rerun.encodings import Range1D # 序列 / 切片 / 类数组均可作为别名输入 r Range1D([0.0, 10.0]) # 等价于 Range1D(slice(0.0, 10.0)) r Range1D((5.0, 15.0)) # 批量为多个实体各设置一个区间 batch Range1D([[0.0, 10.0], [5.0, 15.0]])Rustuse re_sdk::encodings::Range1D; let range Range1D([0.0, 10.0]); let span range.abs_len(); // 10.0 let full Range1D::INFINITY; // [-∞, ∞]Crerun::encodings::Range1D提供同名结构同样以两个double组成的区间构造详见仓库 rerun_cpp 的对应头文件。需要强调的是多数情况下你无需直接操作Range1D而是通过其上层组件如ScalarAxis.range、ValueRange间接使用Range1D扮演的是统一区间表示的底层角色保证三端 SDK 与 Viewer 之间交换区间数据时格式完全一致。七、稳定性与适用边界encodings.Range1D与components.Range1D均标注为stable二进制布局稳定可放心用于长期存储与跨版本回放components.ValueRange为unstable仅限当前版本内使用底层f64双精度意味着它适合表示连续浮点区间坐标、深度、数值标度而不适用于整数枚举或离散索引区间——这类需求应使用整数族编码类型区间端点要求为非空non-null若需要半开区间仅指定一端的语义需要结合Range1D::INFINITY或上层类型另行表达。总结Range1D虽小却是 Rerun 数据模型中区间这一抽象的统一载体它以FixedSizeList(2 x non-null Float64)的紧凑 Arrow 布局存储两个双精度端点向上支撑了 Range1D 组件、Range2D 包围盒与 ValueRange 数值范围并直接驱动了时间序列图中 Y 轴范围的显式配置。理解了它的内存布局、扩展方法与引用链你就能在三端 SDK 中自信地处理一切一个下界、一个上界的数据需求。延伸阅读数据模型分层总览见 docs/content/reference/types/encodings.md组件与 archetype 引用关系可对比 Range2D 文档、Range1D 组件文档 与 ValueRange 文档。【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表