2. MATLAB/Simulink 基础:熟悉 MATLAB 基本操作、矩阵运算、脚本与函数编写,以及 Simulink 建模环境与仿真流程

机械臂运动学与轨迹仿真的核心工作流,无论是正逆运动学求解、轨迹插补、雅可比矩阵计算,还是动力学验证与控制器设计,都高度依赖 MATLAB 的数值计算能力与 Simulink 的图形化建模环境。本章作为课程的技术地基,将系统梳理 MATLAB 的基本操作习惯、矩阵运算的底层逻辑、脚本与函数的工程化编写规范,以及 Simulink 从建模型到跑仿真的完整流程。掌握这些内容,意味着你后续能够高效地将运动学公式转化为可运行的代码,并将控制算法封装为可复用的 Simulink 模块。

MATLAB/Simulink 基础能力架构与仿真链路 MATLAB 数值计算域 矩阵运算(核心:向量化) 脚本(Script)与函数(Function) 数据类型:double, sym, function_handle Simulink 建模域 模块库(Simulink/Simscape) 子系统封装与信号线连接 Solver 配置与仿真步长控制 机械臂应用域 DH 参数与正运动学矩阵 逆运动学数值解(迭代法) 轨迹规划与可视化(plot3) Simulink 仿真流程(五步闭环) ① 模型搭建 拖拽模块/连线 ② 参数配置 Solver/步长/误差 ③ 运行仿真 Ctrl+T / sim() ④ 结果分析 Scope/To Workspace ⑤ 迭代优化 调参/改结构 反馈迭代:基于仿真结果修正模型参数或控制策略 核心原则:MATLAB 负责数值计算与算法验证,Simulink 负责系统级建模与动态仿真,两者通过工作区变量和 sim() 命令无缝交互

2.1 核心原理:矩阵运算与工作区机制

MATLAB 的命名源自 Matrix Laboratory,其一切运算的基础都是矩阵。在机械臂运动学中,旋转矩阵、齐次变换矩阵、雅可比矩阵都是典型的矩阵对象。理解 MATLAB 的矩阵运算,不能停留在“会写 A*B”的层面,而必须深入理解其内存布局与运算效率逻辑。

首先,MATLAB 默认所有数值变量均为 double 类型的矩阵。标量是 1×1 矩阵,向量是 1×n 或 n×1 矩阵。矩阵的索引从 1 开始,这与 C/Python 从 0 开始不同,是初学者最容易犯的错误。其次,MATLAB 的矩阵乘法要求左矩阵列数等于右矩阵行数,而点乘(.*)则要求两矩阵维度完全一致,对应元素相乘。在机械臂轨迹规划中,当我们需要对时间序列上的每个点施加相同的旋转矩阵时,点乘与广播机制(R2016b 之后自动隐式扩展)能极大简化代码。

工作区(Workspace)是 MATLAB 的核心数据容器。所有在命令行或脚本中创建的变量都存储在工作区中,并可通过 whos 命令查看变量名、大小、字节数及类型。Simulink 模型可以通过 From Workspace 模块读取工作区变量,也可以通过 To Workspace 模块将仿真结果写回工作区。这种双向数据交互是 MATLAB 与 Simulink 协同工作的桥梁。

关键认知: 在机械臂仿真中,我们通常将 DH 参数表、关节角度向量、轨迹插值点等数据存放在工作区,然后通过脚本调用 sim() 函数驱动 Simulink 模型运行。模型内部不再硬编码数值,而是通过参数变量引用工作区数据,这样修改参数时无需重新建模。

2.2 判断方法与操作流程:脚本与函数的工程化规范

在课程项目中,代码组织方式直接影响调试效率与可维护性。MATLAB 提供两种代码载体:脚本(Script)与函数(Function)。脚本按顺序执行,共享工作区变量;函数拥有独立的工作区,通过输入输出参数与外部交互。对于机械臂运动学这类计算密集且需要复用的任务,应优先使用函数封装。

判断何时使用脚本、何时使用函数,可依据以下标准:

  • 一次性流程(如加载数据、绘制图形、调用多个函数完成整体仿真)→ 使用脚本。
  • 可复用算法(如正运动学计算、逆运动学求解、轨迹插值)→ 使用函数。
  • 需要返回多个结果(如同时返回位置和姿态)→ 使用函数,并通过 [pos, orient] = fkine(theta) 形式返回。
  • 需要参数校验与错误提示 → 使用函数,配合 validateattributes 或 assert 进行输入检查。

函数文件的基本结构如下:

function [T, J] = compute_kinematics(theta, dh_params)
% COMPUTE_KINEMATICS 计算机械臂正运动学与雅可比矩阵
% 输入:
%   theta     - 1×n 关节角度向量 (rad)
%   dh_params - n×4 DH参数表 [a alpha d offset]
% 输出:
%   T - 4×4 齐次变换矩阵
%   J - 6×n 几何雅可比矩阵

    n = length(theta);
    T = eye(4);
    for i = 1:n
        % 构建第 i 个关节的 DH 变换矩阵
        Ti = [cos(theta(i)), -sin(theta(i))*cos(dh_params(i,2)), ...
              sin(theta(i))*sin(dh_params(i,2)), dh_params(i,1)*cos(theta(i));
              sin(theta(i)), cos(theta(i))*cos(dh_params(i,2)), ...
              -cos(theta(i))*sin(dh_params(i,2)), dh_params(i,1)*sin(theta(i));
              0, sin(dh_params(i,2)), cos(dh_params(i,2)), dh_params(i,3);
              0, 0, 0, 1];
        T = T * Ti;
    end
    % 雅可比计算省略(后续章节展开)
    J = zeros(6, n);
end

在编写函数时,务必注意:函数名必须与文件名一致;输入参数个数用 nargin 判断,输出参数个数用 nargout 判断;函数内部变量默认局部,除非使用 global 声明(不推荐)。此外,利用 help 注释规范,可让其他开发者(或未来的自己)快速理解函数用途。

2.3 案例拆解:六轴机械臂正运动学矩阵计算实战

为了将上述概念落地,我们以一个典型的 6 自由度关节型机械臂(如 PUMA 560 构型)为例,演示如何利用 MATLAB 脚本与函数完成正运动学计算。该案例将贯穿本章核心知识点:矩阵乘法、循环构建、函数封装、工作区数据交互。

背景与约束: 机械臂 DH 参数表如下(单位:mm 和 rad):

关节 ia (mm)alpha (rad)d (mm)theta 初始值 (rad)
10pi/24000
225000-pi/2
30pi/200
40-pi/22500
50pi/200
600800

初始现象与目标: 给定一组关节角度 theta = [0, -pi/2, 0, 0, 0, 0],计算末端执行器的位置与姿态(即 4×4 齐次变换矩阵 T)。

操作步骤:

  1. 在 MATLAB 编辑器中创建函数文件 fkine_puma.m,代码如上节所示(含 DH 变换矩阵构建)。
  2. 在命令行或脚本中定义 DH 参数矩阵:
    dh = [0, pi/2, 400, 0; 250, 0, 0, -pi/2; 0, pi/2, 0, 0; 0, -pi/2, 250, 0; 0, pi/2, 0, 0; 0, 0, 80, 0];
  3. 调用函数:T = fkine_puma(theta, dh);
  4. 提取位置向量:pos = T(1:3, 4); 提取旋转矩阵:R = T(1:3, 1:3);
  5. 使用 disp(T) 查看完整矩阵,验证平移分量是否合理(预期 x=250, y=0, z=480)。

结果对比与复盘: 运行后得到 T 矩阵的平移向量为 [250; 0; 480],与手算一致。此案例验证了函数封装的正确性。复盘要点:在构建 DH 矩阵时,注意 cos(theta(i)) 与 sin(theta(i)) 的符号位置,不同 DH 约定(标准型 vs 改进型)会导致矩阵元素排列差异,务必在代码注释中注明所采用的约定。

经验提醒: 在编写运动学函数时,建议将 DH 参数表作为函数输入而非硬编码在函数内部。这样同一套代码可适用于不同构型的机械臂,只需更换参数表即可。

2.4 Simulink 建模环境与仿真流程详解

Simulink 是 MATLAB 的图形化仿真环境,特别适合对机械臂这种非线性、强耦合的动态系统进行建模与控制验证。与手写微分方程求解相比,Simulink 提供了可视化模块库,能直观展示信号流向与系统结构。

Simulink 建模的核心操作流程:

  • 模型搭建: 从库浏览器(Library Browser)拖拽模块到模型画布。机械臂仿真常用模块包括:Gain(增益)、Integrator(积分器)、Sum(求和)、MATLAB Function(嵌入 MATLAB 代码)、Scope(示波器)、To Workspace(输出到工作区)。
  • 信号连接: 用鼠标从模块输出端口拖线至另一模块输入端口。信号线支持向量与矩阵信号,例如 6×1 的关节力矩向量可通过一条粗线传递。
  • 子系统封装: 对于复杂的机械臂模型,应将动力学计算、控制器、轨迹生成器分别封装为子系统(Subsystem),使用 Ctrl+G 创建。封装后可自定义图标与参数对话框,提升模型可读性。
  • 求解器配置: 在模型配置参数(Model Configuration Parameters)中,选择求解器类型。对于机械臂这种连续系统,推荐使用变步长 ode45(Dormand-Prince)或 ode15s(刚性系统)。若模型中包含离散控制器(如数字 PID),需设置合适的采样时间。

仿真流程五步法:

步骤操作内容机械臂仿真中的具体应用常见错误
① 模型搭建拖拽模块、连线、封装子系统建立关节伺服环(PID+力矩)与机械臂动力学模块信号线未连接导致端口悬空
② 参数配置设置求解器、步长、误差容限设置 ode45,相对误差 1e-6,最大步长 0.01s步长过大导致数值发散
③ 运行仿真点击运行按钮或使用 sim() 命令通过脚本批量修改关节目标位置并循环仿真仿真时间设置过短未达到稳态
④ 结果分析使用 Scope 查看波形,或导出到工作区分析关节角度跟踪误差、末端轨迹坐标Scope 数据未保存,关闭后丢失
⑤ 迭代优化调整 PID 参数、修改轨迹规划算法增大 Kp 减小跟踪误差,或改用 S 曲线规划参数修改后未重新初始化工作区变量

在 Simulink 中嵌入 MATLAB 函数时,推荐使用 MATLAB Function 模块(而非 Interpreted MATLAB Function),前者支持代码生成与自动编译,仿真速度更快。例如,将逆运动学求解算法写入 MATLAB Function 模块,输入为末端位姿,输出为关节角度,即可实现闭环控制。

风险提示: 当 Simulink 模型与 MATLAB 脚本交互时,务必注意变量作用域。模型中的 From Workspace 模块在仿真开始时读取一次工作区变量,若仿真过程中脚本修改了该变量,模型不会自动更新。此时需使用 set_param 命令或重新运行仿真。另外,避免在模型回调函数(如 InitFcn)中定义变量,否则可能导致不可预测的覆盖行为。

2.5 常见误区与总结复盘

在 MATLAB/Simulink 基础学习阶段,学员常陷入以下误区,需要特别警惕:

  • 误区一:过度使用循环。 MATLAB 的循环效率远低于向量化运算。例如计算轨迹上 1000 个点的齐次变换矩阵,应使用 arrayfun 或预分配三维数组 T_all = zeros(4,4,1000),而非在 for 循环中逐个计算。
  • 误区二:忽视变量预分配。 在循环中动态增长数组会导致内存反复分配,严重拖慢速度。应在循环前用 zeros 或 NaN 预分配矩阵。
  • 误区三:Simulink 模型与工作区数据不同步。 修改了工作区的 DH 参数或目标轨迹,但未重新运行初始化脚本,导致仿真仍使用旧数据。
  • 误区四:求解器选择不当。 对于包含摩擦、接触等快速动态的机械臂模型,使用非刚性求解器可能导致仿真极慢或发散。应尝试 ode23t 或 ode15s。
  • 误区五:忽略单位一致性。 在 MATLAB 中角度默认使用弧度,但 DH 参数表中的角度可能习惯用度。建议在脚本开头统一转换为弧度,并在函数注释中明确单位。