Skip to content
Advertisement

GEKKO. X value does not go beyond certain point

I need to solve 1D plane flight optimal control problem. I have a plane that is 1000m high. I need it to travel certain distance (x) forward along x-axis while minimizing fuel consumption. And when it achieves travels that distance x I need program to stop. This function controls it: m.Equation(x*final<=1500).

And for some reason during the simulation my x value does not want to go higher than 1310.

How could I fix that “blockage”?

My gekko script:

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,1,nt)
m.time = tm

# Variables
Ro = m.Const(value=1.1)
g = m.Const(value=9.80665)
T = m.Var()
T0 = m.Const(value=273)
S = m.Const(value=122.6)
Cd = m.Const(value=0.1)
FuelFlow = m.Var()
D = m.Var()
Thrmax = value=200000
Thr = m.Var()
V = m.Var()
nu = m.Var(value=0)
nuu = nu.value
x = m.Var(value=0)
h = m.Var(value=1000)
mass = m.Var(value=60000)
    
p = np.zeros(nt)
p[-1] = 1.0
final = m.Param(value=p)

m.options.MAX_ITER=40000 # iteration max number

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

# Parameters
Tcontr = m.MV(value=0.2,lb=0.2,ub=1)
Tcontr.STATUS = 1
Tcontr.DCOST = 0 #1e-2

# Equations
m.Equation(x.dt()==tf*(V*(math.cos(nuu.value))))#
m.Equation(Thr==Tcontr*Thrmax)
m.Equation(V.dt()==tf*((Thr-D)/mass))#
m.Equation(mass.dt()==tf*(-Thr*(FuelFlow/60)))#
m.Equation(D==0.5*Ro*(V**2)*Cd*S)
m.Equation(FuelFlow==0.75882*(1+(V/2938.5)))
m.Equation(x*final<=1500)
m.Equation(T==T0-h)

# Objective Function
m.Obj(-mass*tf*final)#
m.options.IMODE = 6
m.options.NODES = 3
m.options.MV_TYPE = 1
m.options.SOLVER = 3
#m.open_folder() # to search for infeasibilities
m.solve()


tm = tm * tf.value[0]

print('Final Time: ' + str(tf.value[-1]))
print('Final Speed: ' + str(V.value[-1]))
print('Final X: ' + str(x.value[-1]))

plt.figure(1)
plt.subplot(2,1,1)
plt.plot(tm,Tcontr,'r-',LineWidth=2,label=r'$Tcontr$')
#plt.plot(m.time,x.value,'r--',LineWidth=2,label=r'$x$')
plt.legend(loc='best')
plt.subplot(2,1,2)
plt.plot(tm,x.value,'r--',LineWidth=2,label=r'$x$')
#plt.plot(tm,mass.value,'g:',LineWidth=2,label=r'$mass$')
#plt.plot(tm,D.value,'g:',LineWidth=2,label=r'$D$')
#plt.plot(tm,V.value,'b-',LineWidth=2,label=r'$V$')
plt.legend(loc='best')
plt.xlabel('Time')
plt.ylabel('Value')
plt.show()

Advertisement

Answer

The lower bound on Tcontr is preventing the x value from going above 1310. Setting the lower value to 0.1 improves the final value of x to 2469.76 if the constraint m.Equation(x*final<=1500) is removed.

Tcontr = m.MV(value=0.2,lb=0.1,ub=1)

results

Constraints are often the culprit when the solution is not optimal or there is an infeasible solution. One way to detect problematic constraints is to create plots to verify that the solution is not artificially bound.

Another way to formulate the constraint is to use a combination of a hard constraint m.Equation((x-1500)*final==0) and a soft constraint to guide the solution as m.Minimize(final*(x-1500)**2). It is important to pose the hard constraint correctly. A constraint such as m.Equation(x*final==1500) means that it is infeasible with x*0==1500 when final is not equal to 1. The inequality version is also better posed as m.Equation((x-1500)*final<=0) but the original form also works because x*0<1500.

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,1,nt)
m.time = tm

# Variables
Ro = m.Const(value=1.1)
g = m.Const(value=9.80665)
T = m.Var()
T0 = m.Const(value=273)
S = m.Const(value=122.6)
Cd = m.Const(value=0.1)
FuelFlow = m.Var()
D = m.Var()
Thrmax = value=200000
Thr = m.Var()
V = m.Var()
nu = m.Var(value=0)
nuu = 0
x = m.Var(value=0)
h = m.Var(value=1000)
mass = m.Var(value=60000)
    
p = np.zeros(nt)
p[-1] = 1.0
final = m.Param(value=p)

m.options.MAX_ITER=1000 # iteration max number

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

# Parameters
Tcontr = m.MV(value=0.2,lb=0.1,ub=1)
Tcontr.STATUS = 1
Tcontr.DCOST = 0 #1e-2

# Equations
m.Equation(x.dt()==tf*(V*(math.cos(nuu))))#
m.Equation(Thr==Tcontr*Thrmax)
m.Equation(V.dt()==tf*((Thr-D)/mass))#
m.Equation(mass.dt()==tf*(-Thr*(FuelFlow/60)))#
m.Equation(D==0.5*Ro*(V**2)*Cd*S)
m.Equation(FuelFlow==0.75882*(1+(V/2938.5)))
m.Equation((x-1500)*final==0)
m.Equation(T==T0-h)

# Objective Function
m.Minimize(final*(x-1500)**2)
m.Maximize(mass*tf*final)#
m.options.IMODE = 6
m.options.NODES = 3
m.options.MV_TYPE = 1
m.options.SOLVER = 3
#m.open_folder() # to search for infeasibilities
m.solve()


tm = tm * tf.value[0]

print('Final Time: ' + str(tf.value[-1]))
print('Final Speed: ' + str(V.value[-1]))
print('Final X: ' + str(x.value[-1]))

plt.figure(1)
plt.subplot(2,1,1)
plt.plot(tm,Tcontr,'r-',lw=2,label=r'$Tcontr$')
#plt.plot(m.time,x.value,'r--',lw=2,label=r'$x$')
plt.legend(loc='best')
plt.subplot(2,1,2)
plt.plot(tm,x.value,'r--',lw=2,label=r'$x$')
#plt.plot(tm,mass.value,'g:',lw=2,label=r'$mass$')
#plt.plot(tm,D.value,'g:',lw=2,label=r'$D$')
#plt.plot(tm,V.value,'b-',lw=2,label=r'$V$')
plt.legend(loc='best')
plt.xlabel('Time')
plt.ylabel('Value')
plt.show()
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement