2、MATLAB基础操作:界面、变量、脚本、函数、矩阵运算、绘图基础

飞控系统仿真本质上是一个“建模—计算—可视化”的迭代过程。MATLAB作为该领域的标准工具,其基础操作的熟练程度直接决定了后续开发效率。本章将围绕MATLAB的界面布局、变量管理、脚本与函数编写、矩阵运算以及绘图基础展开,帮助您建立一套高效的仿真工作流。我们不仅会讲解“按钮在哪里”,更会深入剖析“为什么这样做效率更高”,为后续的飞控动力学建模与控制器设计打下坚实的地基。

MATLAB飞控仿真基础操作链路图 ① 界面与变量 工作区/编辑器/命令行 变量命名与数据类型 ② 脚本与函数 脚本顺序执行 函数封装与调用 ③ 矩阵运算 向量化/点运算 线性代数核心 ④ 绘图基础 figure/plot 曲线/三维轨迹 飞控仿真核心应用 姿态解算 → 控制律设计 → 可视化验证 数据流与操作闭环: 1. 在命令行/脚本中定义变量(如姿态角、角速度) 2. 通过矩阵运算实现坐标变换(旋转矩阵、四元数) 3. 使用函数封装控制器模型(PID、LQR) 4. 利用绘图命令实时绘制飞行轨迹与响应曲线 💡 掌握本章内容 = 打通飞控仿真的“任督二脉”

上图展示了MATLAB飞控仿真中四个基础模块的协作关系。界面与变量是操作入口,脚本与函数是代码组织方式,矩阵运算是数学核心,绘图则是结果呈现手段。下面我们逐一深入剖析。

2.1 界面布局与变量管理

核心原理:MATLAB桌面环境由命令行窗口(Command Window)、工作区(Workspace)、当前文件夹(Current Folder)和编辑器(Editor)四大面板构成。在飞控仿真中,命令行用于快速验证数学表达式,工作区实时显示所有变量的值、维度与数据类型,编辑器则用于编写可复用的脚本和函数。理解这四个面板的协作关系,是高效仿真的第一步。

操作流程:

  1. 变量创建:直接输入 roll_angle = 0.5 即创建双精度浮点变量;使用 uint8(180) 可创建整型变量。
  2. 数据导入:通过 load('flight_data.mat') 加载历史飞行数据,或使用 csvread 读取传感器日志。
  3. 变量清理:定期使用 clear all 清空工作区,避免旧数据干扰新仿真。
数据类型典型用途内存占用飞控场景示例
double默认数值类型8字节/元素姿态角、加速度
single节省内存4字节/元素嵌入式部署前验证
logical逻辑判断1字节/元素传感器故障标志
struct数据打包动态IMU数据结构体
经验提醒:在飞控仿真中,建议使用结构体组织传感器数据。例如 imu.accel = [0.1, 0.2, 9.8]; imu.gyro = [0.01, 0.02, 0.03]; 比分散的变量更易管理,且便于作为整体参数传递。

2.2 脚本与函数的编写规范

核心原理:脚本(Script)按顺序执行命令,适合线性流程;函数(Function)具有独立工作区,通过输入输出参数传递数据,适合封装可复用的算法模块。在飞控仿真中,通常将传感器模型、控制律、状态估计器封装为函数,而将仿真主流程写在脚本中。

判断方法:当代码需要被多次调用且参数可变时,应写成函数;若仅需一次性执行,则使用脚本。例如,PID控制器参数(Kp, Ki, Kd)不同,应封装为 function u = pid_controller(error, Kp, Ki, Kd)。

% 飞控仿真主脚本示例
clear; clc;
% 定义仿真参数
dt = 0.001;  % 仿真步长1ms
t_end = 10;  % 仿真时长10s
t = 0:dt:t_end;
% 初始化状态
state = [0; 0; 0];  % 滚转角、俯仰角、偏航角
% 主循环
for k = 1:length(t)
    % 调用控制律函数
    u = pid_controller(state(1), 2.0, 0.5, 0.1);
    % 更新状态(简化模型)
    state = state + dt * [u; 0; 0];
end
风险提示:函数内部变量默认不共享外部工作区。若需在函数间共享配置参数,应使用全局变量(不推荐)或通过参数结构体传递。在飞控仿真中,建议将所有物理常量(重力加速度、飞机质量)放入一个 params 结构体统一传递。

2.3 矩阵运算与向量化编程

核心原理:MATLAB的矩阵运算能力是飞控仿真的基石。飞控算法中大量使用旋转矩阵(3×3)、四元数(4×1向量)、雅可比矩阵等。向量化编程(避免for循环)可提升仿真速度1-2个数量级,尤其在处理长时程仿真时优势明显。

关键运算规则:

  • 矩阵乘法:A * B 执行线性代数乘法,用于坐标变换。
  • 点运算:A .* B 执行元素级乘法,用于逐元素计算。
  • 转置:A' 用于旋转矩阵求逆(正交矩阵的逆等于转置)。
% 飞控中的典型矩阵运算
% 定义旋转矩阵(绕Z轴旋转45度)
theta = pi/4;
Rz = [cos(theta), -sin(theta), 0;
      sin(theta),  cos(theta), 0;
      0,           0,          1];
% 定义机体坐标系下的向量
v_body = [1; 0; 0];
% 转换到地面坐标系
v_ground = Rz * v_body;
% 向量化计算多个时间点的正弦值
t = 0:0.01:10;
y = sin(2*pi*5*t);  % 5Hz正弦波,无需for循环
运算类型符号飞控应用示例
矩阵乘法*姿态旋转R * v
点乘.*增益调度K .* error
左除\求解线性方程组A \ b
克罗内克积kron多旋翼混控矩阵kron(I, M)
实战技巧:在飞控仿真中,应尽量避免在for循环内进行矩阵运算。例如,计算10000个时间点的旋转矩阵,应预先分配三维数组 R_all = zeros(3,3,10000),然后使用向量化方法批量计算,而非循环内逐个计算。

2.4 绘图基础与数据可视化

核心原理:飞控仿真结果的可视化包括时域响应曲线(姿态角变化)、空间轨迹(三维飞行路径)和频域分析(Bode图)。MATLAB的 plot 系列函数提供了从简单曲线到复杂三维渲染的完整能力。

操作流程:

  1. 创建图形窗口:figure('Name', '姿态响应', 'NumberTitle', 'off')
  2. 绘制曲线:plot(t, roll_angle, 'b-', 'LineWidth', 1.5)
  3. 标注与网格:xlabel('时间 (s)'); ylabel('角度 (deg)'); grid on;
  4. 多子图:subplot(2,1,1) 分别绘制滚转、俯仰响应。
% 飞控仿真结果可视化示例
figure('Name', '飞行轨迹', 'Position', [100, 100, 800, 600]);
% 绘制三维轨迹
plot3(position(:,1), position(:,2), position(:,3), 'r-', 'LineWidth', 2);
grid on; axis equal;
xlabel('X (m)'); ylabel('Y (m)'); zlabel('Z (m)');
title('四旋翼三维飞行轨迹');
% 添加起点和终点标记
hold on;
plot3(position(1,1), position(1,2), position(1,3), 'go', 'MarkerSize', 10, 'MarkerFaceColor', 'g');
plot3(position(end,1), position(end,2), position(end,3), 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r');
legend('轨迹', '起点', '终点');
常见误区:绘图时忘记使用 hold on 导致后续图形覆盖前图;未设置 axis equal 导致三维轨迹比例失真;在循环内频繁调用 plot 导致图形窗口卡顿。正确做法是循环内仅更新数据(set 句柄),循环结束后统一刷新。

2.5 案例拆解:从零搭建一个姿态响应仿真

场景与目标:假设我们需要验证一个简化的滚转通道PD控制器性能。已知飞机滚转惯量 Ixx = 0.05 kg·m²,目标滚转角 roll_ref = 30°,控制器参数 Kp = 2.0, Kd = 0.5。要求绘制滚转角响应曲线并计算超调量。

实施步骤:

  1. 初始化参数:设置仿真步长 dt = 0.001,总时长 t_end = 5。
  2. 编写动力学函数:创建 roll_dynamics.m 函数,输入当前状态和控制力矩,输出状态导数。
  3. 主仿真循环:使用for循环迭代计算,存储每个时间点的角度和角速度。
  4. 结果分析:计算超调量 overshoot = (max(roll) - roll_ref) / roll_ref * 100。
% 主仿真代码
dt = 0.001; t = 0:dt:5; n = length(t);
roll = zeros(1,n); roll_rate = zeros(1,n);
roll(1) = 0; roll_rate(1) = 0;
Ixx = 0.05; Kp = 2.0; Kd = 0.5; roll_ref = deg2rad(30);
for k = 1:n-1
    error = roll_ref - roll(k);
    torque = Kp * error - Kd * roll_rate(k);
    roll_rate(k+1) = roll_rate(k) + (torque / Ixx) * dt;
    roll(k+1) = roll(k) + roll_rate(k+1) * dt;
end
% 绘图
figure; plot(t, rad2deg(roll), 'b-', 'LineWidth', 1.5); hold on;
yline(rad2deg(roll_ref), 'r--', '目标角度');
xlabel('时间 (s)'); ylabel('滚转角 (deg)'); grid on;
legend('实际响应', '目标值');
% 计算超调量
overshoot = (max(roll) - roll_ref) / roll_ref * 100;
fprintf('超调量: %.2f%%\n', overshoot);

结果与复盘:运行代码后,若超调量超过15%,说明Kd过小;若响应过慢,则需增大Kp。通过调整参数并重新运行,可快速找到最优控制参数。此案例展示了从变量定义、矩阵运算到绘图分析的全流程,是后续复杂飞控仿真的最小可行示例。

总结复盘:本章所有操作均围绕“数据流”展开——变量存储数据,脚本组织流程,函数封装算法,矩阵加速计算,绘图呈现结果。建议读者在练习时,刻意使用向量化替代for循环,并养成用结构体管理参数的习惯。下一阶段,我们将基于这些基础,开始构建六自由度飞行动力学模型。