3、URDF与机器人建模:从零编写一个简单的URDF模型

说到机器人建模,URDF(Unified Robot Description Format)是绕不开的第一道坎。说白了,它就是机器人的「身份证」——告诉系统你的机器人长什么样、关节怎么动、传感器装在哪。

我刚开始接触URDF时,觉得不就是个XML文件嘛,随便写写就行。结果第一次加载到RViz里,机械臂直接「飞」到了天上。嗯,坐标系搞反了。从那以后,我对URDF的每一个数字都格外小心。

3.1 URDF的核心结构:连杆与关节

URDF的核心就两个东西:连杆(link)和关节(joint)。你可以把连杆想象成骨头,关节就是连接骨头的韧带。

  • link:描述刚体部分,包括视觉外观、碰撞模型、惯性参数
  • joint:描述两个连杆之间的运动关系,包括类型、父子关系、原点偏移

一个最简单的URDF模型,至少需要一个根连杆和一个子连杆,中间用关节连接。我见过不少新手上来就写十几个连杆,结果调试时根本不知道哪里出了问题。我的建议是:从两个连杆开始,逐步增加。

3.2 从零编写一个两连杆机械臂

咱们直接上手写一个。假设我们要做一个简单的两连杆机械臂,基座固定,中间一个旋转关节,末端再连一个连杆。

<?xml version="1.0"?>
<robot name="two_link_arm">

  <!-- 基座连杆 -->
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.1" radius="0.05"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0"/>
    </visual>
  </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="10" velocity="1"/>
  </joint>

  <!-- 连杆1 -->
  <link name="link1">
    <visual>
      <geometry>
        <box size="0.02 0.02 0.3"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0.15"/>
    </visual>
  </link>

</robot>

这段代码里,base_link是一个圆柱体,link1是一个细长的长方体。关节joint1绕Z轴旋转,范围是-180°到180°。

我的小技巧:写URDF时,先把视觉模型调通,再加碰撞模型和惯性参数。分开调试,问题定位快得多。

3.3 坐标系:URDF的「隐形骨架」

URDF里每个连杆都有自己的坐标系。这个坐标系的原点在哪?方向怎么摆?全由<origin>标签决定。

我遇到过最坑的事:一个学生把origin的xyz写成了相对于父连杆的坐标,但rpy却忘了设置。结果机械臂在RViz里看起来是歪的。其实origin的rpy默认是0,但如果你不写,系统不会报错,只会默默给你一个「看起来不对」的模型。

记住一个原则:子连杆的坐标系原点,是相对于父连杆坐标系原点的偏移。关节的origin也是相对于父连杆的。

3.4 关节类型:选对才能动对

URDF支持六种关节类型,但常用的就三种:

类型 说明 典型用途
revolute 旋转关节,有限位 机械臂肩关节、肘关节
continuous 连续旋转,无限位 轮子、转台
prismatic 平移关节,有限位 伸缩臂、滑台
fixed 固定连接 传感器支架、末端工具

我个人的习惯是:能用fixed就别用revolute,能用revolute就别用continuous。关节类型越简单,运动学计算越稳定。曾经有个项目,为了省事把所有关节都设成continuous,结果逆解时角度飘到天上去,查了两天才发现是关节限位没设。

3.5 使用SolidWorks导出URDF的注意事项

手工写URDF适合简单模型。一旦机械臂超过3个关节,或者有复杂的曲面,我强烈建议用SolidWorks导出。

SolidWorks有个官方插件叫SW2URDF,可以自动生成URDF文件。但别以为一键导出就完事了,坑多着呢。

我曾经踩过的坑:
  • 导出前没检查单位——SolidWorks默认是毫米,URDF要求米。导出后模型大1000倍,在RViz里根本看不到。
  • 坐标系没对齐——SolidWorks里随便建个基准面,导出来关节轴方向全乱套。一定要在SolidWorks里把每个关节的坐标系对齐好。
  • 惯性参数自动生成——插件会自动计算惯性矩阵,但如果你模型里有很多装饰性特征(比如螺丝孔、倒角),惯性参数会严重偏离实际。我建议导出后手动检查<inertia>的值。

使用SW2URDF的正确流程:

  1. 在SolidWorks里把每个连杆单独建一个零件文件
  2. 装配体中,每个关节处建立一个坐标系,Z轴指向关节旋转方向
  3. 运行SW2URDF插件,按提示依次选择每个关节的坐标系
  4. 导出后,用check_urdf命令验证模型完整性
  5. 在RViz中加载,手动旋转每个关节,确认运动方向正确

3.6 知识体系:URDF建模核心逻辑

下面这张图,是我自己总结的URDF建模流程。每次写新模型前,我都会按这个思路走一遍。

URDF建模核心流程 1. 定义连杆 视觉 + 碰撞 + 惯性 2. 定义关节 类型 + 父子 + 限位 3. 设置坐标系 origin + rpy 4. 验证模型 check_urdf + RViz 不通过则迭代 常见错误 • 坐标系原点偏移导致模型错位 • 关节限位设置不合理导致运动学奇异 • 惯性参数缺失导致动力学仿真崩溃

3.7 验证你的URDF模型

写完了别急着用,先跑一遍验证工具。ROS自带一个check_urdf命令,能帮你找出语法错误和结构问题。

# 检查URDF文件
check_urdf my_robot.urdf

# 如果一切正常,会输出类似:
# robot name is: two_link_arm
# ---------- Successfully Parsed XML ----------
# root link: base_link has 1 child(ren)
#     child(1):  link1

我每次写完URDF,都会在RViz里手动拖动每个关节,看看运动方向对不对。你想想看,如果关节转反了,后面做运动学规划全是错的。这一步省不得。

核心要点:URDF是机器人的「骨架」,骨架歪了,后面所有东西都站不稳。花时间把URDF写对,后面MoveIt配置、运动学求解、抓取规划才能顺利推进。