数学与编程基础

数学是具身智能的运行时——向量描述运动、矩阵处理坐标变换、概率处理不确定性、微积分驱动优化。不为学数学而学数学,每个概念都绑定一个机器人应用场景。

4-6 周
5 个章节
12 个代码示例
5 个验收实验

本阶段目录

  1. 向量基础与空间直觉
  2. 矩阵运算与线性变换
  3. 特征值与奇异值分解
  4. 微积分与优化基础
  5. 概率统计与贝叶斯推断
  6. Python 科学计算实战

1. 向量基础与空间直觉

你已经知道的

任何一个力学分析都离不开向量:力、力矩、速度、加速度。你每天都在用平行四边形法则做力的合成与分解。本章只是让这些直觉变得精确、可编程。

为什么向量是机器人学的"母语"

机器人学的每一个核心概念——位置、姿态、速度、力、雅可比——都是用向量表达的。理解向量的本质,就理解了机器人学的一半。

向量的两种视角

🔧 工程连接:CAD 软件里你拖拽一个零件,底层就是一个三维向量在不断更新。机器人末端执行器的位置,就是一个 $(x, y, z)$ 向量。

点积(内积)——最重要的向量运算

点积有两种等价定义,这正是它强大的原因:

$\mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i = \|\mathbf{a}\| \|\mathbf{b}\| \cos\theta$

代数定义告诉我们怎么算,几何定义告诉我们什么意思

在机器人学中,点积无处不在:

动手验证

取 $\mathbf{a} = (3, 4)$,$\mathbf{b} = (1, 2)$。手算 $\mathbf{a} \cdot \mathbf{b} = 3 \times 1 + 4 \times 2 = 11$。然后验证 $\|\mathbf{a}\| = 5$,$\|\mathbf{b}\| = \sqrt{5}$,$\cos\theta = 11/(5\sqrt{5}) \approx 0.984$,所以夹角约 $10.3°$。动手算一遍,以后就不会忘了。

叉积(外积)——三维专属

$\mathbf{a} \times \mathbf{b} = (a_2 b_3 - a_3 b_2,\; a_3 b_1 - a_1 b_3,\; a_1 b_2 - a_2 b_1)$

结果是垂直于两个向量所在平面的向量,方向由右手定则确定。大小 $\|\mathbf{a} \times \mathbf{b}\| = \|\mathbf{a}\|\|\mathbf{b}\|\sin\theta$,正是平行四边形的面积。

🔧 工程连接:计算关节力矩时,$\boldsymbol{\tau} = \mathbf{r} \times \mathbf{F}$;在运动学中,旋转关节的轴线方向用叉积求得;雅可比矩阵的转动部分本质上就是一系列叉积。

向量范数(长度)

范数公式工程含义
$L_1$(曼哈顿)$\|\mathbf{v}\|_1 = \sum |v_i|$网格路径距离
$L_2$(欧几里得)$\|\mathbf{v}\|_2 = \sqrt{\sum v_i^2}$真实空间距离,最常用
$L_\infty$$\|\mathbf{v}\|_\infty = \max|v_i|$最大分量,最坏情况

机器人直觉

机械臂末端到目标的距离 = $L_2$ 范数。关节运动的"能量消耗"有时用 $L_2$ 范数近似。碰撞检测中的包围盒距离经常用 $L_\infty$ 范数。

第一个代码实验

import numpy as np

# ===== 向量的表示 =====
pos = np.array([0.5, 0.3, 0.8])      # 末端位置 (m)
target = np.array([0.7, 0.1, 0.9])   # 目标位置 (m)

# ===== 基本运算 =====
dist = np.linalg.norm(pos - target)       # 欧几里得距离
direction = (target - pos) / dist           # 单位方向向量
dot = np.dot(pos, target)                  # 点积

# ===== 力与力矩 =====
F = np.array([5.0, 0.0, 0.0])          # 末端力 (N)
r = np.array([0.3, 0.0, 0.0])          # 力臂 (m)
torque = np.cross(r, F)                   # 力矩 = r × F

print(f"距离: {dist:.4f} m")
print(f"方向向量: {direction}")
print(f"力矩: {torque} Nm")

2. 矩阵运算与线性变换

你已经知道的

有限元分析中,刚度矩阵 $\mathbf{K}\mathbf{u} = \mathbf{F}$ 将一个位移向量映射为力向量。矩阵就是变换规则的数字化表示

矩阵乘法:组合变换

$C_{ij} = \sum_{k} A_{ik} B_{kj}$

矩阵乘法对应变换的组合:先做B变换再做A变换,等价于做 $C = AB$ 这一次变换。但要注意 $AB \neq BA$——变换的顺序不能随意交换!

旋转矩阵:机器人学的"身份证"

绕 $z$ 轴旋转 $\theta$ 角度的旋转矩阵:

$R_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix}$

旋转矩阵有两个关键性质:

🔧 工程连接:UR5 的控制器内部用旋转矩阵表示末端姿态。每次你输入一个欧拉角,底层就构建一个 3×3 的旋转矩阵。理解旋转矩阵 = 理解机器人如何"知道"自己的朝向。

齐次变换:同时处理旋转和平移

$T = \begin{bmatrix} R_{3\times 3} & \mathbf{t}_{3\times 1} \\ \mathbf{0}_{1\times 3} & 1 \end{bmatrix} \in SE(3)$

这是机器人学最重要的数据结构。一个 4×4 矩阵同时编码了旋转和平移:

import numpy as np

def make_transform(rotation, translation):
    """构建齐次变换矩阵"""
    T = np.eye(4)
    T[0:3, 0:3] = rotation
    T[0:3, 3] = translation
    return T

# 构建:绕z轴旋转30°,平移(1, 0, 0.5)
theta = np.radians(30)
R = np.array([
    [np.cos(theta), -np.sin(theta), 0],
    [np.sin(theta),  np.cos(theta), 0],
    [0,            0,            1]
])
t = np.array([1.0, 0.0, 0.5])
T = make_transform(R, t)

# 链式变换:world → robot_base → camera
T_world_camera = T_world_robot @ T_robot_camera # 矩阵乘法 = 变换组合

# 变换一个点:将相机坐标系下的点变换到世界坐标系
point_cam = np.array([0.2, 0.1, 0.3, 1.0])  # 齐次坐标
point_world = T_world_camera @ point_cam
print(f"世界坐标: {point_world[:3]}")

矩阵的迹与行列式

$\text{tr}(A) = \sum A_{ii}$(主对角线元素之和),在旋转矩阵中 $\text{tr}(R) = 1 + 2\cos\theta$,可以反推旋转角度。

$\det(A)$ 的物理意义是变换的体积缩放因子。$\det(R)=1$ 保证旋转不改变体积。

3. 特征值与奇异值分解

你已经知道的

模态分析:结构的固有频率 = 刚度矩阵的特征值,振型 = 特征向量。你做过的每一个振动分析都在用特征值分解。

特征值分解

$A\mathbf{v} = \lambda \mathbf{v}$

$\lambda$ 是特征值,$\mathbf{v}$ 是对应的特征向量。矩阵 $A$ 作用在 $\mathbf{v}$ 上,只是把它拉伸/压缩了 $\lambda$ 倍,方向不变。

机器人学中的特征值

奇异值分解 (SVD)

$A = U \Sigma V^T$

SVD 是"任何矩阵都能对角化"的保证。$\Sigma$ 的对角元素(奇异值)描述了矩阵在各个方向上的"放大倍数"。

import numpy as np

# 机械臂在某姿态下的雅可比矩阵
J = np.array([[0.5, -0.2, 0.1],
              [0.3,  0.8, -0.1],
              [0.0,  0.1,  0.9]])

U, s, Vt = np.linalg.svd(J)

print(f"奇异值: {s}")  # 沿各主轴的"运动能力"
print(f"条件数: {s[0]/s[-1]:.1f}")  # 大→接近奇异
print(f"可操作度: {np.prod(s):.4f}")  # 综合运动能力

机器人直觉

机械臂完全伸直时,最小的奇异值趋近于零 → 条件数很大 → 接近奇异位姿 → 微小的末端位移需要巨大的关节运动 → 电机可能过载。这就是为什么我们要避免奇异位姿。

4. 微积分与优化基础

你已经知道的

速度是位置的导数,加速度是速度的导数。优化问题的本质是"找极值点"——导数为零的地方。

梯度——多变量函数的"斜率"

$\nabla f = \left(\frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, \ldots, \frac{\partial f}{\partial x_n}\right)$

梯度指向函数值增长最快的方向。在机器学习中,梯度下降就是沿着负梯度方向走,逐步走到函数的最小值点。

🔧 工程连接:PID 调参就是找一个三维函数(Kp, Ki, Kd → 超调量+稳态误差)的最小值。梯度下降把这个手动的试凑过程自动化了。

雅可比矩阵——向量函数的"导数"

$J_{ij} = \frac{\partial f_i}{\partial x_j}$

雅可比是机器人学中最核心的矩阵之一:

# 数值雅可比:用有限差分近似
def numerical_jacobian(fk_fn, q, eps=1e-6):
    """用有限差分计算雅可比"""
    n_joints = len(q)
    f0 = fk_fn(q)
    J = np.zeros((len(f0), n_joints))
    for i in range(n_joints):
        q_perturb = q.copy()
        q_perturb[i] += eps
        J[:, i] = (fk_fn(q_perturb) - f0) / eps
    return J

梯度下降 vs 牛顿法

方法更新规则特点
梯度下降$\mathbf{x}_{k+1} = \mathbf{x}_k - \alpha \nabla f$简单、一阶收敛
牛顿法$\mathbf{x}_{k+1} = \mathbf{x}_k - H^{-1}\nabla f$二阶收敛,需Hessian

IK 中的 Newton-Raphson 方法就是牛顿法的应用:$\Delta\mathbf{q} = J^+ \Delta\mathbf{x}$,用雅可比伪逆替代 Hessian 的逆。

5. 概率统计与贝叶斯推断——机器人学的决策语言

为什么概率在机器人学中至关重要

真实机器人永远面对不确定性:传感器有噪声、电机有死区、环境在变化。概率论不是数学装饰,而是机器人做出合理决策的唯一语言。Kalman滤波、粒子滤波、SLAM、贝叶斯优化——所有这些都以概率为根基。

概率分布:随机变量的数学描述

分布公式机器人学应用
高斯(正态)$\mathcal{N}(x|\mu, \sigma^2) = \frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(x-\mu)^2}{2\sigma^2}}$传感器噪声建模、Kalman滤波、位置不确定性
多维高斯$\mathcal{N}(\mathbf{x}|\boldsymbol{\mu}, \Sigma)$机器人位姿估计 (SLAM)、状态空间模型
伯努利$P(x) = p^x(1-p)^{1-x}$夹爪开/合检测、二值传感器
类别分布$P(x=k) = p_k$物体识别分类、技能选择

贝叶斯定理:从先验到后验

$P(H|E) = \frac{P(E|H) \cdot P(H)}{P(E)}$

这是机器人学中最重要的公式。它告诉你:拿到新证据(E)后,你的信念(H)应该如何更新。

import numpy as np

# 机器人接触检测的贝叶斯更新
# 先验:有10%概率在接触某物体
P_contact = 0.10

# 传感器:检测到力 > 阈值
# P(传感器报警 | 接触) = 0.95 (检测率)
# P(传感器报警 | 未接触) = 0.02 (误报率)
P_alarm_given_contact = 0.95
P_alarm_given_no_contact = 0.02

# 传感器报警后,实际接触的概率?
P_alarm = (P_alarm_given_contact * P_contact +
           P_alarm_given_no_contact * (1 - P_contact))

P_contact_given_alarm = (P_alarm_given_contact * P_contact) / P_alarm

print(f"报警后接触概率: {P_contact_given_alarm:.2%}")
🔧 工程直觉:下一次传感器报警时,不要直接信任——把先验知识和传感器特性一起代入贝叶斯公式。这就是Kalman滤波的核心思想:用模型预测(先验) + 传感器测量(似然) → 最优估计(后验)。

期望与方差

$\mathbb{E}[X] = \sum x \cdot P(x) \qquad \text{Var}(X) = \mathbb{E}[(X - \mathbb{E}[X])^2]$

期望 = "平均结果" = 长期平均奖励。方差 = "不确定性大小" = 策略的稳定程度。

协方差矩阵:描述多维不确定性

$\Sigma_{ij} = \text{Cov}(X_i, X_j) = \mathbb{E}[(X_i - \mu_i)(X_j - \mu_j)]$

6. Python 科学计算实战

NumPy:向量化思维

机械工程师习惯用循环处理数据。NumPy 的哲学是向量化——一次操作整个数组。这不仅更简洁,而且利用底层 C/Fortran 实现,速度快 10-100 倍。

import numpy as np

# ❌ 坏习惯:Python 循环
result = []
for i in range(1000000):
    result.append(np.sin(i * 0.01))

# ✅ 好习惯:NumPy 向量化
x = np.arange(0, 10000, 0.01)
result = np.sin(x)  # 一行,快 50 倍

Matplotlib:从数据到直觉

你习惯看工程图纸和仿真云图。Matplotlib 就是把数据变成你熟悉的视觉表示。

import matplotlib.pyplot as plt

# 可视化机械臂工作空间
angles = np.linspace(-np.pi, np.pi, 200)
x = np.cos(angles) + 0.8 * np.cos(angles * 2)
y = np.sin(angles) + 0.8 * np.sin(angles * 2)

plt.figure(figsize=(8, 8))
plt.plot(x, y, 'b-', linewidth=2)
plt.axis('equal')
plt.grid(True, alpha=0.3)
plt.title('2-DOF 机械臂工作空间边界')
plt.xlabel('X (m)'); plt.ylabel('Y (m)')

验收实验

  • 用 NumPy 实现 2-DOF 机械臂的正运动学,计算 100 个随机关节角下的末端位置并绘图
  • 构造一个 3×3 旋转矩阵,验证 $R^TR = I$ 和 $\det(R) = 1$
  • 计算机械臂雅可比矩阵的奇异值,找出使条件数 > 100 的关节角
  • 用梯度下降法求解函数 $f(x,y) = (x-3)^2 + (y+2)^2$ 的最小值
  • 编写一个函数,输入两个坐标系之间的平移和旋转,输出 4×4 齐次变换矩阵,并用测试用例验证

继续下一阶段: 阶段二:机器学习与深度学习 →

在机器人学中,协方差矩阵无处不在:SLAM中的位姿不确定性、Kalman滤波的误差传播、抓取时的接触不确定性。对角线是各维度的方差,非对角线是两个维度之间的"联动"。

机器人直觉

如果SLAM输出的协方差矩阵在对角线出现很大的值 → 定位不可靠 → 不要在这个位置做精确操作。这就是"不确定性感知"(uncertainty-aware)的思维。

拓展资源:线性代数

GitHub 仓库

视频课程

推荐阅读