前言

  • 最近我们一直在玩转无人机和 SLAM,再我们继续解读新的算法和代码之前,我们来玩一点不一样的
  • 刚好最近 VLA(Vision-Language-Action,视觉-语言-动作)具身智能火得不行,从谷歌的 RT-2OpenVLAπ0,大模型开始直接输出机器人动作,而这一切的物理载体,正是机械臂
  • 所以接下来这个系列,我们将逐步上手最近大火的 VLA 具身智能机械臂,计划从 机械臂基础 → MoveIt2 + Gazebo 仿真 → Pinocchio 刚体动力学 → VLA 入门一路推进
  • 本期我们先不碰仿真和代码框架,专注把地基打牢——机械臂基础:机械臂的结构组成、坐标系与位姿表示、正逆运动学、雅可比与奇异位形、动力学、运动规划与控制
  • 全文较长,分上、下两篇:上篇为机械臂建模(第 1-5 章:结构、位姿、运动学、速度运动学、动力学),下篇为规划与控制(第 6-8 章)+ 全部可视化代码附录
    请添加图片描述

目录(本文为上篇,覆盖第 1-5 章)


1 机械臂基础概念

请添加图片描述

1-1 机械臂是什么
  • 机械臂(Manipulator)本质上是一个由连杆(Link)关节(Joint) 串联组成的多刚体链式机构
  • 它一端固定在基座(Base) 上,另一端安装末端执行器(End Effector),通过控制各个关节的转动/平动,把末端送到期望的位置和姿态
  • 说人话:机械臂就是一条"骨头 + 关节链"——骨头是连杆,关节是骨头之间的"转轴/滑轨",最前面那只"手"就是末端执行器
  • 一台完整的机械臂系统,从硬件到控制,可以拆成下面几层:
层次 组成 回答的问题
机械结构 连杆 + 关节 + 电机 + 减速器 机械臂长什么样
运动学 关节角 → 末端位姿 末端在哪、怎么动
动力学 力矩 ↔ 运动 需要多大的力/力矩
运动规划 轨迹生成 从 A 点到 B 点怎么走
控制 电机伺服 + 力控 怎么让机械臂"听话"

核心思想:机械臂的所有"智能",本质上都在回答一个问题——“我的关节该转多少”。运动学告诉你关节和末端的映射关系,规划告诉你关节随时间怎么变化,控制负责把这个变化"逼真"地执行出来

1-2 关节 Joint
  • 关节是机械臂运动的"发动机",也是相邻两个连杆之间的运动副
  • 运动副(Kinematic Pair)是机械原理(机构学)里的术语,指两个构件直接接触、又能产生相对运动的可动连接
  • 在机构学里,任何机构都由两类东西组成:构件(Link)+ 运动副(Pair)——机械臂本质就是一条由连杆(构件)和关节(运动副)组成的开链机构

说人话:运动副就是"两个零件搭在一起、还能相对动"的连接方式。机械臂里叫它"关节",机构学里叫它"运动副",指同一个东西——转动副 = 旋转关节,移动副 = 移动关节

  • 按接触形式,运动副分两类:
类别 接触方式 例子
低副 面接触(接触面积大,耐磨) 转动副、移动副
高副 点/线接触(能实现复杂运动) 齿轮啮合、凸轮
  • 机械臂几乎全用低副——结构简单、承载大、控制也容易
    请添加图片描述

  • 实际机械臂中绝大多数关节都只提供 一个 自由度(详见1-4),主要分两类:

  • 旋转关节(Revolute Joint)

    • 让相邻连杆绕着一个固定轴线旋转,就像门轴
    • 只有一个旋转自由度,用关节角 q i q_i qi 描述
    • 绝大多数工业机械臂(UR、KUKA、ABB)的主关节都是旋转关节
  • 移动关节(Prismatic Joint)

    • 让相邻连杆沿一个固定轴线做直线滑动,就像抽屉
    • 只有一个平移自由度,用关节位移 d i d_i di 描述
    • 常见于直角坐标机械臂或某些并联机构的支腿
  • 除了这两类主关节,还有球关节(Spherical Joint,3 个自由度)圆柱关节(Cylindrical Joint,2 个自由度) 等,但在机器人领域出于结构可靠、控制简单的考虑,几乎都拆成多个旋转/移动关节的组合

说人话:旋转关节就是"转",移动关节就是"滑"。一台 6 自由度机械臂,绝大多数情况下就是 6 个旋转关节——每个关节只负责转一个角度,6 个角度一配合,末端就能在空间里自由翱翔

1-3 连杆 Link

请添加图片描述

  • 连杆是机械臂的"骨头"——连接相邻两个关节的刚性部件
  • 我们通常用连杆 i 表示连接关节 i 和关节 i+1 的刚体,它本身不产生运动,只负责把运动"传递"下去
  • 描述连杆要用两个核心尺寸:
    • 连杆长度 a i − 1 a_{i-1} ai1:沿公法线方向,关节轴 z i − 1 z_{i-1} zi1 到关节轴 z i z_i zi 的距离
    • 连杆偏距 d i d_i di:沿关节轴 z i z_i zi 方向,相邻两连杆公垂线之间的距离
    • (这两个量正是 DH 参数的核心,详见 3-4 节

说人话:关节负责"转",连杆负责"撑"。两个关节之间必须有根杆子连起来,杆子的长度和朝向直接决定了末端能摸到哪里

1-4 自由度 DOF

请添加图片描述

  • 自由度(Degree of Freedom,DOF)指确定机械臂位形所需的最少独立变量个数

  • 一个自由物体在三维空间有 6 个自由度:3 个平动( x , y , z x, y, z x,y,z)+ 3 个转动(roll, pitch, yaw)

  • 要让末端能到达工作空间内任意位置和姿态,机械臂至少需要 6 个自由度

  • 少于 6 个叫欠驱动(underactuated),多于 6 个叫冗余机械臂(redundant)——比如 7 自由度的 KUKA LBR iiwa,多出来的自由度让机械臂能在保持末端位姿不变的情况下调整自身姿态,方便避障

  • 请添加图片描述

  • 机械臂总自由度是各关节自由度之和:

n D O F = ∑ i = 1 m f i n_{DOF} = \sum_{i=1}^{m} f_i nDOF=i=1mfi

  • 其中 f i f_i fi 是第 i i i 个关节的自由度数。对 6 个旋转关节的机械臂, n D O F = 6 n_{DOF} = 6 nDOF=6

说人话:自由度就是"这台机器能独立变几个参数"。6 自由度 = 末端位置 3 个 + 姿态 3 个,正好凑齐;7 自由度 = 多了一个"手臂摆造型"的自由,避障时特别好用

1-5 末端执行器 End Effector

请添加图片描述

  • 末端执行器是安装在机械臂最前端、真正与物体/环境接触的装置
  • 常见类型如下:
末端执行器 典型用途
二指/多指夹爪 抓取、搬运
吸盘 抓取平整表面物体(纸箱、玻璃)
焊枪/喷枪 焊接、喷涂
电动/气动螺丝刀 装配
夹爪 + 力传感器 力控、柔性抓取
  • 在 VLA 具身智能里,末端执行器就是大模型输出动作的"执行端"——模型预测夹爪开合和位置,机械臂把它变成物理上的抓取
  • 最简单的二指夹爪就两个状态:开 = 放松,合 = 夹紧,配合机械臂运动就能完成"抓取 - 搬运 - 放置"的完整闭环

说人话:末端执行器就是机械臂的"手"。运动学把"手"送到位,夹爪决定"手"抓不抓。VLA 模型输出的最终指令,就是"手该去哪 + 手该抓还是放"


2 坐标系与位姿

  • 机械臂运动学要做的事,本质上是在坐标系之间做变换
  • 描述一个刚体的位置和朝向,合起来叫位姿(Pose) = 位置(Position)+ 姿态(Orientation)
  • 我们在 SLAM 里天天打交道的那套东西——TF、外参、SE(3)——在这里全部原样复用
2-1 位置 Position
  • 位置描述刚体上某点在参考系中的坐标,是一个 3 维向量:

p = [ x y z ] ∈ R 3 p = \begin{bmatrix} x \\ y \\ z \end{bmatrix} \in \mathbb{R}^3 p= xyz R3

  • 描述机械臂时,每个连杆都有一个自己的坐标系,位置就是这些坐标系原点之间的平移关系
2-2 姿态 Orientation
  • 位置说完了,还差朝向。姿态(Orientation) 描述刚体相对参考系的朝向,本质是一次旋转
  • 位置是"在哪",姿态是"朝哪"。描述姿态不像位置那样直接给 3 个数就行,它有多种表示方式
  • 三种主流表示,各有优劣:
表示 个数 优点 缺点 典型用途
旋转矩阵 9 数学标准、便于连乘 冗余(9 个数 3 个独立量) 运动学、动力学推导
欧拉角 3 直观,人一眼看懂 万向锁、插值不平滑 人机交互、调试显示
四元数 4 无万向锁、插值平滑 不直观 ROS / MoveIt2 内部存储
  • 下面依次介绍:先讲数学标准表示旋转矩阵,再讲直观的欧拉角和工程常用的四元数
  • 三种表示之间可以互相转换:欧拉角 ↔ 旋转矩阵、四元数 ↔ 旋转矩阵,工程代码里拿到哪种就转哪种

说人话:姿态有三种"写法",旋转矩阵像正规档案、欧拉角像口头描述、四元数像机器编码。内容都一样,看场合选一种。下面一个个讲

2-3 旋转矩阵 Rotation Matrix
  • 姿态的标准数学表示是旋转矩阵 R R R
2-3-1 定义
  • 旋转矩阵是一个正交矩阵,属于三维旋转群 S O ( 3 ) SO(3) SO(3)

R ∈ S O ( 3 ) = { R ∈ R 3 × 3 ∣ R T R = I ,   det ⁡ ( R ) = + 1 } R \in SO(3) = \{ R \in \mathbb{R}^{3\times3} \mid R^T R = I,\ \det(R) = +1 \} RSO(3)={RR3×3RTR=I, det(R)=+1}

  • 旋转矩阵的列向量,就是旋转后坐标系各轴在参考系中的方向余弦

R = [ r 11 r 12 r 13 r 21 r 22 r 23 r 31 r 32 r 33 ] R = \begin{bmatrix} r_{11} & r_{12} & r_{13} \\ r_{21} & r_{22} & r_{23} \\ r_{31} & r_{32} & r_{33} \end{bmatrix} R= r11r21r31r12r22r32r13r23r33

  • 9 个元素只有 3 个独立自由度,因为要满足 R T R = I R^T R = I RTR=I(6 个约束)加上 det ⁡ ( R ) = 1 \det(R) = 1 det(R)=1
2-3-2 基本性质
  • 旋转矩阵的几个基本性质,后面全程都会用到:
    • 正交性 R T R = I R^T R = I RTR=I,于是 R − 1 = R T R^{-1} = R^T R1=RT

    • 绕单轴旋转(欧拉角里用到的 R x / R y / R z R_x / R_y / R_z Rx/Ry/Rz 就是它们): R x ( α ) = [ 1 0 0 0 cos ⁡ α − sin ⁡ α 0 sin ⁡ α cos ⁡ α ] , R y ( β ) = [ cos ⁡ β 0 sin ⁡ β 0 1 0 − sin ⁡ β 0 cos ⁡ β ] , R z ( γ ) = [ cos ⁡ γ − sin ⁡ γ 0 sin ⁡ γ cos ⁡ γ 0 0 0 1 ] R_x(\alpha) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\alpha & -\sin\alpha \\ 0 & \sin\alpha & \cos\alpha \end{bmatrix}, \quad R_y(\beta) = \begin{bmatrix} \cos\beta & 0 & \sin\beta \\ 0 & 1 & 0 \\ -\sin\beta & 0 & \cos\beta \end{bmatrix}, \quad R_z(\gamma) = \begin{bmatrix} \cos\gamma & -\sin\gamma & 0 \\ \sin\gamma & \cos\gamma & 0 \\ 0 & 0 & 1 \end{bmatrix} Rx(α)= 1000cosαsinα0sinαcosα ,Ry(β)= cosβ0sinβ010sinβ0cosβ ,Rz(γ)= cosγsinγ0sinγcosγ0001

    • 组合:多个旋转连乘, R = R 1 R 2 ⋯ R n R = R_1 R_2 \cdots R_n R=R1R2Rn,连乘时注意两点:

      • 不满足交换律 R 1 R 2 ≠ R 2 R 1 R_1 R_2 \ne R_2 R_1 R1R2=R2R1,先绕哪根轴、后绕哪根轴,结果完全不同
      • 乘序看坐标系:矩阵连乘从右往左读,最右边的矩阵先执行。绕固定坐标系旋转时新旋转左乘,绕物体自身坐标系旋转时新旋转右乘——机械臂的坐标系逐级嵌套在连杆上,相邻连杆变换连乘正是右乘(见 2-6 节 T A C = T A B ⋅ T B C T_{AC} = T_{AB} \cdot T_{BC} TAC=TABTBC
    • 反对称矩阵:向量 a = [ a 1 , a 2 , a 3 ] T a = [a_1, a_2, a_3]^T a=[a1,a2,a3]T 的反对称矩阵 [ a ] × [a]_\times [a]×,满足 [ a ] × b = a × b [a]_\times b = a \times b [a]×b=a×b [ a ] × = [ 0 − a 3 a 2 a 3 0 − a 1 − a 2 a 1 0 ] [a]_\times = \begin{bmatrix} 0 & -a_3 & a_2 \\ a_3 & 0 & -a_1 \\ -a_2 & a_1 & 0 \end{bmatrix} [a]×= 0a3a2a30a1a2a10

    • 指数映射:绕单位轴 ω \omega ω 旋转角 θ \theta θ R = exp ⁡ ( [ ω ] × θ ) R = \exp([\omega]_\times \theta) R=exp([ω]×θ)(罗德里格斯公式)——这正是 ESKF 里 ⊞ \boxplus 操作的基础

  • 旋转矩阵是"标准表示",但 9 个数不直观,工程上常用下面两种更省的表示——欧拉角来读、四元数来算

说人话:旋转矩阵就是"把坐标系转到哪去"的三行三列数表。写出来有 9 个数,实际只有 3 个独立量。它是姿态的"标准表示",但人眼看不直观,所以工程上常用欧拉角来读、四元数来算

2-4 欧拉角 Euler Angles

请添加图片描述

  • 姿态最直观的表示是欧拉角:把任意旋转拆成依次绕固定轴旋转的三个角度:Roll(横滚)、Pitch(俯仰)、Yaw(偏航)
  • 三个角度各自对应 2-3 节里的单轴旋转矩阵:

R x ( α ) = [ 1 0 0 0 cos ⁡ α − sin ⁡ α 0 sin ⁡ α cos ⁡ α ] , R y ( β ) = [ cos ⁡ β 0 sin ⁡ β 0 1 0 − sin ⁡ β 0 cos ⁡ β ] , R z ( γ ) = [ cos ⁡ γ − sin ⁡ γ 0 sin ⁡ γ cos ⁡ γ 0 0 0 1 ] R_x(\alpha) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\alpha & -\sin\alpha \\ 0 & \sin\alpha & \cos\alpha \end{bmatrix}, \quad R_y(\beta) = \begin{bmatrix} \cos\beta & 0 & \sin\beta \\ 0 & 1 & 0 \\ -\sin\beta & 0 & \cos\beta \end{bmatrix}, \quad R_z(\gamma) = \begin{bmatrix} \cos\gamma & -\sin\gamma & 0 \\ \sin\gamma & \cos\gamma & 0 \\ 0 & 0 & 1 \end{bmatrix} Rx(α)= 1000cosαsinα0sinαcosα ,Ry(β)= cosβ0sinβ010sinβ0cosβ ,Rz(γ)= cosγsinγ0sinγcosγ0001

  • 最常见的是 ZYX 顺序。这里绕的是固定坐标系,所以是左乘——每转一步,新的旋转矩阵都乘在最左边(对应 2-3 节"绕固定坐标系 → 左乘"那条规则): R = R z ( γ ) ⋅ R y ( β ) ⋅ R x ( α ) R = R_z(\gamma) \cdot R_y(\beta) \cdot R_x(\alpha) R=Rz(γ)Ry(β)Rx(α)

    • 连乘从右往左读、依次执行:最右边 R x R_x Rx 先转 α \alpha α(roll),再 R y R_y Ry β \beta β(pitch),最后 R z R_z Rz γ \gamma γ(yaw)——即先 roll、再 pitch、最后 yaw
  • 欧拉角的优点:直观,只有 3 个数,人一眼能看懂"偏了多少度"

  • 但它有两个致命缺点:

    • 万向锁(Gimbal Lock):当 pitch 转到 ± 90 ∘ \pm 90^\circ ±90 时,roll 和 yaw 的旋转轴重合,丢失一个自由度,出现奇异(万向锁是任意三参数欧拉角的通病,不"因为是绕固定坐标系"才出现:绕固定坐标系时,pitch = ± 90 ∘ \pm 90^\circ ±90 会让固定 x x x 轴和固定 z z z 轴映射到物体的同一根轴上,roll、yaw 退化成同一个自由度;绕物体自身坐标系时同理,先转的 yaw 轴(物体 z z z 轴)会被 pitch 转到 roll 轴(物体 x x x 轴)方向,两根轴在物体上重合,roll、yaw 同样退化成同一个自由度)
    • 插值不平滑:两个欧拉角直接线性插值,中间姿态会"扭"得很奇怪
  • 所以工程上的约定是:人看用欧拉角,机器算用旋转矩阵/四元数

  • 理解万向锁节死锁:【无伤理解欧拉角中的"万向死锁"现象-哔哩哔哩】 https://b23.tv/0hBxmJr

说人话:欧拉角就是"先向左转多少度,再抬头多少度,再歪头多少度"。很好懂,但在 pitch = ±90° 时会"卡死"一个轴——这就是万向锁,做姿态插值和路径规划时必须避开

2-5 四元数 Quaternion

请添加图片描述

  • 欧拉角直观但会万向锁,工程上更常用四元数,用 4 个数表示一个旋转:

q = w + x i + y j + z k = [ w x y z ] , ∥ q ∥ = 1 q = w + xi + yj + zk = \begin{bmatrix} w \\ x \\ y \\ z \end{bmatrix}, \quad \|q\| = 1 q=w+xi+yj+zk= wxyz ,q=1

  • 其中 w w w 是实部(标量), ( x , y , z ) (x, y, z) (x,y,z) 是虚部(向量),单位四元数满足 w 2 + x 2 + y 2 + z 2 = 1 w^2 + x^2 + y^2 + z^2 = 1 w2+x2+y2+z2=1
  • 绕单位轴 ω = [ ω x , ω y , ω z ] T \omega = [\omega_x, \omega_y, \omega_z]^T ω=[ωx,ωy,ωz]T 旋转角 θ \theta θ 的四元数为:

q = [ cos ⁡ ( θ / 2 ) ω x sin ⁡ ( θ / 2 ) ω y sin ⁡ ( θ / 2 ) ω z sin ⁡ ( θ / 2 ) ] q = \begin{bmatrix} \cos(\theta/2) \\ \omega_x \sin(\theta/2) \\ \omega_y \sin(\theta/2) \\ \omega_z \sin(\theta/2) \end{bmatrix} q= cos(θ/2)ωxsin(θ/2)ωysin(θ/2)ωzsin(θ/2)

  • 四元数的核心优势:
    • 没有万向锁:任意旋转都能用单位四元数表示(除差一个正负号)
    • 组合高效:两个旋转的复合就是四元数乘法 q 1 ⊗ q 2 q_1 \otimes q_2 q1q2
    • 插值平滑:用球面线性插值 Slerp q ( t ) = sin ⁡ ( ( 1 − t ) Ω ) sin ⁡ Ω q 1 + sin ⁡ ( t Ω ) sin ⁡ Ω q 2 q(t) = \frac{\sin((1-t)\Omega)}{\sin\Omega} q_1 + \frac{\sin(t\Omega)}{\sin\Omega} q_2 q(t)=sinΩsin((1t)Ω)q1+sinΩsin(tΩ)q2,姿态过渡自然
  • 四元数也可以转回 2-3 节的旋转矩阵:

R = [ 1 − 2 ( y 2 + z 2 ) 2 ( x y − w z ) 2 ( x z + w y ) 2 ( x y + w z ) 1 − 2 ( x 2 + z 2 ) 2 ( y z − w x ) 2 ( x z − w y ) 2 ( y z + w x ) 1 − 2 ( x 2 + y 2 ) ] R = \begin{bmatrix} 1 - 2(y^2+z^2) & 2(xy - wz) & 2(xz + wy) \\ 2(xy + wz) & 1 - 2(x^2+z^2) & 2(yz - wx) \\ 2(xz - wy) & 2(yz + wx) & 1 - 2(x^2+y^2) \end{bmatrix} R= 12(y2+z2)2(xy+wz)2(xzwy)2(xywz)12(x2+z2)2(yz+wx)2(xz+wy)2(yzwx)12(x2+y2)

说人话:四元数是姿态的"4 个数版本",看着不如欧拉角直观,但它不会万向锁、插值又顺滑,所以 ROS / MoveIt2 / 游戏引擎里全用它存姿态

2-6 齐次变换矩阵 Homogeneous Transformation Matrix
  • 这是机械臂运动学里最重要的概念——把旋转和位移打包成一个 4 × 4 4\times4 4×4 矩阵
  • 刚体坐标系相对于参考系的位姿:

T = [ R t 0 1 ] = [ r 11 r 12 r 13 t x r 21 r 22 r 23 t y r 31 r 32 r 33 t z 0 0 0 1 ] ∈ S E ( 3 ) T = \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix} = \begin{bmatrix} r_{11} & r_{12} & r_{13} & t_x \\ r_{21} & r_{22} & r_{23} & t_y \\ r_{31} & r_{32} & r_{33} & t_z \\ 0 & 0 & 0 & 1 \end{bmatrix} \in SE(3) T=[R0t1]= r11r21r310r12r22r320r13r23r330txtytz1 SE(3)

  • 其中 R R R 是旋转矩阵(姿态), t t t 是平移向量(位置)
  • 齐次坐标下,点 p ~ = [ x , y , z , 1 ] T \tilde{p} = [x, y, z, 1]^T p~=[x,y,z,1]T 经变换 T T T 得到新坐标:

p ~ ′ = T ⋅ p ~ = [ R t 0 1 ] [ p 1 ] \tilde{p}' = T \cdot \tilde{p} = \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix} \begin{bmatrix} p \\ 1 \end{bmatrix} p~=Tp~=[R0t1][p1]

  • 为什么重要?因为变换可以连乘

T A C = T A B ⋅ T B C T_{AC} = T_{AB} \cdot T_{BC} TAC=TABTBC

  • 乘法顺序从右往左读、依次执行:最右边 T B C T_{BC} TBC 先把 C 系坐标换算到 B 系, T A B T_{AB} TAB 再把 B 系换算到 A 系——右乘的变换先作用
  • 机械臂的连杆坐标系逐级嵌套在连杆上,每一级都相对"上一级"定义,所以整条臂的变换连乘正是这种右乘链(对应 2-3 节"绕物体自身坐标系 → 右乘"的规则)——下一章的正运动学就是这么算的

说人话:齐次变换矩阵 = "位置 + 姿态"打包成一个 4×4 的盒子,好处是能直接连乘。从基座到手腕,每一节一个盒子,全部乘起来就是末端位姿——这就是正运动学的本质


3 运动学

  • 运动学研究几何关系——关节怎么动、末端怎么走,不关心力
  • 核心就两个方向:正运动学(FK)和逆运动学(IK),中间用 DH 参数把机械臂"数字化"
    请添加图片描述
3-1 关节向量与两个空间
  • 先建立"状态"的语言:机械臂的位形,用一个关节向量描述:

q = [ q 1 q 2 ⋮ q n ] ∈ R n q = \begin{bmatrix} q_1 \\ q_2 \\ \vdots \\ q_n \end{bmatrix} \in \mathbb{R}^n q= q1q2qn Rn

  • 其中 q i q_i qi 是第 i i i 个关节的关节变量,是一个标量,具体长什么样取决于关节类型(对应第 1 章讲的两种关节):
    • 旋转关节 q i = θ i q_i = \theta_i qi=θi,一个角度,比如 q 1 = 30 ∘ q_1 = 30^\circ q1=30——就是第 1 个关节转了多少度(工程代码里通常用弧度 rad \text{rad} rad
    • 移动关节 q i = d i q_i = d_i qi=di,一个位移,比如 q 2 = 0.1   m q_2 = 0.1\,\text{m} q2=0.1m——就是第 2 个关节沿轴伸出多少米
  • 所以关节向量 q q q n n n 个标量拼成的列向量, n n n 是关节数——比如最常见的 6 轴工业机械臂, q = [ q 1 , … , q 6 ] T q = [q_1, \dots, q_6]^T q=[q1,,q6]T,六个分量全是关节角
  • 注意区分两个空间:
    • 关节空间(Joint Space):以关节角为坐标的空间,维度 = 关节数 n n n
    • 操作空间 / 任务空间(Task Space):以末端位姿为坐标的空间,维度 ≤ 6 \le 6 6
3-2 正运动学 FK
  • FK 和 IK 干的事,就是在这两个空间之间"翻译"——正运动学(Forward Kinematics,FK)就是已知关节角 q q q,求末端位姿 T e e T_{ee} Tee
  • 思路:给每个连杆建立坐标系,把每个关节的"旋转 + 平移"用一个齐次变换矩阵 T i T_i Ti 描述,然后连乘:

T e e = T 0 1 ( q 1 ) ⋅ T 1 2 ( q 2 ) ⋯ T n − 1 n ( q n ) = ∏ i = 1 n T i − 1 i ( q i ) T_{ee} = T_0^1(q_1) \cdot T_1^2(q_2) \cdots T_{n-1}^n(q_n) = \prod_{i=1}^{n} T_{i-1}^i(q_i) Tee=T01(q1)T12(q2)Tn1n(qn)=i=1nTi1i(qi)

  • 其中每个 T i − 1 i ( q i ) T_{i-1}^i(q_i) Ti1i(qi) 只依赖第 i i i 个关节的关节角 q i q_i qi
  • 举个最简单的例子:二连杆平面机械臂(两个旋转关节,在 x y xy xy 平面内运动)

x = L 1 cos ⁡ q 1 + L 2 cos ⁡ ( q 1 + q 2 ) , y = L 1 sin ⁡ q 1 + L 2 sin ⁡ ( q 1 + q 2 ) x = L_1 \cos q_1 + L_2 \cos(q_1 + q_2), \quad y = L_1 \sin q_1 + L_2 \sin(q_1 + q_2) x=L1cosq1+L2cos(q1+q2),y=L1sinq1+L2sin(q1+q2)

* 末端姿态(相对基座的偏航角):$\phi = q_1 + q_2$
  • FK 的数学性质:解唯一、计算简单——给一个 q q q,必然有且只有一个末端位姿

说人话:正运动学就是"给我每个关节转多少度,我告诉你手到哪了"。二连杆就像你的手臂,知道肩关节、肘关节的角度,自然知道手在哪里

  • 用 Python 把上面的 FK 公式画出来(完整代码见下篇附录一),左图是一个具体位形,红色星号是末端;右图是遍历所有关节角得到的可达工作空间——一个环形区域:

请添加图片描述

3-3 逆运动学 IK
  • 逆运动学(Inverse Kinematics,IK):已知末端期望位姿 T e e d e s T_{ee}^{des} Teedes,求关节角 q q q
  • 数学上,IK 是解非线性方程 T e e ( q ) = T e e d e s T_{ee}(q) = T_{ee}^{des} Tee(q)=Teedes
  • IK 的求解一般分两类:
求解方法 原理 优点 缺点
解析法 代数/几何推导出显式解 快、稳定、解可枚举 只适用于特定构型(如 6 轴球形手腕)
数值法 迭代优化(Newton、雅可比伪逆) 通用,任意机械臂可用 慢、依赖初值、可能局部收敛
  • 数值 IK 的核心迭代式(雅可比伪逆法):

q k + 1 = q k + J † ( q k ) ⋅ ( x d e s − f ( q k ) ) q_{k+1} = q_k + J^{\dagger}(q_k) \cdot \left( x^{des} - f(q_k) \right) qk+1=qk+J(qk)(xdesf(qk))

  • 其中 J † = J T ( J J T ) − 1 J^{\dagger} = J^T (J J^T)^{-1} J=JT(JJT)1 是雅可比矩阵的伪逆 f ( q k ) f(q_k) f(qk) 是当前关节角下的末端位姿(FK)
  • IK 的三个重要特性:
    • 多解性:同一个末端位姿可能对应多组关节角(比如"肘上/肘下")
    • 奇异问题:在奇异位形附近 J J J 退化, J † J^{\dagger} J 数值爆炸,迭代容易发散
    • 无解:目标点超出工作空间(可达范围),怎么解都到不了

说人话:逆运动学是"我想让手到这,每个关节该转多少"。这是抓取、轨迹规划里天天要算的东西——MoveIt2 里的 KDL / IKFast 求解器,干的就是这件事

  • 雅可比伪逆迭代求解上面的 IK(完整代码见下篇附录二),蓝色细线是迭代的中间位形,绿色粗线是收敛解——多迭代几次,末端就"吸"到目标点了:

请添加图片描述

3-4 DH 参数
3-4-1 定义
  • 用齐次变换矩阵做 FK 时,最规范的方法就是 DH 参数(Denavit–Hartenberg)
  • 它是 1955 年 Denavit 和 Hartenberg 提出的标准做法:给每个连杆坐标系定好建法,用 4 个参数 把相邻两连杆之间的相对位姿"编码"清楚,从此正运动学就变成填表 + 连乘的机械操作
  • DH 约定:给每个连杆建立坐标系,用 4 个参数唯一描述相邻两个坐标系之间的变换:
参数 含义 说明
a i − 1 a_{i-1} ai1 连杆长度 沿 x i − 1 x_{i-1} xi1 轴,从 z i − 1 z_{i-1} zi1 移到 z i z_i zi 的距离
α i − 1 \alpha_{i-1} αi1 连杆扭转角 x i − 1 x_{i-1} xi1 轴,从 z i − 1 z_{i-1} zi1 转到 z i z_i zi 的角度
d i d_i di 连杆偏距 沿 z i z_i zi 轴,从 x i − 1 x_{i-1} xi1 移到 x i x_i xi 的距离
θ i \theta_i θi 关节角 z i z_i zi 轴,从 x i − 1 x_{i-1} xi1 转到 x i x_i xi 的角度

请添加图片描述

  • 相邻两连杆坐标系间的变换矩阵:

T i − 1 i = R x ( α i − 1 ) ⋅ T x ( a i − 1 ) ⋅ R z ( θ i ) ⋅ T z ( d i ) T_{i-1}^i = R_x(\alpha_{i-1}) \cdot T_x(a_{i-1}) \cdot R_z(\theta_i) \cdot T_z(d_i) Ti1i=Rx(αi1)Tx(ai1)Rz(θi)Tz(di)

= [ cos ⁡ θ i − sin ⁡ θ i cos ⁡ α i − 1 sin ⁡ θ i sin ⁡ α i − 1 a i − 1 cos ⁡ θ i sin ⁡ θ i cos ⁡ θ i cos ⁡ α i − 1 − cos ⁡ θ i sin ⁡ α i − 1 a i − 1 sin ⁡ θ i 0 sin ⁡ α i − 1 cos ⁡ α i − 1 d i 0 0 0 1 ] = \begin{bmatrix} \cos\theta_i & -\sin\theta_i \cos\alpha_{i-1} & \sin\theta_i \sin\alpha_{i-1} & a_{i-1}\cos\theta_i \\ \sin\theta_i & \cos\theta_i \cos\alpha_{i-1} & -\cos\theta_i \sin\alpha_{i-1} & a_{i-1}\sin\theta_i \\ 0 & \sin\alpha_{i-1} & \cos\alpha_{i-1} & d_i \\ 0 & 0 & 0 & 1 \end{bmatrix} = cosθisinθi00sinθicosαi1cosθicosαi1sinαi10sinθisinαi1cosθisinαi1cosαi10ai1cosθiai1sinθidi1

  • 对旋转关节, θ i \theta_i θi 是变量;对移动关节, d i d_i di 是变量
  • 一台机械臂的 DH 参数表就是一张 n × 4 n \times 4 n×4 的表格——建好这张表,FK 就只是连乘
3-4-2 二连杆平面机械臂的 DH 参数
  • 二连杆平面机械臂的 DH 参数表(两个旋转关节):
连杆 a i − 1 a_{i-1} ai1 α i − 1 \alpha_{i-1} αi1 d i d_i di θ i \theta_i θi
1 L 1 L_1 L1 0 0 q 1 q_1 q1
2 L 2 L_2 L2 0 0 q 2 q_2 q2
  • 有了这张表格以后,代入 3-4-1 的变换矩阵公式,就能写出每个连杆的变换矩阵(平面臂 α i − 1 = 0 \alpha_{i-1} = 0 αi1=0 d i = 0 d_i = 0 di=0,矩阵退化成"绕 z z z 轴转 + 沿 x x x 轴移"):

T 0 1 ( q 1 ) = [ cos ⁡ q 1 − sin ⁡ q 1 0 L 1 cos ⁡ q 1 sin ⁡ q 1 cos ⁡ q 1 0 L 1 sin ⁡ q 1 0 0 1 0 0 0 0 1 ] , T 1 2 ( q 2 ) = [ cos ⁡ q 2 − sin ⁡ q 2 0 L 2 cos ⁡ q 2 sin ⁡ q 2 cos ⁡ q 2 0 L 2 sin ⁡ q 2 0 0 1 0 0 0 0 1 ] T_0^1(q_1) = \begin{bmatrix} \cos q_1 & -\sin q_1 & 0 & L_1\cos q_1 \\ \sin q_1 & \cos q_1 & 0 & L_1\sin q_1 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}, \quad T_1^2(q_2) = \begin{bmatrix} \cos q_2 & -\sin q_2 & 0 & L_2\cos q_2 \\ \sin q_2 & \cos q_2 & 0 & L_2\sin q_2 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} T01(q1)= cosq1sinq100sinq1cosq1000010L1cosq1L1sinq101 ,T12(q2)= cosq2sinq200sinq2cosq2000010L2cosq2L2sinq201

  • 按 2-6 节的右乘链连乘 T 0 2 = T 0 1 ⋅ T 1 2 T_0^2 = T_0^1 \cdot T_1^2 T02=T01T12,平移部分正好还原 3-2 节的末端位置:
    • x = L 1 cos ⁡ q 1 + L 2 cos ⁡ ( q 1 + q 2 ) x = L_1\cos q_1 + L_2\cos(q_1+q_2) x=L1cosq1+L2cos(q1+q2) y = L 1 sin ⁡ q 1 + L 2 sin ⁡ ( q 1 + q 2 ) y = L_1\sin q_1 + L_2\sin(q_1+q_2) y=L1sinq1+L2sin(q1+q2)
    • DH 表 + 公式 + 连乘,FK 一次到位

说人话:DH 参数就是给机械臂每个关节量"四围"——长度、扭转、偏移、转角,量完填一张表,正运动学就自动出来了。URDF 里每个 joint 的 origin + axis,本质上就是在描述这套参数

  • 用 Python 把上面的 DH 表画在二连杆机械臂上(完整代码见下篇附录三),就能直观看到 4 个参数各自"管"什么:红绿箭头是连杆坐标系, x 0 x_0 x0 x 1 x_1 x1 的转角就是 θ 1 = q 1 \theta_1 = q_1 θ1=q1 x 1 x_1 x1 x 2 x_2 x2 的转角就是 θ 2 = q 2 \theta_2 = q_2 θ2=q2;连杆长度分别是 a 0 = L 1 a_0 = L_1 a0=L1 a 1 = L 2 a_1 = L_2 a1=L2;因为是平面臂,三个 z z z 轴全部垂直纸面向外( α = 0 \alpha = 0 α=0),三个 x x x 轴共面( d = 0 d = 0 d=0):

请添加图片描述


4 速度运动学

  • 第 3 章的运动学只关心"位置关系",速度运动学关心"位置怎么随时间变"——也就是关节速度与末端速度的关系
4-1 雅可比矩阵
  • 雅可比矩阵(Jacobian) J J J末端速度对关节速度的线性映射矩阵
  • 以防你忘记雅可比矩阵(Jacobian)的数学定义:输出对输入的一阶偏导数矩阵

J = ∂ f ∂ x J=\frac{\partial f}{\partial \mathbf{x}} J=xf

  • n n n 关节机械臂,末端有 6 维速度(3 线速度 + 3 角速度),雅可比是一个 6 × n 6 \times n 6×n 矩阵:

X ˙ = [ p ˙ ω ] = J ( q ) ⋅ q ˙ = [ J v ( q ) J ω ( q ) ] q ˙ \dot{\mathcal{X}} = \begin{bmatrix} \dot{p} \\ \omega \end{bmatrix} = J(q) \cdot \dot{q} = \begin{bmatrix} J_v(q) \\ J_\omega(q) \end{bmatrix} \dot{q} X˙=[p˙ω]=J(q)q˙=[Jv(q)Jω(q)]q˙

  • 其中:
    • p ˙ ∈ R 3 \dot{p} \in \mathbb{R}^3 p˙R3:末端线速度
    • ω ∈ R 3 \omega \in \mathbb{R}^3 ωR3:末端角速度
    • J v ( q ) ∈ R 3 × n J_v(q) \in \mathbb{R}^{3\times n} Jv(q)R3×n:线速度雅可比
    • J ω ( q ) ∈ R 3 × n J_\omega(q) \in \mathbb{R}^{3\times n} Jω(q)R3×n:角速度雅可比
  • 对旋转关节,雅可比每列的计算:

J v i = z i × ( p e e − p i ) , J ω i = z i J_{vi} = z_i \times (p_{ee} - p_i), \quad J_{\omega i} = z_i Jvi=zi×(peepi),Jωi=zi

  • 对移动关节,只有平移、不贡献角速度: J v i = z i , J ω i = 0 J_{vi} = z_i, \quad J_{\omega i} = 0 Jvi=zi,Jωi=0

    • 其中 z i z_i zi 是关节 i i i 的旋转/移动轴方向, p i p_i pi 是关节 i i i 的位置, p e e p_{ee} pee 是末端位置
  • 雅可比把"关节空间"和"操作空间"连接起来,是运动学、动力学、控制的枢纽

说人话:雅可比就是"关节转 1°/s,末端能跑多快、往哪个方向跑"的换算表。它是速度层的运动学,后面控制里要用的"力 → 力矩"转换也靠它

4-2 关节速度到末端速度
4-2-1 定义
  • 正运动学给出位置映射 x = f ( q ) x = f(q) x=f(q),对时间求导就是:

x ˙ = ∂ f ∂ q ⋅ q ˙ = J ( q ) q ˙ \dot{x} = \frac{\partial f}{\partial q} \cdot \dot{q} = J(q) \dot{q} x˙=qfq˙=J(q)q˙

  • 反向呢?已知末端速度求关节速度, J J J 是方阵且可逆时: q ˙ = J − 1 ( q ) x ˙ \dot{q} = J^{-1}(q) \dot{x} q˙=J1(q)x˙

  • J J J 不是方阵(冗余机械臂 n > 6 n > 6 n>6)或不可逆时,用伪逆 q ˙ = J † ( q ) x ˙ , J † = J T ( J J T ) − 1 \dot{q} = J^{\dagger}(q) \dot{x}, \quad J^{\dagger} = J^T (J J^T)^{-1} q˙=J(q)x˙,J=JT(JJT)1

    • 为什么叫"伪逆"?因为这时 J − 1 J^{-1} J1 根本不存在,直接求逆会失败。伪逆是"逆"的推广:只要 J J J 行满秩(6 自由度机械臂在非奇异位形就是), J J T J J^T JJT 可逆, J † J^{\dagger} J 就存在
    • 它解的是一个最小范数问题:在所有满足 x ˙ = J q ˙ \dot{x} = J\dot{q} x˙=Jq˙ 的关节速度里,挑范数 ∥ q ˙ ∥ \|\dot{q}\| q˙ 最小的那个——用"最省的关节运动"达到同样的末端速度
  • 还可以利用雅可比的零空间,在完成主任务的同时做冗余优化(避障、关节限位):

q ˙ = J † x ˙ + ( I − J † J ) q ˙ 0 \dot{q} = J^{\dagger} \dot{x} + (I - J^{\dagger}J) \dot{q}_0 q˙=Jx˙+(IJJ)q˙0

  • 其中 ( I − J † J ) (I - J^{\dagger}J) (IJJ) 把次任务速度 q ˙ 0 \dot{q}_0 q˙0 投影到零空间——它在不改变末端速度的前提下调整关节位形
4-2-2 二连杆的雅可比推导
  • 以防你忘记,用解析法再把二连杆的雅可比推一遍(平面臂只需 x , y x, y x,y 两行,是 2 × 2 2\times2 2×2):
  • 从 3-2 节的 FK 公式出发:

x = L 1 cos ⁡ q 1 + L 2 cos ⁡ ( q 1 + q 2 ) , y = L 1 sin ⁡ q 1 + L 2 sin ⁡ ( q 1 + q 2 ) x = L_1 \cos q_1 + L_2 \cos(q_1 + q_2), \quad y = L_1 \sin q_1 + L_2 \sin(q_1 + q_2) x=L1cosq1+L2cos(q1+q2),y=L1sinq1+L2sin(q1+q2)

  • q 1 q_1 q1 q 2 q_2 q2 分别求偏导:

∂ x ∂ q 1 = − L 1 sin ⁡ q 1 − L 2 sin ⁡ ( q 1 + q 2 ) , ∂ x ∂ q 2 = − L 2 sin ⁡ ( q 1 + q 2 ) \frac{\partial x}{\partial q_1} = -L_1\sin q_1 - L_2\sin(q_1+q_2), \quad \frac{\partial x}{\partial q_2} = -L_2\sin(q_1+q_2) q1x=L1sinq1L2sin(q1+q2),q2x=L2sin(q1+q2)

∂ y ∂ q 1 = L 1 cos ⁡ q 1 + L 2 cos ⁡ ( q 1 + q 2 ) , ∂ y ∂ q 2 = L 2 cos ⁡ ( q 1 + q 2 ) \frac{\partial y}{\partial q_1} = L_1\cos q_1 + L_2\cos(q_1+q_2), \quad \frac{\partial y}{\partial q_2} = L_2\cos(q_1+q_2) q1y=L1cosq1+L2cos(q1+q2),q2y=L2cos(q1+q2)

  • 把这 4 个偏导按行列排好,就是雅可比矩阵:

J ( q ) = [ ∂ x ∂ q 1 ∂ x ∂ q 2 ∂ y ∂ q 1 ∂ y ∂ q 2 ] = [ − L 1 sin ⁡ q 1 − L 2 sin ⁡ ( q 1 + q 2 ) − L 2 sin ⁡ ( q 1 + q 2 ) L 1 cos ⁡ q 1 + L 2 cos ⁡ ( q 1 + q 2 ) L 2 cos ⁡ ( q 1 + q 2 ) ] J(q) = \begin{bmatrix} \frac{\partial x}{\partial q_1} & \frac{\partial x}{\partial q_2} \\ \frac{\partial y}{\partial q_1} & \frac{\partial y}{\partial q_2} \end{bmatrix} = \begin{bmatrix} -L_1\sin q_1 - L_2\sin(q_1+q_2) & -L_2\sin(q_1+q_2) \\ L_1\cos q_1 + L_2\cos(q_1+q_2) & L_2\cos(q_1+q_2) \end{bmatrix} J(q)=[q1xq1yq2xq2y]=[L1sinq1L2sin(q1+q2)L1cosq1+L2cos(q1+q2)L2sin(q1+q2)L2cos(q1+q2)]

  • 有了上面的矩阵,我们就能直接算末端速度:给定任意一组关节速度 q ˙ = [ q ˙ 1 , q ˙ 2 ] T \dot{q} = [\dot{q}_1, \dot{q}_2]^T q˙=[q˙1,q˙2]T,代进 x ˙ = J ( q ) ⋅ q ˙ \dot{x} = J(q) \cdot \dot{q} x˙=J(q)q˙,末端线速度立即出来——这就是本节的"关节速度 → 末端速度"
  • 这就是"FK 求导 → J"的解析法,和 4-1 的几何法殊途同归;它的行列式: det ⁡ ( J ) = L 1 L 2 sin ⁡ q 2 \det(J) = L_1 L_2 \sin q_2 det(J)=L1L2sinq2——这直接引出下面的奇异位形
4-3 奇异位形
  • 奇异位形(Singularity):雅可比矩阵降秩的位形
  • 对 6 关节方阵雅可比,就是:

rank ( J ) < 6 ⇔ det ⁡ ( J ) = 0 \text{rank}(J) < 6 \quad \Leftrightarrow \quad \det(J) = 0 rank(J)<6det(J)=0

  • 也就是说,这个矩阵不满秩:有某些方向上的速度"映射不出来"。于是奇异位形下会出现三件"坏事":
    • 末端失去某个方向的运动能力——不管关节怎么转,末端在某方向都"动不了"
    • 关节速度爆炸:要完成某个末端速度, q ˙ = J − 1 x ˙ \dot{q} = J^{-1}\dot{x} q˙=J1x˙ 中的 J − 1 J^{-1} J1 趋于无穷大,关节速度飙到天上去
    • 力控失效:末端在奇异方向上的力映射到关节力矩会很小,机械臂在该方向"无力"
  • 二连杆的例子: det ⁡ ( J ) = L 1 L 2 sin ⁡ q 2 = 0 \det(J) = L_1 L_2 \sin q_2 = 0 det(J)=L1L2sinq2=0 当且仅当 q 2 = 0 q_2 = 0 q2=0 q 2 = ± π q_2 = \pm\pi q2=±π
    • q 2 = 0 q_2 = 0 q2=0:手臂完全伸直——末端只能沿径向(手臂方向)移动,无法沿切向移动
    • q 2 = ± π q_2 = \pm\pi q2=±π:手臂完全折叠——末端只能沿切向移动,无法沿径向移动
  • 处理奇异的方法:
    • 规划时避开奇异位形(代价函数里惩罚接近奇异的位形)

    • 奇异附近用阻尼最小二乘(DLS) J † = J T ( J J T + λ 2 I ) − 1 J^{\dagger} = J^T (J J^T + \lambda^2 I)^{-1} J=JT(JJT+λ2I)1

    • 多出来的 λ 2 I \lambda^2 I λ2I 是阻尼项,牺牲一点精度换数值稳定——下篇附录二我们把它的几何效果画出来

说人话:奇异位形就是机械臂的"死锁姿势"——比如手臂完全伸直时,你只能推着它向外动,没法让它"横着走"。这时候关节转速会飙到天上去,是实际控制中必须躲开的坑

  • 下面左图画出 det ⁡ ( J ) = L 1 L 2 sin ⁡ q 2 \det(J) = L_1 L_2 \sin q_2 det(J)=L1L2sinq2 q 2 q_2 q2 的变化——在 q 2 = 0 , ± π q_2 = 0, \pm\pi q2=0,±π 处归零,正是奇异位形;右图是 q 2 = 0 q_2 = 0 q2=0(手臂完全伸直)时的情形,末端只能沿绿色箭头(径向)移动,红色箭头(切向)方向"锁死"(完整代码见下篇附录二):

请添加图片描述


5 动力学

  • 动力学研究力与运动的关系——机械臂在重力、外力、电机力矩作用下怎么运动
  • 如果说运动学是"几何学",动力学就是"物理学"
5-1 机械臂动力学方程
  • 关节空间中,机械臂的动力学方程(标准形式):

M ( q ) q ¨ + C ( q , q ˙ ) q ˙ + g ( q ) = τ M(q) \ddot{q} + C(q, \dot{q}) \dot{q} + g(q) = \tau M(q)q¨+C(q,q˙)q˙+g(q)=τ

  • 各符号含义(这张表后面推导会反复用,以防你忘记):
符号 含义 单位
M ( q ) M(q) M(q) 惯性矩阵(质量/惯量分布) kg ⋅ m 2 \text{kg}\cdot\text{m}^2 kgm2
C ( q , q ˙ ) C(q, \dot{q}) C(q,q˙) 科氏力 + 离心力矩阵
g ( q ) g(q) g(q) 重力项 N ⋅ m \text{N}\cdot\text{m} Nm
τ \tau τ 关节驱动力矩 N ⋅ m \text{N}\cdot\text{m} Nm
q , q ˙ , q ¨ q, \dot{q}, \ddot{q} q,q˙,q¨ 关节位置、速度、加速度 rad, rad/s, rad/s²
  • 每一项的物理含义:

    • M ( q ) q ¨ M(q)\ddot{q} M(q)q¨:克服惯性——机械臂本身"懒",要加速就得用力
    • C ( q , q ˙ ) q ˙ C(q, \dot{q})\dot{q} C(q,q˙)q˙:科氏力/离心力——关节转动产生的"耦合"和"甩出去"的力
    • g ( q ) g(q) g(q):重力——把机械臂"往上抬"要克服的力
  • 这些符号不是凭空来的,它们由每个连杆的物理量组合而成——先说清楚动力学的"原料":

    • 质量 m i m_i mi:连杆 i 的质量
    • 质心 c i c_i ci:连杆 i 质量中心的位置
    • 转动惯量 I i ∈ R 3 × 3 I_i \in \mathbb{R}^{3\times3} IiR3×3:连杆 i 绕质心的惯性张量,衡量"转起来有多费力"
  • 惯性矩阵 M ( q ) M(q) M(q) 由所有连杆的质量、质心、惯量组合而成,且:

    • M ( q ) M(q) M(q)正定对称矩阵:对任意 q q q M ( q ) = M ( q ) T ≻ 0 M(q) = M(q)^T \succ 0 M(q)=M(q)T0
    • M ( q ) M(q) M(q) q q q 变化:手臂姿势不同,等效惯量不同——伸出去时惯性大,收回来时惯性小
  • 重力项来自重力势能:

g ( q ) = ∂ V ( q ) ∂ q g(q) = \frac{\partial V(q)}{\partial q} g(q)=qV(q)

  • 其中 V ( q ) = ∑ i m i g h i ( q ) V(q) = \sum_i m_i g h_i(q) V(q)=imighi(q) 是系统的重力势能, h i h_i hi 是连杆 i 质心高度
  • 方程右边的驱动力矩 τ \tau τ 还和末端力 f f f 通过雅可比联系起来(力 - 力矩对偶):

τ = J T ( q ) ⋅ f \tau = J^T(q) \cdot f τ=JT(q)f

  • 这表示:末端要产生力 f f f,各关节需要提供力矩 J T f J^T f JTf——这正是阻抗控制、力控的基础,第 7 章控制会用到

说人话:这个方程就是机械臂版的牛顿第二定律 F = m a F = ma F=ma——左边是"动起来需要的力"(惯性 + 科氏离心 + 重力),右边是"电机给的力"。两边平衡了,机械臂就按你想要的加速度运动。方程里的"原料"——质量管"多重"、惯量管"多难转"、重力管"要扛多大分量",其中重力最坑:手臂伸平 vs 垂下,重力矩能差好几倍,后面逆动力学一节会看到怎么对付它

5-2 拉格朗日法(能量法)
  • 那这个方程是哪来的?它来自拉格朗日力学(能量法)——机械臂动力学的两大经典来源之一
  • 拉格朗日法不逐连杆列力平衡,而是只看系统的能量,只需要写一个标量函数(拉格朗日函数):
    L ( q , q ˙ ) = T − V L(q, \dot{q}) = T - V L(q,q˙)=TV
  • 其中 T T T 是动能, V V V 是势能。对旋转关节机械臂,动能是关节速度的二次型,势能只依赖 q q q
    T = 1 2 q ˙ T M ( q ) q ˙ , V = V ( q ) T = \frac{1}{2}\dot{q}^T M(q)\dot{q}, \qquad V = V(q) T=21q˙TM(q)q˙,V=V(q)
  • 代入欧拉-拉格朗日方程,动力学方程就"机械地"长出来了:
    d d t ∂ L ∂ q ˙ − ∂ L ∂ q = τ \frac{d}{dt}\frac{\partial L}{\partial \dot{q}} - \frac{\partial L}{\partial q} = \tau dtdq˙LqL=τ
  • 逐项求导(以防你忘记: M ( q ) M(q) M(q) 只依赖 q q q,所以对时间求导会出现 M ˙ \dot{M} M˙):
    d d t ∂ T ∂ q ˙ = M q ¨ + M ˙ q ˙ , ∂ T ∂ q = 1 2 ∂ ( q ˙ T M q ˙ ) ∂ q , ∂ V ∂ q = g ( q ) \frac{d}{dt}\frac{\partial T}{\partial \dot{q}} = M\ddot{q} + \dot{M}\dot{q}, \qquad \frac{\partial T}{\partial q} = \frac{1}{2}\frac{\partial(\dot{q}^T M\dot{q})}{\partial q}, \qquad \frac{\partial V}{\partial q} = g(q) dtdq˙T=Mq¨+M˙q˙,qT=21q(q˙TMq˙),qV=g(q)
  • 整理一下,三个项的"出身"就一目了然了:
    • M ( q ) q ¨ M(q)\ddot{q} M(q)q¨:动能对 q ˙ \dot{q} q˙ 求导、再对时间求导——惯性项
    • C ( q , q ˙ ) q ˙ = M ˙ q ˙ − 1 2 ∂ ( q ˙ T M q ˙ ) ∂ q C(q,\dot{q})\dot{q} = \dot{M}\dot{q} - \frac{1}{2}\frac{\partial(\dot{q}^T M\dot{q})}{\partial q} C(q,q˙)q˙=M˙q˙21q(q˙TMq˙) M ( q ) M(q) M(q) q q q 求导的组合——科氏/离心项不是凭空加的,它是惯性项的"派生物"
    • g ( q ) = ∂ V / ∂ q g(q) = \partial V/\partial q g(q)=V/q:势能对 q q q 求导——重力项

说人话:拉格朗日法只要喂一个标量 L = T − V L = T - V L=TV(一个数!),方程自己就长出来了,所以叫"能量法"。它的强项是分析——闭式公式、每项物理意义清清楚楚;代价是推导繁琐,大规模机械臂手推很累

5-3 牛顿-欧拉法(递推法)
  • 拉格朗日法从能量出发,适合推导闭式;牛顿-欧拉法对每个连杆老老实实列力/力矩平衡,是逆动力学的经典算法(复杂度 O ( n ) O(n) O(n),实时性好,Pinocchio 这类刚体动力学库底层就是它)。全程只靠两条物理定律:
    • 牛顿方程(力平衡): F = m a F = ma F=ma
    • 欧拉方程(力矩平衡): N = I ω ˙ + ω × ( I ω ) N = I\dot{\omega} + \omega \times (I\omega) N=Iω˙+ω×(Iω)
  • 整条算法就是两条递推,像链式反应一样一正一反把整条链扫两遍:
    • 前向递推(基座 → 末端):由 q , q ˙ , q ¨ q, \dot{q}, \ddot{q} q,q˙,q¨ 沿链算出每个连杆的角速度 ω i \omega_i ωi、角加速度 ω ˙ i \dot{\omega}_i ω˙i、质心加速度 v ˙ C i \dot{v}_{C_i} v˙Ci,再用牛顿/欧拉方程得到该连杆的惯性力 F i F_i Fi惯性力矩 N i N_i Ni
    • 后向递推(末端 → 基座):从末端外力 f n + 1 = 0 f_{n+1} = 0 fn+1=0 出发,倒着解每个连杆的力/力矩平衡,得到每个关节要输出的 f i f_i fi力矩 τ i \tau_i τi
  • 前向递推的核心公式(以旋转关节为例):
    ω i + 1 = ω i + θ ˙ i + 1 z ^ i + 1 \omega_{i+1} = \omega_i + \dot{\theta}_{i+1}\hat{z}_{i+1} ωi+1=ωi+θ˙i+1z^i+1
    ω ˙ i + 1 = ω ˙ i + θ ¨ i + 1 z ^ i + 1 + ω i × ( θ ˙ i + 1 z ^ i + 1 ) \dot{\omega}_{i+1} = \dot{\omega}_i + \ddot{\theta}_{i+1}\hat{z}_{i+1} + \omega_i \times (\dot{\theta}_{i+1}\hat{z}_{i+1}) ω˙i+1=ω˙i+θ¨i+1z^i+1+ωi×(θ˙i+1z^i+1)
    v ˙ C i + 1 = v ˙ i + 1 + ω ˙ i + 1 × r C i + 1 + ω i + 1 × ( ω i + 1 × r C i + 1 ) \dot{v}_{C_{i+1}} = \dot{v}_{i+1} + \dot{\omega}_{i+1} \times r_{C_{i+1}} + \omega_{i+1} \times (\omega_{i+1} \times r_{C_{i+1}}) v˙Ci+1=v˙i+1+ω˙i+1×rCi+1+ωi+1×(ωi+1×rCi+1)
    F i + 1 = m i + 1 v ˙ C i + 1 , N i + 1 = I C i + 1 ω ˙ i + 1 + ω i + 1 × ( I C i + 1 ω i + 1 ) F_{i+1} = m_{i+1}\dot{v}_{C_{i+1}}, \qquad N_{i+1} = I_{C_{i+1}}\dot{\omega}_{i+1} + \omega_{i+1} \times (I_{C_{i+1}}\omega_{i+1}) Fi+1=mi+1v˙Ci+1,Ni+1=ICi+1ω˙i+1+ωi+1×(ICi+1ωi+1)
  • 后向递推的力/力矩平衡(从末端往基座收):
    f i = f i + 1 + F i , n i = n i + 1 + N i + r C i × F i + r i + 1 × f i + 1 , τ i = z ^ i T n i f_i = f_{i+1} + F_i, \qquad n_i = n_{i+1} + N_i + r_{C_i} \times F_i + r_{i+1} \times f_{i+1}, \qquad \tau_i = \hat{z}_i^T n_i fi=fi+1+Fi,ni=ni+1+Ni+rCi×Fi+ri+1×fi+1,τi=z^iTni
5-4 正动力学与逆动力学
  • 5-2、5-3 给了两种求解动力学的方法,先对比一下它们的区别:
对比维度 拉格朗日法(5-2 节) 牛顿-欧拉法(5-3 节)
出发点 系统总能量 L = T − V L = T - V L=TV 每个连杆的力/力矩平衡
手段 欧拉-拉格朗日方程求偏导 前向 + 后向两条递推
产物 闭式方程 M ( q ) , C ( q , q ˙ ) , g ( q ) M(q), C(q,\dot{q}), g(q) M(q),C(q,q˙),g(q) 关节力矩 τ \tau τ
计算复杂度 符号推导繁琐、计算量大 O ( n ) O(n) O(n) 递推、实时性好
擅长 理论分析、建闭式模型 实时控制、逆动力学
典型场景 正动力学(仿真推运动) 逆动力学(控制算力矩)
  • 两种方法殊途同归,最后都落回 5-1 节的动力学方程。方程到手了,接下来按方向分正、逆两种用法(和运动学一样):
方向 已知 求解 用途
正动力学 力矩 τ \tau τ 运动 q , q ˙ , q ¨ q, \dot{q}, \ddot{q} q,q˙,q¨ 仿真(Gazebo 用的就是它)
逆动力学 期望运动 q , q ˙ , q ¨ q, \dot{q}, \ddot{q} q,q˙,q¨ 力矩 τ \tau τ 控制(计算力矩控制)
  • 正动力学:数值积分 q ¨ = M − 1 ( q ) ( τ − C q ˙ − g ) \ddot{q} = M^{-1}(q)(\tau - C\dot{q} - g) q¨=M1(q)(τCq˙g),一步一步推出运动——仿真器(Gazebo、Mujoco)的物理引擎就是干这个的
  • 逆动力学:把期望加速度代进去算力矩——做控制时要算"让机械臂按期望运动需要多大扭矩"
  • 逆动力学最常用的一个例子就是重力补偿(Gravity Compensation):机械臂悬空时电机断电会被重力拽下去,所以要让机械臂"停住",电机必须一直出力对抗重力。重力补偿 = 用逆动力学算出当前位形下的重力项 g ( q ) g(q) g(q),把它加进控制力矩里抵消重力

τ c o m p = g ( q ) \tau_{comp} = g(q) τcomp=g(q)

  • 补偿后机械臂像在"失重"环境里工作,悬停时电机力矩刚好等于重力项、稳稳停住;MoveIt2/UR 的很多 demo 默认开着重力补偿,目的就是让手动拖拽(拖动示教)“轻如无物”——这是逆动力学在实物上最有体验感的应用
  • 两条路线殊途同归——用二连杆做个数值对账(完整代码见下篇附录四):随机抽 20 组 ( q , q ˙ , q ¨ ) (q, \dot{q}, \ddot{q}) (q,q˙,q¨),拉格朗日闭式(5-2 的 M , C , g M, C, g M,C,g)和牛顿-欧拉递推(5-3 节)各算一遍关节力矩,结果全部落在 y = x y = x y=x 直线上,最大误差 10 − 15 10^{-15} 1015 量级(浮点精度):

请添加图片描述

说人话:正动力学是"给力,看它怎么动"(仿真);逆动力学是"想要它这么动,得给多少力"(控制)。Pinocchio 就是干这个的 C++ 刚体动力学库,后面讲 VLA 之前我们会专门用一期来玩它



下篇

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐