如何在MPC上使用向量设定点,以提供有关将来设定点将如何变化的程序信息

时间:2019-10-24 17:39:51

标签: gekko

我正在使用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)

2 个答案:

答案 0 :(得分:3)

frame-ancestor CV对象仅对gekkoSPSPHI使用数组的标量值,因此需要进行一些修改才能使优化器考虑将来的设定值变化。一个简单的MPC应用程序显示了如何在Gekko中使用设定点。

MPC setpoint

SPLO

有一个设定点值是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无法完全遵循参考轨迹。如果您希望优化器知道将来的设定值更改,则有两种选择。

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

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

Anticipate SP Changes

DMAX=10

选项2:简历错误

如果希望使用参考轨迹和Gekko内置的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) 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() 并进行控制。错误变量的设定点始终为零,前馈设定点被实现为前馈参数。

Error as CV

e

答案 1 :(得分:1)

对于每个时间步,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)