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

相关推荐
君义_noip32 分钟前
信息学奥赛一本通 1607:【 例 2】任务安排 2 | 洛谷 P10979 任务安排 2
算法·动态规划·信息学奥赛·斜率优化
因兹菜1 小时前
[LeetCode]day4 977.有序数组的平方
数据结构·算法·leetcode
weixin_537590451 小时前
《C程序设计》第六章练习答案
c语言·c++·算法
泪不是Web妳而流1 小时前
【HTML入门】Sublime Text 4与 Phpstorm
网络·经验分享·编辑器·html·学习方法·sublime text·phpstorm
码农小苏241 小时前
K个不同子数组的数目--滑动窗口--字节--亚马逊
java·数据结构·算法
独自破碎E2 小时前
【4】阿里面试题整理
java·开发语言·算法·排序算法·动态规划
涛ing7 小时前
32. C 语言 安全函数( _s 尾缀)
linux·c语言·c++·vscode·算法·安全·vim
xrgs_shz8 小时前
MATLAB的数据类型和各类数据类型转化示例
开发语言·数据结构·matlab
独正己身8 小时前
代码随想录day4
数据结构·c++·算法
利刃大大11 小时前
【回溯+剪枝】找出所有子集的异或总和再求和 && 全排列Ⅱ
c++·算法·深度优先·剪枝