

一个"反着问"的问题,为何如此难?
大家好,这里是【深蓝具身智能】。
本文出自《具身智能基础》专栏,是本栏目下的第九篇文章,聚焦于逆运动学。
全文 5000 余字,建议收藏阅读。
你的订阅和收藏,将支持我们把这件事持续做下去✨
问:机械臂需要把一颗螺丝精确拧入一个斜面上的孔位,目标位置和姿态已知,每个关节该转多少度?
这个问题,从直觉上看似乎只是"倒着算一遍",但真正推导下来就会发现它完全不是这么回事。
-
正向的计算(已知关节角→求末端位姿)是一条单行道:
给定输入,通过确定性的矩阵连乘,输出唯一结果。整个过程没有歧义,数值稳定,计算量可控。
-
逆向的问题(已知末端位姿→求关节角)则像是在迷宫里找出口:
出口可能有一个、八个、无数个,甚至根本不存在。更麻烦的是,就算出口存在,找到它的路径本身就是一个非线性的高维搜索问题,在某些特殊位置,搜索的"地图"会直接失效。

这就是逆运动学(Inverse Kinematics,IK):机器人控制栈里那个承受着数学压力、工程约束和实时性要求三重夹击的核心模块。
本文尝试从数学本质出发,走完解析解→数值解→现代方法→工程落地这条完整的链路,并在关键节点给出可执行的伪代码和核心公式。

位姿的数学空间:为什么 IK 天然就难
末端位姿活在 SE(3) 上
机械臂末端的位姿(Pose)由位置和姿态两部分组成,数学上它是特殊欧氏群 SE(3) 的一个元素:
字母含义:
-
:齐次变换矩阵,同时编码旋转和平移 -
: 旋转矩阵,满足 -
:末端位置向量 -
: 零向量,维持齐次坐标结构
SE(3) 是一个李群,不是平坦的欧几里得空间。(在专栏的第一篇文章中有详细介绍)
这意味着你不能直接对两个位姿做线性插值——两个旋转矩阵的平均不是旋转矩阵。
这个事实在后续的误差计算和轨迹插值中会反复造成麻烦。
正运动学:确定性的链式计算
正运动学(Forward Kinematics, FK) 通过 DH 参数(Denavit-Hartenberg Convention)将 n 个关节的变换依次连乘:
字母含义:
-
:末端执行器在基坐标系中的位姿 -
:第 个连杆相对于第 个连杆的变换,是关节角 的函数 -
:第 个关节的角度(转动关节)或位移(移动关节)
FK 是一个从关节空间 到位姿空间 的光滑映射 ,有唯一输出,计算量是 的矩阵乘法。
逆运动学:反过来问,问题变质
IK 的目标是找到关节角向量 ,使得正运动学的输出等于目标位姿:
字母含义:
-
:关节角向量(配置空间中的一个点) -
:满足关节限位的可行域 -
:目标位姿 -
: 上的"差"运算(通常分解为位置误差 + 旋转轴角误差) -
:正运动学映射
难点在于:
-
f 是非线性的(含大量三角函数)
-
解可能不存在(目标在工作空间外)
-
解可能不唯一(6DOF 球腕机器人最多有 16 组解析解)
-
解可能无穷多(冗余机器人,n > 6)
-
在奇异点附近,问题的数值条件急剧恶化


解析解(Analytical IK):能算就别迭代
DH 参数与连杆变换
满足 Pieper 条件(后三轴共点)的机器人存在封闭形式解析解。每个连杆的 DH 变换矩阵为:
字母含义(DH 四参数):
-
:关节角,绕轴的旋转量(唯一变量,其余为常量) -
:连杆扭角(Link Twist),绕轴,与的夹角 -
:连杆长度(Link Length),沿方向,与的公垂线长度 -
:连杆偏距(Link Offset),沿方向的偏移 -
,以此类推
解析 IK 的伪代码骨架(以6DOF球腕机器人为例)
解析解的本质:通过代数变换把 矩阵方程降维拆解成一系列一元三角方程,每步用 atan2 消元。
速度是微秒级,但每换一种机器人构型就得重推一遍。

数值解(Numerical IK):雅可比是核心武器
雅可比矩阵:关节速度到末端速度的线性化
雅可比矩阵 是正运动学映射 对 的一阶偏导,描述了当前构型下关节微小运动如何映射到末端速度:
字母含义:
-
:末端速度旋量(前 3 维线速度,后 3 维角速度) -
:各关节的角速度向量 -
:依赖当前关节角 ,每一步迭代都要重新计算
对于第 个转动关节, 的第 列(几何雅可比例)为:
字母含义:
-
:第 坐标系的 轴在基坐标系中的单位方向向量(即旋转轴方向) -
:末端位置(基坐标系) -
:第 关节原点位置(基坐标系) -
:叉积,生成关节旋转对末端线速度的贡献
关节 转一点,末端的线速度贡献旋转轴 从轴到末端的力臂;角速度贡献旋转轴本身。
基于雅可比的迭代 IK 流程
阻尼最小二乘(DLS):奇异点的“救命稻草”
纯伪逆在奇异点附近的问题: 的最小特征值趋向 ,逆矩阵元素爆炸, 变得无穷大。
DLS 的修复方案:
字母含义:
-
:本次迭代的关节角修正量 -
:当前末端位姿与目标之间的误差旋量 -
:阻尼系数,控制数值稳定性与精度的权衡 -
:单位矩阵,加到对角线上,保证正定可逆
自适应 :
def adaptive_lambda(J, eps=0.01, lambda_max=0.1):sigma_min = min_singular_value(J) # SVD最小奇异值if sigma_min >= eps:return 0.0 # 远离奇异点,不加阻尼else:# 奇异点附近,平滑增大阻尼ratio = sigma_min / epsreturn lambda_max * (1 - ratio**2)

奇异性:IK 的死穴
三类奇异构型
当 时机器人处于奇异构型,末端在某些方向上瞬间丧失运动能力。

操纵度指标
Yoshikawa(1985)提出用操纵度 w 量化当前构型的灵活性:
字母含义:
-
:操纵度指标, 时处于奇异点 -
:行列式,捕捉雅可比所有方向上的"体积"缩减程度 -
:操纵度椭球(Manipulability Ellipsoid)的形状矩阵
U, sigma, Vt = svd(J)# sigma: 各方向的放大因子,最小值趋0 = 即将奇异# 奇异方向 = U中对应最小sigma的列w = prod(sigma) # 等价于 sqrt(det(J@J.T))
越大,机器人在当前构型下对末端各方向的控制能力越均衡。
在路径规划阶段把 作为代价函数的一项,可以主动让轨迹绕开奇异区域。


冗余自由度:零空间是"免费的算力"
零空间的数学结构
当 (如7轴机械臂、人形机器人手臂、灵巧手),关节空间的维度高于任务空间,雅可比的零空间()非平凡:
对任意向量,投影到零空间:
字母含义:
-
:雅可比的 Moore-Penrose 伪逆 -
: 阶单位矩阵 -
:零空间投影算子(Null Space Projector),将任意向量投影到零空间 -
:任意向量,用来编码次级任务的优化方向
关键性质:
即零空间运动对末端位姿没有任何影响。
任务优先级分解(Task Priority Framework)
完整的冗余机器人控制律为:
字母含义:
-
:主任务项——完成末端位姿跟踪(最小范数解) -
:次级任务项——在不影响末端的前提下优化 -
:次级代价函数,例如:(最大化操纵度) -
(保持在关节中间位置) -
(避障)
def redundant_ik_step(q, x_target, g_func):J = compute_jacobian(q)J_pinv = pinv(J)# 主任务:追踪末端位姿x_cur = fk(q)dx = compute_error(x_cur, x_target) # 6D误差旋量dq_primary = J_pinv @ dx# 次级任务:在零空间中优化 g(q)grad_g = numerical_gradient(g_func, q)null_proj = I - J_pinv @ Jdq_secondary = null_proj @ grad_greturn dq_primary + dq_secondary

场景痛点 × 解决方案 × 关键代码
场景 A:高速工业分拣(实时性第一)
痛点:传送带节拍 ≤ 0.5s,IK 必须在 ≤ 1ms 内给出关节角,还要从多解中选无碰撞最优解。

解决方案:针对固定构型(满足 Pieper 条件)预推解析解,离线生成闭式代码;运行时纯查表+atan2计算,无迭代。
关键代码(IKFAST 风格输出片段):
def ik_joint1(px, py, pz, d1, a2, a3, d4):# 由腕心(px,py,pz)解第1关节# px,py: 腕心在基坐标xy平面的投影# d1: 机座到第1关节的高度偏置r = sqrt(px**2 + py**2) # 腕心在水平面的半径theta1_up = atan2(py, px)theta1_down = atan2(-py, -px) # 机器人"翻转"构型return theta1_up, theta1_downdef ik_joint3(r, pz, d1, a2, a3, d4):# 用余弦定理求肘关节角# r: 腕心水平距离, pz: 腕心高度D = (r**2 + (pz-d1)**2 - a2**2 - a3**2) / (2*a2*a3)# D 即 cos(θ3),|D|>1 则目标超出工作空间if abs(D) > 1.0:raise WorkspaceError("Target unreachable")theta3_elbow_up = atan2(+sqrt(1 - D**2), D)theta3_elbow_down = atan2(-sqrt(1 - D**2), D)return theta3_elbow_up, theta3_elbow_down
场景 B:7轴冗余臂避障(灵活性第一)
痛点:末端路径固定(如沿缝焊接),但中间连杆必须绕开一个动态障碍物。额外的第7个自由度是解决冗余的钥匙,但如何使用它是个优化问题。

解决方案:零空间投影,次级任务 = 最大化机器人与障碍物的最短距离。
关键公式:
-
:机器人与障碍物的最短距离,关于 的函数 -
:次级任务增益,调节避障激进程度 -
:距离对关节角的梯度(可用 /bullet 的距离查询 + 数值差分计算)
def obstacle_avoidance_secondary(q, obstacle_mesh, k0=0.5):# 计算当前构型到障碍物的最短距离梯度dq = 1e-5grad = zeros(n)for i in range(n):q_plus = q.copy(); q_plus[i] += dqq_minus = q.copy(); q_minus[i] -= dqd_plus = min_distance_to_obstacle(fk_all_links(q_plus), obstacle_mesh)d_minus = min_distance_to_obstacle(fk_all_links(q_minus), obstacle_mesh)grad[i] = (d_plus - d_minus) / (2 * dq)return k0 * grad # 作为 z 向量传入零空间投影
场景 C:灵巧手高自由度 IK(维度爆炸)
痛点:五指灵巧手通常有 20+ 自由度,传统数值 IK 在高维关节空间收敛慢,多解问题更加严重。

解决方案:学习型 IK——用 Normalizing Flow 建模的分布,推理时采样多组解。
IKFlow 核心思路(IKFlow: Generating Diverse Inverse Kinematics Solutions, 2022):
训练阶段:随机采样大量合法关节角 q ~ U(q_min, q_max)计算对应的 T = fk(q)用 (q, T) 训练 Normalizing Flow 网络 F:F: (z ~ N(0,I), T_target) -> q目标:F(F^{-1}(q | T)) = q(可逆映射,精确似然)推理阶段:输入 T_target从标准正态 z_1, z_2, ..., z_K 采样 K 个噪声q_i = F(z_i, T_target) # 并行生成 K 个候选解过滤 fk(q_i) 距 T_target 误差 > ε 的解从合法解中选关节位移最小的
-
推理速度:单次前向传播,K=100 个解在 GPU 上约 5ms
-
适用场景:灵巧手抓取规划、人形机器人全身 IK
当灵巧手开展拧瓶盖、USB 插拔等精细装配操作时,受传感器噪声、接触不确定性影响,仅依靠单一逆运动学解鲁棒性较差,需要解集候选池支撑上层重决策。
IKFlow 能够采样多样化逆运动学候选解,天然匹配 “批量生成候选 + 约束择优” 的分层规划范式;
在建模思想层面,该生成式思路与 Diffusion Policy 等基于扩散模型的动作生成框架具备良好兼容性,可构建 “笛卡尔动作规划→多候选 IK 求解→关节轨迹筛选” 的分层控制链路。

工程落地的"脏活"清单


写在最后
正运动学是一道函数题;逆运动学是一道反函数题,而且这个反函数是多值的、不连续的,在某些点上根本不存在。
从 DH 参数到 SE(3) 李群,从解析剥离到雅可比迭代,从阻尼最小二乘到零空间投影,再到 Normalizing Flow——IK 的每一层解法,都是在用不同的数学工具逼近同一件事:
在物理约束和实时性压力下,找到那个让机器人"够到"目标的关节配置。
具身智能时代让 IK 的重要性再次上升:当机器人需要在非结构化环境中完成开放任务,IK 不再只是一个控制模块,而是连接感知、规划和执行的核心接口。
解的质量、速度和鲁棒性,直接决定了整个系统的上限。
正向/逆向运动学、轨迹生成与运动规划等核心模块,覆盖了本专栏正在连载的完整具身智能基础知识体系⬇️

编辑|小小怪博士
审编|具身君
扫码添加阿蓝,选择想要加入的交流群即可
(按照提交顺序邀请,请尽早选择)
👇
