3、Simulink基础入门:环境搭建、基本模块与子系统封装
说实话,很多做飞控仿真的朋友,一开始都被Simulink的界面吓到过。我当年第一次打开它,满屏的模块库,真有点无从下手。但别担心,这东西用熟了,你会发现它就是个搭积木的工具。
这一章,咱们就踏踏实实把Simulink的基础过一遍。我会结合自己做FlightGear联合仿真时的经验,把那些容易踩的坑提前告诉你。
3.1 环境搭建:别让配置卡住你
安装MATLAB和Simulink,我就不啰嗦了。但有几个关键点,我得提一下。
第一,版本问题。 我个人习惯用2020b以上的版本。为什么?因为低版本对FlightGear的接口支持不太好。我曾经在2018a上折腾了一整天,死活连不上FlightGear,换了2021a,十分钟搞定。
第二,必备工具箱。 做联合仿真,下面这几个工具箱必须装:
- Aerospace Blockset:飞行器专用的模块,比如姿态、导航、大气环境。
- Aerospace Toolbox:配合上面的Blockset,提供一些函数和接口。
- Simulink 3D Animation:这个最关键,它是连接FlightGear的桥梁。
注意: 安装时别图省事选“典型安装”。一定要自定义勾选上面三个工具箱。我有个学生,装完才发现没有Aerospace Blockset,又重装了一遍,浪费时间。
第三,工作路径。 启动Simulink后,第一件事就是设置当前文件夹。我建议专门建一个文件夹,比如 D:\FlightGear_Simulink,所有模型和脚本都放里面。不然文件散落得到处都是,找起来头疼。
3.2 基本模块使用:搭积木的第一步
打开Simulink,你会看到左侧的模块库浏览器。别被它吓到,常用的其实就那几种。
3.2.1 常用模块分类
| 类别 | 常用模块 | 用途 |
|---|---|---|
| 信号源 | Constant, Sine Wave, Step, Ramp | 产生输入信号 |
| 数学运算 | Add, Product, Gain, Sum | 做加减乘除 |
| 连续系统 | Integrator, Derivative, Transfer Fcn | 微分、积分、传递函数 |
| 信号路由 | Mux, Demux, Bus Creator, Goto/From | 合并或拆分信号 |
| 显示/输出 | Scope, Display, To Workspace | 看结果、存数据 |
你想想看,一个飞控系统,无非就是传感器输入、控制律计算、舵机输出。这些模块完全够用。
3.2.2 举个简单的例子
咱们搭一个最简单的模型:输入一个正弦波,乘以2,然后显示出来。
1. 拖一个 Sine Wave 模块到画布
2. 拖一个 Gain 模块,双击设置增益为2
3. 拖一个 Scope 模块
4. 用信号线连起来:Sine Wave → Gain → Scope
5. 点击运行,双击Scope看波形
嗯,就这么简单。但这里有个细节:信号线的方向。Simulink的信号线是有方向的,从输出口到输入口。如果你连反了,线会变成红色,运行会报错。我刚开始学的时候,经常犯这个错。
小技巧: 连线时按住Ctrl键,可以画折线。按住Shift键,可以画直线。这个在复杂模型里特别有用。
3.3 信号线连接:别让线乱成一团
模型一复杂,信号线就会像蜘蛛网一样。怎么管理?我有几个心得。
3.3.1 使用标签
双击信号线,可以输入标签名。比如 roll_cmd、pitch_rate。这样一看就知道这根线是干什么的。我曾经在一个300多个模块的模型里,全靠标签找信号。
3.3.2 用Goto/From模块
如果信号要从模型的一头传到另一头,别拉一根长线。用Goto模块发送,From模块接收。这样模型清爽多了。
// 举个例子
// 在模型左侧放一个Goto模块,标签设为 "air_speed"
// 在模型右侧放一个From模块,标签同样设为 "air_speed"
// 它们就自动连接了,不用画线
3.3.3 信号线的数据类型
默认是double类型。但如果你用FlightGear接口,有时候需要single或者uint8。怎么改?双击信号线,在Signal Attributes里设置。不匹配的话,运行时会报数据类型错误。这个坑我踩过好几次。
3.4 子系统封装:让模型更整洁
模型大了,就得分层。子系统就是用来干这个的。
3.4.1 创建子系统
选中几个模块,右键 → Create Subsystem。或者直接拖一个Subsystem模块进来,双击进去编辑。
我个人习惯把功能相关的模块放在一个子系统里。比如:
- 导航子系统:包含GPS、IMU、气压计模型
- 控制子系统:包含PID控制器、限幅器
- 执行机构子系统:包含舵机、发动机模型
3.4.2 封装子系统(Mask)
这才是重点。封装后的子系统,可以像普通模块一样,双击设置参数。
怎么做?右键子系统 → Mask → Create Mask。然后你会看到:
- Icon & Ports:设置图标和端口
- Parameters:定义参数,比如PID的Kp、Ki
- Initialization:初始化代码
- Documentation:写帮助文档
举个例子,我封装过一个PID控制器子系统:
// 在Parameters里添加三个参数:Kp, Ki, Kd
// 在Initialization里写:
Kp = eval(Kp_str); // 把字符串转成数值
Ki = eval(Ki_str);
Kd = eval(Kd_str);
// 然后在子系统内部,用这些变量设置Gain模块的值
封装好后,双击这个子系统,就会弹出对话框,让你输入Kp、Ki、Kd。是不是很方便?
核心思想: 封装不是为了炫技,是为了复用。你做好一个PID子系统,以后每个项目都能直接用。我现在的模型库里,有几十个封装好的子系统,拖出来就能用。
3.5 本章知识体系
下面这张图,帮你理清这一章的核心逻辑。从环境搭建开始,到基本模块,再到信号连接,最后是子系统封装。每一步都是下一步的基础。
说白了,这一章就是让你学会用Simulink搭积木。环境搭好了,模块认识了,线会连了,子系统会封装了,后面做联合仿真就水到渠成。
嗯,今天就到这儿。记住,动手练才是关键。光看不练,看十遍也记不住。