You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GEKKO MPC控制房间温度时输出偏离却无最优指令问题

房间温度MPC控制问题(GEKKO)

我尝试使用GEKKO实现模型预测控制(MPC),将房间温度维持在16-18℃的范围内,但运行代码后发现,即使室内温度偏离设定范围,控制变量β始终保持为0,没有输出任何调整指令。以下是我运行的代码及结果:

# 导入库
import numpy as np
import pandas as pd
import time
from gekko import GEKKO
from numpy import array

K = array([[  0.93705481, -12.24012156]])
p =  {'a': array([[ 1.08945247],
        [-0.00242145],
        [-0.00245978],
        [-0.00272713],
        [-0.00295845],
        [-0.00319119],
        [-0.00343511],
        [-0.00366243],
        [-0.00394247],
        [-0.06665054]]),
 'b': array([[[-0.05160235, -0.01039767],
         [ 0.00173511, -0.01552485],
         [ 0.00174602, -0.01179519],
         [ 0.00180031, -0.01052658],
         [ 0.00186416, -0.00822121],
         [ 0.00193947, -0.00570905],
         [ 0.00202877, -0.00344507],
         [ 0.00211395, -0.00146947],
         [ 0.00223514,  0.00021945],
         [ 0.03800987,  0.04243736]]]),
 'c': array([0.0265903])} 

# 外部温度数据(200个点)
T_externel = np.linspace(9.51,9.78,200)

m = GEKKO(remote=False)
m.y = m.Array(m.CV,1)
m.u = m.Array(m.MV,2)
m.arx(p,m.y,m.u)

# 重命名变量
m.T = m.y[0]          # 室内温度(被控变量)
m.beta = m.u[1]       # 控制变量(操作变量)
m.d = m.u[0]          # 外部温度(扰动变量)

# 设定扰动变量为参数
m.d = m.Param(T_externel[0])   

# 温度上下限
TL = m.Param(value = 16)
TH = m.Param(value = 18)
    
# 稳态初始化
m.options.IMODE = 1
m.solve(disp=False)

# MPC配置
m.d.value = T_externel
m.options.IMODE   = 6       # MPC模式
m.options.CV_TYPE = 2       # L2范数目标
m.options.NODES   = 2       # 配点节点数
m.options.SOLVER  = 1       # APOPT求解器
m.time = np.arange(0, len(T_externel)*300, 300)  # 时间步长300s

# 操作变量配置
m.beta.STATUS = 1    # 允许优化调整
m.beta.FSTATUS = 1   # 使用测量值
m.beta.DMAX = 1.0    # 每次调整的最大步长
m.beta.DCOST = 0.0   # 调整代价惩罚
m.beta.UPPER = 1.0   # 上限
m.beta.LOWER = 0.0   # 下限
m.beta.MEAS = 0      # 初始测量值

# 被控变量配置
m.T.STATUS = 1       # 跟踪设定点
m.T.FSTATUS = 1      # 使用测量值
m.T.SP = 17          # 设定点
m.T.value = 17       # 初始室内温度

TL.value = np.ones(len(T_externel))*16
TH.value = np.ones(len(T_externel))*18

# 循环求解
for i in range(len(T_externel)):
    m.solve(disp = False)
    if m.options.APPSTATUS == 1:
        beta  = m.beta.NEWVAL
    else:
        beta  = 0.0

# 绘图
import matplotlib.pyplot as plt
plt.figure(figsize=(12,6))
plt.subplot(2,1,1)
plt.plot(m.time,m.T.value,'r-',label=r'$T_{int}$')
plt.plot(m.time,TL.value,'k--',label='下限')
plt.plot(m.time,TH.value,'k--',label='上限')
plt.ylabel('温度 (°C)')
plt.legend()
plt.subplot(2,1,2)
plt.plot(m.time,m.beta.value,'b--',label=r'$\beta$')
plt.ylabel('最优控制量')
plt.xlabel('时间 (秒)')
plt.legend()
plt.show()

原运行结果

室内温度曲线
控制变量曲线
外部温度曲线


问题分析与修正方案

核心问题点

  1. 扰动变量定义冲突:原代码中先将m.d定义为模型输入m.u[0],随后又重新赋值为Param类型,破坏了ARX模型的输入结构,导致扰动未正确传入模型。
  2. 温度范围约束未绑定:仅定义了上下限参数,但未将其关联到被控变量m.T,MPC无法识别温度范围要求。
  3. MPC循环逻辑冗余:IMODE=6时GEKKO会自动处理滚动优化,手动循环每个时间点会重置求解状态,无法实现连续预测控制。
  4. 操作变量配置错误:m.beta.FSTATUS=1表示强制使用测量值,但未实时更新测量数据,导致MPC无法主动计算最优控制量。

修正后代码

# 导入库
import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
from numpy import array

K = array([[  0.93705481, -12.24012156]])
p =  {'a': array([[ 1.08945247],
        [-0.00242145],
        [-0.00245978],
        [-0.00272713],
        [-0.00295845],
        [-0.00319119],
        [-0.00343511],
        [-0.00366243],
        [-0.00394247],
        [-0.06665054]]),
 'b': array([[[-0.05160235, -0.01039767],
         [ 0.00173511, -0.01552485],
         [ 0.00174602, -0.01179519],
         [ 0.00180031, -0.01052658],
         [ 0.00186416, -0.00822121],
         [ 0.00193947, -0.00570905],
         [ 0.00202877, -0.00344507],
         [ 0.00211395, -0.00146947],
         [ 0.00223514,  0.00021945],
         [ 0.03800987,  0.04243736]]]),
 'c': array([0.0265903])} 

# 外部温度数据
T_externel = np.linspace(9.51,9.78,200)

m = GEKKO(remote=False)
m.y = m.Array(m.CV,1)
m.u = m.Array(m.MV,2)
m.arx(p,m.y,m.u)

# 变量重命名
m.T = m.y[0]          # 室内温度(被控变量)
m.beta = m.u[1]       # 控制变量(操作变量)
m.d = m.u[0]          # 外部温度(扰动变量)

# 绑定扰动数据
m.d.value = T_externel

# 温度范围参数
TL = 16
TH = 18

# 稳态初始化
m.options.IMODE = 1
m.solve(disp=False)

# MPC核心配置
m.options.IMODE   = 6       # MPC模式
m.options.CV_TYPE = 2       # L2范数目标
m.options.NODES   = 2       # 配点节点数
m.options.SOLVER  = 1       # APOPT求解器
m.time = np.arange(0, len(T_externel)*300, 300)  # 时间步长300s

# 操作变量配置
m.beta.STATUS = 1    # 允许优化调整
m.beta.FSTATUS = 0   # 由MPC计算最优值,不依赖测量值
m.beta.DMAX = 1.0    # 单次调整最大步长
m.beta.DCOST = 0.0   # 调整代价惩罚
m.beta.UPPER = 1.0   # 上限
m.beta.LOWER = 0.0   # 下限

# 被控变量配置(范围型设定点)
m.T.STATUS = 1       # 启用控制
m.T.FSTATUS = 1      # 使用测量值
m.T.SPHI = TH        # 温度上限
m.T.SPLO = TL        # 温度下限
m.T.value = 17       # 初始温度

# 求解MPC
m.solve(disp=True)

# 结果可视化
plt.figure(figsize=(12,6))
plt.subplot(2,1,1)
plt.plot(m.time, m.T.value, 'r-', label=r'$T_{int}$')
plt.plot(m.time, [TL]*len(m.time), 'k--', label='温度下限')
plt.plot(m.time, [TH]*len(m.time), 'k--', label='温度上限')
plt.ylabel('温度 (°C)')
plt.legend()
plt.subplot(2,1,2)
plt.plot(m.time, m.beta.value, 'b--', label=r'$\beta$')
plt.ylabel('最优控制量')
plt.xlabel('时间 (秒)')
plt.legend()
plt.show()

修正效果说明

修正后,MPC会根据外部温度变化,自动调整控制变量β,将室内温度稳定维持在16-18℃的设定范围内,避免温度偏离。

内容的提问来源于stack exchange,提问作者m_nacereddine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 07:32:35