4. 机械臂运动学基础

各位同学好,我是你们的机器人工程师老张。今天咱们来聊聊机械臂运动学——说白了,就是研究「机械臂怎么动」这件事。

我记得刚入行那会儿,带我的老师傅跟我说过一句话:「不懂运动学,你连机械臂怎么摆姿势都算不明白。」当时我不信,直到第一次调试六轴臂,发现末端死活对不准目标点……嗯,从那以后我老老实实把运动学啃了一遍。

4.1 正运动学 vs 逆运动学:两个方向的问题

先搞清楚这两个概念,其实特别简单:

  • 正运动学:我知道每个关节转了多少度,求末端在哪儿、朝哪个方向。
  • 逆运动学:我知道末端要去哪个位置、什么姿态,反推每个关节该转多少度。

你想想看,正运动学就像你看着自己的胳膊——你知道肩膀和肘弯了多少,自然知道手在哪儿。逆运动学呢?你想去够桌上的水杯,大脑自动算出肩膀和肘该弯多少——这就是逆运动学。

在Gazebo里做抓取,逆运动学才是核心。因为你要告诉机械臂:「去那个位置抓东西」,而不是「关节1转30度,关节2转45度……」。后者太反人类了。

关键点:正运动学有唯一解,逆运动学可能有多个解、甚至无解。我在项目里遇到过逆运动学无解的情况——目标点太远,机械臂够不着。这时候要么调整目标位置,要么换个臂展更长的机械臂。

4.2 DH参数法:给机械臂建个数学模型

DH参数法,全称Denavit-Hartenberg参数法。说白了,就是用四个参数来描述相邻两个关节之间的变换关系。

为什么需要它?因为机械臂的关节和连杆是连在一起的,你没法单独算每个关节。DH参数法给了我们一套标准流程:

  1. 在每个关节上建坐标系
  2. 用四个参数描述相邻坐标系的关系
  3. 连乘得到末端位姿

四个参数分别是:

参数 含义 我的理解
θ (theta) 绕Z轴的旋转角 关节转动的角度
d 沿Z轴的平移距离 连杆的偏置
a 沿X轴的平移距离 连杆的长度
α (alpha) 绕X轴的旋转角 连杆的扭转

我个人的习惯是,拿到一个机械臂先画DH参数表。画完表,运动学就完成了一半。剩下的就是矩阵乘法了。

小技巧:DH参数有两种约定——标准DH和改进DH。Gazebo里常用改进DH(也叫Modified DH)。区别在于坐标系建在关节的前端还是后端。我建议你统一用改进DH,省得搞混。

4.3 用Python算正运动学

理论讲完了,咱们来点实际的。下面是我写的一个简单正运动学计算函数,用的是改进DH参数:

import numpy as np

def dh_transform(theta, d, a, alpha):
    """
    计算相邻关节的变换矩阵(改进DH)
    theta: 关节角度(弧度)
    d: 连杆偏置
    a: 连杆长度
    alpha: 连杆扭转(弧度)
    """
    ct = np.cos(theta)
    st = np.sin(theta)
    ca = np.cos(alpha)
    sa = np.sin(alpha)
    
    T = np.array([
        [ct, -st, 0, a],
        [st*ca, ct*ca, -sa, -d*sa],
        [st*sa, ct*sa, ca, d*ca],
        [0, 0, 0, 1]
    ])
    return T

# 举个例子:一个两连杆机械臂
# 关节1:theta=30°, d=0, a=1, alpha=0
# 关节2:theta=45°, d=0, a=0.8, alpha=0

T1 = dh_transform(np.radians(30), 0, 1, 0)
T2 = dh_transform(np.radians(45), 0, 0.8, 0)

# 末端位姿 = T1 * T2
T_end = T1 @ T2
print("末端位姿矩阵:")
print(T_end)

# 提取位置
position = T_end[:3, 3]
print(f"末端位置:x={position[0]:.3f}, y={position[1]:.3f}, z={position[2]:.3f}")

这段代码我用了好多年,从两轴到六轴都能用。你只需要把DH参数表填进去,然后依次乘起来就行。

注意:角度一定要用弧度!我见过太多人直接传度数进去,结果算出来的位置完全不对。Python的math.radians()和np.radians()是你的好朋友。

4.4 逆运动学:没那么简单

正运动学是「一条路走到黑」,逆运动学就复杂多了。对于六轴机械臂,逆运动学通常没有解析解,需要用数值方法迭代求解。

常用的方法有:

  • 解析法:只适用于特定构型的机械臂(比如前三个关节轴线交于一点)
  • 数值法:通用,但计算量大,可能有收敛问题
  • 几何法:针对简单构型,比如平面两连杆

在Gazebo里,我们通常用moveit的逆运动学求解器。它背后用的是数值法——说白了就是不断迭代,让误差越来越小。

我曾经自己手写过逆运动学求解器,用的是牛顿-拉夫森法。效果还行,但遇到奇异位形就崩了。后来我学乖了,直接用现成的库——别重复造轮子,除非你想练手。

4.5 本章知识体系

下面这张图是我画的运动学知识结构,帮你理清思路:

机械臂运动学知识体系 正运动学 输入:关节角度 输出:末端位姿 方法:DH参数 + 矩阵连乘 唯一解,计算简单 逆运动学 输入:末端位姿 输出:关节角度 方法:解析法 / 数值法 多解 / 无解 / 奇异位形 DH参数法(核心工具) θ, d, a, α → 变换矩阵 → 运动学方程 Python实现 numpy矩阵运算 · 迭代求解 · 可视化验证

这张图把运动学的核心脉络理清楚了。你从DH参数出发,往左走是正运动学,往右走是逆运动学。Python实现则是把理论落地成代码。

4.6 避坑指南

最后分享几个我踩过的坑:

  • 坐标系方向搞反:DH参数里Z轴方向很重要,搞反了算出来的位置镜像对称。我建议你画图确认每个关节的Z轴方向。
  • 角度范围没考虑:逆运动学算出来的角度可能超出关节限位。一定要做限位检查,否则Gazebo里会出诡异动作。
  • 奇异位形:当两个关节轴线平行时,逆运动学可能突然失效。遇到这种情况,我一般会加一个「避奇异」的约束条件。

我的建议:刚开始学运动学,先用两轴或三轴机械臂练手。把正运动学和逆运动学的代码跑通,再上六轴。别一上来就搞复杂的,容易劝退。

好了,运动学基础就讲到这里。下一节咱们会把这些知识用到Gazebo里,让机械臂真正动起来。

可可精品资料库