Переменные границы в МП C с GEKKO - PullRequest
3 голосов
/ 19 марта 2020

Я пытаюсь реализовать управление термостатом, используя MP C и GEKKO.

Переменная состояния (температура) должна быть в пределах нижних и верхних предварительно заданных значений температуры, temp_low и temp_upper в приведенном ниже коде.

Обе границы варьируются в течение дня: одно значение в час.

Целевой функцией является стоимость go использования отопления. Цена также меняется в течение дня, TOU ниже. T_external - это внешняя температура в комнате, которая играет роль в дифференциальном уравнении.

Как реализовать это для оптимизации?

Это моя попытка:

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)

Когда я запускаю это, я получаю:

@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
    ?

1 Ответ

2 голосов
/ 19 марта 2020

Гекко нуждается в содержании в качестве выражения неравенства, где переменная T сравнивается с верхними TH или более низкими TL значениями. Если у вас есть b=1., это приведет к невозможному решению, потому что нагреватель недостаточно мощный, чтобы поддерживать температуру в верхнем и нижнем пределах. Я изменил значение на 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)

Потенциально лучшим решением является установка мягких ограничений путем переопределения пределов как ошибки. Вы можете минимизировать ошибку, чтобы оставаться в пределах . Даже если он не может выйти за пределы, оптимизатор сделает все возможное, чтобы минимизировать невозможность. Это также позволяет одновременно компенсировать несколько целей , например, между комфортом и стоимостью.

Stay within temperature bounds

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