URDF(Unified Robot Description Format),这是机器人领域中用于描述机器人模型的标准 XML 格式。
1. URDF 概述
URDF 是 ROS(Robot Operating System)中用于描述机器人结构的标准格式。它使用 XML 格式定义机器人的:
- 连杆(Links):机器人的刚性部件
介绍 URDF(Unified Robot Description Format),ROS 中描述机器人结构的 XML 标准。涵盖 Link、Joint、Transmission 等核心元素,对比 URDF 与 SDF,介绍 Xacro 宏扩展解决代码重复问题,并提供语法检查、RViz 可视化工具及 Python 解析示例。最后总结命名规范、坐标系标准及模块化设计最佳实践。
URDF(Unified Robot Description Format),这是机器人领域中用于描述机器人模型的标准 XML 格式。
URDF 是 ROS(Robot Operating System)中用于描述机器人结构的标准格式。它使用 XML 格式定义机器人的:
<?xml version="1.0"?>
<robot name="my_robot">
<!-- 材料定义 -->
<material name="blue">
<color rgba="0 0 0.8 1"/>
</material>
<!-- 连杆定义 -->
<link name="base_link"> ... </link>
<!-- 关节定义 -->
<joint name="joint1" type="revolute"> ... </joint>
<!-- 传动装置(可选) -->
<transmission name="trans1"> ... </transmission>
</robot>
<link> 定义机器人的一个刚性部件,包含三个主要子元素:
<link name="link_name">
<!-- 1. 惯性属性(动力学必需) -->
<inertial>
<origin xyz="0 0 0.5" rpy="0 0 0"/>
<!-- 质心相对于 link 坐标系 -->
<mass value="10"/>
<!-- 质量 (kg) -->
<inertia ixx="0.4" ixy="0" ixz="0" iyy="0.4" iyz="0" izz="0.2"/>
<!-- 惯性张量 (kg·m²) -->
</inertial>
<!-- 2. 视觉属性(显示用) -->
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<!-- 视觉原点偏移 -->
<geometry>
<!-- 基本几何体 -->
<box size="1 2 3"/>
<!-- 长方体 -->
<cylinder radius="0.5" length="2"/>
<!-- 圆柱体 -->
<sphere radius="1"/>
<!-- 球体 -->
<!-- 或外部网格 -->
<mesh filename="package://pkg/mesh.dae" scale="1 1 1"/>
</geometry>
<material name="blue"/>
<!-- 引用或内联材质 -->
</visual>
<!-- 3. 碰撞属性(碰撞检测用,通常简化) -->
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="1.1 2.1 3.1"/>
<!-- 通常比视觉模型简单 -->
</geometry>
</collision>
</link>
关键属性说明:
xyz(位置,单位米)和 rpy(roll-pitch-yaw 欧拉角,单位弧度)定义偏移.dae(COLLADA)、.stl、.obj 格式<joint> 定义两个连杆之间的连接关系和运动约束:
<joint name="joint_name" type="revolute">
<!-- 父连杆(参考坐标系) -->
<parent link="parent_link_name"/>
<!-- 子连杆(随关节运动) -->
<child link="child_link_name"/>
<!-- 关节坐标系原点(相对于父连杆) -->
<origin xyz="0 0 1" rpy="0 0 0"/>
<!-- 关节轴方向(相对于关节坐标系,单位向量) -->
<axis xyz="0 0 1"/>
<!-- 关节限制(部分类型必需) -->
<limit lower="-3.14" upper="3.14" effort="100" velocity="10"/>
<!-- 动力学属性(可选) -->
<dynamics damping="0.5" friction="0.1"/>
<!-- 安全性限制(可选) -->
<safety_controller soft_lower_limit="-3.0" soft_upper_limit="3.0" k_position="100" k_velocity="10"/>
<!-- 校准信息(可选) -->
<calibration rising="0.0" falling="0.0"/>
<mimic joint="other_joint" multiplier="1" offset="0"/>
</joint>
关节类型(type):
| 类型 | 说明 | 约束 |
|---|---|---|
revolute | 旋转关节(有角度限制) | <limit> 必需 |
continuous | 连续旋转关节(无限制) | 无上下限 |
prismatic | 滑动关节(线性运动) | <limit> 必需 |
fixed | 固定关节(无运动) | 常用于连接静态部件 |
floating | 6 自由度浮动关节 | 用于基座或浮动基 |
planar | 平面运动关节(2 自由度) | 在平面内移动 |
spherical | 球关节(3 自由度旋转) | 使用四元数表示 |
用于连接关节与执行器(电机),在 Gazebo 仿真中必需:
<transmission name="arm_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="arm_joint">
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
</joint>
<actuator name="arm_motor">
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
用于仿真环境的特定属性:
<!-- 在 <robot> 内 -->
<gazebo>
<static>true</static>
<!-- 是否静态物体 -->
</gazebo>
<!-- 在 <link> 内 -->
<gazebo reference="link_name">
<material>Gazebo/Orange</material>
<!-- Gazebo 材质 -->
<mu1>0.5</mu1>
<!-- 摩擦系数 -->
<mu2>0.5</mu2>
<kp>1000000.0</kp>
<!-- 接触刚度 -->
<kd>1.0</kd>
<!-- 接触阻尼 -->
<selfCollide>true</selfCollide>
<!-- 自碰撞检测 -->
<gravity>true</gravity>
<!-- 受重力影响 -->
</gazebo>
<!-- 在 <joint> 内 -->
<gazebo reference="joint_name">
<provideFeedback>true</provideFeedback>
<implicitSpringDamper>true</implicitSpringDamper>
</gazebo>
<?xml version="1.0"?>
<robot name="simple_arm" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- 基础材料 -->
<material name="blue">
<color rgba="0.0 0.0 0.8 1.0"/>
</material>
<material name="grey">
<color rgba="0.5 0.5 0.5 1.0"/>
</material>
<!-- ========== 基座 ========== -->
<link name="base_link">
<visual>
<geometry>
<cylinder radius="0.2" length="0.1"/>
</geometry>
<material name="grey"/>
</visual>
<collision>
<geometry>
<cylinder radius="0.2" length="0.1"/>
</geometry>
</collision>
<inertial>
<mass value="5.0"/>
<inertia ixx="0.052" ixy="0" ixz="0" iyy="0.052" iyz="0" izz="0.1"/>
</inertial>
</link>
<!-- ========== 连杆 1 ========== -->
<link name="link1">
<visual>
<origin xyz="0 0 0.5" rpy="0 0 0"/>
<geometry>
<cylinder radius="0.05" length="1.0"/>
</geometry>
<material name="blue"/>
</visual>
<collision>
<origin xyz="0 0 0.5" rpy="0 0 0"/>
<geometry>
<cylinder radius="0.05" length="1.0"/>
</geometry>
</collision>
<inertial>
<origin xyz="0 0 0.5" rpy="0 0 0"/>
<mass value="2.0"/>
<inertia ixx="0.168" ixy="0" ixz="0" iyy="0.168" iyz="0" izz="0.0025"/>
</inertial>
</link>
<!-- 关节 1:基座旋转 -->
<joint name="joint1" type="revolute">
<parent link="base_link"/>
<child link="link1"/>
<origin xyz="0 0 0.05" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
<limit lower="-3.14" upper="3.14" effort="100" velocity="2.0"/>
<dynamics damping="0.5" friction="0.1"/>
</joint>
<!-- ========== 连杆 2 ========== -->
<link name="link2">
<visual>
<origin xyz="0 0 0.4" rpy="0 0 0"/>
<geometry>
<box size="0.1 0.1 0.8"/>
</geometry>
<material name="grey"/>
</visual>
<collision>
<origin xyz="0 0 0.4" rpy="0 0 0"/>
<geometry>
<box size="0.1 0.1 0.8"/>
</geometry>
</collision>
<inertial>
<origin xyz="0 0 0.4" rpy="0 0 0"/>
<mass value="1.5"/>
<inertia ixx="0.08" ixy="0" ixz="0" iyy="0.08" iyz="0" izz="0.0025"/>
</inertial>
</link>
<!-- 关节 2:俯仰关节 -->
<joint name="joint2" type="revolute">
<parent link="link1"/>
<child link="link2"/>
<origin xyz="0 0 1.0" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
<limit lower="-1.57" upper="1.57" effort="50" velocity="1.0"/>
</joint>
<!-- ========== 末端执行器 ========== -->
<link name="end_effector">
<visual>
<geometry>
<sphere radius="0.05"/>
</geometry>
<material name="blue"/>
</visual>
<inertial>
<mass value="0.5"/>
<inertia ixx="0.0005" ixy="0" ixz="0" iyy="0.0005" iyz="0" izz="0.0005"/>
</inertial>
</link>
<joint name="fixed_joint" type="fixed">
<parent link="link2"/>
<child link="end_effector"/>
<origin xyz="0 0 0.8" rpy="0 0 0"/>
</joint>
<!-- 传动装置(用于 Gazebo) -->
<transmission name="trans1">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint1">
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
</joint>
<actuator name="motor1">
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
<transmission name="trans2">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint2">
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
</joint>
<actuator name="motor2">
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
<!-- Gazebo 插件:ROS 控制 -->
<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/simple_arm</robotNamespace>
</plugin>
</gazebo>
</robot>
Xacro 是 URDF 的宏扩展,解决上述问题:
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="advanced_robot">
<!-- ===== 属性定义(参数) ===== -->
<xacro:property name="pi" value="3.14159"/>
<xacro:property name="wheel_radius" value="0.1"/>
<xacro:property name="wheel_width" value="0.05"/>
<xacro:property name="chassis_length" value="0.5"/>
<!-- ===== 宏定义(模板) ===== -->
<xacro:macro name="wheel" params="prefix side reflect">
<link name="${prefix}_wheel_link">
<visual>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_width}"/>
</geometry>
<material name="black"/>
</visual>
<collision>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_width}"/>
</geometry>
</collision>
<inertial>
<mass value="0.5"/>
<inertia ixx="${0.5 * 0.5 * wheel_radius * wheel_radius}" ixy="0" ixz="0" iyy="${0.5 * 0.5 * wheel_radius * wheel_radius}" iyz="0" izz="${0.5 * wheel_radius * wheel_radius}"/>
</inertial>
</link>
<joint name="${prefix}_wheel_joint" type="continuous">
<parent link="chassis"/>
<child link="${prefix}_wheel_link"/>
<origin xyz="${reflect * chassis_length/2} 0 ${wheel_radius}" rpy="${-pi/2} 0 0"/>
<axis xyz="0 0 1"/>
</joint>
</xacro:macro>
<!-- ===== 使用宏 ===== -->
<xacro:wheel prefix="left" side="left" reflect="1"/>
<xacro:wheel prefix="right" side="right" reflect="-1"/>
<!-- ===== 数学运算 ===== -->
<link name="chassis">
<visual>
<geometry>
<box size="${chassis_length} 0.3 0.1"/>
</geometry>
</visual>
</link>
<!-- ===== 包含其他文件 ===== -->
<xacro:include filename="$(find pkg)/urdf/sensors.urdf.xacro"/>
<xacro:lidar_sensor parent="chassis"/>
</robot>
Xacro 编译命令:
# 将 xacro 转换为纯 URDF
rosrun xacro xacro robot.xacro > robot.urdf
# 或
xacro robot.xacro -o robot.urdf
# 检查 URDF 语法
check_urdf robot.urdf
# 解析并显示结构
urdf_to_graphiz robot.urdf
# 生成 PDF 结构图
# RViz 可视化(ROS1)
roslaunch urdf_tutorial display.launch model:=robot.urdf
# 或使用 joint_state_publisher_gui 调整关节
roslaunch urdf_tutorial display.launch model:=robot.urdf gui:=true
import xml.etree.ElementTree as ET
# 解析 URDF
tree = ET.parse('robot.urdf')
root = tree.getroot()
# 遍历所有连杆
for link in root.findall('link'):
name = link.get('name')
print(f"Link: {name}")
# 获取质量
inertial = link.find('inertial')
if inertial is not None:
mass = inertial.find('mass')
if mass is not None:
print(f" Mass: {mass.get('value')} kg")
# 遍历所有关节
for joint in root.findall('joint'):
name = joint.get('name')
jtype = joint.get('type')
parent = joint.find('parent').get('link')
child = joint.find('child').get('link')
print(f"Joint: {name} ({jtype}) - {parent} -> {child}")
| 特性 | URDF | SDF (Simulation Description Format) |
|---|---|---|
| 设计目标 | 机器人描述(ROS) | 通用仿真场景(Gazebo) |
| 闭链结构 | 不支持 | 支持 |
| 多机器人 | 单机器人 | 支持多机器人/环境 |
| 传感器定义 | 有限 | 丰富 |
| 插件系统 | 简单 | 完整 |
| 世界描述 | 不支持 | 支持(光照、物理属性等) |
转换工具:
# URDF 转 SDF
gz sdf -p robot.urdf > robot.sdf
left_arm_joint 而非 joint1)URDF 是 ROS 机器人开发的基石,掌握它对于机器人建模、仿真和控制至关重要。对于更复杂的应用,建议结合 Xacro 和 SDF 使用。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online