3. 数学基础回顾(下):四元数、齐次变换矩阵、运动学与动力学基础

好,咱们接着聊。上一节我们把向量、旋转矩阵这些基础过了一遍,这一节要啃的骨头更硬一些——四元数、齐次变换,还有运动学和动力学。别紧张,我会用我踩过的坑帮你把这些概念串起来。

3.1 四元数:旋转的“防万向锁”利器

说到旋转,很多人第一反应是欧拉角。嗯,我刚开始做仿真时也这么干。直到有一次,我做一个机械臂的末端姿态规划,用欧拉角做插值,结果在某个特定角度下,机械臂突然“抽搐”了一下——这就是著名的万向锁问题。

说白了,欧拉角有三个自由度,但旋转顺序固定,当中间轴转到90度时,首尾两轴就重合了,丢失一个自由度。四元数就是为了解决这个问题而生的。

四元数的定义:一个四元数 q = w + xi + yj + zk,其中 w 是实部,(x, y, z) 是虚部。它本质上是一个超复数,用来表示三维空间中的旋转。

我个人习惯把四元数理解为“绕一个单位轴 n 旋转 θ 角度”的数学表达:

q = [cos(θ/2), n·sin(θ/2)]

这里 n 是单位向量,θ 是旋转角度。你看,它比欧拉角直观多了——没有顺序依赖,没有万向锁。

我的经验:在ROS和很多机器人框架中,四元数是标准接口。我曾经在项目里用欧拉角传参,结果不同模块对旋转顺序的理解不一致,导致末端位姿差了十万八千里。从那以后,我所有内部计算都用四元数,只在人机交互界面才转成欧拉角显示。

3.1.1 四元数的基本运算

四元数的乘法不满足交换律,这点和矩阵乘法一样。两个四元数 q1 和 q2 相乘,表示先应用 q1 的旋转,再应用 q2 的旋转:

q = q1 * q2

注意顺序!我见过不少新手在这里栽跟头。在大多数框架中,q1 * q2 表示先转 q1 再转 q2,但有些库可能相反。一定要看文档。

四元数的共轭和逆也很常用:

  • 共轭:q* = [w, -x, -y, -z],相当于反向旋转
  • :q⁻¹ = q* / |q|²,对于单位四元数,逆等于共轭

用四元数旋转一个向量 v 的公式是:

v' = q * v * q⁻¹

这里 v 要写成纯四元数 [0, vx, vy, vz] 的形式。

避坑指南:我曾经在代码里忘记归一化四元数,结果旋转后的向量长度变了,调试了一整天。记住:四元数一定要是单位四元数,否则旋转会附带缩放效果。

3.2 齐次变换矩阵:把旋转和平移打包

在机器人学里,我们经常需要描述一个坐标系相对于另一个坐标系的位置和姿态。旋转矩阵处理姿态,平移向量处理位置,但每次都要分开算,很麻烦。

齐次变换矩阵就是干这个的——它把旋转和平移打包成一个 4×4 矩阵:

T = [ R   t ]
    [ 0   1 ]

其中 R 是 3×3 旋转矩阵,t 是 3×1 平移向量。最后一行是 [0, 0, 0, 1]。

为什么是 4×4?说白了,就是为了能用矩阵乘法一次性完成旋转和平移。你想想看,如果只用 3×3 矩阵,平移就得单独加,没法链式变换。

3.2.1 齐次变换的链式法则

假设我们有三个坐标系:基座 {0}、关节1 {1}、关节2 {2}。从 {0} 到 {2} 的变换就是:

T_0_2 = T_0_1 * T_1_2

这个链式法则在运动学里无处不在。我习惯用下标表示“从哪到哪”,比如 T_0_1 表示从坐标系 {1} 到 {0} 的变换。不同教材可能符号不同,但逻辑一样。

实际应用:在六自由度机械臂中,从基座到末端的变换就是一连串的齐次变换矩阵相乘:T_0_6 = T_0_1 * T_1_2 * T_2_3 * T_3_4 * T_4_5 * T_5_6。每个 T_i_i+1 由关节变量(角度或位移)决定。

3.3 运动学基础:正解与逆解

运动学分两种:正运动学和逆运动学。正运动学是已知关节角度,求末端位姿;逆运动学是已知末端位姿,求关节角度。

正运动学相对简单,就是链式法则的矩阵乘法。但逆运动学就复杂多了——它可能有多个解,甚至无解。

3.3.1 正运动学

以六自由度机械臂为例,每个关节 i 对应一个齐次变换矩阵 T_i_i+1,它由关节类型(旋转或平移)和连杆参数决定。常用的建模方法是 Denavit-Hartenberg 参数法,简称 DH 参数。

DH 参数有四个:

参数 含义
θ_i 绕 z_i 轴的旋转角(关节变量)
d_i 沿 z_i 轴的平移(关节变量)
a_i 沿 x_i 轴的长度(连杆长度)
α_i 绕 x_i 轴的扭转角(连杆扭角)

每个关节的变换矩阵就是这四个参数的函数。我记得第一次手算 DH 参数时,坐标系建立就搞反了,结果算出来的末端位置完全不对。后来我养成了一个习惯:先在纸上画清楚坐标系,再填参数。

3.3.2 逆运动学

逆运动学没有通用解析解,但对于常见的六自由度机械臂(比如有球形腕的),可以解析求解。一般思路是:

  1. 先解前三个关节(位置部分)
  2. 再解后三个关节(姿态部分)

但要注意,逆解可能有多个:

  • 左肩/右肩:肘关节上下翻转
  • 肘上/肘下:肘关节弯曲方向
  • 腕翻转:腕关节的两种姿态

我的建议:在实际仿真中,不要试图一次性求出所有逆解。我通常先根据当前关节位置选一个“最近”的解,然后做碰撞检测,如果不行再换另一个解。这样可以避免关节突变。

3.4 动力学基础:力与运动的关系

运动学只关心位置和速度,不关心力。动力学则要回答:给定关节力矩,机械臂会怎么动?或者反过来,给定运动轨迹,需要多大的力矩?

动力学方程的一般形式是:

M(q) * q̈ + C(q, q̇) * q̇ + G(q) = τ

其中:

  • M(q) 是惯性矩阵(质量分布)
  • C(q, q̇) 是科里奥利力和离心力矩阵
  • G(q) 是重力项
  • τ 是关节力矩
  • q, q̇, q̈ 是关节位置、速度、加速度

这个方程看着复杂,但说白了就是牛顿第二定律 F=ma 在机器人身上的推广。每一项都有物理意义:

  • 惯性项:加速需要力矩
  • 科里奥利项:关节运动时相互耦合产生的力
  • 重力项:克服重力需要的力矩

避坑指南:我曾经在仿真中忽略了科里奥利项,结果高速运动时轨迹偏差很大。低速时还好,一旦速度上去,耦合效应就不可忽视了。如果你的机械臂要跑高速,动力学模型必须完整。

3.4.1 动力学建模方法

常用的动力学建模方法有两种:

  1. 牛顿-欧拉法:基于力平衡和力矩平衡,递推计算。计算效率高,适合实时控制。
  2. 拉格朗日法:基于能量(动能和势能),推导出解析表达式。物理意义清晰,但计算量大。

我个人在仿真中常用牛顿-欧拉法,因为它容易编程实现,而且可以方便地加入摩擦力、关节柔性等非线性因素。

3.5 本章知识体系

下面这张图是我自己整理的本章知识结构,帮你理清脉络:

数学基础回顾(下)知识体系 四元数 齐次变换矩阵 运动学 动力学 定义:w + xi + yj + zk 运算:乘法、共轭、逆 应用:旋转向量 v' = q·v·q⁻¹ 结构:[R t; 0 1] 链式法则:T_0_n = T_0_1 · ... · T_n-1_n DH参数:θ, d, a, α 正运动学:关节角 → 末端位姿 逆运动学:末端位姿 → 关节角 多解问题:左/右肩、肘上/下 方程:M(q)q̈ + C(q,q̇)q̇ + G(q) = τ 牛顿-欧拉法(递推) 拉格朗日法(能量) 核心逻辑:四元数 → 齐次变换 → 运动学 → 动力学 从数学工具到物理建模,逐层递进

嗯,这一节内容确实不少。四元数帮你绕开万向锁,齐次变换矩阵让你能链式运算,运动学告诉你关节和末端的关系,动力学则让你理解力与运动之间的耦合。这些是搭建仿真环境的数学基石,后面每一章都会用到它们。

最后说一句:数学工具是死的,但应用是活的。我见过有人用四元数做插值做出丝滑的动画,也见过有人用齐次变换矩阵算错坐标系导致机械臂撞墙。工具本身没有好坏,关键是你怎么用。多动手写代码,多画图,慢慢就熟了。


公众号:蓝海资料掘金营,微信deep3321