4 · 创建第一个URDF模型

说实话,第一次亲手写出一个能动的URDF模型,那种感觉挺奇妙的。我记得自己刚接触ROS2那会儿,对着一个两连杆模型折腾了一下午,最后在RViz里看到两个方块动起来的时候,心里就俩字:成了。这一章咱们就一起走一遍这个过程——从零搭一个简单的两连杆机器人,定义link和joint,再用工具看看它的结构,最后扔进RViz里显示出来。

两连杆URDF模型 定义 link 定义 joint urdf_to_graphiz RViz 显示

4.1 搭建两连杆模型——从零开始

先别想太复杂。两连杆,说白了就是两个刚体(link)用一根关节(joint)串起来。我习惯把第一个link叫 base_link,第二个叫 arm_link,中间用一个旋转关节连着。你想想看,这就像你的上臂和小臂,肘关节就是那个joint。

下面这个URDF文件,就是最精简的两连杆模型。直接复制到你的工作空间里,命名为 two_link.urdf。

<?xml version="1.0"?>
<robot name="two_link_robot">
  <link name="base_link">
    <visual>
      <geometry>
        <box size="0.2 0.2 0.1"/>
      </geometry>
      <origin xyz="0 0 0" rpy="0 0 0"/>
    </visual>
  </link>

  <link name="arm_link">
    <visual>
      <geometry>
        <box size="0.1 0.1 0.4"/>
      </geometry>
      <origin xyz="0 0 0.2" rpy="0 0 0"/>
    </visual>
  </link>

  <joint name="elbow_joint" type="revolute">
    <parent link="base_link"/>
    <child link="arm_link"/>
    <origin xyz="0 0 0.05" rpy="0 0 0"/>
    <axis xyz="0 1 0"/>
    <limit lower="-1.57" upper="1.57" effort="10" velocity="1.0"/>
  </joint>
</robot>
💡 个人小习惯: 我写URDF时喜欢先把link的视觉几何搭出来,再调joint的位置。这样能快速看到形状对不对,再微调关节原点。你试试看,先别管惯性参数,视觉上对了再说。

4.2 定义link与joint——拆开揉碎了讲

link 就是机器人的一个刚体部件。上面代码里 base_link 是一个扁平的方块,arm_link 是一个竖长的方块。每个link里至少要有 <visual> 标签,不然RViz里啥也看不见。

joint 描述两个link怎么连。这里用了 revolute 类型,也就是旋转关节。注意 <origin> 定义的是joint在父link坐标系下的位置,我一开始老搞反——记住:origin 是joint相对于parent的位置,child link再相对于joint摆放。

属性含义我的经验值
parent / child父子link关系父link通常是固定的基座
origin xyz关节原点在父link中的位置单位米,我习惯先画个草图再填
axis旋转轴方向0 1 0 绕Y轴转,像点头
limit关节限位、力矩、速度lower/upper单位弧度,别设太大
⚠️ 我曾经踩过的坑: 有一次我把joint的origin写成了 xyz="0 0 0.2",结果arm_link直接飞到半空中,跟base_link脱节了。后来才意识到,joint的origin是相对于parent的,而child link的视觉原点又是相对于child link自身的。嗯,这里要特别留意坐标系嵌套。

4.3 使用 urdf_to_graphiz 可视化

URDF写没写对?结构清不清晰?别靠猜。ROS2自带一个小工具叫 urdf_to_graphiz,能把模型结构画成一张图。我个人觉得这玩意儿特别适合教学,一看就明白父子关系。

在终端里运行下面命令(假设你的URDF文件在当前目录):

urdf_to_graphiz two_link.urdf

它会生成两个文件:two_link.gv 和 two_link.pdf。打开PDF,你会看到类似下面的结构:

  • base_link (根节点)
  • └── elbow_joint (revolute)
  •   └── arm_link (子节点)

说白了,这就是一棵树。ROS2里所有机器人模型都是树状结构,不能有环。如果你看到图里出现了循环,那肯定是joint的parent/child配错了。

🔧 实用技巧: 我每次写完URDF都会先跑一遍 urdf_to_graphiz,再打开PDF扫一眼。如果树结构跟我预想的一样,再进RViz。这习惯帮我省了不少调试时间。

4.4 在RViz中显示模型

终于到了最激动人心的环节。把模型放进RViz里,你才能真真切切看到它长啥样。ROS2里最常用的方法是借助 robot_state_publisher 加上一个简单的launch文件。不过这一章咱们先用手动命令,让你感受每一步。

打开终端,先启动 robot_state_publisher 节点:

ros2 run robot_state_publisher robot_state_publisher --ros-args -p robot_description:="$(cat two_link.urdf)"

然后另开一个终端,启动RViz2:

rviz2

在RViz里,你需要做两件事:

  1. 在左侧面板「Global Options」里,把 Fixed Frame 设为 base_link。
  2. 点击左下角「Add」按钮,选择 RobotModel 并添加。

搞定。你应该能看到两个方块,一个扁平的base_link,一个竖长的arm_link,它们通过一个旋转关节连在一起。用 joint_state_publisher_gui 还能拖动关节角度——不过那是下一章的内容了。

📌 如果看不到模型? 别慌。检查一下终端有没有报错,最常见的问题是 robot_description 参数没传进去。我有时候会忘记加 $(cat ...) 的括号,导致描述为空。另外,Fixed Frame 一定要设成存在的link名。

嗯,到这儿你已经亲手创建了第一个URDF模型,并且成功在RViz里显示出来了。虽然只是两个简单的方块,但骨架已经搭好。后面几章我们会往上面加颜色、加传感器、加更复杂的关节——但今天这一步,是地基。