4

我正在使用 MPC 来运行加热器系统。目前,我让它在给定的时间点从我的设定点数组中获取一个单独的值,以调整要达到的过程。我希望能够给它当前的期望值和未来的几个点作为设定点,以便它可以随着设定点的变化更好地调整。我怎样才能给 gekko 一个向量,以便让它更好地适应未来的设定点?

这是我的代码中当前更新我的设定值的部分。

T1[i] = a.T1
T2[i] = a.T2

TC1.MEAS = T1[i]
TC2.MEAS = T2[i]

DT = .1
TC1.SPHI = sp1[i] + DT   #sp1 and sp2 are set point arrays for the two heaters
TC1.SPLO = sp1[i] - DT
TC2.SPHI = sp2[i] + DT
TC2.SPLO = sp2[i] - DT

m.solve(disp=False)
4

2 回答 2

3

gekkoCV 对象仅使用数组的标量值, SPSPHI因此SPLO需要进行一些修改以使优化器考虑未来的设定点更改。一个简单的 MPC 应用程序显示了如何在 Gekko 中使用设定点。

MPC 设定点

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt  
m = GEKKO()
m.time = np.linspace(0,20,41)
p = m.MV(value=0, lb=0, ub=100) # Declare MV
p.STATUS = 1  # allow optimizer to change
p.DCOST = 0.1 # smooth MV response
p.DMAX = 10.0 # max move each cycle
v = m.CV(value=0) # Declare CV
v.STATUS = 1  # add CV to the objective
m.options.CV_TYPE = 2 # squared error
v.SP = 40     # set point
v.TR_INIT = 1 # set point trajectory
v.TAU = 5     # time constant of trajectory
m.Equation(10*v.dt() == -v + 2*p)
m.options.IMODE = 6 # control
m.solve(disp=False)
# get additional solution information
import json
with open(m.path+'//results.json') as f:
    results = json.load(f)
plt.figure()
plt.subplot(2,1,1)
plt.plot(m.time,p.value,'b-',label='MV Optimized')
plt.legend()
plt.ylabel('Input')
plt.subplot(2,1,2)
plt.plot(m.time,results['v1.tr'],'k-',label='Reference Trajectory')
plt.plot(m.time,v.value,'r--',label='CV Response')
plt.ylabel('Output')
plt.xlabel('Time')
plt.legend(loc='best')
plt.show()

有一个设定值是 的目标,40参考轨迹定义为时间常数5。MPC 不能准确地遵循参考轨迹,因为变化率约束为DMAX=10。如果您希望优化器了解未来的设定点更改,有两个选项。

选项 1:不使用 CV,使用前馈参数

如果您不需要参考轨迹并且可以使用平方误差目标,那么预测未来设定点变化的最简单方法是使用设定点值的前馈参数向量定义您自己的 MPC 目标。示例问题表明,优化器正在预测设定值更改,并在下一次设定值更改之前主动移动以最小化总平方误差。这在许多情况下可能是可取的,但在产品等级发生变化且生产活动的结束应在生产过渡材料之前符合规格的制造中可能是不可取的。

预测 SP 变化

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt  
m = GEKKO()
m.time = np.linspace(0,20,41)
p = m.MV(value=0, lb=0, ub=100) # Declare MV
p.STATUS = 1  # allow optimizer to change
p.DCOST = 0.1 # smooth MV response
p.DMAX = 10.0 # max move constraint
v = m.Var(value=0) 
sp = np.ones(41)*40
sp[20:] = 60
s = m.Param(value=sp)
m.Obj((s-v)**2)
m.Equation(10*v.dt() == -v + 2*p)
m.options.IMODE = 6 # control
m.solve(disp=False)
plt.figure()
plt.subplot(2,1,1)
plt.plot(m.time,p.value,'b-',label='MV Optimized')
plt.legend()
plt.ylabel('Input')
plt.subplot(2,1,2)
plt.plot(m.time,sp,'k-',label='Setpoint')
plt.plot(m.time,v.value,'r--',label='CV Response')
plt.ylabel('Output')
plt.xlabel('Time')
plt.legend(loc='best')
plt.show()

选项 2:错误为 CV

如果希望使用参考轨迹和 Gekko 内置 CV 选项,则可以选择定义一个新的误差变量e并对其进行控制。误差变量的设定点始终为零,前馈设定点作为前馈参数实现。

CV 错误

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt  
m = GEKKO()
m.time = np.linspace(0,20,41)
p = m.MV(value=0, lb=0, ub=100) # Declare MV
p.STATUS = 1  # allow optimizer to change
p.DCOST = 0.1 # smooth MV response
p.DMAX = 10.0 # max move constraint
v = m.Var(value=0) 
sp = np.ones(41)*40
sp[20:] = 60
s = m.Param(value=sp)
e = m.CV(value=0) # Declare CV
e.STATUS = 1  # add CV to the objective
m.options.CV_TYPE = 2 # squared error
e.SP = 0     # set point
e.TR_INIT = 1 # error trajectory
e.TAU = 5     # time constant of trajectory
m.Equation(e==s-v)
m.Equation(10*v.dt() == -v + 2*p)
m.options.IMODE = 6 # control
m.solve(disp=False)
plt.figure()
plt.subplot(2,1,1)
plt.plot(m.time,p.value,'b-',label='MV Optimized')
plt.legend()
plt.ylabel('Input')
plt.subplot(2,1,2)
plt.plot(m.time,sp,'k-',label='Setpoint')
plt.plot(m.time,v.value,'r--',label='CV Response')
plt.ylabel('Output')
plt.xlabel('Time')
plt.legend(loc='best')
plt.show()
于 2019-10-25T13:20:43.543 回答
2

对于每个时间步,Gekko 会自动以数组的形式为未来的控制范围生成设定点。而且,数组通常填充有您分配的单个值。但是,您可以将设定值作为数组提供,如下所示。

sp1 = np.array([[1,2,3,4,5],
                [2,3,4,5,6],
                [3,4,5,6,7],
                [4,5,6,7,8]])

然后,您可以为每个时间步分配矩阵的每一行,就像您在问题中所做的那样。

DT = .1
TC1.SPHI = sp1[i] + DT

笔记:

  1. 您需要具有相同长度的设定点数组,这意味着您的设定点矩阵中的列的大小与控制范围(例如'm.time')。

  2. 如果您不想过滤掉阵列中的设定点序列,您可能需要设置设定点轨迹选项“0”。(TR_INIT = 0)

于 2019-10-24T18:26:50.890 回答