docs/content/howto/logging-and-ingestion/urdf.md
Rerun features a built-in data-loader for URDF files.
<picture style="zoom: 0.5"> <source media="(max-width: 480px)" srcset="https://static.rerun.io/urdf-viewer/ebdefa158ab6f26f9dc1cb1924fce4b846fe8db2/480w.png"> <source media="(max-width: 768px)" srcset="https://static.rerun.io/urdf-viewer/ebdefa158ab6f26f9dc1cb1924fce4b846fe8db2/768w.png"> <source media="(max-width: 1024px)" srcset="https://static.rerun.io/urdf-viewer/ebdefa158ab6f26f9dc1cb1924fce4b846fe8db2/1024w.png"> </picture>Using a URDF in Rerun only requires you to load the file with the logging API.
This will automatically invoke the data-loader, which will take care of:
Once that is done, the joints can be updated by sending Transform3Ds, where you have to set the parent_frame and child_frame fields explicitly to each joint's specific frame IDs.
⚠️ Note: previous versions (< 0.28) required you to send transforms with implicit frame IDs, i.e. having to send each joint transform on a specific entity path. This was dropped in favor of named frame IDs, which is more in line with ROS and allows you to send all transform updates on one entity (e.g. a
transformsentity like in the example below).
Here is an example that demonstrates how to load and update a URDF with the Python SDK:
snippet: howto/load_urdf
For a full animation example, see the Python animated URDF example. There's also a Rust example.
Rerun provides the rr.urdf Python module that can facilitate the handling of URDF models in your code.
It can be used as an alternative to other 3rd-party packages like yourdfpy or pytransforms3d.
As shown below, you can use it e.g. to access individual joints of the URDF model and to compute their respective transforms based on joint states (e.g. angles for revolute joints).
These transforms can be directly sent to Rerun.
Load a URDF file and access its structure:
urdf_tree = rr.urdf.UrdfTree.from_file_path("robot.urdf", entity_path_prefix=None)
# Access properties
robot_name = urdf_tree.name
root_link = urdf_tree.root_link()
joints = urdf_tree.joints()
# Lookup by name
urdf_tree.get_joint_by_name("shoulder")
urdf_tree.get_link_by_name("base_link")
# Get the entity paths of collision or visual geometries of a link.
# This can be used for example to update the color / transparency during runtime:
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)
When loading the same URDF multiple times (e.g. a dual-arm setup), use frame_prefix to give each instance unique frame IDs and entity_path_prefix to separate their geometry in the entity tree. Use log_urdf_to_recording() to log the model with prefixed frame IDs:
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()
Transforms computed via joint.compute_transform() will automatically use the prefixed frame IDs (e.g. "left/base", "right/shoulder").
Each joint exposes properties from the URDF file:
namejoint_type (e.g. revolute, continuous, prismatic, fixed)parent_link, child_linkaxis, origin_xyz, origin_rpylimit_lower, limit_upper, limit_effort, limit_velocityUse compute_transform() to get a Transform3D with the correct parent_frame and child_frame already set:
# For revolute/continuous joints: pass angle in radians
# For prismatic joints: pass distance in meters
transform = joint.compute_transform(angle)
rec.log("transforms", transform)
If you already have a recording with transforms loaded in Rerun and want to add an URDF to it, you can do so via drag-and-drop or the menu ("Import into current recording").
In this video, we load an ROS 2 .mcap file with TF messages that automatically get translated into Rerun Transform3D.
As indicated by the errors displayed in the viewer, there are some connections missing in the transform tree of this example MCAP.
In our case, these missing transforms are static links that are stored in URDF models separate from the MCAP file.
To add them, we can simply drag the corresponding URDF files into the viewer where we have loaded the MCAP:
<video width="100%" autoplay loop muted controls> <source src="https://static.rerun.io/69e08d9dcaed77f5f93190ffb9ccf75376c7d1c4_urdf_drag_and_drop.mp4" type="video/mp4" /> </video>