gekko - 为什么 12 秒后 MHE 对我的模型持怀疑态度?
问题描述
我是控制系统的新手,并尝试使用 GEKKO。对于我的模型模拟,geos 正确并在 MHE 和 MPC 上运行它在 t = 15 秒后正确运行,如果 t = 16 秒在 12 秒,它会如附图所示持怀疑态度。这有什么原因吗?
m = GEKKO(remote = False)
g = m.Const(value = 9.81)
Cc = m.Const(value = 2*10**-5)
D1 = m.Const(value = 0.1016)
D2 = m.Const(value = 0.1016)
h1 = m.Const(value = 100)
hv = m.Const(value = 1000)
L1 = m.Const(value = 500)
L2 = m.Const(value = 1100)
V1 = m.Const(value = 4.054)
V2 = m.Const(value = 9.729)
A1 = m.Const(0.008107)
A2 = m.Const(0.008107)
beta1 = m.Const(value = 1.5 * 10**9)
beta2 = m.Const(value = 1.5* 10**9)
Pres = m.Const(value = 1.261 * 10**7)
M = m.Const(value = 1.992 * 10**8)
rho = m.Const(value = 932)
PI = m.Const(value = 2.32 * 10**(-9))
visc = m.Const(value = 0.024)
fo = m.Const(value = 60)
Inp = m.Const(value = 65)
Pnp = m.Const(value = 1.625 * 10**5)
z = m.MV(1, lb = 0.1, ub = 1)
f = m.MV(35, lb = 35, ub = 65)
f.STATUS = 1
f.DMAX = 30
f.DCOST = 0.0002 # slow down change of frequency
f.UPPER = 65
Ppin = m.CV()
Ppin.STATUS = 1 # add the SP to the objective
Ppin.SP = 6e6 # set point
Ppin.TR_INIT = 1 # set point trajectory
Ppin.TAU = 5 # time constant of trajectory
Pwf = m.Var(ub = Pres)
Ppout = m.Var()
Pwh = m.Var()
Pm = m.Var()
P_fric_drop = m.Var()
F1 = m.Var()
F2 = m.Var()
q = m.Var(lb = 0)
qc = m.Var(lb = 0)
qr = m.Var(lb = 0)
I = m.Var()
H = m.Var()
BHP = m.Var(lb = 0)
BHPo = m.Var()
qo = m.Var()
Ho = m.Var()
m.Equation([Pwh.dt() == beta2*(q-qc)/V2,
Pwf.dt() == beta1*(qr-q)/V1,
q.dt() == (1/M)*(Pwf - Pwh - rho*g*hv - P_fric_drop + (Ppout-Ppin))])
m.Equation([qr == PI*(Pres - Pwf),
qc == Cc*z*(m.sqrt((Pwh - Pm))),
Pm == Pwh/2,
P_fric_drop == F1 + F2,
F1 == 0.158 * rho * L1* q**2 * visc**0.5 /(D1 * A1**2 * (rho*D1*q)**0.5),
F2 == 0.158 * rho * L2* q**2 * visc**0.5 /(D2 * A2**2 * (rho*D2*q)**0.5)])
m.Equation([
qo == q * fo/f,
H == Ho * (f/fo)**2,
BHPo == -2.3599e9*qo**3 - 1.8082e7*qo**2 + 4.3346e6*qo + 9.4355e4,
BHP == BHPo * (f/fo)**3,
Ppin == Pwf - rho*g*h1 - F1,
Ho == 9.5970e2+7.4959e3*qo+-1.2454e6*qo**2,
I == Inp * BHP / Pnp,
Ppout == H*rho*g + Ppin
])
m.options.solver = 1
m.options.MAX_ITER = 250
m.options.IMODE = 1
m.solve(debug=True)
tf = 30 # final time (sec)
st = 2.0 # simulation time intervals
nt = int(tf/st)+1 # simulation time points
m.time = np.linspace(0,tf,nt)
m.options.CV_TYPE = 2 # squared error
m.options.solver = 3
m.options.NODES=2
m.options.IMODE = 5
m.solve(debug = False)
解决方案
我无法重现您遇到的问题,因此我将针对您的应用程序故障排除和提高求解器找到解决方案的能力提供一些具体建议。
帮助求解器找到解决方案
- 避免
sqrt(-negative)
#qc == Cc*z*(m.sqrt((Pwh - Pm)))
qc**2 == Cc**2 * z**2 * (Pwh - Pm) # avoid negative in sqrt
- 避免被零除的可能性。的值
q
被限制为远离零,但寻找可以通过重新排列来改进的其他方程。
#qo == q * fo/f
qo * f == q * fo
#H == Ho * (f/fo)**2
H * fo**2 == Ho * f**2
#I == Inp * BHP / Pnp
I * Pnp == Inp * BHP
- 约束 FV 和 MV
它通常有助于缩小DMAX
或限制 和 的上限和FVs
下限MVs
。对Var
类型的约束可能导致不可行的解决方案。
- 降低自由度
对于 MHE 应用程序,我建议您使用FVs
而不是MVs
用于未知参数。FVs
计算所有测量值的单个值。为每个MVs
时间点计算一个新的参数值。使用 anFV
而不是 anMV
可以帮助求解器,因为优化器的决策更少,并且不会调整参数值以跟踪信号噪声。
检查解决方案
- 配置目标函数。
对于 MHE 应用程序,您需要有一些CV
试图匹配的值具有FSTATUS=1
. 在您发布的示例中,没有任何插入CVs
的FSTATUS=1
测量值或任何插入的测量值。CVs
MHE 是通过将未知参数调整为FVs
或来使模型与测量值对齐MVs
。
- 检查求解器状态以确保它找到了成功的解决方案
APPSTAUTS==1
if m.options.APPSTATUS==1:
print('Successful Solution)
else:
print('Solver Failed to Find a Solution')
- 创建变量图,尤其是在有问题的时期。
qr
您经常可以看到哪里有一个积分变量,例如qc
接近一个变量约束。这是我将您的 MHE 应用程序转换为 MPC 应用程序的示例。我正在调整摩擦系数f
(不现实)和阀门开z
度,以显示 MPC 如何驱动Ppin
到目标设定点。
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
m = GEKKO(remote = False)
g = m.Const(value = 9.81)
Cc = m.Const(value = 2*10**-5)
D1 = m.Const(value = 0.1016)
D2 = m.Const(value = 0.1016)
h1 = m.Const(value = 100)
hv = m.Const(value = 1000)
L1 = m.Const(value = 500)
L2 = m.Const(value = 1100)
V1 = m.Const(value = 4.054)
V2 = m.Const(value = 9.729)
A1 = m.Const(0.008107)
A2 = m.Const(0.008107)
beta1 = m.Const(value = 1.5 * 10**9)
beta2 = m.Const(value = 1.5* 10**9)
Pres = m.Const(value = 1.261 * 10**7)
M = m.Const(value = 1.992 * 10**8)
rho = m.Const(value = 932)
PI = m.Const(value = 2.32 * 10**(-9))
visc = m.Const(value = 0.024)
fo = m.Const(value = 60)
Inp = m.Const(value = 65)
Pnp = m.Const(value = 1.625 * 10**5)
z = m.MV(1, lb = 0.1, ub = 1)
z.STATUS = 1
z.DMAX = 0.01
f = m.MV(35, lb = 35, ub = 65)
f.STATUS = 1
f.DMAX = 30
f.DCOST = 0.0002 # slow down change of frequency
f.UPPER = 65
Ppin = m.CV()
Ppin.STATUS = 1 # add the SP to the objective
Ppin.SP = 6e6 # set point
Ppin.TR_INIT = 1 # set point trajectory
Ppin.TAU = 5 # time constant of trajectory
Pwf = m.Var(ub = Pres)
Ppout = m.Var()
Pwh = m.Var()
Pm = m.Var()
P_fric_drop = m.Var()
F1 = m.Var()
F2 = m.Var()
q = m.Var(lb = 0)
qc = m.Var(lb = 0)
qr = m.Var(lb = 0)
I = m.Var()
H = m.Var()
BHP = m.Var(lb = 0)
BHPo = m.Var()
qo = m.Var()
Ho = m.Var()
m.Equation([Pwh.dt() == beta2*(q-qc)/V2,
Pwf.dt() == beta1*(qr-q)/V1,
M * q.dt() == Pwf - Pwh - rho*g*hv - P_fric_drop + (Ppout-Ppin)])
m.Equation([qr == PI*(Pres - Pwf),
qc == Cc*z*(m.sqrt((Pwh - Pm))),
Pm == Pwh/2,
P_fric_drop == F1 + F2,
F1 == 0.158 * rho * L1* q**2 * visc**0.5 /(D1 * A1**2 * (rho*D1*q)**0.5),
F2 == 0.158 * rho * L2* q**2 * visc**0.5 /(D2 * A2**2 * (rho*D2*q)**0.5)])
m.Equation([
qo * f == q * fo,
H * fo**2 == Ho * f**2,
BHPo == -2.3599e9*qo**3 - 1.8082e7*qo**2 + 4.3346e6*qo + 9.4355e4,
BHP == BHPo * (f/fo)**3,
Ppin == Pwf - rho*g*h1 - F1,
Ho == 9.5970e2+7.4959e3*qo+-1.2454e6*qo**2,
I * Pnp == Inp * BHP,
Ppout == H*rho*g + Ppin
])
m.options.solver = 1
m.options.MAX_ITER = 250
m.options.IMODE = 1
m.solve()
tf = 30 # final time (sec)
st = 2.0 # simulation time intervals
nt = int(tf/st)+1 # simulation time points
m.time = np.linspace(0,tf,nt)
m.options.CV_TYPE = 2 # squared error
m.options.solver = 3
m.options.NODES=2
m.options.IMODE = 6
plt.figure(figsize=(10,5))
for i in range(10):
m.solve(disp=False)
print(i,m.options.APPSTATUS)
plt.subplot(10,1,i+1)
plt.plot(m.time+i*st,Ppin.value)
plt.xlim([0,50])
plt.ylim([6e6,7e6])
plt.show()
您的应用程序看起来像是用于钻井中的液压控制。GitHub 上还有其他可用模型。我希望您考虑将您的模型或案例研究贡献给开源存储库。
推荐阅读
- c# - 某些类型无法从本地项目编译的 dll 加载
- flask - 烧瓶应用程序正确启动但登录后显示错误
- ios - 在我关闭应用程序时继续 userActivity
- python - FileExistsError Errno 17 -- 我不知道为什么会发生这个错误
- vba - TrackRevisions:带有原始文本和最终文本的表格
- r - ggplot2 将 alpha 的图例修改为一系列值
- java - 如何检查 FTP 服务器是否处于活动状态?
- javascript - 如何在 React.js 中不重复从数组中生成随机项?
- scikit-learn - BaggingClassifier 可以在 Sklearn 中手动定义多个 base_estimator 吗?
- r - 我需要能够对 r 中的时间列进行排序(但它是花费的小时、天、周的集合,而不是正常格式的时间)