正运动学从关节变量计算末端状态;逆运动学则寻找满足目标末端状态的关节变量。后一问题可能多解、无解,也可能只得到近似解。

“求解器返回了一组数字”和“机器人能够安全到达目标”之间,还有很多检查。这篇先用独立推导的二维几何例子说明最基本的一项:把解代回正运动学。

二连杆平面例子

设两根杆长分别为 l1、l2,关节角为 q1、q2。末端位置为:

x = l1*cos(q1) + l2*cos(q1 + q2)
y = l1*sin(q1) + l2*sin(q1 + q2)

用余弦定理可求出一个分支的逆解。以下代码仅进行数学计算,不连接仿真器或真实设备。

from math import acos, atan2, cos, hypot, isfinite, sin

def inverse_two_links(x, y, l1=1.0, l2=1.0):
    if not all(isfinite(v) for v in (x, y, l1, l2)) or min(l1, l2) <= 0:
        raise ValueError("invalid geometry")
    c2 = (x*x + y*y - l1*l1 - l2*l2) / (2*l1*l2)
    if abs(c2) > 1 + 1e-10:
        raise ValueError("unreachable target")
    q2 = acos(max(-1.0, min(1.0, c2)))
    q1 = atan2(y, x) - atan2(l2*sin(q2), l1 + l2*cos(q2))
    return q1, q2

q1, q2 = inverse_two_links(1.0, 1.0)
x_check = cos(q1) + cos(q1 + q2)
y_check = sin(q1) + sin(q1 + q2)
assert hypot(x_check - 1.0, y_check - 1.0) < 1e-9
try:
    inverse_two_links(3.0, 0.0)
except ValueError:
    pass
else:
    raise AssertionError("an unreachable target was accepted")
print("IK round-trip and unreachable-target checks passed")

这里取的是一个分支,尚未处理关节限位、碰撞、奇异位形附近的稳定性或轨迹连续性。极小的浮点误差可以限幅修正,但不能把明显不可达的目标强行截断成“可达”。

从课堂示例扩展到仿真时的检查

  • 核对末端 link、参考坐标系、长度单位和角度单位。
  • 分清目标位置与目标姿态;只约束位置不代表姿态也符合要求。
  • 检查解的限位、残差与相邻时刻的连续性,不仅看求解是否返回。
  • 保持“求角度”“规划路径”“控制执行”这三个问题的区别。

课堂例子使用了数值求解器,但不能据此概括成“所有 IK 都没有解析解”。本篇二连杆例子就有几何解。也不能将仿真中的短代码直接用作真实设备的安全控制程序。

课程对应与整理边界

对应疏锦行《26 强化学习专题》的《05_逆运动学》及逆运动学视频目录。当前这部分实际是机器人仿真与运动学基础,不把它冒称为已经完成策略训练的强化学习项目。示例为独立推导,视频口头补充尚未完整核验。

原课程