第3章 MATLAB/Simulink环境搭建:MATLAB安装与配置、Simulink基础操作、Stateflow入门

说实话,很多做飞控的朋友一开始就急着写代码。我当年也是这样,觉得画模型浪费时间。直到有一次,我在调试一个四旋翼的姿态控制器,代码改了十几版,每次烧录都提心吊胆。后来我老老实实把Simulink用起来,才发现——模型设计不是花架子,是保命的工具

这一章,咱们就把环境搭好。别小看这一步,环境配不好,后面全是坑。

3.1 MATLAB安装与配置:别让版本坑了你

MATLAB的版本问题,我吃过亏。有一次项目赶进度,我用了R2020a,结果同事用的是R2019b,模型互相打不开。嗯,从那以后,我养成了一个习惯:团队统一版本

3.1.1 版本选择建议

我个人习惯用R2021b以上版本。为什么?因为从R2021b开始,Simulink对C代码生成的支持更稳定了。特别是针对飞控这种硬实时系统,代码生成的质量直接关系到飞行安全。

用途 推荐版本 说明
学习/原型验证 R2021b ~ R2023a 功能完整,社区资源多
嵌入式代码生成 R2022b+ 对ARM Cortex-M支持更好
团队协作 统一版本 避免模型兼容性问题
注意:不要用太老的版本(比如R2018a以下)。很多飞控相关的工具箱(如Aerospace Blockset、Embedded Coder)在新版本里才有完整支持。

3.1.2 安装时的关键配置

安装过程其实很简单,但有几个地方我建议你留意一下:

  • 工具箱选择:做飞控开发,下面这几个工具箱是必须装的:
    • Simulink(核心)
    • Stateflow(状态机建模)
    • Embedded Coder(代码生成)
    • Aerospace Blockset(飞控专用模块)
    • Signal Processing Toolbox(信号处理)
  • 路径设置:我个人习惯把项目文件夹单独放,然后在MATLAB里用addpath添加。千万别把工作路径设成桌面,否则模型文件一多,你会疯的。
  • 编译器配置:如果你要做代码生成,记得配好C编译器。在MATLAB命令行输入mex -setup,选择MinGW-w64或者你板子对应的交叉编译器。
小技巧:安装完成后,运行一下ver命令,看看所有工具箱是否都加载成功。我曾经遇到过工具箱装上了但没激活的情况,折腾了半天才发现。

3.2 Simulink基础操作:从拖模块到跑仿真

Simulink说白了就是一个图形化的编程工具。你想想看,写代码的时候,一个PID控制器要写几十行。但在Simulink里,拖几个模块就搞定了。而且,你能直观地看到信号怎么流,这对理解飞控系统特别有帮助。

3.2.1 模型的基本结构

一个典型的飞控Simulink模型,通常包含这几部分:

  1. 输入源:比如传感器数据(IMU、GPS)、遥控器信号
  2. 控制器:姿态控制、位置控制、导航逻辑
  3. 被控对象:飞机动力学模型(或者真实硬件)
  4. 输出显示:示波器、数据记录

我第一次搭飞控模型时,把所有的模块都堆在一个画布里。结果呢?信号线乱得像蜘蛛网,自己都看不懂。后来我学会了用子系统(Subsystem)来分层管理。

3.2.2 常用模块速览

模块类别 常用模块 飞控中的应用
数学运算 Add, Product, Gain PID计算、坐标变换
连续/离散 Integrator, Discrete PID Controller 姿态角积分、控制器实现
信号路由 Mux, Demux, Bus Creator 多路传感器数据合并
逻辑判断 Relational Operator, Switch 模式切换、保护逻辑

3.2.3 仿真设置要点

跑仿真之前,有3个参数我建议你检查一下:

  • 求解器(Solver):飞控系统通常是离散的,选discrete (no continuous states)。如果你用连续求解器,仿真步长不对,结果会差很多。
  • 步长(Step size):一般设成0.001秒(1ms),和飞控的实际控制周期一致。
  • 仿真时间:先跑个10秒看看效果,别一上来就跑100秒,万一模型有bug,等半天才发现。
核心经验:仿真步长一定要和实际硬件匹配。我在做Pixhawk代码生成时,仿真步长设了0.01秒,结果生成的代码在飞控板上跑起来,控制周期对不上,飞机抖得厉害。后来改成0.001秒,问题就解决了。

3.3 Stateflow入门:用状态机管理飞控逻辑

飞控系统里有很多状态切换的场景。比如:

  • 解锁 -> 起飞 -> 悬停 -> 降落
  • 手动模式 -> 增稳模式 -> 自主飞行模式
  • 正常飞行 -> 低电量保护 -> 紧急降落

这些逻辑如果用纯C代码写,if-else嵌套会让你怀疑人生。而Stateflow就是专门干这个的——用状态图来管理复杂逻辑

3.3.1 Stateflow的核心概念

说白了,Stateflow就三个东西:

  • 状态(State):系统处于什么模式。比如DISARMEDARMEDFLYING
  • 转移(Transition):什么条件下从一个状态跳到另一个状态。比如油门 > 10% && 解锁信号有效
  • 动作(Action):进入状态时做什么、在状态中做什么、离开状态时做什么。

我举个例子。一个简单的飞控解锁逻辑:

// 伪代码逻辑
if (状态 == DISARMED) {
    if (遥控器解锁信号 == TRUE && 电池电压 > 3.5V) {
        状态 = ARMED;
        解锁电机;
    }
}

在Stateflow里,你只需要画两个方框,连一条带条件的箭头。是不是直观多了?

3.3.2 一个简单的飞控状态机

咱们来搭一个最简的飞控状态机。包含三个状态:

  • DISARMED:上锁状态,电机不转
  • ARMED:解锁状态,电机怠速
  • FLYING:飞行状态,正常控制

转移条件:

  • DISARMED -> ARMED:解锁信号 && 电压正常
  • ARMED -> FLYING:油门 > 20%
  • FLYING -> ARMED:油门 < 5%
  • 任何状态 -> DISARMED:急停信号
我的习惯:在Stateflow里,我会把每个状态的进入动作(entry)、持续动作(during)、退出动作(exit)都写清楚。这样生成的代码结构特别清晰,调试的时候一眼就能看出问题。

3.3.3 Stateflow与Simulink的联动

Stateflow不是孤立的。它通常作为Simulink模型中的一个模块存在。比如:

  • Stateflow接收来自Simulink的传感器信号(电压、油门值)
  • Stateflow输出当前状态(解锁/锁定)给控制器
  • 控制器根据状态决定是否输出PWM

这种联动方式,说白了就是逻辑与算法的分离。Stateflow管逻辑,Simulink管算法,各司其职。

避坑指南:我曾经在Stateflow里用了大量的after()延时函数,结果生成的代码里出现了定时器冲突。后来我改用Simulink的计时器模块,把延时逻辑放到外面,问题就解决了。记住:Stateflow适合做逻辑判断,不适合做精确计时

3.4 本章知识体系总览

下面这张图,是我对本章内容的一个梳理。你可以把它当作一个导航图,看看自己学到哪了。

第3章:MATLAB/Simulink环境搭建 MATLAB安装与配置 Simulink基础操作 Stateflow入门 版本选择 工具箱安装 编译器配置 模型结构 常用模块 仿真设置 状态与转移 飞控状态机 Simulink联动 目标:搭建可用的飞控模型开发环境 三个模块层层递进,最终服务于飞控模型开发

嗯,环境搭建这部分,说白了就是磨刀不误砍柴工。我见过太多人一上来就急着写控制算法,结果模型跑不通,回头才发现是环境没配好。所以,花点时间把这一步做扎实,后面你会感谢自己的


公众号:蓝海资料掘金营,微信deep3321