控制系统建模仿真(六):非线性控制系统的建模与仿真

前言

在《控制系统计算机辅助设计》书中,第六章 是 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); % 转化为第五章学过的状态空间对象

这是针对非线性特性的手把手详细教程

1. 常见非线性模块详解 (Library: Discontinuities)

需要熟练掌握以下四个"拦路虎"模块:

模块名称 图标特征 功能讲解与用处
Saturation (饱和) 阶梯状折线 功能 :限制信号上下限。用处:模拟电机驱动电压限制(如 ±12V)。
Dead Zone (死区) 中间平坦的线 功能 :输入在范围内输出为0。用处:模拟控制阀的摩擦力或不敏感区。
Relay (继电器) 开关符号 功能 :具有滞环(Hysteresis)的开关。用处:模拟恒温器(开启和关闭温度不同)。
Backlash (间隙) 平行四边形 功能 :输入反向时输出不立即反应。用处:模拟机械齿轮的啮合间隙。

2. 详细建模步骤:搭建一个"带限幅的伺服系统"

目标:模拟一个二阶系统,其控制器输出不能超过 ±0.5。

  1. 打开 Simulink :在命令行输入 simulink,点击 "Blank Model"。

  2. 放置受控对象

    • 在库浏览器搜索 Transfer Fcn,拖入画布。
    • 双击它,设置 Numerator[10]Denominator[1 2 10]

  3. 加入限幅器

    • 在库中找到 Saturation 模块,放在传递函数前面。
      * 双击设置:Upper limit: 0.5, Lower limit: -0.5。(默认设置)
  4. 建立反馈环

    • 拖入 Sum(求和)模块,双击将符号改为 |+-

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

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

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

  5. 配置解算器 (Solver)

    • Ctrl+E 打开设置。
    • Stop time 设为 10
    • TypeVariable-stepSolverode45(这是最通用的)。
  6. 运行 :点击顶部的绿色 Run 按钮。双击 Scope 观察:你会发现波形在达到 0.5 左右时变平缓了,这就是饱和特性。


3. S-Function 编写教程:用代码定义模块

当 Simulink 自带模块不够用时(比如你要写一个复杂的数学逻辑),就需要用到 S-Function

操作步骤:

  1. 在画布中拖入 MATLAB S-Function 模块。
  2. 在命令行输入 edit sfuntmpl(这是 MATLAB 提供的标准模板)。
  3. 核心填空
    • mdlInitializeSizes 里定义:sizes.NumContStates = 2; (假设系统是2阶)。
    • mdlDerivatives 里写微分方程:sys = A*x + B*u;
    • mdlOutputs 里写输出:sys = C*x;
  4. 保存为 my_logic.m,在模块属性里填入这个文件名。

第三部分:本章阶段性综合练习 (Milestone 2)

综合题目:非线性系统的稳定性对比

要求

  1. 在 Simulink 中建立两个相同的二阶系统 G(s)=100s2+10s+100G(s) = \frac{100}{s^2+10s+100}G(s)=s2+10s+100100。
  2. 系统 A:纯线性闭环。
  3. 系统 B:在反馈回路上增加一个 Dead Zone (死区) 模块,范围设为 [-0.2, 0.2]
  4. 编写一个 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('死区非线性对系统响应的影响');

第六章 学习要点总结:

  1. Simulink 并不是只能点鼠标 :学会用 sim()set_param() 操纵它,你才能做自动化的设计(如参数扫描)。
  2. 理解解算器 :如果波形出现奇怪的锯齿,记得去配置里调小 Max step size
  3. 非线性是本质 :学会用 SaturationDead Zone 模拟真实的电机和阀门。
相关推荐
gihigo19982 小时前
MATLAB中点扩散函数(PSF)的实现方案
开发语言·matlab
Gofarlic_OMS2 小时前
Fluent许可证使用合规性报告自动化生成系统
java·大数据·运维·人工智能·算法·matlab·自动化
TTGGGFF2 小时前
控制系统建模仿真(七):控制系统的经典设计方法
matlab·simulink
yong99902 小时前
基于MATLAB的激光器锁模技术仿真
开发语言·matlab
bubiyoushang88812 小时前
基于CLEAN算法的杂波抑制Matlab仿真实现
数据结构·算法·matlab
Evand J13 小时前
【MATLAB例程】雷达测距+测角的二维定位,基于CV运动的EKF和RTS平滑。滤波与平滑后的结果对比、误差分析。附例程
matlab·ekf·扩展卡尔曼滤波·rts平滑
guygg8815 小时前
5G PDSCH信道吞吐量MATLAB仿真实现(含信道生成与解调)
开发语言·5g·matlab
yugi98783816 小时前
基于字典缩放的属性散射中心参数提取MATLAB仿真程序
开发语言·matlab
机器学习之心20 小时前
MATLAB基于近红外光谱检测的菠萝含水率预测(多种预处理+PLS)
人工智能·算法·matlab·近红外光谱检测