Я пытаюсь построить модель MPC с предварительно оцененными значениями k, tau и theta в уравнении FOPDT. Я реализовал это предложение для оценки мертвого времени с помощью cspline: Как оценить значение тета в уравнении FOPDT с помощью gekko?.
Однако я не могу сделать то же самое с MPC, потому что я не могу использовать MV в качестве второго аргумента cspline для применения мертвого времени. Если вместо этого я использую переменную gekko для этого второго аргумента, MV не меняются, потому что они не присутствуют в уравнении. У меня есть две MV, одна CV и две возмущающие переменные. Как в этом случае применить мертвое время? Спасибо
import numpy as np
import time
import plotly.express as px
from gekko import GEKKO
import json
from datetime import datetime
start_time_count = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print("start_time: ", start_time_count)
dist1 = d19jcSliceMPC['Cond_PID_SP'].values
mv1 = d19jcSliceMPC['Front_PID_PV'].values
mv2 = d19jcSliceMPC['Rear_PID_PV'].values
dist2 = d19jcSliceMPC['Pull_rolling'].values
cv1 = d19jcSliceMPC['Cond_Center_Btm_TC'].values
run_time = 3.0 * 60.0
n = int(0.2*run_time)
Tsp1 = 1163.0 #setpoint
m = GEKKO(name='MPCbtmTC',remote=False)
m.time = np.linspace(0,n-1,n)
time_uc = m.Param(m.time)
# MV
Front = m.MV(value=mv1)
Front_ss = m.Param(value=mv1[0])
KpFront = m.Param(value=1.685312)
tauFront = m.Param(value=5.770839)
thetaFront = m.Param(value=0.114705)
t1 = np.linspace(-1,n-1,n)
ucFront = m.Var(); tm1 = m.Var(); m.Equation(tm1==time_uc-thetaFront)
m.cspline(tm1,ucFront,t1,np.array(Front),bound_x=False)
Rear = m.MV(value=mv2)
Rear_ss = m.Param(value=mv2[0])
KpRear = m.Param(value=0.1)
tauRear = m.Param(value=36.0)
thetaRear = m.Param(value=3.779397)
t2 = np.linspace(-4,n-1,n)
ucRear = m.Var(); tm2 = m.Var(); m.Equation(tm2==time_uc-thetaRear)
m.cspline(tm2,ucRear,t2,np.array(Rear),bound_x=False)
Front.STATUS = 1 # use to control temperature
Front.FSTATUS = 0 # no feedback measurement
Front.LOWER = 1160.0
Front.UPPER = 1200.0
Front.DMAX = 2.0
Front.COST = 0.0
Front.DCOST = 1.0e-4
Rear.STATUS = 1 # use to control temperature
Rear.FSTATUS = 0 # no feedback measurement
Rear.LOWER = 1180.0
Rear.UPPER = 1220.0
Rear.DMAX = 2.0
Rear.COST = 0.0
Rear.DCOST = 1.0e-4
# Parameters (disturbance)
CondSP = m.Param(value=dist1)
CondSP_ss = m.Param(value=dist1[0])
KpCondSP = m.Param(value=4.990293)
tauCondSP = m.Param(value=29.272660)
thetaCondSP = m.Param(value=2.554230)
t3 = np.linspace(-3,n-1,n)
ucCondSP = m.Var(); tm3 = m.Var(); m.Equation(tm3==time_uc-thetaCondSP)
m.cspline(tm3,ucCondSP,t3,dist1,bound_x=False)
Pull = m.Param(value=dist2)
Pull_ss = m.Param(value=dist2[0])
KpPull = m.Param(value=0.151304)
tauPull = m.Param(value=4.128567)
thetaPull = m.Param(value=0.0)
t4 = np.linspace(-0,n-1,n)
ucPull = m.Var(); tm4 = m.Var(); m.Equation(tm4==time_uc-thetaPull)
m.cspline(tm4,ucPull,t4,dist2,bound_x=False)
# Controlled variable
TC1_ss = m.Param(value=cv1[0])
TC1 = m.CV(value=TC1_ss.value)
TC1.STATUS = 1 # minimize error with setpoint range
TC1.FSTATUS = 1 # receive measurement
TC1.TR_INIT = 2 # reference trajectory
TC1.TAU = 2 # time constant for response
# Equation
m.Equation(TC1.dt()==(KpFront*(ucFront-Front_ss)-(TC1-TC1_ss))/tauFront + (KpRear*(ucRear-Rear_ss)-(TC1-TC1_ss))/tauRear+
(KpCondSP*(ucCondSP-CondSP_ss)-(TC1-TC1_ss))/tauCondSP + (KpPull*(ucPull-Pull_ss)-(TC1-TC1_ss))/tauPull)
# Global Options
m.options.IMODE = 6 # MPC
m.options.CV_TYPE = 1 # Objective type
m.options.NODES = 3 # Collocation nodes
m.options.SOLVER = 1 # 1=APOPT, 3=IPOPT
TC1.MEAS = cv1[0]
# input setpoint with deadband +/- DT
DT = 0.1
TC1.SPHI = Tsp1 + DT
TC1.SPLO = Tsp1 - DT
# solve MPC
m.solve(disp=False)
# get additional solution information
with open(m.path+'//results.json') as f:
results = json.load(f)
finish_time_count = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print("end_time: ", finish_time_count)
df_plot = pd.DataFrame({'DateTime' : d19jcSliceMPC.time,
'CV (TC1)' : results['v9.bcv'],
'SPHI' : results['v9.sp_hi'],
'SPLO' : results['v9.sp_lo'],
'Front' : Front,
'Rear' : Rear})
figGekko = px.line(df_plot,
x='DateTime',
y=['CV (TC1)','SPHI','SPLO','Front','Rear'],
labels={"value": "Degrees Celsius"},
title = "MPC")
figGekko.update_layout(legend_title_text='')
figGekko.show()
Изменить:
Как и было предложено, я изменил на
ucFront = m.Var(); m.Equation(ucFront==Front)
tm1 = m.Var(); m.Equation(tm1==time_uc-thetaFront)
m.cspline(tm1,ucFront,t1,np.array(Front),bound_x=False)
но я получаю эту ошибку:
Error: Exception: Access Violation
At line 359 of file ./f90/cqp.f90
Traceback: not available, compile with -ftrace=frame or -ftrace=full
Error: 'results.json' not found. Check above for additional error details
Если я оставлю только MV в качестве несмещенного ввода, я получу ту же ошибку, что и раньше
TypeError: y_data must be a python list or numpy array