前言
在《控制系统计算机辅助设计》书中,第六章 是 Simulink 的深度应用区。为了让大家彻底学会,我将这一章拆解为 MATLAB 编程篇 和 Simulink 实战教程篇。
如果说 MATLAB 是编写数学公式的"演草纸",那么 Simulink 就是搭建工业设备的"实验室"。在这一章,你将学会如何直接用"模块"和"导线"去模拟真实的物理系统。我们将重点解决:如何处理现实中常见的非线性环节 ,以及如何让 MATLAB 自动操纵 Simulink 进行大规模仿真。
第一部分:MATLAB 脚本操纵 Simulink (编程篇)
这部分函数是连接"文字编程"和"图形建模"的桥梁。
1. sim() ------ 脚本自动化仿真
-
功能:在 M 文件里直接启动 Simulink 模型并获取数据。
-
输入 :
model_name(模型名),options(仿真参数对象)。 -
返回值 :
SimOut对象(包含时间、状态、输出)。 -
代码示例 :
matlab% 1. 设置仿真配置 opt = simset('Solver','ode45','FixedStep',0.01); % 2. 运行模型 (假设模型文件名为 MyModel.slx) simOut = sim('MyModel', [0 10], opt); % 3. 提取数据 t = simOut.get('tout'); y = simOut.get('yout'); plot(t, y); title('从脚本调用的仿真结果');
2. set_param() ------ 动态修改模块参数
-
功能:在仿真运行前或循环中,用代码修改某个模块的数值。
-
用法 :
set_param('模型名/模块名', '属性名', '新值') -
代码示例 :
matlab% 将模型中名为 'Gain1' 的增益模块的值改为 15 set_param('MyModel/Gain1', 'Gain', '15');
3. linmod() ------ 模型线性化提取
-
功能 :将复杂的非线性 Simulink 框图转化为线性状态空间矩阵 A,B,C,DA, B, C, DA,B,C,D。
-
代码示例 :
matlab[A, B, C, D] = linmod('MyModel'); G = ss(A, B, C, D); % 转化为第五章学过的状态空间对象
第二部分:Simulink 建模实战教程 (图形篇)
这是针对非线性特性的手把手详细教程。
1. 常见非线性模块详解 (Library: Discontinuities)
需要熟练掌握以下四个"拦路虎"模块:
| 模块名称 | 图标特征 | 功能讲解与用处 |
|---|---|---|
| Saturation (饱和) | 阶梯状折线 | 功能 :限制信号上下限。用处:模拟电机驱动电压限制(如 ±12V)。 |
| Dead Zone (死区) | 中间平坦的线 | 功能 :输入在范围内输出为0。用处:模拟控制阀的摩擦力或不敏感区。 |
| Relay (继电器) | 开关符号 | 功能 :具有滞环(Hysteresis)的开关。用处:模拟恒温器(开启和关闭温度不同)。 |
| Backlash (间隙) | 平行四边形 | 功能 :输入反向时输出不立即反应。用处:模拟机械齿轮的啮合间隙。 |
2. 详细建模步骤:搭建一个"带限幅的伺服系统"
目标:模拟一个二阶系统,其控制器输出不能超过 ±0.5。
-
打开 Simulink :在命令行输入
simulink,点击 "Blank Model"。 -
放置受控对象:
- 在库浏览器搜索
Transfer Fcn,拖入画布。

- 双击它,设置
Numerator为[10],Denominator为[1 2 10]。


- 在库浏览器搜索
-
加入限幅器:
- 在库中找到
Saturation模块,放在传递函数前面。
* 双击设置:Upper limit: 0.5,Lower limit: -0.5。(默认设置)

- 在库中找到
-
建立反馈环:
-
拖入
Sum(求和)模块,双击将符号改为|+-。

-
拖入
Step(阶跃信号)作为输入。

-
拖入
Scope(示波器)接在最末端。

-
连线:Step -> Sum(+) -> Saturation -> Transfer Fcn -> Scope。再从 Transfer Fcn 输出连回 Sum(-)。
-

-
-
配置解算器 (Solver):
- 按
Ctrl+E打开设置。 Stop time设为10。Type选Variable-step,Solver选ode45(这是最通用的)。

- 按
-
运行 :点击顶部的绿色 Run 按钮。双击 Scope 观察:你会发现波形在达到 0.5 左右时变平缓了,这就是饱和特性。

3. S-Function 编写教程:用代码定义模块
当 Simulink 自带模块不够用时(比如你要写一个复杂的数学逻辑),就需要用到 S-Function。
操作步骤:
- 在画布中拖入
MATLAB S-Function模块。 - 在命令行输入
edit sfuntmpl(这是 MATLAB 提供的标准模板)。 - 核心填空 :
- 在
mdlInitializeSizes里定义:sizes.NumContStates = 2;(假设系统是2阶)。 - 在
mdlDerivatives里写微分方程:sys = A*x + B*u;。 - 在
mdlOutputs里写输出:sys = C*x;。
- 在
- 保存为
my_logic.m,在模块属性里填入这个文件名。
第三部分:本章阶段性综合练习 (Milestone 2)
综合题目:非线性系统的稳定性对比
要求:
- 在 Simulink 中建立两个相同的二阶系统 G(s)=100s2+10s+100G(s) = \frac{100}{s^2+10s+100}G(s)=s2+10s+100100。
- 系统 A:纯线性闭环。
- 系统 B:在反馈回路上增加一个
Dead Zone(死区) 模块,范围设为[-0.2, 0.2]。 - 编写一个 MATLAB 脚本,运行该仿真,并在一张图中对比两个 Scope 的输出数据。
参考 MATLAB 控制脚本:
matlab
% 假设模型名为 'Nonlinear_Comp',包含两个 Outport 模块:Out1(线性), Out2(非线性)
set_param('Nonlinear_Comp', 'StopTime', '5');
simOut = sim('Nonlinear_Comp');
t = simOut.get('tout');
y_lin = simOut.get('yout').getElement(1).Values.Data; % 获取线性路数据
y_non = simOut.get('yout').getElement(2).Values.Data; % 获取带死区路数据
figure;
plot(t, y_lin, 'b', t, y_non, 'r--');
grid on;
legend('线性系统', '带死区系统');
title('死区非线性对系统响应的影响');
第六章 学习要点总结:
- Simulink 并不是只能点鼠标 :学会用
sim()和set_param()操纵它,你才能做自动化的设计(如参数扫描)。 - 理解解算器 :如果波形出现奇怪的锯齿,记得去配置里调小
Max step size。 - 非线性是本质 :学会用
Saturation和Dead Zone模拟真实的电机和阀门。