机器人真正要回答的问题
上一篇指南把运动链正向走了一遍:已知一组关节角度,正运动学能精确告诉你手部最终落在哪里。这个答案令人满意,却不是机器人通常被问到的问题。没人会对机器人说「把第二个关节设成 37 度」,人们只会说「去抓那个杯子」。机器人知道它希望末端执行器达到的位姿——也就是位置和姿态——它必须反推出哪一组关节角度能让末端到达那里。这个反向问题就是逆运动学,简称 IK。
可以把这种差别想成算术与代数的区别。正运动学是把数字代入公式算出结果——永远只有一个干净的答案。逆运动学则是给你结果、要你反推输入,这是更难的方向。从关节角度到手部位姿的映射横跨两个不同的空间:角度位于关节空间(每个关节一个数),手部位姿位于任务空间(夹爪在房间里的位置)。IK 就是把你从任务空间送回关节空间的那座桥。
为什么反向映射很难
正运动学有个令人安心的性质:每个输入恰好对应一个输出。逆运动学却同时在两个方向上打破这个承诺。第一,一个目标可能有很多个有效解。把你自己的手臂伸出去触碰前方某一点:你可以把肘部抬高,也可以把肘部压低,都能碰到。机械臂也有同样的自由度——工程师称这些为「肘上」和「肘下」构型,两者都能把手放在完全相同的位置。一条典型的六关节机械臂,对同一个目标位姿可能有多达八个不同的解。
第二,一个目标可能根本无解。如果你要求机械臂去够它可达工作空间之外的点——可达工作空间是手能在物理上达到的所有位姿的集合——那就根本不存在能到达那里的关节角度。让它去拿一个比完全伸直还远一厘米的杯子,诚实的回答是「我够不到」。优秀的 IK 代码必须识别这种情况并报告失败,而不是返回会把手臂甩到错误位置的垃圾角度。
还有第三层复杂。如果机械臂的关节数比任务严格所需的还多——也就是冗余机械臂,比如用七关节臂去做一个六维任务——那它不只是有几个解,而是有无穷多个连续的解族。你可以让肘部沿一道弧线摆动,而手却纹丝不动。这对于避障是一份礼物,但也意味着「那个」答案并不存在;你必须从中挑一个。
解析法 IK:手算三角形
对于几何结构整齐的机械臂,你可以像做几何作业那样求解 IK:用三角学,手算,一次性,提前算好。这就是解析逆运动学——也叫闭式 IK,因为答案是一个精确的公式,而非近似。你输入目标位姿,关节角度就直接算出来,就像把数字代进一元二次方程求根公式一样。
经典的成全条件是球形手腕——最后三个旋转关节的轴线都相交于一点。这种布置让你能把问题干净地一分为二:手腕点的位置由前三个关节决定,手的姿态由后三个关节决定。于是变成两个小三角问题,而不是一个纠缠的六维大问题。大多数工业机械臂都特意设计成球形手腕,正是因为这个原因——它让机械臂能以闭式求解。
Two-link arm in a plane, hand target = (x, y), link lengths L1, L2:
r2 = x*x + y*y # squared distance to target
cos_e = (r2 - L1*L1 - L2*L2) / (2*L1*L2)
if cos_e < -1 or cos_e > 1:
FAIL -> target is outside the reachable workspace
elbow = acos(cos_e) # the +/- below give the two solutions
shoulder = atan2(y, x) - atan2(L2*sin(elbow), L1 + L2*cos(elbow))
# solution A: (shoulder, +elbow); solution B: mirror with -elbow
# the two signs are the elbow-up and elbow-down configurations回报是巨大的。闭式解在微秒级就能算完,一次性找出所有解,而且永远不会卡住或乱跑。代价是它只对具有正确特殊结构的机械臂存在,而且推导是一项费力的、与具体几何强绑定的工作——若改动机械臂的尺寸而破坏了那种结构,或加一个关节,你可能就得从头重新推导一遍。
数值法 IK:猜测、检验、微调、重复
当不存在干净的公式时——奇怪的几何、定制的机械臂,或多带了关节的——你就退而求助于数值逆运动学。它不去精确求解方程,而是悄悄逼近答案:从一个猜测出发,一步步改进,直到手离目标足够近。这和你伸手够东西时差一点就调整一下是同一种本能:看到差距,就再往前探一点。
让这种微调变得精确的引擎是雅可比矩阵。雅可比是一个矩阵,它针对机械臂当前的位姿,告诉你每个关节的微小转动会如何带动手移动。正着读,它从关节运动预测手的运动;把它求逆,它就告诉你哪些关节运动能产生你想要的手部运动——也就是能缩小到目标距离的那个微小动作。
- 先给关节角度一个猜测(通常就用机械臂当前的位姿)。
- 对猜测跑一遍正运动学,量出误差:在位置和姿态上,手离目标还差多少?
- 用求逆后的雅可比把这个手部误差换算成对每个关节角度的微小修正。
- 施加这个修正,然后回到第 2 步。每一轮都让误差变小。
- 当误差降到容差以下就停止——若误差不再缩小,则在固定次数后放弃。
这个循环妙在极其通用——给它任意一条机械臂和一个正运动学函数,它就会去尝试,不需要任何手工推导。但这份通用是有代价的。它只返回一个解(取决于从你的初始猜测出发恰好收敛到哪一个),如果需要很多次迭代它可能会慢,而且它会在奇异点附近卡住——奇异点是机械臂某一时刻在某个方向上失去移动能力的位姿,此时雅可比无法被干净地求逆。在这种位姿附近,所求的关节修正量会爆炸式增大,而幼稚的求解器就会乱抖。
选对工具
这两种方法与其说是对手,不如说是适合不同活计的工具。解析法 IK 在速度、完整性和可靠性上取胜:每次调用只需微秒,一次性给出所有解,不会卡住。对于产线上一台标准六轴机械臂、一天跑同一个闭式求解器一百万次的场景,它就是正确的选择。
数值法 IK 在灵活性上取胜。它能处理没有闭式解的机械臂、希望挑一个既巧妙又能避障的构型的冗余机械臂,以及几何结构在不同实验间会变的研究型机器人。代价是速度,以及必须提防奇异点和糟糕的初始猜测——但同一套机制还能自然地扩展去满足次要目标,比如让手保持在目标上的同时把肘部收拢。
实践中这条界线是模糊的。许多系统在机械臂结构允许时跑解析法 IK,否则退回数值求解器。而当冗余机械臂有无穷多个答案时,数值法可以游走的自由反倒成了头号卖点——那份多余的运动正是你将在冗余指南里遇到的零空间运动:手保持不动,肘部却重新安排去做点有用的事。