简体   繁体   English

带 GEKKO 的 MPC 中的变量边界

[英]Variable bounds in MPC with GEKKO

I'm trying to implement a thermostat control using MPC and GEKKO.我正在尝试使用 MPC 和 GEKKO 实现恒温器控制。

The state variable (temperature) should be within a lower and upper pre-specified temp values , temp_low and temp_upper in the code below.状态变量(温度)应该在下面代码中预先指定的下限和上限温度值temp_lowtemp_upper内。

Both bound vary along the day: one value per hour.两者的界限在一天中都不同:每小时一个值。

The objective function is the cost-to-go of using the heating.目标函数是使用加热的成本。 The price also changes along the day, TOU below.价格也随着一天而变化, TOU如下。 T_external is the room's exterior temperature that plays a role in the differential equation. T_external是在T_external的房间外部温度。

How can implement this so that it optimizes?如何实现它以使其优化?

This is my attempt:这是我的尝试:

from gekko import GEKKO
import numpy as np

m = GEKKO(remote=False)
m.time = np.linspace(0,23,24)

#initialize variables
T_external = [50.,50.,50.,50.,45.,45.,45.,60.,60.,63.,64.,45.,45.,50.,52.,53.,53.,54.,54.,53.,52.,51.,50.,45.]
temp_low = [55.,55.,55.,55.,55.,55.,55.,68.,68.,68.,68.,55.,55.,68.,68.,68.,68.,55.,55.,55.,55.,55.,55.,55.]
temp_upper = [75.,75.,75.,75.,75.,75.,75.,70.,70.,70.,70.,75.,75.,70.,70.,70.,70.,75.,75.,75.,75.,75.,75.,75.]
TOU = [0.05,0.05,0.05,0.05,0.05,0.05,0.05,200.,200.,200.,200.,200.,200.,200.,200.,200.,200.,200.,200.,200.,200.,0.05,0.05,0.05]

b = m.Param(value=1.)
k = m.Param(value=0.05)
T_e = m.Param(value=T_external)

u = m.MV(value=[0]*24, lb=[0.0]*24, ub=[1.]*24)
u.STATUS = 1  # allow optimizer to change

# Controlled Variable
T = m.SV(value=[60]*24, lb=temp_low, ub=temp_upper)

m.Equation(T.dt() == k*(T_e-T) + b*u)

m.Obj(np.dot(TOU,u))

m.options.IMODE = 6
m.solve(debug=True)

When I run this I get:当我运行这个时,我得到:

@error: Model Expression
 *** Error in syntax of function string: Missing operator

Position: 4                   
 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
    ?

Gekko needs the constaints as inequality expressions where the variable T is compared to the upper TH or lower TL values. Gekko 需要将约束作为不等式表达式,其中将变量T与上TH或下TL值进行比较。 If you have b=1.如果你有b=1. , it leads to an infeasible solution because the heater isn't powerful enough to maintain the temperature within the upper and lower limits. ,这导致了一个不可行的解决方案,因为加热器的功率不足以将温度保持在上限和下限内。 I changed the value to b=10 to get a feasible solution.我将值更改为b=10以获得可行的解决方案。

from gekko import GEKKO
import numpy as np

m = GEKKO(remote=False)
m.time = np.linspace(0,23,24)

#initialize variables
T_external = [50.,50.,50.,50.,45.,45.,45.,60.,60.,63.,\
              64.,45.,45.,50.,52.,53.,53.,54.,54.,\
              53.,52.,51.,50.,45.]
temp_low = [55.,55.,55.,55.,55.,55.,55.,68.,68.,68.,68.,\
            55.,55.,68.,68.,68.,68.,55.,55.,55.,55.,55.,55.,55.]
temp_upper = [75.,75.,75.,75.,75.,75.,75.,70.,70.,70.,70.,75.,\
              75.,70.,70.,70.,70.,75.,75.,75.,75.,75.,75.,75.]
TOU_v = [0.05,0.05,0.05,0.05,0.05,0.05,0.05,200.,200.,200.,200.,\
         200.,200.,200.,200.,200.,200.,200.,200.,200.,200.,0.05,\
         0.05,0.05]

b = m.Param(value=10.)
k = m.Param(value=0.05)
T_e = m.Param(value=T_external)
TL = m.Param(value=temp_low)
TH = m.Param(value=temp_upper)
TOU = m.Param(value=TOU_v)

u = m.MV(lb=0, ub=1)
u.STATUS = 1  # allow optimizer to change

# Controlled Variable
T = m.SV(value=60)

m.Equations([T>=TL,T<=TH])
m.Equation(T.dt() == k*(T_e-T) + b*u)

m.Minimize(TOU*u)

m.options.IMODE = 6
m.solve(disp=True,debug=True)

A potentially better solution is to set up soft constraints by redefining the limits as an error.一个可能更好的解决方案是通过将限制重新定义为错误来设置软约束。 You can minimize the error to stay within the limits .您可以将误差降至最低以保持在限制范围内 Even if it can't stay within the limits, the optimizer will do the best it can to minimize the infeasibility.即使不能保持在限制范围内,优化器也会尽其所能将不可行性降到最低。 This also allows you to trade-off multiple objectives simultaneously such as between comfort and cost.这也允许您同时权衡多个目标,例如在舒适度和成本之间。

保持在温度范围内

from gekko import GEKKO
import numpy as np

m = GEKKO(remote=False)
m.time = np.linspace(0,23,24)

#initialize variables
T_external = [50.,50.,50.,50.,45.,45.,45.,60.,60.,63.,\
              64.,45.,45.,50.,52.,53.,53.,54.,54.,\
              53.,52.,51.,50.,45.]
temp_low = [55.,55.,55.,55.,55.,55.,55.,68.,68.,68.,68.,\
            55.,55.,68.,68.,68.,68.,55.,55.,55.,55.,55.,55.,55.]
temp_upper = [75.,75.,75.,75.,75.,75.,75.,70.,70.,70.,70.,75.,\
              75.,70.,70.,70.,70.,75.,75.,75.,75.,75.,75.,75.]
TOU_v = [0.05,0.05,0.05,0.05,0.05,0.05,0.05,200.,200.,200.,200.,\
         200.,200.,200.,200.,200.,200.,200.,200.,200.,200.,0.05,\
         0.05,0.05]

b = m.Param(value=10.)
k = m.Param(value=0.05)
T_e = m.Param(value=T_external)
TL = m.Param(value=temp_low)
TH = m.Param(value=temp_upper)
TOU = m.Param(value=TOU_v)

u = m.MV(lb=0, ub=1)
u.STATUS = 1  # allow optimizer to change

# Controlled Variable
T = m.SV(value=60)

# Soft constraints
eH = m.CV(value=0)
eL = m.CV(value=0)

eH.SPHI=0; eH.WSPHI=100; eH.WSPLO=0  ; eH.STATUS = 1
eL.SPLO=0; eL.WSPHI=0  ; eL.WSPLO=100; eL.STATUS = 1

m.Equations([eH==T-TH,eL==T-TL])

m.Equation(T.dt() == k*(T_e-T) + b*u)

m.Minimize(TOU*u)

m.options.IMODE = 6
m.solve(disp=True,debug=True)

import matplotlib.pyplot as plt
plt.subplot(2,1,1)
plt.plot(m.time,temp_low,'k--')
plt.plot(m.time,temp_upper,'k--')
plt.plot(m.time,T.value,'r-')
plt.ylabel('Temperature')
plt.subplot(2,1,2)
plt.step(m.time,u.value,'b:')
plt.ylabel('Heater')
plt.xlabel('Time (hr)')
plt.show()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM