> 技术文档 > 机器人模型文件urdf介绍

机器人模型文件urdf介绍


一、什么是urdf文件

URDF 文件:机器人建模的标准描述格式

URDF(Unified Robot Description Format) 是一种用于描述机器人模型的 XML 格式文件,由 ROS(机器人操作系统)社区开发,主要用于定义机器人的几何结构、运动学特性、惯性参数等。它如同机器人的 “数字蓝图”,能被 ROS 系统解析并用于仿真、控制或可视化。urdf文件的后缀名可以是.urdf,也可以是.xml

二、怎么写urdf文件

我们以一个自己创建的极其简单的六自由度机器人urdf文件为例介绍urdf文件的撰写方式,下面是创建的机器人文件robot.xml代码:

                                                                                                                                                                                             

下面是创建urdf机械臂在pybullet里面的可视化:

 

2.1  标签:文件根节点

每个 URDF 文件以开头,定义机器人的整体名称,并包含所有连杆关节的定义。

 

2.2 标签:定义机器人连杆

描述机器人的刚体部件(如基座、手臂),包含可视化、碰撞检测和惯性参数:

              
  • 可视化与碰撞模型:通常使用相同的几何形状,但碰撞模型可简化以提高性能。
  • 惯性矩阵:需根据连杆质量和尺寸计算(见教程后文)。

2.3  标签:定义关节连接

描述连杆之间的连接方式和运动特性:

           
  • 关节类型
    • revolute:旋转关节(如肩关节)
    • prismatic:平移关节(如滑块)
    • fixed:固定连接(无自由度)
    • continuous:无限制旋转关节
    • floating:浮动关节(6 自由度)
  • origin 参数
    • xyz:位置偏移(米)
    • rpy:姿态偏移(弧度,按 Roll/Pitch/Yaw 顺序)

 2.4  标签:定义材质

为连杆指定颜色或纹理:

  
  • 材质可在多个连杆中复用。

 2.5 计算惯性矩阵(标签)

惯性参数需根据连杆质量和几何形状计算。对于立方体(边长:lxlylz,质量:m):

  

示例:边长为0.1 0.1 0.3、质量为 3.0kg 的连杆:

 2.6  坐标系与关节链设计

    • URDF 默认使用右手坐标系(X 前、Y 左、Z 上)。
    • 标签定义子坐标系相对于父坐标系的变换。
  • 关节链规则

    • 从基座开始,按顺序定义连杆和关节。
    • 每个关节连接一个父连杆和一个子连杆,形成树形结构。

 2.7 最佳实践

(1)模块化设计

  • 按功能分组连杆和关节(如基座、大臂、小臂)。
  • 使用注释分隔不同模块:
............

(2)参数校验

  • 使用check_urdf工具验证语法:
check_urdf your_robot.urdf
  • 使用urdf_to_graphiz生成可视化结构图:
urdf_to_graphiz your_robot.urdf

(3)避免常见错误: 

  • 确保关节的parentchild名称与已定义的连杆匹配。
  • 惯性矩阵需满足物理约束(如ixx + iyy > izz)。

2.8  进阶技巧

  • 合并重复定义
    若多个连杆使用相同材质,可将定义移至文件顶部复用。

  • 使用 Xacro 扩展
    Xacro(XML 宏)可简化 URDF 编写,支持变量、数学运算和代码复用:

       

2.9  验证与调试

(1)可视化检查
使用 RViz 查看机器人模型:

roslaunch urdf_tutorial display.launch model:=your_robot.urdf

 (2)动力学仿真:
在 Gazebo 中测试机器人运动:

roslaunch gazebo_ros empty_world.launchrosrun gazebo_ros spawn_model -file your_robot.urdf -urdf -model my_robot

三、在pybullet中加载urdf文件

下面是main文件代码,使用 PyBullet 物理引擎实现了一个机器人的仿真控制。首先,它初始化了物理环境,设置重力并加载平面和机器人模型,然后调整相机视角以便观察。代码会打印机器人的关节信息并验证关节数量,接着通过关节名称获取目标关节的索引。之后设置了关节控制参数,包括目标位置和最大驱动力,并将关节初始化为指定位置。在主循环中,代码实现了周期性运动演示:前两个关节会随时间做正弦运动,其他关节保持固定位置,同时按照 240Hz 的频率进行仿真步进,让用户能直观看到机器人的运动状态。

import pybullet as pimport pybullet_dataimport mathimport time# 连接物理引擎physicsClient = p.connect(p.GUI)p.setAdditionalSearchPath(pybullet_data.getDataPath())p.setGravity(0, 0, -9.81)# 加载平面和机器人(确保文件名正确)planeId = p.loadURDF(\"plane.urdf\")robotId = p.loadURDF( \"robot.xml\", # 确保文件名与实际一致 basePosition=[0, 0, 0], baseOrientation=p.getQuaternionFromEuler([0, 0, 0]), useFixedBase=True)# 设置相机视角p.resetDebugVisualizerCamera( cameraDistance=1.5, cameraYaw=45, cameraPitch=-30, cameraTargetPosition=[0, 0, 0.3])# 打印关节信息print(\"机器人关节信息:\")for joint_idx in range(p.getNumJoints(robotId)): joint_info = p.getJointInfo(robotId, joint_idx) joint_name = joint_info[1].decode(\"utf-8\") joint_type = joint_info[2] print(f\"关节 {joint_idx}: {joint_name}, 类型: {joint_type}\")# 验证关节数量total_joints = p.getNumJoints(robotId)print(f\"机器人总关节数: {total_joints}\")# 通过关节名称获取索引(更可靠)joint_names = [\"joint1\", \"joint2\", \"joint3\", \"joint4\", \"joint5\", \"joint6\"]control_joints = []for name in joint_names: found = False for joint_idx in range(total_joints): joint_info = p.getJointInfo(robotId, joint_idx) if joint_info[1].decode(\"utf-8\") == name: control_joints.append(joint_idx) found = True break if not found: print(f\"警告: 未找到关节 \'{name}\'\")print(f\"控制的关节索引: {control_joints}\")# 关节控制参数target_positions = [0, 0.5, -1.0, 0, 0.5, 0] # 目标关节角度(弧度)max_forces = [50, 50, 30, 20, 10, 5] # 最大驱动力# 设置关节初始位置for i, joint_idx in enumerate(control_joints): p.resetJointState(robotId, joint_idx, target_positions[i])# 主循环while p.isConnected(): # 周期性运动演示 t = time.time() for i, joint_idx in enumerate(control_joints): # 关节1和2做周期性运动,其他关节保持固定 if i < 2: target_pos = 0.5 * math.sin(t * 0.5) + target_positions[i] else: target_pos = target_positions[i] p.setJointMotorControl2( bodyUniqueId=robotId, jointIndex=joint_idx, controlMode=p.POSITION_CONTROL, targetPosition=target_pos, force=max_forces[i] ) p.stepSimulation() time.sleep(1. / 240.) # 240Hz仿真频率

其中加载urdf文件的代码是这一段:

robotId = p.loadURDF( \"robot.xml\", # 确保文件名与实际一致 basePosition=[0, 0, 0], baseOrientation=p.getQuaternionFromEuler([0, 0, 0]), useFixedBase=True)

p.loadURDF()参数

  • fileName:URDF 文件路径。

  • basePosition:机器人基座的初始位置。

  • baseOrientation:机器人基座的初始朝向(四元数表示)。

  • useFixedBase:是否固定基座(如机械臂需固定,移动机器人则不需要)。

四、查看Franka Panda机械臂的urdf文件

我们查看一下franka panda机械臂的urdf文件。只要在pycharm里面安装了pybullet库,就会自动有franka panda的urdf文件,如果想到找到panda的urdf文件路径,可以运行下面代码获得

import pybullet_dataimport os# 获取panda.urdf文件的路径panda_urdf_path = os.path.join(pybullet_data.getDataPath(), \"franka_panda/panda.urdf\")# 打印文件路径print(panda_urdf_path)

在控制台就可以看到路径了

 下面是打开的franka panda机械臂的urdf文件

                                                                                                                                                                                                                                                                                                                                          

Franka机械臂的urdf文件中大部分内容和我们在上面介绍过的知识都差不多,唯一不太相同的就是创建几何形状时的代码,不再是形式,因为这里的连杆不再是简单的长方体了,因此使用子标签来导入外部网格模型作为连杆的几何形状。

 

(1)子标签:
用于导入外部网格模型作为连杆的几何形状,主要参数:

  • filename:模型文件路径,使用 ROS 的package://语法。

(2)package://路径语法:
ROS 中特有的路径表示方式,格式为:

package:///

在本urdf文件中,package://meshes/collision/link0.obj表示:

  • 从名为meshes的 ROS 包中查找collision/link0.obj文件。
  • 实际物理路径可能是:~/catkin_ws/src/meshes/collision/link0.obj

还有一个不同的就是设置了关节安全控制约束, 是 URDF(Unified Robot Description Format)中用于描述关节安全控制参数的标签。

 

其属性含义如下:

  • k_position:用于说明位置和速度之间的关系,一旦某个关节要接近极限位置的时候,它能对同向位置施加的同向速度便更小,而对阻碍它运动的异向速度则可以更大。
  • k_velocity:用于说明力和速度之间的关系,一旦某个方向的关节速度过大,则能对同向速度施加的同向扭矩便更小,而对阻碍它运动的扭矩(即异向扭矩)则可以更大。
  • soft_lower_limit:指定了关节安全控制边界的下界,是关节安全控制的起始限制点,这个值需要大于  标签中的 lower 值。
  • soft_upper_limit:指定了关节安全控制边界的上界,是关节安全控制的起始限制点,这个值需要小于  标签中的 upper 值。