第二章 空间描述与变换基础:位置与姿态的表示、旋转矩阵、齐次变换矩阵
各位同学,欢迎来到第二章。
上一章我们聊了机器人运动学到底在干什么。说白了,就是搞清楚机器人各个关节动起来之后,末端到底在哪儿、朝哪个方向。那问题来了——我们怎么在数学上描述「在哪儿」和「朝哪儿」?
这就是本章要啃的硬骨头:空间描述与变换基础。
我个人习惯把这一章叫做「机器人学的坐标系圣经」。你后面学正运动学、逆运动学、雅可比矩阵,全得靠这章打底。我当年刚入行时,觉得旋转矩阵不就是个3x3的表格嘛,有啥难的?结果第一次做六轴机器人离线编程,坐标系搞反了,末端执行器直接怼到工件上……嗯,从那以后我再也不敢小看这章了。
2.1 位置与姿态:描述一个物体到底需要几个数?
先问个问题:你要告诉别人桌子上有个杯子,怎么说?
你可能会说:「杯子在桌子右上角,杯口朝上。」
这就包含了两个信息:位置(桌子右上角)和姿态(杯口朝上)。在机器人学里,我们把这两者合起来叫做一个物体的位姿(Pose)。
位置好办,三维空间里用三个坐标 (x, y, z) 就能搞定。但姿态呢?光说「朝上」可不够精确——杯子可以正着朝上,也可以歪着朝上,对吧?
所以,描述一个刚体在空间中的完整状态,需要:
- 位置:3个自由度(x, y, z)
- 姿态:3个自由度(绕x、y、z轴的旋转)
一共6个自由度。这就是为什么工业机器人通常有6个关节——6个自由度刚好能控制末端执行器到达空间中的任意位姿。
核心概念:位姿 = 位置 + 姿态。位置用矢量描述,姿态用旋转矩阵描述。两者合在一起,就是齐次变换矩阵。
2.2 旋转矩阵:姿态的「身份证」
好了,位置用矢量 p = [x, y, z]^T 表示,这个大家都能理解。那姿态怎么表示?
我最喜欢用的工具就是旋转矩阵。
旋转矩阵 R 是一个 3x3 的矩阵。它的每一列,代表被旋转坐标系的三个坐标轴在参考坐标系中的投影。
举个例子:假设有一个坐标系 {B},它相对于参考坐标系 {A} 绕z轴转了30度。那么旋转矩阵就是:
R = | cos30° -sin30° 0 |
| sin30° cos30° 0 |
| 0 0 1 |
你看,第一列 [cos30°, sin30°, 0]^T 就是坐标系 {B} 的x轴在 {A} 中的方向。第二列是y轴,第三列是z轴。
旋转矩阵有两个重要性质:
- 正交性:R^T * R = I,也就是说旋转矩阵的逆等于它的转置。这个性质在计算中非常有用。
- 行列式为1:det(R) = 1,表示这是一个纯旋转,没有缩放或镜像。
我的小技巧:在实际编程中,我从来不会手动计算旋转矩阵的逆。直接用 R^T 代替 R^{-1},又快又不容易出错。但前提是你确认这个矩阵确实是旋转矩阵——行列式得是1。
2.3 绕坐标轴的三种基本旋转
在实际项目中,我们很少直接写出一个任意旋转矩阵。通常的做法是:先绕x轴转一个角度,再绕y轴转一个角度,最后绕z轴转一个角度。这就是所谓的欧拉角表示法。
三种基本旋转矩阵如下:
| 旋转轴 | 旋转矩阵(绕该轴转θ角) |
|---|---|
| 绕x轴 | R_x(θ) = | 1 0 0 | | 0 cosθ -sinθ | | 0 sinθ cosθ | |
| 绕y轴 | R_y(θ) = | cosθ 0 sinθ | | 0 1 0 | | -sinθ 0 cosθ | |
| 绕z轴 | R_z(θ) = | cosθ -sinθ 0 | | sinθ cosθ 0 | | 0 0 1 | |
你想想看,如果我要让一个物体先绕x轴转30度,再绕z轴转45度,最终的旋转矩阵就是:
R = R_z(45°) * R_x(30°)
注意顺序! 矩阵乘法不满足交换律。先转x再转z,和先转z再转x,结果完全不同。我在项目中就吃过这个亏——写代码时把乘法顺序搞反了,结果机械臂末端姿态偏了十几度,找了半天bug才发现是这里的问题。
避坑指南:我曾经在调试一个焊接机器人时,发现焊枪姿态总是差那么一点点。查了两天,最后发现是旋转矩阵的乘法顺序错了。记住:后乘的旋转先执行。如果你想让物体先绕x轴转,再绕z轴转,公式是 R = R_z * R_x,而不是 R_x * R_z。
2.4 齐次变换矩阵:位置+姿态,一网打尽
有了旋转矩阵描述姿态,有了位置矢量描述位置,我们能不能把它们合在一起?
当然可以。这就是齐次变换矩阵 T。
它是一个 4x4 的矩阵:
T = | R p |
| 0 1 |
其中 R 是 3x3 的旋转矩阵,p 是 3x1 的位置矢量,最下面一行是 [0, 0, 0, 1]。
为什么非要多加一行?因为这样我们就可以用一个矩阵同时完成旋转和平移,而且还能连续变换——把多个变换矩阵乘在一起,就得到了从基坐标系到末端坐标系的完整变换。
举个例子:假设有一个点,在坐标系 {B} 中的坐标是 [1, 2, 3]^T。而 {B} 相对于 {A} 的齐次变换矩阵是 T。那么该点在 {A} 中的坐标就是:
| x_A | | R p | | x_B |
| y_A | = | | * | y_B |
| z_A | | 0 1 | | z_B |
| 1 | | 1 |
你看,一次矩阵乘法,既转了又移了,干净利落。
为什么叫「齐次」? 因为我们在三维坐标后面加了一个1,变成了四维齐次坐标。这样一来,平移变换就能用矩阵乘法表示了——否则平移只能用加法,没法跟旋转统一成一次乘法。
2.5 知识体系总览
说了这么多,我们来画一张图,把本章的知识结构串起来。
这张图把本章的核心逻辑说清楚了:位姿拆成位置和姿态,位置用矢量,姿态用旋转矩阵,最后合在一起就是齐次变换矩阵。后面的章节里,我们会用这个 T 矩阵来串联机器人的各个关节。
2.6 实战中的几个要点
最后,分享几个我在实际项目中积累的经验:
- 坐标系定义要统一:我习惯用右手定则,z轴朝上。团队里如果有人用左手系,那代码一合并就出问题。所以项目一开始就要定好规矩。
- 旋转矩阵的数值稳定性:连续多次旋转后,由于浮点数误差,旋转矩阵可能会失去正交性。我一般每隔几步就做一次正交化:R = (R * R^T)^(-1/2) * R。虽然计算量大了点,但能避免累积误差。
- 调试时打印矩阵:不要只看数值。我会在代码里加一个可视化函数,把旋转矩阵的三个列向量画成红绿蓝三个箭头,一眼就能看出坐标系有没有翻转。
- 欧拉角的万向锁问题:用欧拉角表示姿态时,当第二个旋转角接近±90度时,会丢失一个自由度。我在做云台控制时就遇到过——云台突然卡住转不动了。后来改用四元数才解决。不过那是后话了,本章先打好旋转矩阵的基础。
我的习惯:在写机器人运动学代码时,我会先写一个坐标系类,里面封装好旋转矩阵、位置矢量、齐次变换矩阵的运算。这样后面写正运动学、逆运动学时,直接调用这个类的方法就行,代码干净又不容易出错。
好了,这一章的内容就到这里。空间描述与变换是机器人学的基石,你花多少时间在上面都不为过。下一章我们会用这些工具来建立机器人的连杆坐标系,那才是真正开始「动」起来的时候。
可可精品资料库