第1章:坐标系与空间描述

大家好,我是你们这门课的主讲。今天咱们聊聊机器人学里最基础、也最绕不开的东西——坐标系与空间描述。

说实话,我刚开始做机器人那会儿,觉得坐标系嘛,不就是个xyz轴吗?有什么好学的。结果第一次调试机械臂,就栽了个大跟头。明明算好的位置,机械臂就是抓不到目标。后来才发现,是坐标系搞混了。嗯,从那以后,我再也不敢小看这个基础了。

1.1 全局坐标系与局部坐标系

先说说全局坐标系。你可以把它想象成一个「世界地图」。不管机器人走到哪里,这个坐标系是固定不变的。比如,你的工位左上角就是原点,X轴指向东,Y轴指向北。这就是全局坐标系。

那局部坐标系呢?说白了,就是「跟着机器人走的坐标系」。比如机械臂的末端夹爪,它自己有一个坐标系。夹爪往前伸,就是它自己的Z轴方向。这个坐标系会随着机械臂运动而改变。

我举个例子你就明白了。你站在房间里,房间的墙角是全局坐标系。你手里拿着一个手机,手机屏幕朝向你,这是手机的局部坐标系。你转身,手机也跟着转。手机上的点相对于房间的位置变了,但相对于手机本身没变。

关键点:全局坐标系是「世界」的视角,局部坐标系是「物体自身」的视角。两者之间的转换,就是机器人定位和导航的核心。

在项目中,我经常看到新手犯一个错误:把传感器测到的数据直接当成全局坐标。比如激光雷达扫到一个障碍物,距离是2米,角度30度。这个数据是在激光雷达自己的局部坐标系下的。你得先知道激光雷达装在机器人什么位置,才能把它换算到全局坐标系。

我的习惯:每次拿到传感器数据,第一件事就是问自己:「这个数据是在哪个坐标系下的?」养成这个习惯,能省掉你80%的调试时间。

1.2 齐次变换矩阵

好了,现在我们知道坐标系之间需要转换。怎么转?用齐次变换矩阵。

你可能会问:「为什么叫齐次?」因为我们在普通的3x3旋转矩阵下面加了一行,变成4x4矩阵。这一行主要是平移信息。

一个标准的齐次变换矩阵长这样:

| R11  R12  R13  tx |
| R21  R22  R23  ty |
| R31  R32  R33  tz |
|  0    0    0    1  |

左上角3x3是旋转矩阵,右上角3x1是平移向量。最后一行永远是[0,0,0,1]。这个结构很巧妙,它把旋转和平移打包在一起了。

我记得有一次做多传感器融合,需要把IMU的数据和相机数据对齐。IMU装在机器人底盘,相机装在头部。两个坐标系之间差了30厘米,还歪了15度。我直接用齐次变换矩阵,一行代码就搞定了坐标转换。

核心公式:P_global = T * P_local

其中T是4x4齐次变换矩阵,P是4x1齐次坐标(x,y,z,1)。

为什么要加那个「1」?因为只有齐次坐标才能用矩阵乘法同时处理旋转和平移。你想想看,如果只用3x3矩阵,平移就得单独加,多麻烦。

注意:齐次变换矩阵的乘法顺序很重要!T1 * T2 表示先做T2变换,再做T1变换。这个顺序搞反了,结果就完全不对。我曾经因为这个bug调了整整一个下午。

1.3 欧拉角

旋转矩阵虽然好用,但不够直观。你看到一堆数字,很难想象出物体到底转成了什么样子。所以就有了欧拉角。

欧拉角用三个角度来描述旋转:绕X轴转(滚转Roll)、绕Y轴转(俯仰Pitch)、绕Z轴转(偏航Yaw)。

比如,一架无人机抬头30度,就是俯仰角30度。它向左转45度,就是偏航角45度。很直观,对吧?

但是!欧拉角有个大坑——万向锁。当俯仰角达到±90度时,滚转和偏航会变得无法区分。说白了,就是丢失了一个自由度。

我在做无人机飞控时遇到过这个问题。无人机垂直爬升时,俯仰角接近90度,结果姿态解算直接崩了。嗯,从那以后,我只要涉及大角度运动,就改用四元数。

表示方式 优点 缺点
欧拉角 直观,容易理解 有万向锁,不适合插值
旋转矩阵 计算方便,无奇异性 不直观,占用内存大
四元数 无奇异性,适合插值 不太直观

我的建议:人机交互时用欧拉角(比如遥控器显示姿态),内部计算用四元数或旋转矩阵。各取所长。

1.4 四元数基础

四元数,听起来很高大上。其实你可以把它理解成「带方向的旋转」。它用四个数表示:一个实部和三个虚部。

形式是:q = w + xi + yj + zk

其中w是实部,x,y,z是虚部。而且满足 i² = j² = k² = ijk = -1。

你可能会问:「为什么不用欧拉角?」原因很简单:四元数没有万向锁,而且做旋转插值非常平滑。

比如,你想让相机从A姿态平滑转到B姿态。用欧拉角插值,中间可能会乱转。用四元数插值(球面线性插值,简称Slerp),路径是最短的,而且很平滑。

// 四元数乘法(表示旋转叠加)
q_result = q1 * q2

// 用四元数旋转一个向量
v_rotated = q * v * q_conjugate

// 球面线性插值
q_interp = slerp(q_start, q_end, t)  // t从0到1

我在做视觉SLAM时,后端优化用的就是四元数。因为优化过程中需要不断调整姿态,四元数没有奇异性,不会出现「跳变」的情况。

记住:四元数虽然不直观,但它是机器人领域最可靠的旋转表示方式。尤其是做滤波、优化、插值时,首选四元数。

避坑指南:四元数需要归一化!如果四元数的模不等于1,旋转结果会变形。我见过有人把四元数当普通向量用,结果姿态越算越歪。每次更新完四元数,记得做归一化:q = q / norm(q)。

1.5 总结与实战建议

好了,这一章的内容就这些。总结一下:

  • 全局坐标系 vs 局部坐标系:搞清楚数据在哪个坐标系下,是第一步。
  • 齐次变换矩阵:把旋转和平移打包,方便计算。
  • 欧拉角:直观,但小心万向锁。
  • 四元数:可靠,适合计算和插值。

我个人习惯是:写代码时用四元数,调试时转成欧拉角看,保存数据时用齐次变换矩阵。这样既保证了计算精度,又方便排查问题。

下一章,咱们聊聊传感器模型与数据预处理。到时候会用到今天讲的坐标系知识,所以这一章一定要吃透。

有什么问题,欢迎在课程群里讨论。咱们下期见。