第三章 Simulink入门:模型搭建、子系统、信号线、仿真配置、常用模块库

在MATLAB飞控仿真中,Simulink是连接控制算法与动力学模型的桥梁。它采用基于模型的设计(MBD)理念,将复杂的飞控系统拆解为可视化的模块化框图。本章将围绕Simulink的核心操作展开,从模型搭建的基础操作、子系统封装、信号线管理、仿真配置到常用模块库的深度解析,帮助您建立一套高效的飞控仿真工作流。我们将以四旋翼的姿态控制回路为贯穿案例,让每一个知识点都落地到实际工程场景中。

Simulink飞控仿真核心链路 信号源 阶跃/正弦/遥控器PWM 控制器子系统 PID/姿态解算 (子系统封装) 执行器模型 电机+电调响应 飞行动力学 六自由度刚体模型 (含重力/气动) 传感器反馈(IMU/姿态角) Scope/To Workspace 数据可视化与导出 仿真配置要点 • 求解器: fixed-step / discrete • 步长: 0.001s (1kHz) • 停止时间: 10s • 代数环: 避免直接反馈 常用模块库 • Math Operations: Gain/Sum/Product • Continuous: Integrator/Transfer Fcn • Sinks: Scope/Out1/To Workspace • Sources: Step/Constant/Signal Gen 子系统封装 • Ctrl+G 创建子系统 • Mask Editor 参数化 • 输入/输出端口管理 • 原子子系统(Atomic)

3.1 模型搭建基础:从零构建第一个飞控仿真模型

核心原理

Simulink模型本质上是一个数据流图,信号沿着信号线从源模块流向目标模块。在飞控仿真中,我们通常采用前向通道+反馈回路的结构:参考输入(期望姿态)经过控制器计算,输出控制量驱动执行器模型,执行器带动飞行动力学模型产生响应,传感器模型将测量值反馈回控制器形成闭环。理解这一数据流是搭建模型的前提。

操作流程

  1. 新建模型:在MATLAB命令行输入 simulink 或点击工具栏"Simulink"按钮,选择"Blank Model"。
  2. 添加模块:使用库浏览器(Library Browser)拖拽模块到画布。飞控仿真最常用的库路径为:Simulink > Sources(信号源)、Simulink > Math Operations(数学运算)、Simulink > Continuous(连续系统)、Simulink > Sinks(输出显示)。
  3. 连接信号线:将鼠标移动到模块输出端口,光标变为十字形后按住左键拖拽至目标输入端口。信号线支持分支(右键拖动)和标注(双击信号线输入文本)。
  4. 设置参数:双击模块打开参数对话框。例如,Gain模块设置增益值,Step模块设置阶跃时间与初始值。
飞控仿真最小模型示例:搭建一个比例控制器驱动一阶惯性环节的模型。使用Step模块(阶跃输入)、Gain模块(比例增益Kp=2)、Transfer Fcn模块(传递函数1/(0.5s+1))、Scope模块(示波器显示)。连接顺序为:Step → Gain → Transfer Fcn → Scope。运行仿真(点击"Run"按钮),观察阶跃响应曲线。

案例拆解:四旋翼俯仰角速率环搭建

假设我们要验证一个角速率内环的比例控制器。已知飞行器俯仰角速率模型近似为一阶惯性环节,时间常数τ=0.2s,控制增益K=1.5。目标:设计Kp使得闭环带宽约为10rad/s。

模块参数设置作用
StepStep Time=0.1, Final Value=30(°/s)模拟遥控器阶跃指令
GainGain=Kp(待整定)比例控制器
Transfer FcnNumerator=[1.5], Denominator=[0.2 1]被控对象模型
ScopeNumber of input ports=2同时显示指令与响应

通过理论计算,闭环传递函数为Kp*K/(τs+1+Kp*K),当Kp=1.33时,闭环带宽约为10rad/s。在模型中设置Kp=1.33,运行仿真,观察响应曲线是否在0.3s内达到稳态且无超调。若超调过大,可适当减小Kp。

常见误区:初学者容易忽略信号线数据类型。默认情况下,Simulink使用double类型,但在飞控仿真中,如果后续要生成嵌入式代码,需要将信号转换为single或fixed-point类型。建议在模型搭建初期就明确数据类型,避免后期转换带来的精度问题。

3.2 子系统封装:模块化飞控代码的基石

核心原理

子系统(Subsystem)是将一组相关模块封装为一个独立单元,类似于编程中的函数。在飞控仿真中,我们将姿态控制器、位置控制器、电机混控器等分别封装为子系统,不仅使模型结构清晰,还便于参数化复用。子系统分为虚拟子系统(Virtual Subsystem,仅用于图形组织)和原子子系统(Atomic Subsystem,强制作为一个整体执行)。

操作流程

  1. 创建子系统:框选需要封装的模块,右键选择"Create Subsystem from Selection",或使用快捷键Ctrl+G。
  2. 添加输入输出端口:子系统自动生成In1和Out1端口,双击子系统进入内部,可添加多个In/Out模块并重命名。
  3. 封装(Mask):右键子系统选择"Mask > Create Mask",可以定义参数对话框。例如,将PID控制器的Kp、Ki、Kd作为可调参数暴露给用户。
  4. 设置子系统属性:在子系统参数中,勾选"Treat as atomic unit"可强制原子执行,避免仿真步长内的代数环问题。

案例拆解:PID控制器子系统封装

我们封装一个标准PID控制器,要求外部用户只需输入Kp、Ki、Kd三个参数,内部自动实现比例、积分、微分运算。

内部结构:
In1 → Sum1 → Out1
       ↑
Gain(Kp) → 并联路径
Gain(Ki) → Integrator → 并联路径
Gain(Kd) → Derivative → 并联路径
三个路径通过Sum2合并后输入Sum1

封装参数设置:在Mask Editor中定义三个编辑框(Prompt: Kp, Variable: Kp; 同理Ki、Kd)。内部Gain模块的Gain参数直接填写"Kp"、"Ki"、"Kd"即可实现参数关联。这样,在飞控总模型中,双击该子系统即可快速整定PID参数,无需进入内部修改。

经验提醒:在飞控仿真中,建议将传感器模型(IMU、GPS)也封装为独立子系统,并添加噪声参数。这样在后续进行滤波器设计时,可以方便地切换不同噪声特性的传感器模型,而无需改动主模型结构。

3.3 信号线管理:数据流与总线操作

核心原理

信号线是Simulink模型的"血管"。在飞控仿真中,信号线不仅传递标量,还传递向量、矩阵和总线(Bus)数据。例如,姿态控制器输出的是四元数(4维向量),电机混控器输出的是4个PWM占空比(4维向量)。合理使用信号线管理工具,可以避免模型连线混乱,提高可读性。

判断方法与操作流程

  • 信号线标注:双击信号线输入文本,如"q_ref"表示期望四元数。标注后,在模型调试时可通过"Signal Logging"查看该信号。
  • Goto/From标签:当信号线跨越较远距离时,使用Goto模块(信号发送端)和From模块(信号接收端)代替直接连线。例如,将IMU输出的加速度信号通过Goto标签"accel_raw"发送,在导航子系统中使用From模块接收。
  • 总线创建:使用Bus Creator将多个信号打包为总线,使用Bus Selector解包。在飞控中,常将"姿态角+角速度"打包为"attitude_bus"。
  • 信号线颜色与线型:默认黑色实线表示double类型,蓝色表示复数,红色表示定点数。在模型配置中可开启"Signal Dimensions"显示信号维度。
工具适用场景飞控应用示例
Goto/From跨层级信号传递将GPS位置信号从传感器子系统传递到导航子系统
Bus Creator/Selector多信号聚合/解聚将电机转速、电流、温度打包为"motor_status"总线
Data Store Memory全局变量共享存储飞行模式标志位(手动/定高/定点)
Signal Conversion数据类型转换将double转换为single以减小内存
风险提示:在飞控仿真中,避免使用Data Store Memory存储频繁更新的信号(如姿态角),因为这会破坏Simulink的数据流执行顺序,可能导致仿真结果与真实系统不一致。推荐使用Goto/From或总线方式显式传递信号。

3.4 仿真配置:求解器选择与步长控制

核心原理

仿真配置决定了模型如何随时间推进。飞控系统是典型的连续-离散混合系统:飞行动力学是连续系统,而控制器和传感器采样是离散系统。选择错误的求解器会导致仿真速度慢、精度低甚至发散。

关键配置项

  1. 求解器类型:飞控仿真推荐使用固定步长(Fixed-step)求解器,因为后续代码生成需要固定步长。常用选项:ode4(四阶龙格-库塔,精度高)、ode3(三阶,速度快)、discrete(无连续状态,纯离散系统)。
  2. 步长设置:固定步长通常设置为控制器采样时间的1/10~1/5。例如,控制器运行在500Hz(2ms),仿真步长设为0.0002s(5kHz)以保证动力学仿真精度。
  3. 停止时间:根据飞行场景设置,如悬停仿真10s,航线飞行60s。
  4. 代数环处理:当信号存在直接反馈且无延迟时会产生代数环。在飞控中,若控制器输出直接作用于动力学模型,而动力学模型输出又直接反馈给控制器,且没有采样保持,就会产生代数环。解决方法:在反馈路径中插入Memory模块或Unit Delay模块。
配置示例:对于四旋翼悬停仿真,建议配置如下:Solver=Fixed-step, ode4, Fixed-step size=0.001, Stop time=10。若模型包含PWM生成模块(离散),则需将求解器设为discrete,并设置采样时间。

案例拆解:仿真步长对结果的影响

我们对比不同步长下,同一PID控制器的阶跃响应差异。模型为:Step → PID → 电机模型(1/(0.1s+1)) → 刚体动力学(1/s^2) → Scope。

步长(s)仿真时间(10s)超调量(%)稳态误差结论
0.010.8s12.5%0.02步长过大,动力学失真
0.0016.2s8.3%0.001推荐步长,精度与速度平衡
0.000158s8.2%0.001精度无提升,耗时增加

从结果可见,步长从0.01减小到0.001时,超调量显著降低,但继续减小步长对精度提升有限。因此,在飞控仿真中,步长选择应基于系统最小时间常数。对于时间常数为0.1s的电机模型,步长0.001s(为其1/100)已足够。

3.5 常用模块库深度解析

核心原理

Simulink模块库按功能分类,飞控仿真最常用的模块库包括:Sources(信号源)、Sinks(输出)、Continuous(连续系统)、Math Operations(数学运算)、Discrete(离散系统)、Logic and Bit Operations(逻辑运算)。掌握这些模块的典型用法,可以覆盖90%以上的飞控建模需求。

模块库对比与选择

库名称常用模块飞控应用场景注意事项
SourcesStep, Constant, Signal Generator, From Workspace模拟遥控器指令、传感器噪声注入From Workspace需定义时间序列变量
SinksScope, To Workspace, Out1, Display波形观察、数据导出、子系统输出To Workspace变量名需唯一
ContinuousIntegrator, Derivative, Transfer Fcn, State-Space飞行动力学建模、滤波器设计Derivative模块对噪声敏感,建议用近似微分
Math OperationsGain, Sum, Product, Dot Product, SaturationPID计算、坐标变换、限幅Saturation用于输出限幅,防止积分饱和
DiscreteUnit Delay, Discrete-Time Integrator, Zero-Order Hold数字控制器实现、采样保持采样时间需与控制器频率一致
Logic and BitRelational Operator, Logical Operator, Switch飞行模式切换、故障检测Switch模块需设置判断条件

实战场景:构建完整的姿态控制模型

我们综合运用上述模块库,构建一个完整的四旋翼姿态控制模型(仅俯仰通道)。模型结构如下:

1. 信号源:Step模块(期望俯仰角10°)
2. 控制器:Gain(Kp=2.5) + Gain(Ki=0.8) + Integrator + Sum → PID输出
3. 限幅:Saturation(±30°) → 防止执行器饱和
4. 执行器:Transfer Fcn(1/(0.05s+1)) → 电机响应
5. 动力学:Transfer Fcn(1/(0.8s^2+0.4s)) → 俯仰角响应
6. 反馈:Gain(1) → 直接反馈至Sum模块
7. 输出:Scope + To Workspace("theta_out")

运行仿真后,通过Scope观察响应曲线。若出现持续振荡,可适当减小Kp或增加微分项。通过To Workspace导出的数据,可在MATLAB中进一步分析超调量、调节时间等性能指标。

效率提升技巧:在飞控仿真中,建议将常用的模块组合保存为自定义库。例如,将"电机模型+电调模型"封装为自定义库模块,后续在多个仿真项目中直接拖拽使用,避免重复搭建。

3.6 常见误区与总结复盘

误区一:忽略仿真步长与采样时间的匹配

很多初学者在搭建飞控模型时,将控制器采样时间设为0.01s,但仿真步长设为0.001s,导致控制器在每个仿真步长内都执行一次,相当于控制器频率被错误地提高到了1000Hz。正确做法是:在控制器模块中显式设置采样时间(如0.002s),并确保仿真步长能整除该采样时间。

误区二:滥用Derivative模块

Derivative模块在仿真中会放大噪声,且可能导致代数环。在飞控中,微分项通常通过离散差分实现,或使用带低通滤波的近似微分。推荐使用 Transfer Fcn 模块实现:s/(τs+1),其中τ为滤波时间常数。

误区三:子系统封装后参数无法修改

如果封装子系统时未正确设置Mask参数,外部用户将无法修改内部参数。务必在Mask Editor中定义参数变量,并在内部模块中引用这些变量名。

总结复盘