第3章 Joint与运动学
关节(Joint)是URDF里最核心的零件之一。没有关节,你的机器人就是一坨铁块。说白了,关节定义了零件之间怎么动——是旋转、平移,还是焊死不动。我刚开始学URDF时,总觉得关节就是“转轴”,后来踩了不少坑才明白,关节类型、轴方向、极限值,每一个细节都直接影响运动学解算。
3.1 joint标签详解
每个关节都用 <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>
你看,parent 和 child 定义了谁是谁的爹。坐标系原点 origin 表示子关节相对于父关节的位置和姿态。嗯,这里要注意:rpy 是绕固定轴旋转,顺序是 Z-Y-X。
3.2 关节类型——四种选择
URDF 一共就四种关节类型,但足够覆盖绝大多数机器人。我按常用度排个序:
| 类型 | 自由度 | 典型用途 | 个人经验 |
|---|---|---|---|
fixed | 0 | 焊死的连接,比如摄像头支架 | 我经常用 fixed 把传感器固定在基座上,省得算多余自由度 |
revolute | 1 (旋转) | 关节臂、肘关节 | 记得设 limit,不然仿真里会转疯掉 |
prismatic | 1 (平移) | 滑轨、升降台 | 轴方向一定要和实际运动方向对齐,否则运动学会出错 |
continuous | 1 (无限旋转) | 车轮、转台 | 没有上下限,但小心绕线问题 |
3.3 关节轴与极限设置
轴用 <axis xyz="x y z"/> 定义。这是一个单位向量,表示旋转轴或平移方向。举个例子,xyz="0 0 1" 就是绕 Z 轴旋转。我见过有人把轴写成 0 0 2,虽然 URDF 会帮你归一化,但最好直接写单位向量,看着清楚。
极限设置只对 revolute 和 prismatic 有效。格式是:
<limit lower="-1.57" upper="1.57" effort="50" velocity="1.0"/>
- lower / upper:弧度(旋转)或米(平移)。
- effort:最大驱动力/力矩。我一般根据电机选型填,别瞎填太大,仿真会失真。
- velocity:最大速度。单位 rad/s 或 m/s。
3.4 父子坐标系关系
每个关节都建立了一个从父连杆到子连杆的变换。这个变换由 <origin> 决定。我习惯把父连杆的坐标系想象成“世界”,子连杆的坐标系是“局部”。举个例子:
<origin xyz="0.1 0 0.3" rpy="0 0 1.57"/>
这表示子关节的原点相对于父关节偏移了 (0.1, 0, 0.3) 米,并且绕 Z 轴旋转了 90 度。你想想看,如果这里写错了,整个运动链都会歪掉。我在做六轴机械臂时,就因为 rpy 顺序搞反,导致末端执行器位置差了十万八千里。
origin 是静态偏移,而关节的运动(旋转/平移)是在这个偏移基础上叠加的。说白了,origin 定义的是“初始安装位置”,关节动的是“相对运动”。
3.5 实战中的运动学小记
关节配置直接影响正逆运动学。比如,revolute 关节的轴方向错了,逆运动学可能无解。我建议你在写 URDF 时,先用 Rviz 可视化一下,动动关节看看方向对不对。另外,prismatic 关节的轴最好和世界坐标系对齐,否则计算平移量时会很绕。
嗯,最后提一句:continuous 关节在 MoveIt 里会被当作无限制旋转,规划时要注意别让线缆缠绕。我一般会在真实机器人上加机械限位,但仿真里用 continuous 省事。