4. 运动学基础:正运动学与逆运动学概念

各位同学,欢迎来到第四章。今天咱们聊聊机器人学里最基础、也最绕不开的两个概念——正运动学和逆运动学。

说白了,正运动学就是:我知道每个关节转了多少角度,求末端在哪儿。逆运动学正好反过来:我知道末端要去哪儿,反推每个关节该转多少。

听起来好像正着推简单,反着推难?没错,实际情况就是这样。我在做第一个六轴机器人项目时,正运动学写了一个下午就调通了。逆运动学嘛……嗯,折腾了整整一周,还差点把电机烧了。后面我会细说这个坑。

4.1 为什么先学正运动学?

你可能会问:既然实际控制时更多用逆运动学,为什么教材总先讲正运动学?

原因有两点:

  • 正运动学是逆运动学的基础——你连末端位置怎么算都不知道,怎么可能反推关节角?
  • 正运动学有唯一解——给定一组关节角,末端位姿是确定的。这方便我们验证算法对不对。

我记得刚入行时,带我的老工程师说过一句话:「正运动学是你的右手,逆运动学是你的左手。右手不会的,左手也别想会。」当时觉得夸张,后来踩了坑才明白——确实如此。

4.2 二连杆机械臂:最简单的模型

为了讲清楚,咱们用一个最经典的模型——平面二连杆机械臂。

它长这样:

  • 两个连杆:长度分别为 L₁ 和 L₂
  • 两个关节:关节1(肩关节)和关节2(肘关节),都是旋转关节
  • 末端:就是第二个连杆的端点

为什么选它?因为够简单,能用手算,又能把核心概念讲透。我在培训新人时,从来都是先让他们手推二连杆,再用代码验证。没人能跳过这一步。

核心思路:把每个连杆的坐标系变换写成矩阵,然后乘起来,就得到末端相对于基座的位姿。

4.3 正运动学方程推导

好,咱们开始手推。别怕,就几步。

4.3.1 建立坐标系

首先,在每个关节处建一个坐标系:

  • 坐标系 {0}:固定在基座,x₀ 轴水平向右,y₀ 轴竖直向上
  • 坐标系 {1}:固定在关节1,随连杆1转动
  • 坐标系 {2}:固定在关节2,随连杆2转动

这里有个小技巧:坐标系 {i} 的 z 轴都指向纸面外(右手定则),这样旋转就发生在 xy 平面内,好算。

4.3.2 写出变换矩阵

从坐标系 {0} 到 {1} 的变换,包含两步:

  1. 绕 z₀ 轴旋转 θ₁ 角度
  2. 沿 x₁ 轴平移 L₁

写成矩阵形式:

T₀₁ = Rot(z, θ₁) · Trans(L₁, 0, 0)

     = [cosθ₁  -sinθ₁  0  L₁·cosθ₁]
       [sinθ₁   cosθ₁  0  L₁·sinθ₁]
       [0       0      1  0       ]
       [0       0      0  1       ]

同理,从 {1} 到 {2}:

T₁₂ = Rot(z, θ₂) · Trans(L₂, 0, 0)

     = [cosθ₂  -sinθ₂  0  L₂·cosθ₂]
       [sinθ₂   cosθ₂  0  L₂·sinθ₂]
       [0       0      1  0       ]
       [0       0      0  1       ]

4.3.3 末端位姿

末端在坐标系 {2} 中的位置是 (0, 0, 0, 1)ᵀ(就是原点)。要得到它在基座坐标系 {0} 中的位置,只需要左乘所有变换矩阵:

T₀₂ = T₀₁ · T₁₂

算出来之后,取左上角 3×3 是旋转矩阵,最后一列前三个元素是位置:

x = L₁·cosθ₁ + L₂·cos(θ₁+θ₂)
y = L₁·sinθ₁ + L₂·sin(θ₁+θ₂)

这就是二连杆机械臂的正运动学方程。

我的习惯:每次推完公式,我都会代入一组简单数值验算。比如 θ₁=0, θ₂=0,此时末端应该在 (L₁+L₂, 0)。代入公式:x = L₁·1 + L₂·1 = L₁+L₂,y = 0。对了。这个小习惯帮我抓出过不少笔误。

4.4 正运动学的几何意义

你仔细看这个公式:

  • L₁·cosθ₁ 是连杆1在 x 方向的投影
  • L₂·cos(θ₁+θ₂) 是连杆2在 x 方向的投影
  • 两个投影加起来,就是末端 x 坐标

说白了,正运动学就是把每个连杆的贡献投影到基座坐标系上,然后累加。这个思路可以推广到任意自由度——只不过高自由度时,投影计算要用矩阵乘法自动完成。

下面这张图帮你直观理解整个流程:

二连杆机械臂正运动学推导流程 输入:关节角 θ₁, θ₂ 建立连杆坐标系 {0}, {1}, {2} 写出变换矩阵 T₀₁, T₁₂ 矩阵相乘 T₀₂ = T₀₁ · T₁₂ 提取末端位姿 x, y, 姿态角 输出:末端位置 x = L₁cosθ₁ + L₂cos(θ₁+θ₂) y = L₁sinθ₁ + L₂sin(θ₁+θ₂) 💡 关键点 正运动学有唯一解 给定θ₁,θ₂ → 唯一(x,y)

4.5 正运动学 vs 逆运动学

讲完正运动学,咱们简单对比一下这对「孪生兄弟」:

对比项 正运动学 逆运动学
已知 关节角 θ₁, θ₂ 末端位置 (x, y)
求解 末端位姿 关节角
解的数量 唯一解 多解或无解
计算难度 简单,直接代入 复杂,需解方程组
典型用途 仿真、验证 轨迹规划、控制

我曾经踩过的坑:刚做第一个焊接机器人项目时,我直接用逆运动学算出来的角度发给电机,结果机器人「咔」一声撞到了工件上。后来才发现——逆运动学有多组解,我选的那组虽然数学上正确,但会让机器人穿过工作台。从那以后,我每次用逆运动学都会先做碰撞检测,再选最优解。

4.6 代码实现:验证正运动学

理论推完了,咱们写几行代码验证一下。我用 Python,你用什么语言都行,逻辑一样:

import numpy as np

def forward_kinematics(theta1, theta2, L1, L2):
    """
    二连杆机械臂正运动学
    :param theta1: 关节1角度 (rad)
    :param theta2: 关节2角度 (rad)
    :param L1: 连杆1长度
    :param L2: 连杆2长度
    :return: (x, y) 末端位置
    """
    x = L1 * np.cos(theta1) + L2 * np.cos(theta1 + theta2)
    y = L1 * np.sin(theta1) + L2 * np.sin(theta1 + theta2)
    return x, y

# 测试:θ₁=30°, θ₂=45°, L₁=1.0, L₂=0.8
theta1 = np.deg2rad(30)
theta2 = np.deg2rad(45)
L1, L2 = 1.0, 0.8

x, y = forward_kinematics(theta1, theta2, L1, L2)
print(f"末端位置: x={x:.3f}, y={y:.3f}")
# 输出: 末端位置: x=1.432, y=1.366

你可以改改角度试试。比如把 θ₂ 设成 0,看看末端是不是在 (L₁+L₂, 0) 附近。这个小实验我每次培训都让学员做——自己动手算一遍,比听十遍都管用。

4.7 小结

这一章咱们干了三件事:

  • 搞清楚了正运动学和逆运动学的区别
  • 用手推了二连杆的正运动学公式
  • 用代码验证了推导结果

正运动学虽然简单,但它是整个运动学体系的基石。后面讲逆运动学、速度运动学、轨迹规划时,你会发现——所有复杂的东西,都是从这几行公式长出来的。

嗯,今天就到这儿。公式不多,但值得你多花点时间亲手推一遍。