2、MATLAB基础速通:矩阵操作、脚本与函数、绘图基础、Simulink入门
各位同学,欢迎来到第二章。
说实话,很多初学者一上来就急着调PID、跑仿真,结果连矩阵怎么索引都搞不清楚。我见过太多人卡在「为什么我的代码报错」这种基础问题上。所以这一章,咱们把MATLAB的底子打牢。你想想看,飞控算法说白了就是矩阵运算 + 逻辑判断 + 数据可视化,这三样玩转了,后面就顺了。
本章核心脉络: 矩阵是飞控的数据骨架 → 脚本和函数是组织代码的方式 → 绘图是调试的眼睛 → Simulink是系统级仿真的战场。
2.1 矩阵操作——飞控的「数据骨架」
飞控里到处都是矩阵。姿态角是3x1向量,旋转矩阵是3x3,雅可比矩阵可能更大。我个人习惯把矩阵操作分成三块:创建、索引、运算。
2.1.1 创建与索引
创建矩阵最简单的方式就是直接写:
% 创建一个3x3矩阵
A = [1, 2, 3; 4, 5, 6; 7, 8, 9];
% 索引——从1开始,不是0!
first_elem = A(1,1); % 结果是1
second_row = A(2, :); % 第二行所有列
last_col = A(:, end); % 最后一列
我曾经踩过的坑: 在C语言里数组从0开始,到了MATLAB还习惯写A[0],结果报错「索引超出矩阵维度」。记住,MATLAB索引从1开始,end关键字表示最后一个位置。
2.1.2 矩阵运算——飞控的核心
飞控里最常用的就是点乘和叉乘。比如从机体坐标系转换到世界坐标系,就是旋转矩阵乘以向量:
% 旋转矩阵 R (3x3) 乘以 向量 v (3x1)
R = [cos(theta), -sin(theta), 0;
sin(theta), cos(theta), 0;
0, 0, 1];
v = [1; 0; 0];
v_rotated = R * v; % 矩阵乘法
% 点乘——计算投影
dot_product = dot(v1, v2);
% 叉乘——计算力矩
cross_product = cross(r, F); % r是力臂,F是力
嗯,这里要注意:矩阵乘法用 *,对应元素相乘用 .*。我刚开始学的时候经常搞混,仿真结果出来全是错的。
2.2 脚本与函数——把代码组织起来
写飞控算法,你不能把所有代码都堆在一个文件里。我建议这样分:脚本用来跑流程,函数用来封装核心算法。
2.2.1 脚本 vs 函数
| 特性 | 脚本 | 函数 |
|---|---|---|
| 工作空间 | 共享全局变量 | 独立局部变量 |
| 输入输出 | 无 | 有明确接口 |
| 适用场景 | 数据预处理、快速测试 | 核心算法、模块化代码 |
| 性能 | 较慢(逐行解释) | 较快(预编译) |
举个例子,写一个计算欧拉角到四元数的函数:
function q = euler2quat(roll, pitch, yaw)
% 输入:滚转角、俯仰角、偏航角(弧度)
% 输出:四元数 [w, x, y, z]
cy = cos(yaw * 0.5);
sy = sin(yaw * 0.5);
cp = cos(pitch * 0.5);
sp = sin(pitch * 0.5);
cr = cos(roll * 0.5);
sr = sin(roll * 0.5);
q = [cr*cp*cy + sr*sp*sy;
sr*cp*cy - cr*sp*sy;
cr*sp*cy + sr*cp*sy;
cr*cp*sy - sr*sp*cy];
end
我的习惯: 每个函数开头写清楚输入输出,加一行注释。这样三个月后回头看代码,不用重新猜「这个变量是干嘛的」。
2.3 绘图基础——调试的眼睛
你想想看,飞控数据都是数字,光看数字很难发现问题。画个图,趋势、超调、震荡一目了然。我个人调试PID的时候,90%的时间都在看图。
2.3.1 基本绘图命令
% 画一条曲线
t = 0:0.01:10;
y = sin(t);
plot(t, y, 'LineWidth', 2);
xlabel('时间 (s)');
ylabel('幅值');
title('正弦波');
grid on; % 加网格,方便读数
2.3.2 多曲线对比
% 对比期望值和实际值
plot(t, desired, 'r--', 'LineWidth', 1.5); hold on;
plot(t, actual, 'b-', 'LineWidth', 1.5);
legend('期望', '实际');
xlabel('时间 (s)');
ylabel('角度 (deg)');
我曾经犯过的错: 画图时忘了加 hold on,结果第二条曲线把第一条覆盖了。折腾了半天才发现。还有,grid on 一定要加,不加网格你很难判断曲线是否收敛。
2.4 Simulink入门——系统级仿真
Simulink说白了就是图形化的MATLAB。你不需要写代码,拖拽模块就能搭出整个飞控系统。我刚开始觉得这玩意儿花里胡哨,后来发现做系统级仿真,Simulink比手写代码快10倍。
2.4.1 基本操作
- 在命令行输入
simulink打开库浏览器 - 新建空白模型(Ctrl+N)
- 从库中拖拽模块:
Sources(信号源)、Continuous(连续系统)、Math Operations(数学运算) - 连线:鼠标左键从输出端口拖到输入端口
- 双击模块设置参数
2.4.2 一个简单的例子:一阶低通滤波器
飞控里常用低通滤波器滤除传感器噪声。在Simulink里搭一个:
模块清单:
1. Step(阶跃信号)—— 模拟传感器突变
2. Transfer Fcn(传递函数)—— 设置 1/(s+1)
3. Scope(示波器)—— 看波形
参数设置:
Transfer Fcn 分子:[1]
Transfer Fcn 分母:[1, 1]
我的建议: 刚开始用Simulink,别贪多。先搭一个简单的传递函数,跑通,看波形。然后再加PID控制器、加饱和模块、加噪声源。一步一步来,出问题了也知道是哪一步的问题。
2.4.3 仿真配置
点击菜单栏的「仿真」→「模型配置参数」,这里有几个关键设置:
- 求解器: 飞控一般用定步长(fixed-step),步长0.001秒(1ms)
- 仿真时间: 根据你的场景设,一般10秒够看稳态
- 容差: 默认1e-6,如果仿真卡顿可以适当放大
嗯,这里要注意:如果你用变步长求解器,仿真结果可能不连续,后面做代码生成会出问题。所以飞控仿真一律用定步长。
好了,这一章的内容就这些。矩阵操作、脚本函数、绘图、Simulink,这四个东西是后面所有章节的基石。你花一周时间把这些练熟,后面学PID、卡尔曼滤波会轻松很多。
记住:飞控仿真不是写代码,是搭积木。每一块积木都要稳,整个系统才能飞得起来。