matlab+Simulink实现微分方程求解及子系统封装

1.内容

(一)、Lorenz模型的状态方程表示为:

初值为

要求:

1.建立脚本,采用四阶五级的(Runge-Kutta-Felhberg, RKF)方法,调用ode45()方法求解该方程;

2.在Simulink下完成下列要求:

(1) 在Simulink下为上述方程组建立仿真模型,保存在st1.mdl中;

(2)仿真时间tout初值为0,终值根据实际情况而定,在图形窗口中设置4个子窗口,将x 1 (t), x 2 (t), x 3 *(t)*和相三维图分别绘在其中:

(a) 给该图形窗口增加标题"Lorenz模型的状态方程仿真图形";

(b)给每个子窗口加坐标轴名称。

(3)将tout, x 1 (t), x 2 (t), x 3 *(t)*中的数据分别保存到变量t,x1,x2及x3中,将这四个变量保存到st1_data.mat数据文件中。

(二)、下面给出的微分代数方程表示为:

初始条件为x 10=0.8, x 20=x30=0.1

要求:

1.建立脚本,采用刚性方程求解算法ode15()函数求解该方程;

2.在Simulink下完成下列要求

(1)在Simulink下为上述一阶微分方程组建立仿真模型,保存在st1.mdl中;

(2)利用(1)中的仿真模型,在Simulink下调用ode15( )方法进行仿真求解x1(t), x2(t)和x3(t),仿真时间tout初值为0,终值为20,在图形窗口中设置2×2四个子窗口,将x1(t),x2(t),x3(t)和x(t)(包含x1(t), x2(t)和x3(t)三个变量),分别绘在四个子窗口中,并包括:

(a)给该图形窗口增加标题"微分代数方程仿真图形";(b)给每个子窗口加坐标轴名称。

(3) 将tout,x1(t),,x2(t)和x3(t)中的数据分别保存到变量t,y1,y2和y3中,将这四个变量保存到st1_data.mat数据文件中。

(三)、子系统封装及仿真

(1)将图1中的PID Controller模型图在Simulink下封装成子系统;其中:

图1 PID Controller模型图

(2)将(1)中的子系统用在图2所示的仿真模型(保存到st2.mdl)中,在Simulink下调用ode45( )方法进行仿真求解单位阶跃响应y(t)(包括y(t)响应曲线和tout在0-20秒内的y(t)的值)。

    

图2 PID控制系统仿真图

Kp=11.520,Ti=0.658,Td=0.164,Step为单位阶跃函数。如果仿真输出超调量过大,希望调整以上参数以获取更好的动态性能。

2. 过程

(一)、Lorenz模型

  1. 建立脚本,采用四阶五级的(Runge-Kutta-Felhberg, RKF)方法,调用ode45()方法求解该方程;

脚本:

复制代码
clear;

f=@(t,x)[-8*x(1)/3+x(2)*x(3);-10*x(2)+10*x(3);-x(1)*x(2)+28*x(2)-x(3)];

t=50;

x0=[0;0;1e-10];

[t,x]=ode45(f,[0,t],x0); 

x1=x(:,1);

x2=x(:,2);

x3=x(:,3);

plot3(x1,x2,x3);%绘制相三维图

xlabel('x1(t)'),ylabel('x2(t)'),zlabel('x3(t)');

title('Lorenz模型的状态方程仿真图形');

运行图形:

图3 Lorenz模型三维仿真图

  1. Simulink仿真

Lorenz仿真模型:

图4 Lorenz仿真模型

设置相关属性:

形式改为数组形式

图5 修改为数组形式

调用ode45( )方法进行仿真求解x1(t), x2(t)和x3(t),仿真时间tout初值为0,终值为50

图6 修改方法以及时间

设置初值为

图7 修改x1,x2,x3初始值

脚本实现绘图保存数据等功能:

复制代码
t=tout;

x1=yout(:,1);

x2=yout(:,2);

x3=yout(:,3);

subplot(2,2,1);%设置2*2四个子窗口

plot(t,x1);%绘制x1(t)曲线

xlabel('时间t'),ylabel('x1(t)');%设置坐标轴

subplot(2,2,2);

plot(t,x2);%绘制x2(t)曲线

xlabel('时间t'),ylabel('x2(t)');

subplot(2,2,3);

plot(t,x3);%绘制x3(t)曲线

xlabel('时间t'),ylabel('x3(t)');

subplot(2,2,4);

plot3(x1,x2,x3);%绘制相三维图

xlabel('x1(t)'),ylabel('x2(t)'),zlabel('x3(t)');

suptitle('Lorenz模型的状态方程仿真图形');

save st1_data t x1 x2 x3;%保存

仿真图形

图8 Lorenz模型仿真图形

比较脚本和仿真的运行图形可以发现它们是有区别的

在脚本和仿真模型都运行过后,查看工作区:

图9 工作区

可以发现,脚本中运行后时间和结果长度都是2597,而仿真中tout和yout长度都是530,这导致所绘制的图形有所不同,经过查阅得知可能与ode45为变步长算法有关,自动根据连续状态变化速度,来改变步长,但是具体原因还未弄清。但是可以验证它们的趋势一致,由此可见,ode45脚本解方程与仿真解方程两种方式都是没有问题的。

保存的数据文件st1_data.mat

图10 保存的st1_data.mat文件

(二)微分方程

  1. 建立脚本,采用刚性方程求解算法ode15()函数求解该方程;

脚本:

复制代码
clear;

f=@(t,x)[-0.2*x(1)+x(2)*x(3)+0.3*x(1)*x(2);2*x(1)*x(2)-5*x(2)*x(3)-2*x(2)*x(2);x(1)+x(2)+x(3)-1];

A=[1 0 0;0 1 0;0 0 0];

options=odeset;

options.Mass=A;

x0=[0.8;0.1;0.1];

[t,x]=ode15s(f,[0 20],x0,options); 

ph=plot(t,x);

xlabel('时间t'),ylabel('x(t)');

legend([ph(1),ph(2),ph(3)],'x1(t)','x2(t)','x3(t)');

suptitle('微分代数方程仿真图形');

仿真图形:

图11 微分代数方程仿真图形

  1. Simulink仿真

微分代数方程仿真模型:

图12 微分代数方程仿真模型

设置相关属性:

形式改为数组形式

图13 修改输出形式

调用ode15( )方法进行仿真求解x1(t), x2(t)和x3(t),仿真时间tout初值为0,终值为20

图14 修改调用方法以及时间

设置初值为

图15 修改初始值

脚本实现绘图保存数据等功能:

脚本:

复制代码
t=tout;

x1=yout(:,1);

x2=yout(:,2);

x3=yout(:,3);

subplot(2,2,1);%设置2*2四个子窗口

plot(t,x1);%绘制x1(t)曲线

xlabel('时间t'),ylabel('x1(t)');%设置坐标轴

subplot(2,2,2);

plot(t,x2);%绘制x2(t)曲线

xlabel('时间t'),ylabel('x2(t)');

subplot(2,2,3);

plot(t,x3);%绘制x3(t)曲线

xlabel('时间t'),ylabel('x3(t)');

subplot(2,2,4);

ph=plot(t,yout);%绘制x(t)曲线

xlabel('时间t'),ylabel('x(t)');

legend([ph(1),ph(2),ph(3)],'x1(t)','x2(t)','x3(t)');

suptitle('微分代数方程仿真图形');

y1=x1;y2=x2;y3=x3;

save st1_data t y1 y2 y3;%保存

仿真图形

图16 微分代数方程仿真图形

可以看出与ode15脚本所绘制图形一致,表明两种解代数方程的方法均有效实现

保存的数据文件st1_data.mat

图17 保存的文件

(三)、子系统封装及仿真

(1)将图1中的PID Controller模型图在Simulink下封装成子系统

图18 子系统封装内部结构

图19 封装后

(2)将(1)中的子系统用在图2所示的仿真模型(保存到st2.mdl)中,在Simulink下调用ode45( )方法进行仿真求解单位阶跃响应y(t)(包括y(t)响应曲线和tout在0-20秒内的y(t)的值)。

G(s)值设置:

图20 设置G(s)值

仿真模型:

图21 仿真模型

鼠标右击simulink子系统mask如下图所示

图22 创建mask

设置相关参数的值:

图23 修改参数初始值

设置起始到终止时间0-20,调用ode45

图24 修改方法以及时间

此时示波器中仿真图形:

图25 Kp=11.52,Ti=0.658,Td=0.164

将Kp值减小为8,所的仿真图形:

图26 Kp=8,Ti=0.658,Td=0.164

超调量减小

继续将Kp值减小为4,所的仿真图型如下:

图27 Kp=4,Ti=0.658,Td=0.164

可以看出此时超调量几乎没有了,且曲线变得更加平缓

而若将Kp值升高为15:

图28 Kp=15,Ti=0.658,Td=0.164

超调量将会增大,且曲线上升的趋势更加陡峭

保持Kp值为15不变,此时如果我们将Ti值增加到1:

图29 Kp=11.52,Ti=1,Td=0.164

超调量明显减小,系统响应趋于稳态值的速度加快

此时继续升高Ti至1.5:

图30 Kp=11.52,Ti=1.5,Td=0.164

曲线无超调,初期曲线陡峭,然后快速平缓趋于稳态

将Ti减小至0.5:

图31 Kp=11.52,Ti=0.5,Td=0.164

曲线振荡,稳定性降低

此时,再将Td值增加至1:

图32 Kp=11.52,Ti=0.658,Td=1

曲线振荡减弱

而若将Td减少至0.5:

图33 Kp=11.52,Ti=0.658,Td=0.5

振荡幅度增加

3. 结果分析

通过上述过程分析可以发现,随着Kp的增大系统的响应速度越快,系统的调节精度越高,但是系统易产生超调,系统的稳定性变差,甚至会导致系统不稳定。Kp取值过小,调节精度降低,响应速度变慢,调节时间加长,使系统的动静态性能变坏。Ti可以消除系统的稳态误差。Ti越大系统的稳态误差消除的越快,但Ti如果过大,在响应过程的初期会产生积分饱和现象。若Ti过小,系统的稳态误差将难以消除,影响系统的调节精度,系统可能会更加不稳定,此时可以增加Td的值改善系统的动态性能,抑制响应过程中出现的振荡偏差,系统的抗干扰性能增强。

相关推荐
江畔柳前堤14 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore15 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考16 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX17 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面18 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号18 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽18 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI18 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者20 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者20 小时前
【征程6】校准量化中HistogramObserver解析
算法