机械臂逆运动学:结构决定解的形状
同一个末端位姿,四台机械臂给的是有限个解、一条解圆,还是必须先给种子再抛光
同一个末端位姿,在不同机械臂上意味着不同的事:UR5e 有 8 支孤立解,Lite 6 也有 8 支,iiwa 14 的解集是一条连续的圆,而 Franka Panda 只能先给种子再迭代抛光。
这份展示用四台机械臂(UR5e、UFACTORY Lite 6、KUKA LBR iiwa 14、Franka Emika Panda)把这件事画出来。画面全部从 MuJoCo 里的真实模型离屏渲染,同一目标的定格、动画、徽章和数字来自同一次求解。看的时候只需要记住一件事:每张图里的琥珀色球加三根坐标轴,是同一个「目标位姿」标记——球说明位置到了,坐标轴说明姿态也到了。
先看琥珀色的末端标记:它一动不动。再看手臂:它沿着那条蓝色的肘部圆走完一整圈,蓝色小段是随臂型角 走动的刻度。左上角两个数在整个循环里都不变。
末端停着,手臂沿肘部圆走完一圈,迭代次数一直是 0。

先看这张图例,后面每张结构图都沿用同一套颜色和徽章:

再看每台腕部标出的那一段偏移,以及下面三行:几何条件、因此采用的解法、解集长什么样。UR5e 靠 J2–J4 三轴平行、Lite 6 靠腕三轴汇交,两条都是 Pieper 条件,各自把问题拆开;iiwa 肩腕两个球,解是一条圆;Panda 只满足肩那一个球,腕差着 0.088 m,所以只能先给种子再补。
UR 靠平行轴拆开,Lite 6 靠球腕拆开;iiwa 的腕也是球,但多了一维冗余,所以解是一条圆,不是有限个点。

先找 (肩心)和 (腕心)两个红蓝小球,再看穿过它们的那条直线:肘只能落在垂直于这条直线、半径由两段臂长决定的那个圆上。 就是肘点。

四格是同一个目标、四个不同的 ,每一格徽章都是 精确、迭代印成 0,残差印到 量级。它们是同一个连续圆上的四个采样,不是四段不同的运动。
关于采样和闭式:任意一个 代进去都是精确解;把 切成网格只影响能不能正好找回某一个事先给定的位形,不影响精度。
上面封面那条循环就是这台、这个目标的同一次求解。

把 J2–J4 那三根平行轴收成平面三连杆:橙色三角形是现在这一支,紫色是它关于 – 连线的镜像。余弦定理一步就把肘上、肘下两个三角形同时给出来。

这是这个目标真实存在的全部分支——八支,按真实解出的个数摆,没有凑数。每支的徽章都是 精确、迭代 0;名字里左中右分别是肘、肩、腕选了哪一侧。

下面这条是小字号的对照:同一个目标,阻尼最小二乘从六个随机初值出发,全都贴回上面已经列过的某一支,徽章是 收敛。主角仍是一次列全的那些分支。
六轴、有一组平行轴,所以解是数得清的几支,不存在末端不动还能继续摆的那一维。

三格是同一套画法下的腕部特写。Lite 6 的三根轴交在一个点(偏移 0),UR5e 的腕心到最后一轴约 0.10 m,Panda 约 0.088 m。橙色小段就是那段偏移的长度。

末端位姿定了以后,腕心 落在前三个关节够得着的地方,姿态留给腕的三根轴。

同一个末端标记下,这个目标真实存在的八支都摆在这里,每支 精确、迭代 0。它是六轴,分支之间用并排,不做连续摆动。
腕的三根轴交在一点上,位置由手臂决定,姿态由腕决定,所以这些构型可以一次列全。

左边是 iiwa 的腕:三轴交于一点,对应长度是 0。右边是 Panda 的腕:肩三轴仍交于一点,但腕心到最后一轴有一段台阶式的偏移,长度 0.088 m。这是两台唯一的差别。

半透明的手臂停在几何种子上,末端标记和种子的末端之间有一条肉眼可见的缝;实心手臂是抛光之后,末端与标记重合。

旁边这条很短的残差曲线只有抛光那几步,从「有缝」落进容差内。

这个目标找到的分支都硬切并排在这里。顶到关节限位的那两支留在画面里并标成 失败,让人看见「列出来」和「选哪一支」是两件事。
腕差着一截,位置和姿态拆不干净,闭式几何负责落到正确分支旁边,剩下的交给阻尼迭代。
前面几节的末端标记是钉死的。这里反过来:标记要动,而且必须贴着一条直线。四台用同一套走法,运动过程中每一段都用上一点的关节解做热启动。
UR5e
Lite 6
iiwa 14
Panda

每格里橙色直线是要求的路径,浅蓝色是「同一起点终点、只在关节角之间匀速插值」走出来的一条弯线。画面上印的是末端到直线的距离和整段最大值,最大值停在这一步逆解的容差量级(四台分别是 、、、)。

这是 Lite 6 的错误示范:末端仍贴在直线上,但中途换了一支,手臂猛地翻过去。末端对了,这段运动不能用。
末端要走直线,就沿着这条直线逐点解;关节自己匀速插过去,末端是弯的。

左边是同一个目标,但腕心几乎顶到最远:肘部圆半径 收成一个点。右边是三条曲线,同一起点、同一目标。伪逆的步子被放大,转置停滞(末残差 ,标 失败),阻尼最小二乘的步子始终有界、落进容差()。左下角的小直方图说明:伸直是随机位形里 变小的一个主要来源。
冗余补得了肩和腕的奇异,补不了肘被拉直;这时候靠的是阻尼,不是再换一个闭式公式。
| 机器人 | 解集形状 | 为什么是这种形状 | 迭代 | 残差量级 | 一次返回 |
|---|---|---|---|---|---|
| UR5e | 有限个点(本例 8 支) | J2–J4 三轴平行,满足 Pieper;平面三连杆一次写出 | 0 | 整族 | |
| Lite 6 | 有限个点(本例 8 支) | J4–J6 交于腕心、偏移 0,满足 Pieper;球腕解耦 | 0 | 整族 | |
| iiwa 14 | 一条圆 | 肩三轴、腕三轴各汇交,7 轴多一维冗余 | 0 | 整族(按 采样) | |
| Panda | 有限个分支,每支补一小步 | 只有肩三轴汇交,腕偏移 0.088 m,位置姿态不严格解耦 | 几步 | 一支(种子 + 抛光) |
- 结构允许拆开、又需要全部分支时,用闭式:UR5e、Lite 6、iiwa 走的就是这条路。
- 只要当前附近的一支时,用阻尼最小二乘:Panda 的抛光、以及任何一台的直线跟踪都是这么用的。
- 纯数值的成功率写在「初值个数」上(同一次实验,30 个随机目标,DLS):
| 初值个数 | UR5e | Lite 6 | iiwa 14 | Panda |
|---|---|---|---|---|
| 1 个 | 40% | 67% | 77% | 67% |
| 5 个 | 93% | 100% | 100% | 100% |
| 20 个 | 100% | 100% | 100% | 100% |
要整族解用几何,要附近一支用阻尼迭代,两者经常一起用。
模型来自 mujoco_menagerie 的四台机械臂 XML(universal_robots_ur5e、ufactory_lite6、kuka_iiwa_14、franka_emika_panda),几何常量全部从模型在 处实测,没有手写连杆参数。原理推导与子问题分类整理在配套文档 docs/ik_survey.md 与 docs/solver_bench.md,文中用到的球腕解耦代数在逆运动学原理这篇笔记里完整展开。
在仓库根目录重新渲染上面所有画面:
python -m scripts.showcase.build # 全部python -m scripts.showcase.build 1 3 7 # 只做封面、iiwa、直线运动渲染脚本在 scripts/showcase/:scene.py 负责离屏渲染与共用相机,style.py 负责字体 / 徽章 / 拼图,solvers.py 是统一求解入口,common.py 做结构分类与目标挑选,各 ex_*.py 对应一个展项。本站展示用的图表与短片由 scripts/sync_ik_showcase_media.py 从该目录同步而来。