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()
原运行结果



问题分析与修正方案
核心问题点
- 扰动变量定义冲突:原代码中先将
m.d定义为模型输入m.u[0],随后又重新赋值为Param类型,破坏了ARX模型的输入结构,导致扰动未正确传入模型。 - 温度范围约束未绑定:仅定义了上下限参数,但未将其关联到被控变量
m.T,MPC无法识别温度范围要求。 - MPC循环逻辑冗余:IMODE=6时GEKKO会自动处理滚动优化,手动循环每个时间点会重置求解状态,无法实现连续预测控制。
- 操作变量配置错误:
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
相关产品推荐
相关产品推荐

