To simulate the dead-time in the FOPDT model using the GEKKO package, I used the Gekko 'cspline' function to make the time-shifting operation smoother.
It works well when the input changes after the length of dead-time. (eg. The input changes at t=15 when dead-time=10)
However, when the input changes before the length of dead-time (eg. The input changes at t=5 when dead-time=10), it looks like the cspline function overly extrapolates the input value. Please give some suggestions to avoid this problem.
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()