2. MATLAB/Simulink 基础:熟悉 MATLAB 基本操作、矩阵运算、脚本与函数编写,以及 Simulink 建模环境与仿真流程
机械臂运动学与轨迹仿真的核心工作流,无论是正逆运动学求解、轨迹插补、雅可比矩阵计算,还是动力学验证与控制器设计,都高度依赖 MATLAB 的数值计算能力与 Simulink 的图形化建模环境。本章作为课程的技术地基,将系统梳理 MATLAB 的基本操作习惯、矩阵运算的底层逻辑、脚本与函数的工程化编写规范,以及 Simulink 从建模型到跑仿真的完整流程。掌握这些内容,意味着你后续能够高效地将运动学公式转化为可运行的代码,并将控制算法封装为可复用的 Simulink 模块。
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 协同工作的桥梁。
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):
| 关节 i | a (mm) | alpha (rad) | d (mm) | theta 初始值 (rad) |
|---|---|---|---|---|
| 1 | 0 | pi/2 | 400 | 0 |
| 2 | 250 | 0 | 0 | -pi/2 |
| 3 | 0 | pi/2 | 0 | 0 |
| 4 | 0 | -pi/2 | 250 | 0 |
| 5 | 0 | pi/2 | 0 | 0 |
| 6 | 0 | 0 | 80 | 0 |
初始现象与目标: 给定一组关节角度 theta = [0, -pi/2, 0, 0, 0, 0],计算末端执行器的位置与姿态(即 4×4 齐次变换矩阵 T)。
操作步骤:
- 在 MATLAB 编辑器中创建函数文件
fkine_puma.m,代码如上节所示(含 DH 变换矩阵构建)。 - 在命令行或脚本中定义 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]; - 调用函数:
T = fkine_puma(theta, dh); - 提取位置向量:
pos = T(1:3, 4);提取旋转矩阵:R = T(1:3, 1:3); - 使用
disp(T)查看完整矩阵,验证平移分量是否合理(预期 x=250, y=0, z=480)。
结果对比与复盘: 运行后得到 T 矩阵的平移向量为 [250; 0; 480],与手算一致。此案例验证了函数封装的正确性。复盘要点:在构建 DH 矩阵时,注意 cos(theta(i)) 与 sin(theta(i)) 的符号位置,不同 DH 约定(标准型 vs 改进型)会导致矩阵元素排列差异,务必在代码注释中注明所采用的约定。
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 模块,输入为末端位姿,输出为关节角度,即可实现闭环控制。
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 参数表中的角度可能习惯用度。建议在脚本开头统一转换为弧度,并在函数注释中明确单位。