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的值改善系统的动态性能,抑制响应过程中出现的振荡偏差,系统的抗干扰性能增强。

相关推荐
JSU_曾是此间年少4 分钟前
数据结构——线性表与链表
数据结构·c++·算法
此生只爱蛋1 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
momo_aa1 小时前
mac找到主目录下的文件夹
经验分享
咕咕吖1 小时前
对称二叉树(力扣101)
算法·leetcode·职场和发展
九圣残炎2 小时前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
lulu_gh_yu2 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
丫头,冲鸭!!!2 小时前
B树(B-Tree)和B+树(B+ Tree)
笔记·算法
Re.不晚3 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
远望清一色3 小时前
基于MATLAB的实现垃圾分类Matlab源码
开发语言·matlab
为什么这亚子3 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算