Rerun 加载与驱动 URDF 机器人模型实战:内置导入器、命名帧 Transform3D 与 rr.urdf 工具
2026/9/16 13:15:00 网站建设 项目流程

Rerun 加载与驱动 URDF 机器人模型实战:内置导入器、命名帧 Transform3D 与 rr.urdf 工具

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

Rerun 针对 ROS 生态中最常见的机器人描述格式 URDF(Unified Robot Description Format)内置了一个文件导入器:只要把.urdf文件交给日志 API(Python / Rust / C++ 的log_file_from_path),它就会自动解析网格引用、加载几何体为 Rerun 实体、并为每个 link 生成带 frame ID 的关节变换。读完本文你将掌握:URDF 导入器在底层做了什么、如何在运行时用命名帧的Transform3D驱动关节运动、如何用rr.urdf.UrdfTree访问关节/连杆结构并计算关节变换,以及如何把 URDF 合并进一个已经打开的录制(例如 ROS 2 MCAP)中。

内置 URDF 导入器与一次导入背后发生的事情

Rerun 内置了面向 URDF 的UrdfImporter(导入器名称为rerun.importers.Urdf),实现在 crates/data_flow/re_importer/src/importer_urdf/mod.rs。在导入器框架中,所有导入器都会被无条件通知待打开的文件路径,URDF 导入器通过检查扩展名(不区分大小写的urdf)决定是否接手该文件,不匹配则返回ImporterError::Incompatible。这与 导入器总览 中描述的内置/外部/自定义三类导入器机制一致。

在 Rerun 中使用 URDF 非常简单——只需用日志 API 加载文件,导入器会自动完成三件事:

  • 解析网格(mesh)的路径引用并加载它们;
  • 把网格与基本几何体(box、cylinder、capsule、sphere)作为 Rerun 实体加载;
  • 加载各 link 的关节变换(joint transforms)以及对应的 frame ID。

实体路径布局

从 urdf_tree.rs 中UrdfLogPaths::new的源码可以看到模型被组织到几个固定的实体路径下(entity_path_prefix可选):

内容默认实体路径说明
机器人根坐标系{robot_name}(可加前缀)CoordinateFrame标记,值为 root link 的 frame ID
视觉几何体{prefix}{robot_name}/visual_geometries/{link}/{visual_name}便于整体切换视觉几何体显隐
碰撞几何体{prefix}{robot_name}/collision_geometries/{geometry_type}/{link}/{collision_name}按几何类型分目录,可单独隐藏某类碰撞体(如只隐藏 mesh 保留基本体)
静态关节变换/tf_static所有默认变换集中到同一个实体路径,且不受entity_path_prefix影响

所有静态关节变换会被合并为一个 chunk 批量写入/tf_static(见emit_static_transforms_batch)。源码注释明确说明“对 URDF 总是以 static 方式写入”,这样用户后续可以在任意自己选择的变换实体上覆盖它们。

网格资源如何被解析

load_ros_resource支持四种资源寻址方式:

  • 相对路径:相对.urdf文件所在目录解析;
  • file://协议:直接读取本地绝对路径;
  • package://协议:在ROS_PACKAGE_PATH(ROS 1)和AMENT_PREFIX_PATH(ROS 2)中查找<entry>/pkg_name<entry>/share/pkg_name,适用于 ROS 包内引用的网格(见resolve_package_uri);
  • http(s)://协议:通过 HTTP 下载网格,连接超时 30 秒,且单次下载有 512 MiB 的内存保护上限(MAX_MESH_DOWNLOAD_SIZE)。

对于无法解析的网格资源,导入不会整体失败:错误会被收集并按原因汇总、去重后以警告形式输出(例如“Could not resolve package URI…”),其余 link、joint 与几何体照常导入。这一点有端到端测试佐证:test_urdf_importer.rs 中的test_urdf_importer_dangling_mesh专门验证“网格无法加载时其余实体仍然全部产出,且不会发出任何Asset3D”。另外在 WebAssembly 目标上,ROS 资源加载不可用(返回UnsupportedInWasm)。

几何体与材质的映射

emit_geometry给出了 URDF 几何类型到 Rerun 原语/资产的映射关系:

URDF 几何Rerun 输出
meshAsset3D(按扩展名猜测 MediaType),支持albedo_factor
boxBoxes3D,带颜色
cylinderCylinders3D(URDF 与 Rerun 都以 Z 为主轴)
capsuleCapsules3D(同上)
sphereEllipsoids3D,带颜色

材质处理上,优先使用 visual 内联定义的 color/texture,否则回退到按名称查找全局<material>;未指定颜色时回退为白色。纹理(texture)目前未支持,会输出一次性警告(源码中的warn_once!("Material texture not supported"))。碰撞几何体不携带材质,统一按白色渲染。

用命名帧的 Transform3D 更新关节

模型加载完成后,关节的驱动方式是通过发送[Transform3D](https://link.gitcode.com/i/45e8ba7e4c8c00777da1c66c744bf20a)完成的,关键要求是:必须显式设置parent_framechild_frame为每个关节对应的 frame ID(URDF 中即 parent link 与 child link 的名字)。

版本提示(≥ 0.28 的行为变化)0.28 之前的版本要求使用“隐式 frame ID”,即把每个关节的变换分别发送到特定实体路径上。该方案已被命名 frame ID取代,这与 ROS 的 TF 语义更一致,并且允许你在一个实体(例如示例中的transforms实体)上发送全部关节的变换更新。

下面是一个最小可运行的加载并更新关节的 Python 示例,来自文档配套片段 docs/snippets/all/howto/load_urdf.py:

from pathlib import Path import rerun as rr from rerun import RecordingStream with RecordingStream("rerun_example_load_urdf") as rec: rec.spawn() # `log_file_from_path` 会自动调用内置的 URDF 导入器。 urdf_path = Path(__file__).parent / "minimal.urdf" rec.log_file_from_path(urdf_path, static=True) # 可选的 flush:确保 URDF 加载完成后再继续后续日志。 rec.flush() # 后续在日志代码中,用 Transform3D 更新关节。 joint_axis = [0, 0, 1] # 取自 URDF joint_angle = 1.216 # 弧度 origin_xyz = [0, 0, 0.1] # 取自 URDF # 务必保证 parent_frame / child_frame 与 URDF 中关节的 frame ID 一致。 rec.log( "transforms", rr.Transform3D( rotation=rr.RotationAxisAngle(axis=joint_axis, angle=joint_angle), translation=origin_xyz, parent_frame="base_link", child_frame="child_link", ), )

Rust 与 C++ SDK 同样通过RecordingStream::log_file_from_path触发同一套内置导入器,之后也以Transform3D(含parent_frame/child_frame)更新关节。

完整动画示例:animated_urdf

文档推荐了两个可直接运行的动画示例:

  • Python 版 animated_urdf:python -m animated_urdf
  • Rust 版 animated_urdf:加载并驱动同一份so100.urdf机械臂

以 Python 版为例,它的核心循环展示了几种典型用法:

  1. 一次性加载模型rec.log_file_from_path(urdf_path),然后用rr.urdf.UrdfTree.from_file_path(urdf_path)把 URDF 结构读入内存;
  2. 隐藏碰撞几何体:通过 blueprint 对so_arm100/collision_geometries设置rrb.EntityBehavior(visible=False),这正是前文实体路径布局中“视觉/碰撞分离”设计的目的;
  3. 逐关节驱动:对每个revolute关节用joint.compute_transform(angle, clamp=True)计算变换并rec.log("transforms", transform)——compute_transform会自动填好 frame ID,无需手动指定;
  4. 运行期修改材质:通过urdf_tree.get_joint_child(joint)拿到关节的子 link,再对get_visual_geometry_paths(link)返回的每个视觉几何体路径,用rr.Asset3D.from_fields(albedo_factor=rgba)按关节角度动态改颜色/透明度(示例中“jaw”关节的夹爪颜色随角度从红渐变到绿);
  5. 假关节角度_fake_angle使用joint.limit_lower/joint.limit_upper生成在限位内振荡的正弦角,模拟真实测量数据。

Python URDF 工具:rr.urdf

除了导入器,Rerun 还在 Python 侧提供了 rerun_py/rerun_sdk/rerun/urdf.py 模块(即rr.urdf),可作为yourdfpypytransform3d等第三方包之外的轻量替代。它的底层是rerun_bindings中暴露的_UrdfTreeInternal/_UrdfJointInternal等原生绑定,再封装为符合 Rerun 日志语义的高层 API。

UrdfTree:加载并访问模型结构

urdf_tree = rr.urdf.UrdfTree.from_file_path("robot.urdf", entity_path_prefix=None) # 访问属性 robot_name = urdf_tree.name root_link = urdf_tree.root_link() joints = urdf_tree.joints() # 按名字查找 urdf_tree.get_joint_by_name("shoulder") urdf_tree.get_link_by_name("base_link") # 获取某个 link 的视觉/碰撞几何体实体路径, # 可用于运行期修改颜色/透明度: for visual_path in urdf_tree.get_visual_geometry_paths("gripper"): rec.log(visual_path, rr.Asset3D.from_fields(albedo_factor=[255, 0, 0, 100]), static=True)

UrdfTree.from_file_path的完整签名还支持三个配置参数(源码见 urdf.py):

参数作用
entity_path_prefix可选,给几何体实体路径加前缀
frame_prefix可选,给所有 frame ID 加前缀,用于多次加载同一份 URDF
static_transform_entity_path可选,静态变换写入的实体路径,默认/tf_static不受entity_path_prefix影响

UrdfTree还提供get_joint_child(joint)(取关节子 link)、log_urdf_to_recording()(把完整模型——几何体 + 静态变换——写入录制,是log_file_from_path在需要frame_prefix等额外配置时的替代方案)、stream()(实验性的惰性 chunk 流)等接口。

多机器人场景:frame prefix

当需要把同一份 URDF 加载多次(例如双臂设置)时,用frame_prefix让每份实例的 frame ID 唯一,用entity_path_prefix在实体树中隔离几何体,然后通过log_urdf_to_recording()写入带前缀 frame ID 的模型:

left = rr.urdf.UrdfTree.from_file_path("robot.urdf", entity_path_prefix="left", frame_prefix="left/") right = rr.urdf.UrdfTree.from_file_path("robot.urdf", entity_path_prefix="right", frame_prefix="right/") left.log_urdf_to_recording() right.log_urdf_to_recording()

之后通过joint.compute_transform()计算出的变换会自动带上前缀 frame ID(例如"left/base""right/shoulder")。这正是 animated_urdf 示例中--dual模式的实现方式:左右臂分别以left/right/前缀加载,再各自rec.log("left", rr.Transform3D(translation=[-0.2, 0, 0]), static=True)平移错开位置。

UrdfJoint:读取关节属性并计算变换

每个关节都暴露了来自 URDF 文件的属性:

  • name
  • joint_type(如revolutecontinuousprismaticfixed
  • parent_linkchild_link
  • axisorigin_xyzorigin_rpy
  • limit_lowerlimit_upperlimit_effortlimit_velocity
  • mimic:若该关节带<mimic>标签,返回UrdfMimic(含jointmultiplieroffset,语义为value = multiplier * driver_value + offset),否则为None

compute_transform()得到Transform3D,其parent_framechild_frame已自动设置好:

# 对 revolute / continuous 关节传入弧度角 # 对 prismatic 关节传入平移距离(米) transform = joint.compute_transform(angle) rec.log("transforms", transform)

compute_transform(value, clamp=True)的行为细节对应底层实现 joint_transform.rs:revolute 关节在值超出[limit_lower, limit_upper]时会被钳制(clamp)并产生一条警告(clamp=False时不做钳制、不警告);continuous 关节没有限位因此不检查;变换由 origin 姿态与绕关节轴axis的动态旋转(轴角)组合而成,prismatic 关节则在 origin 平移基础上叠加沿轴的位移。

此外UrdfJoint还提供面向批量数据的两组方法:

  • compute_transform_columns(values, clamp=True):对同一关节的多个值批量计算,返回列式(columnar)数据,可直接配合rerun.send_columns使用,适合一次性发送整段关节轨迹;
  • UrdfTree.compute_joint_transform_batches(names, values, clamp=False):接收 ArrowListArray(关节名 + 关节值,按行成对),输出包含translationquaternionparent_framechild_frameListArray,源码注释说明这是为 lens(查询/变换流水线)设计的辅助接口——下游通常再接一个把每个 batch 展开成最终Transform3D行的 lens。

把 URDF 加载进已有的录制

如果 Rerun 中已经打开了一个带变换的录制,想往里追加 URDF,可以通过拖拽文件进 Viewer,或使用菜单中的“Import into current recording”实现。

一个典型场景:加载 ROS 2 的.mcap文件时,TF 消息会被自动翻译为 Rerun 的Transform3D,但示例 MCAP 的变换树中会缺失一些连接(Viewer 中会以错误形式提示这些缺失的静态变换)。这些缺失的静态变换往往存放在与 MCAP 分离的 URDF 模型里。此时只需把对应的 URDF 文件直接拖入已加载 MCAP 的 Viewer 窗口,缺失的静态 link 就会补上,变换树随之闭合。

参考与进一步阅读

  • 三种语言统一的文件入口:Pythonrerun.log_file_from_path、RustRecordingStream::log_file_from_path、C++RecordingStream::log_file_from_path
  • 导入器框架总览:了解内置/外部/自定义三类导入器及扩展方式;
  • Transform3D 原型参考:parent_frame/child_frame/旋转/平移的完整字段说明;
  • Rust 端导入器实现 与 URDF 树构造、关节变换计算;
  • 导入器端到端测试:验证网格悬空(dangling mesh)时导入仍能容错完成;
  • 配套片段资源:load_urdf.py 与 minimal.urdf(仓库中以 Git LFS 指针形式存储);
  • 完整动画示例:Python animated_urdf 与 Rust animated_urdf。

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询