Python 用于FOPDT模型(死区时间)仿真的Gekko-cspline函数

Python 用于FOPDT模型(死区时间)仿真的Gekko-cspline函数,python,process,gekko,timedelay,cubic-spline,Python,Process,Gekko,Timedelay,Cubic Spline,为了使用GEKKO软件包模拟FOPDT模型中的死区时间,我使用了GEKKO“cspline”函数使时间转移操作更加平滑。 当输入在死区时间长度之后发生变化时,它工作得很好。(例如,当死区时间=10时,输入在t=15时变化) 然而,当输入在死区时间长度之前发生变化时(例如,死区时间=10时,输入在t=5时发生变化),cspline函数似乎过度外推了输入值。请给出一些避免此问题的建议。 cspline对象的数据范围为t=0到t=50,但它访问t=-10到t=40的值。误差是由三次样条曲线的外推造

为了使用GEKKO软件包模拟FOPDT模型中的死区时间,我使用了GEKKO“cspline”函数使时间转移操作更加平滑。
当输入在死区时间长度之后发生变化时,它工作得很好。(例如,当死区时间=10时,输入在t=15时变化)

然而,当输入在死区时间长度之前发生变化时(例如,死区时间=10时,输入在t=5时发生变化),cspline函数似乎过度外推了输入值。请给出一些避免此问题的建议。


cspline对象的数据范围为
t=0
t=50
,但它访问
t=-10
t=40
的值。误差是由三次样条曲线的外推造成的。您可以在
t=-theta_ub
t=50
的范围内生成样条曲线数据,以避免外推问题

从gekko导入gekko
将numpy作为np导入
作为pd进口熊猫
将matplotlib.pyplot作为plt导入
θub=30
tf=50
m=GEKKO(远程=True)
m、 时间=np.linspace(0,tf,tf+1)
时间=m.Param(m.time)
K1=m.FV(1,lb=0,ub=1)
tau1=m.FV(5,lb=1,ub=300)
θ1=m.FV(10,lb=2,ub=θu-ub)

u_step=[0如果死区时间是静态的,那么我建议使用离散状态空间形式。这在Gekko中实现为
m.delay()
。以下是更多详细信息:和
from gekko import GEKKO
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

tf = 50 
npt = 51 
t = np.linspace(0,tf,npt)
u1 = np.zeros(npt)
u1[5:] = 5

m = GEKKO(remote=True)
m.time = t 
time = m.Var(0)
m.Equation(time.dt()==1)

K1 = m.FV(1,lb=0,ub=1);      K1.STATUS=1
tau1 = m.FV(5, lb=1,ub=300);  tau1.STATUS=1
theta1 = m.FV(10, lb=2,ub=30); theta1.STATUS=1

uc1 = m.Var(u1) 
tc1 = m.Var(t) 
m.Equation(tc1==time-theta1)
m.cspline(tc1,uc1,t,u1,bound_x=False)

yp1 = m.Var()
m.Equation(yp1.dt() == -yp1/tau1 + K1*uc1/tau1) 

m.options.IMODE=4
m.solve()

print('K1: ', K1.value[0])
print('tau1: ',  tau1.value[0])
print('theta1: ', theta1.value[0])
print('')

plt.figure()
plt.subplot(2,1,1)
plt.plot(t,u1)
plt.legend([r'u1'])
plt.ylabel('Input')
plt.subplot(2,1,2)
plt.plot(t,yp1)
plt.legend([r'y1'])
plt.ylabel('Output')
plt.xlabel('Time')
plt.savefig('sysid.png')
plt.show()