3. 机器人关节(joint)定义
关节,说白了就是连接两个连杆的“活动枢纽”。没有关节,机器人就是一坨死零件。我刚开始学URDF时,总觉得关节不就是个转轴嘛,后来踩了坑才明白——关节类型、父子关系、坐标轴方向,随便一个搞错,模型就散架。
3.1 joint标签长什么样?
一个标准的关节定义,大概长这样。我习惯把关节想象成“一根带属性的骨头”——它告诉系统:谁是谁的爹,它们之间怎么动。
<joint name="shoulder_pan" type="revolute">
<parent link="base_link"/>
<child link="upper_arm"/>
<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>
嗯,这里要注意:name 必须唯一,type 决定了关节的行为。后面我会一个个拆开讲。
3.2 关节类型——选对类型,模型才听话
URDF 里一共定义了 6 种关节类型。我当年做机械臂时,把 revolute 和 continuous 搞混过,结果仿真时关节转起来没完没了……
| 类型 | 自由度 | 典型用途 | 说明 |
|---|---|---|---|
fixed | 0 | 固定连接(如相机支架) | 两个连杆完全焊死,不能动 |
revolute | 1 (旋转) | 关节臂、轮子转向 | 绕轴旋转,有角度限制 |
prismatic | 1 (平移) | 伸缩臂、升降台 | 沿轴直线滑动,有行程限制 |
continuous | 1 (无限旋转) | 车轮、转台 | 像轮子一样可以一直转,没有限位 |
floating | 6 | 无人机、自由物体 | 三个平移 + 三个旋转,完全自由 |
planar | 3 | 全向移动底盘(简化) | 在平面内移动 + 绕垂直轴旋转 |
💡 我的经验: 90% 的机器人关节用
revolute 和 prismatic 就够了。fixed 关节常用于固定传感器,别小看它——我曾经因为漏写一个 fixed 关节,导致激光雷达在仿真里乱晃。
3.3 父子关系——谁是谁的爹?
每个关节必须指定 parent 和 child。父连杆是“参考系”,子连杆相对于父连杆运动。你想想看,整个机器人就是一棵树——从 base_link 开始,关节像树枝一样分叉出去。
<joint name="elbow" type="revolute">
<parent link="upper_arm"/>
<child link="forearm"/>
<origin xyz="0.3 0 0" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
</joint>
这里 upper_arm 是父,forearm 是子。关节的原点 origin 是相对于父连杆的坐标。我见过有人把父子写反,结果整个机械臂倒挂——嗯,仿真画面相当魔幻。
🔧 核心原则: 父连杆固定,子连杆动。关节的
origin 定义在父连杆坐标系下,axis 也是相对于父连杆的。
3.4 其他重要子标签
- origin:位置 (xyz) 和姿态 (rpy),决定关节在父连杆上的安装位置。我习惯把 rpy 写成 0 0 0 先,后面再调。
- axis:旋转或平移的轴向量,比如
0 0 1表示绕 Z 轴转。注意一定要归一化! - limit:对 revolute 和 prismatic 必须设置。包含 lower、upper、effort(最大力)、velocity(最大速度)。
- dynamics:阻尼和摩擦系数,仿真时影响运动手感。我一般先不写,调完运动学再加。
<limit lower="-1.57" upper="1.57" effort="50" velocity="1.0"/>
<dynamics damping="0.7" friction="0.1"/>
⚠️ 避坑指南: 我曾经在 prismatic 关节里忘了写 limit,结果仿真时滑块直接飞出去了…… 另外,axis 不要写成
0 0 0,那样关节就废了。
3.5 关节与运动学的关系
关节定义了机器人的运动自由度。每个关节就是一个自由度,所有关节串起来就是运动链。你想想看,6 轴机械臂就是 6 个 revolute 关节首尾相连。我调试时经常用 check_urdf 工具看关节树,一目了然。
说白了,关节就是机器人的“骨架关节”——没有它,连杆只是一堆散落的零件。我个人习惯在写 URDF 时,先画一个关节树草图,再动手写代码,这样不容易乱。