2

I tried Example 1b of https://apmonitor.com/do/index.php/Main/DynamicOptimizationBenchmarks.

I construct two different form of the same terminal conditions as follows:

import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO

m = GEKKO()
nt = 101
m.time = np.linspace(0,2,nt)

# Variables
x1 = m.Var(value=1)
x2 = m.Var(value=0)
u = m.Var(value=-0.48)
p = np.zeros(nt)
p[-1] = 1.0
final = m.Param(value=p)

# Equations
m.Equation(x1.dt()==u)
m.Equation(x2.dt()==x1**2 + u**2)

# terminal conditions
m.Equation(final*(x1-1)==0) # 1st form
# m.fix_final(x1,val=1) # 2nd form

m.Obj(x2*final)
m.options.IMODE = 6
m.solve()

plt.figure(1)
plt.plot(m.time,x1.value,'k:',linewidth=2,label=r'$x_1$')
plt.plot(m.time,x2.value,'b-',linewidth=2,label=r'$x_2$')
plt.plot(m.time,u.value,'r--',linewidth=2,label=r'$u$')
plt.legend(loc='best')plt.xlabel('Time')plt.ylabel('Value')plt.show()

They behave differently and achieved different solutions as follows.

1st form m.Equation(final*(x1-1)==0):

enter image description here

2nd form m.fix_final(x1,val=1):

enter image description here

I prefer to use fix_final to define such a terminal constraint like x(tf)=0. But it seems to make the problem unsolvable. Like the 13rd problem in https://apmonitor.com/wiki/index.php/Main/GekkoPythonOptimization.

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt  

m = GEKKO() # initialize GEKKO
nt = 501
m.time = np.linspace(0,1,nt)

x1 = m.Var(value=np.pi/2.0)
x2 = m.Var(value=4.0)
x3 = m.Var(value=0.0)
p = np.zeros(nt) # final time = 1
p[-1] = 1.0
final = m.Param(value=p)
tf = m.FV(value=1.0,lb=0.1,ub=100.0)
tf.STATUS = 1

u = m.MV(value=0,lb=-2,ub=2)
u.STATUS = 1
m.Equation(x1.dt()==u*tf)
m.Equation(x2.dt()==m.cos(x1)*tf)
m.Equation(x3.dt()==m.sin(x1)*tf)

# terminal constraints
m.Equation(x2*final<=0) # get solution
m.Equation(x3*final<=0)
# or
# m.fix(x2, pos=len(m.time)-1,val=0) # solution not found
# m.fix(x3, pos=len(m.time)-1,val=0)
# or
# m.fix_final(x2,val=0) # solution not found
# m.fix_final(x3,val=0)

m.Obj(tf)
m.options.IMODE = 6
m.solve()

plt.figure(1)
plt.plot(tm,x1.value,'k-',label=r'$x_1$')
plt.plot(tm,x2.value,'b-',label=r'$x_2$')
plt.plot(tm,x3.value,'g--',label=r'$x_3$')
plt.plot(tm,u.value,'r--',label=r'$u$')plt.legend(loc='best')plt.xlabel('Time')plt.show()
abmin
  • 133
  • 2
  • 12

1 Answers1

0

When you fix the final condition of a variable it also sets the derivative to zero. This is also discussed as an issue on GitHub. There are workarounds for this issue such as soft terminal constraints (see Trajectory Planner with GEKKO is not able to handle given goal velocities) or hard terminal constraints in the way that you showed.

John Hedengren
  • 12,068
  • 1
  • 21
  • 25