3. 运动学基础(二):DH参数法、正运动学建模、逆运动学求解初步

好,咱们接着聊。上一节我们把坐标系变换和旋转矩阵这些基本功打扎实了。这一节,我们要解决一个实际问题:怎么用数学描述一个机器人手臂的每个关节? 然后,怎么算出末端执行器在哪儿(正运动学),以及反过来,知道末端位置怎么反推关节角度(逆运动学)。

我个人习惯,做运动学分析前,先画一张图把整个逻辑理清楚。你看下面这张图,就是咱们这一节要讲的核心脉络。

运动学基础(二)知识体系 机器人运动学建模 DH参数法 a, α, d, θ 四个参数 坐标系建立规则(Craig法) 正运动学建模 齐次变换矩阵连乘 T = T1 * T2 * ... * Tn 逆运动学求解初步 解析法 vs 数值法 多解与奇异问题 目标:实现关节空间 ↔ 笛卡尔空间 的映射

3.1 DH参数法:给每个关节一个身份证

DH参数法,说白了就是一套标准流程。你按照这个流程,给每个连杆和关节贴上四个参数,就能唯一确定它们之间的相对位置和姿态。

这四个参数分别是:

  • ai-1(连杆长度):沿着 xi-1 轴,从 zi-1 到 zi 的距离。
  • αi-1(连杆扭转角):绕着 xi-1 轴,从 zi-1 转到 zi 的角度。
  • di(连杆偏距):沿着 zi 轴,从 xi-1 到 xi 的距离。
  • θi(关节角):绕着 zi 轴,从 xi-1 转到 xi 的角度。

嗯,这里要注意。坐标系怎么建,不同教材有不同习惯。我个人比较推荐 Craig 的建系方法,也就是《Introduction to Robotics》那本书里的。为什么?因为它的规则最清晰,不容易搞混。

我的小技巧: 建系的时候,先找 z 轴(关节轴线),再找 x 轴(公垂线方向)。记住一句话:z 轴是转动的轴,x 轴是连杆的方向。这样不容易乱。

有了这四个参数,我们就可以写出相邻连杆的齐次变换矩阵了。公式长这样:

i-1T_i = Rot(x, αi-1) * Trans(x, ai-1) * Rot(z, θi) * Trans(z, di)

展开成矩阵形式:

| cosθi   -sinθi   0    ai-1 |
| sinθicosαi-1  cosθicosαi-1  -sinαi-1  -disinαi-1 |
| sinθisinαi-1  cosθisinαi-1   cosαi-1   dicosαi-1 |
| 0        0         0    1       |

你想想看,这个矩阵其实就干了一件事:把上一个坐标系里的点,变换到下一个坐标系里。

3.2 正运动学建模:从关节到末端

正运动学,说白了就是已知每个关节的角度(或者位移),求末端执行器在空间中的位姿。

怎么做?很简单。把每个相邻连杆的变换矩阵乘起来就行。

0T_n = 0T_1 * 1T_2 * 2T_3 * ... * n-1T_n

这个 0T_n 矩阵的左上角 3x3 是姿态(旋转矩阵),右上角 3x1 是位置(平移向量)。

我记得有一次做六轴机械臂的仿真,正运动学算出来末端位置总是差几毫米。查了半天,发现是 DH 参数表里一个 a 值写错了。所以啊,参数表一定要反复核对,尤其是从 CAD 模型里提取尺寸的时候。

核心要点: 正运动学是唯一的。给定一组关节角,末端位姿是确定的。这是逆运动学求解的基础。

下面是一个简单的 Python 示例,用 numpy 实现正运动学计算:

import numpy as np

def dh_transform(a, alpha, d, theta):
    """计算相邻连杆的齐次变换矩阵"""
    ct = np.cos(theta)
    st = np.sin(theta)
    ca = np.cos(alpha)
    sa = np.sin(alpha)
    
    T = np.array([
        [ct, -st*ca,  st*sa, a*ct],
        [st,  ct*ca, -ct*sa, a*st],
        [0,   sa,     ca,    d],
        [0,   0,      0,     1]
    ])
    return T

# 示例:一个2自由度平面臂
# DH参数表:a, alpha, d, theta
dh_params = [
    [1.0, 0, 0, np.pi/4],   # 关节1
    [0.8, 0, 0, np.pi/6]    # 关节2
]

T = np.eye(4)
for params in dh_params:
    T = T @ dh_transform(*params)

print("末端位姿矩阵:")
print(T)
print("末端位置:", T[:3, 3])

3.3 逆运动学求解初步:从末端到关节

逆运动学就麻烦多了。已知末端位姿,求关节角。这玩意儿通常不是唯一的,甚至可能无解。

为什么?你想想看,一个六轴机械臂,末端在空间中有 6 个自由度(3 个位置 + 3 个姿态)。但有些姿态就是够不到,比如让手臂扭到背后去。这就是工作空间限制。

求解方法主要有两类:

  • 解析法(封闭解):通过几何关系或代数推导,直接写出关节角的表达式。速度快,精度高,但不是所有机器人都有解析解。
  • 数值法(迭代法):比如牛顿-拉夫森法、雅可比伪逆法。通用性强,但计算慢,而且可能陷入局部最优。
我曾经踩过的坑: 用数值法做逆运动学求解时,初始值选不好,迭代半天不收敛。后来我学乖了,先用解析法算一个粗略解,再用数值法精调。这叫「粗精结合」,效果很好。

对于人形机器人来说,逆运动学还有个特殊问题:冗余自由度。人形机器人通常有几十个关节,但末端任务只需要 6 个自由度。多出来的自由度怎么用?可以用来避障、优化能耗、保持平衡等等。

举个例子,让机器人伸手去拿桌子上的杯子。你可以用肘部朝外,也可以肘部朝下。两种方式都能拿到杯子,但稳定性完全不同。这就是冗余自由度带来的「多解」问题。

处理多解,我一般用 关节限位约束 + 最小范数解。先排除超出关节范围的解,再选一个关节运动量最小的。这样机器人动作看起来最自然,也最省电。

一句话总结: 正运动学是「因」到「果」,逆运动学是「果」找「因」。做控制的时候,我们大部分时间都在和逆运动学打交道。

好了,这一节的内容就到这儿。DH 参数法给了我们标准化的建模工具,正运动学让我们能预测末端位姿,逆运动学则是控制的基础。下一节我们会深入逆运动学的具体求解方法,包括雅可比矩阵和奇异位形分析。

可可精品资料库