Функция Gekko cspline для моделирования FOPDT (мертвое время)

Чтобы смоделировать мертвое время в модели FOPDT с помощью пакета GEKKO, я использовал функцию Gekko 'cspline', чтобы сделать операцию сдвига во времени более плавной.
Она хорошо работает, когда входные данные меняются после длительности мертвого времени. . (например, вход изменяется в t = 15, когда мертвое время = 10)
< img src = "https://i.stack.imgur.com/QuClX.png" alt = "введите описание изображения здесь" />

Однако, когда вход изменяется до длительности мертвого времени (например, вход изменяется при t = 5, когда мертвое время = 10), похоже, что функция cspline чрезмерно экстраполирует входное значение. Пожалуйста, дайте несколько советов, чтобы избежать этой проблемы.
 введите описание изображения здесь

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()

person Junho Park    schedule 11.12.2020    source источник
comment
Если мертвое время статично, я рекомендую вместо этого дискретную форму пространства состояний. Это реализовано как m.delay() в Gekko. Вот более подробная информация: apmonitor.com/wiki/index.php/Apps/TimeDelay и apmonitor.com/wiki/index.php/Apps/DiscreteStateSpace   -  person John Hedengren    schedule 12.12.2020


Ответы (1)


Объекту cspline предоставляются данные для диапазона от t=0 до t=50, но он получает доступ к значениям от t=-10 до t=40. Ошибка связана с экстраполяцией кубического сплайна. Вы можете сгенерировать данные сплайна в диапазоне от t=-theta_ub до t=50, чтобы избежать проблем с экстраполяцией.

Экстраполяция Cspline

from gekko import GEKKO
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

theta_ub = 30
tf = 50

m = GEKKO(remote=True)
m.time = np.linspace(0,tf,tf+1)
time = m.Param(m.time)

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

u_step = [0 if ti<=5 else 5 for ti in m.time]
uc1 = m.Var() 
tc1 = m.Var()
m.Equation(tc1==time-theta1)

# for cspline
t1 = np.linspace(-theta_ub,tf,500)
u1 = [0 if ti<=5 else 5 for ti in t1]
m.cspline(tc1,uc1,t1,u1,bound_x=False)

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

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(t1,u1,label='Unshifted Input')
plt.plot(m.time,uc1,label='Shifted Spline')
plt.xlim([0,tf])
plt.legend()
plt.ylabel('Input')
plt.subplot(2,1,2)
plt.plot(m.time,yp1)
plt.legend([r'y1'])
plt.ylabel('Output')
plt.xlabel('Time')
plt.savefig('sysid.png')
plt.show()
person John Hedengren    schedule 11.12.2020