3、坐标系与运动学基础:世界坐标系与关节坐标系、正运动学与逆运动学、齐次变换矩阵
各位同学好,我是老张。今天咱们聊聊运动学基础。说实话,这部分内容看着有点数学味,但它是所有运动控制算法的根基。你想想看,机器人要动起来,首先得知道「它在哪」、「要去哪」、「怎么去」。这三个问题,全得靠坐标系和运动学来解决。
我刚开始做运动控制那会儿,就吃过坐标系的亏。有一次调试六轴机械臂,明明关节角度算对了,末端执行器却跑偏了十几毫米。查了两天才发现——世界坐标系和工具坐标系的转换矩阵写反了。嗯,从那以后,我对坐标系转换就格外上心。
3.1 世界坐标系与关节坐标系
先说说这两个最基础的坐标系。
世界坐标系,也叫基坐标系。它是固定不动的参考系,通常定义在机器人的底座上。你可以把它想象成「绝对坐标」。不管机器人怎么动,世界坐标系的原点和方向都不变。我习惯用右手定则来定义它的X、Y、Z轴方向。
关节坐标系,则是每个关节自己的坐标系。每个关节都有一个独立的坐标系,原点在关节轴线上,方向随关节转动而变化。说白了,关节坐标系是「跟着关节走的」。
为什么要区分这两个?因为控制指令通常在世界坐标系下发(比如「末端移动到(100, 200, 300)」),但电机执行的是关节角度(比如「关节1转30度」)。这两者之间需要桥梁——就是后面要讲的正逆运动学。
关键区别:
- 世界坐标系:固定、全局、不随机器人运动改变
- 关节坐标系:局部、随关节运动而旋转平移
- 控制指令通常用世界坐标系,执行层面用关节坐标系
3.2 正运动学与逆运动学
这两个概念,说白了就是「已知关节角度求末端位置」和「已知末端位置求关节角度」。
正运动学相对简单。给定每个关节的角度,通过几何关系或DH参数法,就能算出末端执行器在世界坐标系下的位置和姿态。这个过程是唯一的——一组关节角度只对应一个末端位姿。
我在项目中常用DH参数法做正运动学计算。举个例子,一个两连杆机械臂,已知连杆长度L1、L2,关节角度θ1、θ2,末端位置(x, y)可以这样算:
// 两连杆机械臂正运动学
x = L1 * cos(θ1) + L2 * cos(θ1 + θ2);
y = L1 * sin(θ1) + L2 * sin(θ1 + θ2);
逆运动学就麻烦多了。给定末端位姿,反求关节角度。这玩意儿可能有多个解,也可能无解。比如六轴机械臂,同一个末端位置可能有8组关节角度解。怎么选?我一般选「关节运动量最小」的那组,或者「离奇异点最远」的那组。
避坑指南:我曾经在逆运动学求解时忽略了奇异点。结果机械臂在某个姿态下突然「卡死」,关节速度瞬间飙升。后来我加了个奇异点检测——当雅可比矩阵的行列式接近0时,切换为阻尼最小二乘法求解。这个坑,大家一定要记住。
3.3 齐次变换矩阵
齐次变换矩阵,是坐标系转换的「瑞士军刀」。它用一个4×4的矩阵,同时描述旋转和平移。
结构是这样的:
| R11 R12 R13 Tx |
| R21 R22 R23 Ty |
| R31 R32 R33 Tz |
| 0 0 0 1 |
左上角3×3是旋转矩阵R,右上角3×1是平移向量T。最后一行固定为[0 0 0 1]。
为什么要用齐次坐标?说白了,就是为了把旋转和平移统一成矩阵乘法。否则你得先旋转再平移,写两行代码。用齐次变换矩阵,一次矩阵乘法搞定。
举个例子,从关节坐标系到世界坐标系的转换:
// 齐次变换矩阵乘法
T_world = T_0_1 * T_1_2 * T_2_3 * ... * T_n-1_n;
其中T_i_i+1表示从第i个关节坐标系到第i+1个关节坐标系的变换矩阵。把所有变换矩阵乘起来,就得到了末端在世界坐标系下的位姿。
我的小技巧:调试时,我会把每个关节的齐次变换矩阵单独打印出来,检查旋转部分是否正交(R^T * R = I)。如果发现矩阵不正交,说明DH参数或者角度计算有误。这个方法帮我抓过不少bug。
3.4 知识体系总览
下面这张图,是我自己总结的运动学知识框架。你可以看到,世界坐标系和关节坐标系是「地基」,正逆运动学是「桥梁」,齐次变换矩阵是「工具」。三者缺一不可。
3.5 实际应用中的注意事项
讲完了理论,说说实际干活时要注意的点。
- 坐标系定义要统一:我见过不同工程师用不同方向定义Z轴,结果联调时乱成一锅粥。建议团队内部统一标准,比如都用右手系、Z轴向上。
- 逆运动学解的选择:多解情况下,别随便选。我一般按这个优先级判断:关节限位约束 > 运动距离最短 > 避障需求 > 能耗最小。
- 齐次变换矩阵的精度:浮点数运算会有误差。长时间运行后,矩阵可能不再正交。建议每隔一段时间做一次正交化处理。
- 奇异点处理:逆运动学在奇异点附近会「炸」。我常用的方法是加阻尼项,或者提前规划路径绕开奇异区域。
一句话总结:坐标系是「地图」,运动学是「导航」,齐次变换矩阵是「方向盘」。三者配合好,机器人才能指哪打哪。
好了,这一章就到这里。内容不多,但都是干货。下次调试遇到坐标系问题,记得回来翻翻这章。