第1章:坐标系与空间描述
做机器人轨迹规划,第一件事是什么?
不是写代码,不是调参数。而是搞清楚——你的机器人现在在哪儿,要去哪儿。
说白了,就是坐标系和空间描述。我刚开始入行时,觉得这玩意儿太基础了,不就是个坐标嘛。结果第一次调试机械臂,末端执行器撞上了工作台……嗯,从那以后我再也不敢轻视坐标系了。
1.1 位置与姿态:机器人的“身份证”
一个刚体在空间中有几个自由度?6个。3个位置自由度,3个姿态自由度。
位置好理解,就是(x, y, z)。但姿态呢?你想想看,一个螺丝刀头朝上还是朝下,拧螺丝的效果完全不同。所以光有位置不够,还得告诉机器人“怎么摆”。
我个人习惯把位置和姿态合起来叫位姿。位姿 = 位置 + 姿态,缺一不可。
- 位置:用三维向量 p = [x, y, z]^T 表示
- 姿态:用旋转矩阵、欧拉角或四元数表示
- 位姿:位置 + 姿态,完整描述刚体状态
1.2 旋转矩阵:最直观,但最啰嗦
旋转矩阵是个3×3的矩阵,每一列代表一个坐标轴的方向。比如绕Z轴旋转θ角:
R_z(θ) = [cosθ -sinθ 0]
[sinθ cosθ 0]
[0 0 1]
旋转矩阵的好处是直观,而且可以连续相乘。但坏处也很明显——9个元素,只有3个自由度,冗余信息太多。我在项目中遇到过,用旋转矩阵做插值,结果矩阵不再正交,还得做正交化处理,麻烦得很。
1.3 欧拉角:直观但小心“万向锁”
欧拉角用三个角度描述旋转,比如ZYX顺序:先绕Z轴转γ,再绕Y轴转β,最后绕X轴转α。
为什么用欧拉角?因为直观啊!你告诉机器人“先转30度,再转45度”,它听得懂。
但欧拉角有个致命问题——万向锁。当β = ±90°时,α和γ的旋转轴重合,丢失一个自由度。我在调试六轴机器人时遇到过,末端执行器突然卡住不动,查了半天才发现是欧拉角表示导致奇异性。
| 表示方法 | 优点 | 缺点 |
|---|---|---|
| 旋转矩阵 | 直观,可连续相乘 | 冗余,需正交化 |
| 欧拉角 | 直观,参数少 | 万向锁,插值困难 |
| 四元数 | 无奇异性,插值平滑 | 不够直观 |
1.4 四元数:工程师的“瑞士军刀”
四元数是个四维向量 q = [w, x, y, z]^T,满足 w² + x² + y² + z² = 1。
为什么用四元数?因为它没有万向锁,而且插值平滑。我建议所有做轨迹规划的工程师,都学会用四元数。虽然一开始觉得抽象,但用熟了就知道它的好。
// 四元数乘法(C++示例)
Quaternion q_mult(Quaternion q1, Quaternion q2) {
Quaternion result;
result.w = q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z;
result.x = q1.w*q2.x + q1.x*q2.w + q1.y*q2.z - q1.z*q2.y;
result.y = q1.w*q2.y - q1.x*q2.z + q1.y*q2.w + q1.z*q2.x;
result.z = q1.w*q2.z + q1.x*q2.y - q1.y*q2.x + q1.z*q2.w;
return result;
}
1.5 齐次变换矩阵:把位置和姿态打包
齐次变换矩阵是个4×4矩阵,把旋转和位移打包在一起:
T = [R p]
[0 1]
其中R是3×3旋转矩阵,p是3×1位置向量。最后一行是[0, 0, 0, 1]。
为什么用齐次变换矩阵?因为可以连续变换。比如从基座到末端,可以写成:
T_末端 = T_1 × T_2 × T_3 × ... × T_n
我在调试机器人运动学时,就是用齐次变换矩阵做链式乘法,方便得很。
齐次变换矩阵的逆:T⁻¹ = [R^T -R^T p; 0 1]
这个公式在坐标系转换中经常用到,建议背下来。
1.6 知识体系总览
下面这张图,是我自己总结的坐标系与空间描述的知识结构。你看一遍,心里就有谱了。
1.7 实际调试中的选择建议
说了这么多,到底用哪个?我个人的经验是:
- 做运动学推导:用齐次变换矩阵,链式乘法最方便
- 做轨迹插值:用四元数,Slerp插值平滑无奇异性
- 做人机交互:用欧拉角,操作员看得懂
- 做底层计算:用旋转矩阵,矩阵运算效率高
好了,坐标系与空间描述就讲到这里。记住一句话:搞不清坐标系,就别谈轨迹规划。下一章我们聊聊运动学,到时候这些知识全用得上。