4 · 创建第一个URDF模型
说实话,第一次亲手写出一个能动的URDF模型,那种感觉挺奇妙的。我记得自己刚接触ROS2那会儿,对着一个两连杆模型折腾了一下午,最后在RViz里看到两个方块动起来的时候,心里就俩字:成了。这一章咱们就一起走一遍这个过程——从零搭一个简单的两连杆机器人,定义link和joint,再用工具看看它的结构,最后扔进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>
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单位弧度,别设太大 |
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_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里,你需要做两件事:
- 在左侧面板「Global Options」里,把 Fixed Frame 设为
base_link。 - 点击左下角「Add」按钮,选择 RobotModel 并添加。
搞定。你应该能看到两个方块,一个扁平的base_link,一个竖长的arm_link,它们通过一个旋转关节连在一起。用 joint_state_publisher_gui 还能拖动关节角度——不过那是下一章的内容了。
robot_description 参数没传进去。我有时候会忘记加 $(cat ...) 的括号,导致描述为空。另外,Fixed Frame 一定要设成存在的link名。
嗯,到这儿你已经亲手创建了第一个URDF模型,并且成功在RViz里显示出来了。虽然只是两个简单的方块,但骨架已经搭好。后面几章我们会往上面加颜色、加传感器、加更复杂的关节——但今天这一步,是地基。