GEKKO: avoid the implication of the first MV Value in prediction

207 views Asked by At

I am using GEKKO in MPC mode (Solver APOPT). I am defining my manipulated variable as follows:

u = m.MV(lb=0, ub=1, integer=True)
u.STATUS = 1 

I am intentionally not using:

u = m.MV(value=1 ,lb=0, ub=1, integer=True)
u.STATUS = 1 

Or:

u = m.MV(value=0 ,lb=0, ub=1, integer=True)
u.STATUS = 1 

because I don't know what the next decision is and I want my optimizer to define it. Apparently when you don't define the value of u, GEKKO gives it a default value of 0.

The problem is that this value of u is used in my model predictions and also in other calculations which is not desirable (see figure). As you can see, the new value of u is one meaning the fridge in on in my case. But, the temperature prediction starts with a default value of u which is 0. Therefore, the temperature in the fridge rises for the next time step and only starts to fall in the next time step. I have the possibility to define value as the previous result of u but also this would not be 100% right.

How can I avoid this? Are there any other options so that my prediction starts right?

I appreciate the help :)

refrigerator temperature control

1

There are 1 answers

3
John Hedengren On BEST ANSWER

There is an option to calculate the initial condition for any parameter or variable including an MV:

m.free_initial(u)

Here is a simple application that shows the difference that this function makes on the solution.

With free_initial(mv)

Free initial condition

import numpy as np
from gekko import GEKKO
m = GEKKO(remote=False)
m.time = np.linspace(0,10,11)
mv = m.MV(value=0,lb=0,ub=1,integer=True);    mv.STATUS=1
cv = m.CV(value=1); cv.SPHI=0.6; cv.SPLO=0.4; cv.STATUS=1
m.Equation(3*cv.dt()+(cv-1)==-0.8*mv)
m.free_initial(mv)
m.options.IMODE=6; m.options.CV_TYPE=1
m.options.NODES=3; m.options.MV_TYPE=0
m.options.SOLVER =1
m.solve(disp=False)

import matplotlib.pyplot as plt
plt.step(m.time,mv,'r.',markersize=5,where='post',label='MV')
plt.plot(m.time,cv,'b:',label='CV')
plt.plot([0,10],[0.6,0.6],'k:',label='SP Range')
plt.plot([0,10],[0.4,0.4],'k:')
plt.legend(); plt.xlabel('Time')
plt.show()

Without free_initial(mv)

With fixed initial condition