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

前言

在《控制系统计算机辅助设计》书中,第六章 是 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 模拟真实的电机和阀门。
相关推荐
机器学习之心HML2 小时前
MATLAB豆渣发酵工艺优化 - 基于响应面法结合遗传算法
matlab
aini_lovee20 小时前
MATLAB基于小波技术的图像融合实现
开发语言·人工智能·matlab
3GPP仿真实验室21 小时前
【Matlab源码】6G候选波形:OFDM-IM 增强仿真平台 DM、CI
开发语言·matlab·ci/cd
rit84324991 天前
MATLAB中Teager能量算子提取与解调信号的实现
开发语言·matlab
我找到地球的支点啦1 天前
通信扩展——扩频技术(超级详细,附带Matlab代码)
开发语言·matlab
Dev7z2 天前
基于 MATLAB 的铣削切削力建模与仿真
开发语言·matlab
fengfuyao9852 天前
基于MATLAB的表面织构油润滑轴承故障频率提取(改进VMD算法)
人工智能·算法·matlab
机器学习之心2 天前
基于随机森林模型的轴承剩余寿命预测MATLAB实现!
算法·随机森林·matlab
rit84324992 天前
基于MATLAB的环境障碍模型构建与蚁群算法路径规划实现
开发语言·算法·matlab
hoiii1872 天前
MATLAB SGM(半全局匹配)算法实现
前端·算法·matlab