第3章 URDF关节建模
关节,说白了就是连接两个连杆的“活动点”。没有关节,你的机器人就是一整块铁疙瘩。我刚开始学URDF时,总觉得关节就是转个轴,后来踩了不少坑才明白——关节类型选错,整个运动学树都会崩掉。这一章咱们就把关节的底细摸清楚。
3.1 <joint> 标签的结构
每个关节都写在 <joint> 里。我个人习惯先写 name 和 type,再写父子连杆。你想想看,如果连名字和类型都没定,后面写再多参数也是白搭。
<joint name="shoulder_pan" type="revolute">
<parent link="base_link"/>
<child link="shoulder_link"/>
<origin xyz="0 0 0.2" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
<limit lower="-3.14" upper="3.14" effort="100" velocity="1.5"/>
</joint>
嗯,这里要注意:origin 描述的是子坐标系相对于父坐标系的偏移。我曾经见过有人把 xyz 和 rpy 搞反,结果机械臂直接拧成了麻花。
3.2 六种关节类型,你选对了吗?
URDF 一共支持六种关节类型。我把它们分成两类:运动型和约束型。
| 类型 | 自由度 | 典型用途 | 避坑提醒 |
|---|---|---|---|
fixed | 0 | 焊接、固定支架 | 别把传感器装成revolute,除非你想让它转圈 |
revolute | 1 (旋转) | 关节电机、舵机 | 必须设置 limit,否则MoveIt!会报错 |
prismatic | 1 (平移) | 滑轨、伸缩臂 | 轴方向一定要和实际运动方向一致 |
continuous | 1 (无限旋转) | 轮子、转台 | 不需要 limit,但最好加个 calibration |
floating | 6 | 无人机、自由物体 | ROS中很少直接用,一般用 fixed 替代 |
planar | 3 (平面运动) | AGV底盘简化 | 小心与 prismatic 混淆 |
💡 我的经验: 做六轴机械臂时,我习惯把基座到第一个连杆用
fixed,其余全部 revolute。有一次项目里把腰部关节写成了 continuous,结果仿真时它一直转圈停不下来……嗯,从那以后我每次都会再三确认关节类型。
3.3 父子坐标系关系——树结构的灵魂
URDF 本质上是一棵树。每个关节定义了一个父连杆和一个子连杆。父连杆的坐标系是参考系,子连杆通过 origin 偏移和旋转。
举个例子:
<joint name="elbow" type="revolute">
<parent link="upper_arm"/>
<child link="forearm"/>
<origin xyz="0 0 0.4" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
</joint>
这里 forearm 的原点相对于 upper_arm 在 Z 方向偏移了 0.4 米。旋转轴是 Y 轴。说白了,关节的旋转就是子连杆绕着 axis 转,而父连杆纹丝不动。
🔧 核心原则: 每个连杆只能有一个父关节,但可以有多个子关节。如果你发现机器人模型在RViz里“散架”了,八成是父子关系写反了。我调试时经常用
urdf_to_graphiz 生成树图,一眼就能看出层级错误。
3.4 轴、极限与动力学参数
关节光有类型还不够,你得告诉ROS:
- axis — 旋转或平移的方向向量。单位向量,比如
0 0 1就是绕Z轴转。 - limit — 运动范围(
lower/upper)、最大力矩(effort)和最大速度(velocity)。 - dynamics — 阻尼和摩擦,非必须但仿真时很有用。
<limit lower="-1.57" upper="1.57" effort="50" velocity="2.0"/>
<dynamics damping="0.1" friction="0.01"/>
⚠️ 我曾经踩过的坑: 给
prismatic 关节设置 axis 时,我写成了 1 0 0,但实际滑轨是沿Y轴运动。结果在Gazebo里一推,连杆直接横着飞出去了。所以一定要和机械设计图对照着写轴方向。
3.5 避坑指南 & 个人习惯
- 关节命名用
snake_case,别用空格或大写开头。我见过有人叫Joint_1,结果解析时大小写搞混。 - 每个
revolute关节的limit单位是弧度,不是角度。我刚开始老写成lower="-90",然后机械臂只转了1.57度…… - 如果机器人有对称结构,比如双轮,记得每个轮子单独一个
continuous关节,别偷懒共用一个。 - 用
check_urdf命令验证文件。我每次写完都会跑一遍,它能查出缺失的origin或错误的父子引用。
其实关节建模没那么玄乎,你只要记住:类型决定运动方式,父子关系决定运动链,轴和极限决定运动范围。把这三点吃透,URDF关节部分就稳了。