3、运动学基础(二):齐次变换矩阵、正向运动学(FK)推导
上一章我们聊了位姿描述和坐标变换的基本概念。说白了,就是知道了怎么描述一个点在空间里“在哪儿”、“朝哪儿看”。但机器人是由一串连杆和关节组成的,每个关节都在动。怎么把每个关节的局部运动,最终映射到末端执行器的全局位姿?
嗯,这就是本章要解决的核心问题。我会从最基础的旋转矩阵讲起,然后引入齐次变换矩阵这个“瑞士军刀”,最后带你手推一遍正向运动学。别怕,跟着我的节奏来,你会发现这东西其实挺有规律的。
3.1 从旋转矩阵到齐次变换矩阵
先问个问题:一个刚体在三维空间里,它的自由度是多少?
答案是6个——3个平移(x, y, z)加上3个旋转(绕x、y、z轴)。我们之前用旋转矩阵 R 来描述姿态,用位置矢量 p 来描述位置。但问题是,旋转矩阵是3x3的,位置矢量是3x1的,它们俩没法直接乘在一起做连续变换。
我在做第一个机械臂项目时就踩过这个坑。当时想把基座坐标系下的一个点,经过旋转再平移,结果写了一大串矩阵乘法,代码又长又容易出错。后来前辈告诉我:用齐次变换矩阵,一行代码搞定。
核心思想:齐次变换矩阵把旋转和平移统一到一个4x4的矩阵里。这样,连续的坐标变换就变成了矩阵的连乘,简洁又优雅。
齐次变换矩阵长这样:
| R p |
| 0 1 |
其中 R 是3x3的旋转矩阵,p 是3x1的平移矢量,最后一行是 [0 0 0 1]。
举个例子,绕Z轴旋转θ角,再平移 (dx, dy, dz) 的齐次变换矩阵是:
| cosθ -sinθ 0 dx |
| sinθ cosθ 0 dy |
| 0 0 1 dz |
| 0 0 0 1 |
你想想看,这个矩阵左上角3x3是旋转,右边3x1是平移,是不是一目了然?
3.2 齐次变换矩阵的几何意义
齐次变换矩阵 T 其实描述了坐标系 {B} 相对于坐标系 {A} 的位姿。具体来说:
- 旋转部分:R 的每一列,是 {B} 的坐标轴在 {A} 中的方向余弦。
- 平移部分:p 是 {B} 的原点在 {A} 中的位置。
我记得有一次调试一个六轴机器人,末端姿态总是不对。排查了半天,发现是旋转矩阵的某一列写反了。从那以后,我每次写齐次变换矩阵,都会先检查旋转矩阵的列向量是不是对应着目标坐标系的轴方向。
小技巧:验证齐次变换矩阵是否正确,可以看它的逆矩阵。逆矩阵等于转置加平移变换,即 T^{-1} = [R^T, -R^T * p; 0, 1]。如果算出来不对,那肯定有地方写错了。
3.3 正向运动学(FK)推导
正向运动学,说白了就是:给定每个关节的角度(或位移),求末端执行器的位姿。
怎么做?核心就是齐次变换矩阵的连乘。
假设一个机器人有n个关节,从基座到末端,依次有坐标系 {0}, {1}, ..., {n}。那么,相邻两个坐标系之间的变换关系可以用齐次变换矩阵 i-1Ti 表示。末端坐标系 {n} 相对于基座坐标系 {0} 的位姿就是:
0Tn = 0T1 * 1T2 * ... * n-1Tn
就这么简单?对,就这么简单。但难点在于,每个 i-1Ti 怎么求?这就要用到我们下一章会详细讲的Denavit-Hartenberg(D-H)参数法了。不过,为了让你现在就能上手,我先用一个简单的2连杆平面机械臂来演示。
3.4 实例:2连杆平面机械臂的FK推导
假设一个2连杆机械臂,两个关节都是旋转关节,连杆长度分别为 L1 和 L2。关节角度为 θ1 和 θ2。
我们建立坐标系:
- 基座坐标系 {0}:原点在第一个关节处,x轴水平向右,y轴竖直向上。
- 连杆1坐标系 {1}:原点在第一个关节处,x轴沿连杆1方向。
- 连杆2坐标系 {2}:原点在第二个关节处,x轴沿连杆2方向。
- 末端坐标系 {3}:原点在末端,x轴沿连杆2方向。
那么,相邻坐标系的齐次变换矩阵为:
0T1 = | cosθ1 -sinθ1 0 0 |
| sinθ1 cosθ1 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
1T2 = | cosθ2 -sinθ2 0 L1 |
| sinθ2 cosθ2 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
2T3 = | 1 0 0 L2 |
| 0 1 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
注意看,1T2 的平移部分有 L1,因为坐标系 {2} 的原点相对于 {1} 的原点沿x轴移动了 L1。同理,2T3 平移了 L2。
现在,末端位姿就是三个矩阵的乘积:
0T3 = 0T1 * 1T2 * 2T3
算出来之后,末端的位置 (x, y) 就是:
x = L1*cosθ1 + L2*cos(θ1+θ2)
y = L1*sinθ1 + L2*sin(θ1+θ2)
这个结果你肯定很熟悉,就是高中物理里的“向量合成”。但通过齐次变换矩阵,我们把它系统化了,可以推广到任意复杂度的机器人。
注意:矩阵乘法不满足交换律!顺序一定不能搞反。从基座到末端,必须从左到右依次乘。我曾经见过有人把顺序写反了,结果末端位置跑到天上去,调试了一整天。
3.5 知识体系总览
为了让你对本章内容有个整体把握,我画了一张图。你可以看到,从旋转矩阵出发,引入齐次变换矩阵,然后通过连乘实现正向运动学。整个过程环环相扣。
3.6 常见问题与避坑指南
在实际项目中,正向运动学推导最容易出问题的几个地方,我帮你列出来:
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 末端位置算出来不对 | 矩阵乘法顺序错误 | 从基座到末端,严格按顺序乘 |
| 旋转方向反了 | 旋转矩阵符号搞错 | 用右手定则验证,或代入特殊角度测试 |
| 平移量不对 | 坐标系原点定义不一致 | 统一坐标系定义,画图确认 |
| 代码实现慢 | 手动计算矩阵乘法 | 用NumPy等库,一行代码搞定 |
我的习惯:每次写完FK代码,我都会先代入一组简单的关节角度(比如所有关节为0),看末端位置是不是等于所有连杆长度之和。如果是,那基本就对了。这个“冒烟测试”帮我省了无数调试时间。
我曾经在一个六轴机器人项目里,因为一个连杆的坐标系Z轴方向定义反了,导致末端姿态在某个角度下突然跳变。排查了整整两天,最后发现是D-H参数表里一个符号写错了。从那以后,我每次定义坐标系,都会在纸上画清楚,然后用仿真软件验证一遍。