4、模型构建基础:模块的添加、连接、信号线操作、子系统创建与封装(Mask)入门
Simulink 的建模过程本质上是在图形化画布上构建一个数据流与状态机混合的运算网络。无论是简单的传递函数仿真,还是复杂的多域物理系统,其底层操作都离不开三个核心动作:放置模块、连接信号线、组织子系统。本章将围绕这三个基础动作展开,并深入讲解子系统封装(Mask)这一提升模型复用性与可读性的关键技能。我们将从模块库的检索逻辑出发,逐步过渡到信号线的数据流语义,最后通过一个完整的PID控制器封装案例,串联起本章全部知识点。
上图展示了从模块库到封装子系统的完整操作链路。在实际工程中,这四个环节并非严格串行,而是不断迭代优化的过程。例如,工程师可能先搭建一个未封装的子系统用于快速验证算法,待功能稳定后再进行 Mask 封装,以便在团队中共享。下面我们将逐一拆解每个环节的操作细节与底层逻辑。
4.1 模块的添加与参数配置
核心原理:Simulink 的模块库(Library Browser)本质是一个分层组织的函数与系统集合。每个模块都封装了特定的数学运算、逻辑判断或信号源功能。模块的添加不仅仅是拖拽一个图标,更重要的是理解其端口语义(输入/输出个数、数据类型、维度)和采样时间(连续/离散/继承)。
操作流程:
- 打开库浏览器:在 MATLAB 命令行输入
simulink或在 Simulink 起始页点击"库浏览器"图标。 - 检索模块:使用浏览器顶部的搜索框直接输入模块名(如 "Gain"、"PID Controller"),或按目录浏览:
Simulink > Continuous(连续系统)、Simulink > Math Operations(数学运算)、Simulink > Sinks(输出显示)。 - 添加模块:双击库中的模块,或直接拖拽到模型画布。推荐使用双击添加,因为模块会自动放置在画布中心附近,便于后续连线。
- 参数配置:双击画布上的模块实例,打开参数对话框。例如,增益模块(Gain)需要设置增益值(K),传递函数模块(Transfer Fcn)需要设置分子分母系数向量。
Ctrl+I 可翻转模块(左右镜像),Ctrl+R 可旋转90度,这在整理连线布局时非常高效。
| 模块类别 | 典型模块 | 关键参数 | 常见用途 |
|---|---|---|---|
| 信号源 | Sine Wave, Step, Constant | 幅值、频率、相位、阶跃时间 | 测试激励输入 |
| 连续系统 | Transfer Fcn, Integrator, PID Controller | 分子/分母系数、初值、PID增益 | 线性动态系统建模 |
| 数学运算 | Gain, Sum, Product, Math Function | 增益值、符号列表、函数类型 | 信号运算与标定 |
| 信号路由 | Mux, Demux, Goto, From, Bus Creator | 输入个数、信号名称 | 信号合并、拆分与跨层传递 |
| 输出显示 | Scope, Display, To Workspace | 坐标轴数量、变量名、采样间隔 | 结果可视化与数据导出 |
常见误区:初学者常混淆 Gain 模块与 Constant 模块。前者是乘法运算,输出等于输入乘以增益值;后者是常数信号源,输出始终为设定值。另一个误区是忽略模块的采样时间属性。在混合系统(连续+离散)中,若离散模块的采样时间与连续求解器不匹配,会导致仿真结果异常或报错。
4.2 信号线操作与数据流管理
核心原理:信号线(Signal Line)是 Simulink 模型中的"血管",它承载着数据流。与电路图中的物理导线不同,信号线传递的是数值矩阵,且具有方向性。信号线的颜色和线型能直观反映数据类型:黑色实线表示 double 类型,蓝色表示 int8/uint8 等整数类型,红色虚线表示数据类型错误或维度不匹配。
操作流程:
- 基本连接:将鼠标移至输出端口(>符号),光标变为十字形,按住左键拖拽至目标输入端口(>符号)后松开。若端口兼容,连线变为黑色实线。
- 信号分支:将信号线连接到多个模块时,在已有连线上按住
Ctrl键,然后从连线上拖出新线。分支线共享同一信号源,但可分别连接不同模块。 - 信号标签:双击任意一段信号线,输入名称(如
error_signal)。标签不仅用于注释,还可用于Goto/From模块的跨层引用。 - 删除与重连:选中连线按
Delete删除。若需改变连线路径,可按住Shift键拖动连线中间节点。
Data Type Conversion 模块进行类型转换,或使用 Selector 模块提取向量中的特定元素。切勿强行连接,否则仿真会立即报错。
案例拆解:假设我们需要将两个传感器信号(温度 T 和压力 P)合并为一个向量,并分别送入显示模块和计算模块。操作步骤如下:
- 添加两个
Constant模块(分别设为 25 和 101.3)作为模拟传感器值。 - 添加一个
Mux模块,双击设置输入个数为 2。 - 将两个 Constant 输出分别连接至 Mux 的两个输入端口。
- 从 Mux 输出端引出分支线:一条连接至
Scope用于观察,另一条连接至Gain模块(增益设为 0.1)进行压力换算。 - 在 Mux 输出线上双击,输入标签
sensor_data。
此案例展示了信号线分支、合并与标签的典型用法。通过标签 sensor_data,我们可以在模型的其他位置使用 From 模块引用该信号,而无需绘制跨越整个模型的连线。
4.3 子系统创建与封装(Mask)入门
核心原理:子系统(Subsystem)是将一组相关模块封装为一个独立模块的机制,用于降低模型复杂度、提高可读性。而封装(Mask)则是在子系统基础上,为其创建自定义的参数对话框、图标和文档,使其行为类似于一个独立的、可配置的模块。封装的核心价值在于参数化复用:同一个子系统,通过不同的 Mask 参数,可以表现出不同的行为。
创建子系统的两种方法:
- 自上而下:先添加一个
Subsystem模块(位于Simulink > Ports & Subsystems),然后双击进入其内部,自行添加输入输出端口(In1/Out1)和逻辑模块。 - 自下而上(推荐):在画布中选中多个模块(按住鼠标框选或 Ctrl+点击),右键选择
Create Subsystem from Selection。Simulink 会自动将选中模块的输入输出端口映射为子系统的 In1/Out1 端口。
Mask 封装操作流程:
- 选中已创建的子系统,右键选择
Mask > Create Mask。 - 在 Mask 编辑器中,切换到 Parameters 标签页,点击"Edit"添加参数。例如,添加一个名为
Kp的编辑框(Prompt 为 "比例增益"),类型选择edit。 - 切换到 Icon 标签页,在绘图命令中输入
disp('PID')或使用port_label函数标注端口名称。 - 切换到 Documentation 标签页,填写封装模块的描述文本,便于他人理解。
- 点击 OK 完成封装。此时双击该模块,将弹出自定义的参数对话框,而非直接进入子系统内部。
Kp(即 Mask 参数名)。这样,当用户在封装模块对话框中输入 Kp=2.5 时,子系统内部的增益模块会自动更新为 2.5。这是实现参数化复用的核心机制。
案例拆解:PID 控制器封装
假设我们需要一个可调参数的 PID 控制器,用于多个不同被控对象的仿真。若直接使用 Simulink 自带的 PID Controller 模块,虽然参数可调,但无法自定义图标和文档。我们通过封装实现一个"教学版 PID":
| 步骤 | 操作内容 | 关键参数/命令 |
|---|---|---|
| 1. 搭建内部结构 | 创建子系统,内部包含 Gain(P)、Gain(I)、Gain(D)、Sum、Integrator、Derivative 模块 | P 增益设为 Kp,I 增益设为 Ki,D 增益设为 Kd |
| 2. 创建 Mask | 右键子系统 → Mask > Create Mask | 添加三个编辑框参数:Kp, Ki, Kd |
| 3. 设置图标 | 在 Icon 页输入 disp('PID') 和 port_label('input',1,'e')、port_label('output',1,'u') | 显示 PID 文本及端口标签 |
| 4. 填写文档 | 在 Documentation 页输入描述:"教学用 PID 控制器,支持 P/I/D 参数独立调节" | — |
| 5. 测试封装 | 双击封装模块,输入 Kp=1.2, Ki=0.5, Kd=0.1,点击 OK | 观察子系统内部 Gain 模块数值是否更新 |
复盘与经验:封装过程中最常见的错误是参数名拼写不一致。例如,Mask 参数名为 Kp,但子系统内部 Gain 模块写成了 kp,这会导致参数无法传递。此外,封装后的模块在模型文件中只显示为一个图标,这大大减少了顶层模型的连线数量。但要注意,过度封装会隐藏内部细节,不利于团队协作调试。建议在模型开发初期保持子系统内部可见,待功能冻结后再进行封装。
edit 表示文本输入,popup 表示下拉选择),并在 Evaluate 选项中勾选"评估",确保输入值被正确解析为数值或表达式。