3、逆运动学求解方法(下):数值法
上一讲我们聊了解析解,说白了就是直接套公式算角度。但现实中的机器人,尤其是六轴、七轴协作臂,结构复杂得很,很难写出解析式。这时候就得靠数值法——迭代着逼近,算到误差足够小为止。
我个人习惯把数值法分成两类:一类是牛顿-拉夫森法,另一类是雅可比伪逆法。两者核心思路一样,但实现细节和适用场景差别挺大。今天咱们就把这两个方法掰开揉碎,再聊聊收敛性和奇异位形这些坑。
3.1 牛顿-拉夫森法:从一维到多维
先回忆一下一维牛顿法。你要求方程 f(x)=0 的根,先猜一个 x₀,然后沿着切线方向迭代:
x_{k+1} = x_k - f(x_k) / f'(x_k)
放到逆运动学里,f(x) 就变成了正向运动学函数 T(θ),我们要找的 θ 使得 T(θ) 等于目标位姿 T_d。说白了就是:
T(θ) - T_d = 0
多维情况下,导数 f'(x) 变成了雅可比矩阵 J(θ)。迭代公式变成:
θ_{k+1} = θ_k - J(θ_k)⁺ · (T(θ_k) - T_d)
这里的 J⁺ 是雅可比矩阵的伪逆。为什么不用普通逆?因为 J 不一定是方阵——六轴机器人的雅可比是 6×6 的方阵,但如果你只控制末端位置(3 个自由度),J 就是 3×6 的矩形阵,没法直接求逆。
核心要点:牛顿-拉夫森法在逆运动学中就是不断用雅可比矩阵的伪逆修正关节角,直到末端误差小于阈值。
3.2 雅可比伪逆法:更通用的迭代框架
其实雅可比伪逆法可以看作是牛顿-拉夫森法在机器人学里的特化版本。两者的区别在于:牛顿法直接对位姿误差做线性化,而伪逆法更强调用最小二乘解来处理冗余自由度。
伪逆法的迭代公式长这样:
Δθ = J⁺ · Δx
θ_{k+1} = θ_k + Δθ
其中 Δx 是末端位姿误差,J⁺ = Jᵀ(J·Jᵀ)⁻¹。这里有个细节——当 J 不是满秩时,J·Jᵀ 可能奇异,没法求逆。这时候就得用阻尼最小二乘法(DLS),也就是加个阻尼因子 λ:
J⁺ = Jᵀ(J·Jᵀ + λ²I)⁻¹
我在项目中遇到过这种情况:六轴机器人运动到某个位置,末端突然抖了一下,然后迭代就不收敛了。查了半天,发现就是雅可比矩阵接近奇异,伪逆计算不稳定。加上阻尼因子后,问题就解决了。
实战技巧:阻尼因子 λ 一般取 0.01~0.1 之间。太小了起不到阻尼作用,太大了会引入额外误差。我习惯在迭代过程中动态调整 λ——误差大时用大阻尼保证稳定,误差小时用小阻尼提高精度。
3.3 迭代收敛性分析
数值法好不好用,关键看收敛性。说白了就是:你给一个初始猜测,它能不能稳定地走到正确解?
影响收敛性的因素主要有三个:
- 初始值:离真实解越近,收敛越快。离远了可能发散,或者收敛到另一个解。
- 雅可比矩阵的奇异性:接近奇异时,迭代步长会变得很大,容易震荡甚至发散。
- 步长控制:直接用 Δθ = J⁺·Δx 可能步子迈太大。我习惯加个步长因子 α(0<α≤1),变成 Δθ = α·J⁺·Δx。
收敛判据一般有两个:
- 位置误差:||Δx|| < ε₁,比如 0.001 mm
- 关节角变化量:||Δθ|| < ε₂,比如 0.0001 rad
两个条件满足一个就算收敛。但要注意——有时候位置误差很小了,关节角还在微调,这时候可以提前退出,节省计算时间。
避坑指南:我曾经遇到过迭代 100 次还不收敛的情况。后来发现是初始值给得太离谱——把关节角设成了 [0,0,0,0,0,0],而真实解在 [π/2, -π/3, π/4, 0, π/6, 0] 附近。初始值离真实解太远,牛顿法这种局部方法根本救不回来。建议先用解析法或查表法给个粗略的初始值,再用数值法精调。
3.4 奇异位形处理
奇异位形是逆运动学里最头疼的问题。说白了就是机器人某个关节的运动会失去一个自由度——比如肘关节伸直时,末端只能沿着一个方向移动,另一个方向动不了。
奇异位形在雅可比矩阵上的表现是:矩阵的秩下降,行列式接近零。这时候伪逆法算出来的 Δθ 会非常大,导致关节角突变。
处理奇异位形,我常用的方法有四种:
| 方法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 阻尼最小二乘法 | 在伪逆中加阻尼因子 λ | 实现简单,稳定 | 引入额外误差 |
| 截断奇异值分解 | 去掉小的奇异值 | 精度高 | 计算量大 |
| 奇异值滤波 | 对奇异值设阈值 | 可调性好 | 需要调参 |
| 任务优先级法 | 优先保证主要任务 | 灵活 | 实现复杂 |
我个人最常用的是阻尼最小二乘法。你想想看,在奇异位形附近,雅可比矩阵的某些奇异值变得很小,伪逆就会放大这些方向上的误差。加个阻尼因子,相当于告诉算法:「这个方向我不确定,别走太快。」
下面这张图展示了数值法求解逆运动学的完整流程:
3.5 实战中的选择建议
说了这么多理论,到底该用哪种方法?我根据项目经验给个参考:
- 六轴工业机器人:优先用阻尼最小二乘法。计算量适中,稳定性好。
- 七轴冗余机器人:用任务优先级法。可以同时处理主任务和副任务(比如避障、关节限位)。
- 移动机械臂:用截断奇异值分解。移动平台和机械臂的雅可比矩阵条件数差异大,SVD 能精确控制每个方向上的步长。
- 高速场景(比如焊接、喷涂):用查表法+数值法精调。先离线算好关键点的解,在线运行时只做局部迭代。
个人习惯:我一般在仿真阶段先用解析法验证运动学模型是否正确,再用数值法做实际控制。这样既能保证模型没错,又能利用数值法的灵活性。另外,迭代次数上限我通常设 20~50 次——超过这个数还不收敛,说明初始值有问题或者遇到了奇异位形,不如直接报错重新规划路径。
数值法虽然不如解析法那么「优雅」,但胜在通用性强。你想想看,不管机器人有多少个关节,只要你能写出正向运动学和雅可比矩阵,数值法就能算。这也是为什么工业界绝大多数机器人控制器都用数值法做逆运动学求解。