Python Gekko最优控制。如何创建多个终止目标/条件?

Python Gekko最优控制。如何创建多个终止目标/条件?,python,gekko,Python,Gekko,所以我在模拟飞机飞行。飞机飞行一定距离(pathx和pathy变量),然后在达到某些pathx和pathy值时停止模拟。解算器试图通过最大化质量值来最小化燃油消耗量(m.Maximize(mass*tf*final)。解算器控制油门踏板位置(tcont) 现在,终止条件的定义如下: 对于X轴: m.Equation(x*final<=pathx) 对于Y轴: m.Equation(y*final<=pathy) 现在,当达到所需的X值时,模拟结束,而没有达到所需的Y值 当达到所需

所以我在模拟飞机飞行。飞机飞行一定距离(
pathx
pathy
变量),然后在达到某些
pathx
pathy
值时停止模拟。解算器试图通过最大化质量值来最小化燃油消耗量(m.Maximize(mass*tf*final)。解算器控制油门踏板位置(
tcont

现在,终止条件的定义如下:

对于X轴:

m.Equation(x*final<=pathx)
对于Y轴:

m.Equation(y*final<=pathy)
现在,当达到所需的X值时,模拟结束,而没有达到所需的Y值

当达到所需(X和Y)值时,如何强制结束模拟

我的代码:

import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
import math
#Gekko model
m = GEKKO(remote=False)

#Time points
nt = 11
tm =  np.linspace(0,100,nt)
m.time = tm

# Variables
Ro = m.Var(value=1.1)#air density
g = m.Const(value=9.80665)
pressure = m.Var(value=101325)#
T = m.Var(value=281,lb=100)#temperature
T0 = m.Const(value=288)#temperature at see level
S = m.Const(value=122.6)
Cd = m.Const(value=0.1)#drag coef
Cl = m.Var(value=1)#lift couef
FuelFlow = m.Var()
D = m.Var(value=25000,lb=0)#drag
Thrmax = m.Const(value=200000)#maximum throttle
Thr = m.Var()#throttle
V = m.Var(value=100,lb=50,ub=240)#velocity
gamma = m.Var(value=0)# Flight-path angle
gammaa = gamma.value
Xi = m.Var(value=0)# Heading angle
Xii = Xi.value
x = m.Var(value=0,lb=0)#x position
y = m.Var(value=0,lb=0)#y position
h = m.Var(value=1000,lb=0)# height
mass = m.Var(value=60000,lb=10000)
pathx = m.Const(value=50000) #intended distance length
pathy = m.Const(value=50000)
L = m.Var(value=0.1)#lift

p = np.zeros(nt)
p[-1] = 1.0
final = m.Param(value=p)

m.options.MAX_ITER=10000 # iteration number

#Fixed Variable
tf = m.FV(value=1,lb=0.0001,ub=1000.0)#
tf.STATUS = 1

# Controlled parameters
Tcontr = m.MV(value=0.2,lb=0.1,ub=1)# solver controls throttle pedal position
Tcontr.STATUS = 1
Tcontr.DCOST = 0

#Mu = m.Var(value=0)
Mu = m.MV(value=0,lb=-1.5,ub=1.5)# solver controls bank angle 
Mu.STATUS = 1
Mu.DCOST = 0

Muu = Mu.value

# Equations
m.Equation(Thr==Tcontr*Thrmax)
m.Equation(FuelFlow==0.75882*(1+(V/2938.5)))
m.Equation(D==0.5*Ro*(V**2)*Cd*S)
m.Equation(mass.dt()==tf*(-Thr*(FuelFlow/60000)))#
m.Equation(V.dt()==tf*((Thr-D)/mass))#
m.Equation(x.dt()==tf*(V*(math.cos(gammaa.value))*(math.cos(Xii.value))))#
m.Equation(x*final<=pathx)
#pressure and density part
m.Equation(T==T0-(0.0065*h))
m.Equation(pressure==101325*(1-(0.0065*h)/T0)**((g*0.0289652)/(8.31446*0.0065)))#
m.Equation(Ro*(8.31446*T)==(pressure*0.0289652))
#2D addition part
m.Equation(L==0.5*Ro*(V**2)*Cl*S)
m.Equation(Xi.dt()==tf*((L*math.sin(Muu.value))/(mass*V)))
m.Equation(y.dt()==tf*(V*(math.cos(gammaa.value))*(math.sin(Xii.value))))#
m.Equation(y*final<=pathy)

# Objective Function
m.Minimize(final*(x-pathx)**2) #1D part
m.Minimize(final*(y-pathy)**2) #2D part
m.Maximize(mass*tf*final) #objective function
m.options.IMODE = 6
m.options.NODES = 2 # it was 3 before
m.options.MV_TYPE = 1
m.options.SOLVER = 3
#m.open_folder() # to search for infeasibilities
m.solve()

tm = tm * tf.value[0]
    
fig, axs = plt.subplots(8)
fig.suptitle('Results')
axs[0].plot(tm,Tcontr,'r-',LineWidth=2,label=r'$Tcontr$')
axs[0].legend(loc='best')
axs[1].plot(tm,V.value,'b-',LineWidth=2,label=r'$V$')
axs[1].legend(loc='best')
axs[2].plot(tm,x.value,'r--',LineWidth=2,label=r'$x$')
axs[2].legend(loc='best')
axs[3].plot(tm,D.value,'g-',LineWidth=2,label=r'$D$')
axs[3].legend(loc='best')
axs[4].plot(tm,mass.value,'g:',LineWidth=2,label=r'$mass$')
axs[4].legend(loc='best')
axs[5].plot(tm,T.value,'p-',LineWidth=2,label=r'$T$')
axs[5].legend(loc='best')
axs[6].plot(tm,Mu.value,'p-',LineWidth=2,label=r'$Mu$')
axs[6].legend(loc='best')
axs[7].plot(tm,y.value,'p-',LineWidth=2,label=r'$y$')
axs[7].legend(loc='best')
plt.xlabel('Time')
#plt.ylabel('Value')
plt.show()
将numpy导入为np
将matplotlib.pyplot作为plt导入
从gekko进口gekko
输入数学
#盖柯模型
m=GEKKO(远程=False)
#时点
nt=11
tm=np.linspace(0100,新界)
m、 时间=tm
#变数
Ro=m.Var(值=1.1)#空气密度
g=m.Const(值=9.80665)
压力=m.Var(值=101325)#
T=m.Var(值=281,磅=100)#温度
T0=m.Const(值=288)#见标高处的温度
S=m.Const(值=122.6)
Cd=m.Const(值=0.1)#阻力系数
Cl=m.Var(值=1)#升力系数
燃料流量=m.Var()
D=m.Var(值=25000,磅=0)#阻力
Thrmax=m.Const(值=200000)#最大节气门
Thr=m.Var()#油门
V=m.Var(值=100,磅=50,磅=240)#速度
伽马=m.Var(值=0)#飞行轨迹角
gammaa=伽马值
席=M.Var(值=0)α航向角
Xi= Xi值
x=m.Var(值=0,磅=0)#x位置
y=m.Var(值=0,磅=0)#y位置
h=m.Var(值=1000,磅=0)#高度
质量=m.Var(值=60000,磅=10000)
路径x=m.Const(值=50000)#预期距离长度
path=m.Const(值=50000)
L=m.Var(值=0.1)#升力
p=np.零(nt)
p[-1]=1.0
最终=m.Param(值=p)
m、 选项。最大迭代次数=10000次
#固定变量
tf=m.FV(值=1,磅=0.0001,磅=1000.0)#
tf.STATUS=1
#受控参数
Tcontr=m.MV(值=0.2,磅=0.1,磅=1)#解算器控制油门踏板位置
Tcontr.STATUS=1
Tcontr.DCOST=0
#Mu=m.Var(值=0)
Mu=m.MV(值=0,lb=-1.5,ub=1.5)#解算器控制倾斜角度
Mu.STATUS=1
Mu.DCOST=0
Muu=Mu.value
#方程式
m、 方程(Thr==Tcontr*Thrmax)
m、 方程式(燃料流量==0.75882*(1+(V/2938.5)))
m、 方程(D==0.5*Ro*(V**2)*Cd*S)
m、 方程(质量dt()==tf*(-Thr*(燃料流量/60000)))#
m、 方程(V.dt()==tf*((Thr-D)/质量))#
m、 方程(x.dt()==tf*(V*(math.cos(gammaa.value))*(math.cos(Xii.value)))#

m、 等式(x*final尝试为以下两种情况添加硬端子约束:

m.方程((x-pathx)*final==0)
m、 方程((y-y)*最终==0)
或者,增加终端条件下的重量

w=1e3
m、 最小化(w*最终*(x路径)**2)#1D零件
m、 最小化(w*最终*(y型)**2)#2D零件
您可能需要使用一种或两种策略。终端条件可能很难解决

对重要更新的响应

将Gekko函数与
m.sin()和
m.cos()一起使用
而不是
数学
函数。另外,不要在方程中使用
.value
。Gekko需要完整的符号图,以便将方程编译成字节码,并生成函数求值和自动微分的导数

m.方程(y.dt()==tf*(V*(m.cos(gammaa))*(m.sin(Xii)))
通过将任何分母相乘到另一边,它也有助于避免被零除

m.方程(质量*V*Xi.dt()==tf*((L*m.sin(Muu)))

谢谢!但是硬终端约束本身会产生这个问题:恢复阶段中的恢复阶段失败。如果我同时实施硬约束并增加终端条件的权重,那么程序将一直运行,直到超出最大迭代次数。仅实施增加的权重的效果可以忽略不计并且没有实现最终y值的严重增加。因此,我测试了一些东西,看起来所有软终止条件都按预期工作,但还有其他一些东西不按预期工作。我将在问题的底部描述它们。因此,既然我从Mu导出Mu值,就像这样:Muu=Mu.value,那么确实如此这意味着,如果我想使用m.cos和其他三角函数,我需要停止像那样导出Mu值,开始只使用Mu和其他类似的纯形式变量?我删除了所有的导出值(比如Muu)an将其替换为原始副本。在41711次迭代后,模拟返回了一个错误:在几乎可行的点调用恢复阶段,违反了约束7.275958e-011。中止。恢复阶段中的恢复阶段失败。在此更改之前,模拟未返回此类错误卢比。
m.Minimize(final*(y-pathy)**2)
import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
import math
#Gekko model
m = GEKKO(remote=False)

#Time points
nt = 11
tm =  np.linspace(0,100,nt)
m.time = tm

# Variables
Ro = m.Var(value=1.1)#air density
g = m.Const(value=9.80665)
pressure = m.Var(value=101325)#
T = m.Var(value=281,lb=100)#temperature
T0 = m.Const(value=288)#temperature at see level
S = m.Const(value=122.6)
Cd = m.Const(value=0.1)#drag coef
Cl = m.Var(value=1)#lift couef
FuelFlow = m.Var()
D = m.Var(value=25000,lb=0)#drag
Thrmax = m.Const(value=200000)#maximum throttle
Thr = m.Var()#throttle
V = m.Var(value=100,lb=50,ub=240)#velocity
gamma = m.Var(value=0)# Flight-path angle
gammaa = gamma.value
Xi = m.Var(value=0)# Heading angle
Xii = Xi.value
x = m.Var(value=0,lb=0)#x position
y = m.Var(value=0,lb=0)#y position
h = m.Var(value=1000,lb=0)# height
mass = m.Var(value=60000,lb=10000)
pathx = m.Const(value=50000) #intended distance length
pathy = m.Const(value=50000)
L = m.Var(value=0.1)#lift

p = np.zeros(nt)
p[-1] = 1.0
final = m.Param(value=p)

m.options.MAX_ITER=10000 # iteration number

#Fixed Variable
tf = m.FV(value=1,lb=0.0001,ub=1000.0)#
tf.STATUS = 1

# Controlled parameters
Tcontr = m.MV(value=0.2,lb=0.1,ub=1)# solver controls throttle pedal position
Tcontr.STATUS = 1
Tcontr.DCOST = 0

#Mu = m.Var(value=0)
Mu = m.MV(value=0,lb=-1.5,ub=1.5)# solver controls bank angle 
Mu.STATUS = 1
Mu.DCOST = 0

Muu = Mu.value

# Equations
m.Equation(Thr==Tcontr*Thrmax)
m.Equation(FuelFlow==0.75882*(1+(V/2938.5)))
m.Equation(D==0.5*Ro*(V**2)*Cd*S)
m.Equation(mass.dt()==tf*(-Thr*(FuelFlow/60000)))#
m.Equation(V.dt()==tf*((Thr-D)/mass))#
m.Equation(x.dt()==tf*(V*(math.cos(gammaa.value))*(math.cos(Xii.value))))#
m.Equation(x*final<=pathx)
#pressure and density part
m.Equation(T==T0-(0.0065*h))
m.Equation(pressure==101325*(1-(0.0065*h)/T0)**((g*0.0289652)/(8.31446*0.0065)))#
m.Equation(Ro*(8.31446*T)==(pressure*0.0289652))
#2D addition part
m.Equation(L==0.5*Ro*(V**2)*Cl*S)
m.Equation(Xi.dt()==tf*((L*math.sin(Muu.value))/(mass*V)))
m.Equation(y.dt()==tf*(V*(math.cos(gammaa.value))*(math.sin(Xii.value))))#
m.Equation(y*final<=pathy)

# Objective Function
m.Minimize(final*(x-pathx)**2) #1D part
m.Minimize(final*(y-pathy)**2) #2D part
m.Maximize(mass*tf*final) #objective function
m.options.IMODE = 6
m.options.NODES = 2 # it was 3 before
m.options.MV_TYPE = 1
m.options.SOLVER = 3
#m.open_folder() # to search for infeasibilities
m.solve()

tm = tm * tf.value[0]
    
fig, axs = plt.subplots(8)
fig.suptitle('Results')
axs[0].plot(tm,Tcontr,'r-',LineWidth=2,label=r'$Tcontr$')
axs[0].legend(loc='best')
axs[1].plot(tm,V.value,'b-',LineWidth=2,label=r'$V$')
axs[1].legend(loc='best')
axs[2].plot(tm,x.value,'r--',LineWidth=2,label=r'$x$')
axs[2].legend(loc='best')
axs[3].plot(tm,D.value,'g-',LineWidth=2,label=r'$D$')
axs[3].legend(loc='best')
axs[4].plot(tm,mass.value,'g:',LineWidth=2,label=r'$mass$')
axs[4].legend(loc='best')
axs[5].plot(tm,T.value,'p-',LineWidth=2,label=r'$T$')
axs[5].legend(loc='best')
axs[6].plot(tm,Mu.value,'p-',LineWidth=2,label=r'$Mu$')
axs[6].legend(loc='best')
axs[7].plot(tm,y.value,'p-',LineWidth=2,label=r'$y$')
axs[7].legend(loc='best')
plt.xlabel('Time')
#plt.ylabel('Value')
plt.show()