The goal is to minimize time to complete the lap with Energy constraint this is why my objective is the integral of the speed over distance, but I can’t seem to figure out how to derive and integrate over distance and not time(dt).
How to do space discretization in Gekko?
257 Views Asked by trimat At
2
There are 2 best solutions below
1

If you don't have time in your problem then you can specify m.time as the distance points for integration. However, your differential equations are based on time such as ds/dt = v
in 1D. You need to keep time as the variable because that is defined for each of the differentials.
One way to minimize the lap time is to create a new tlap=FV()
and then scale all of the differentials by that new adjustable value.
tlap=FV()
m.Equation(s.dt()==v*tlap)
With this tf
value, you can minimize final time to reach a final destination.
m.Minimize(tf*final)
This is similar to the rocket launch problem that minimizes final time and control action.
import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
# create GEKKO model
m = GEKKO()
# scale 0-1 time with tf
m.time = np.linspace(0,1,101)
# options
m.options.NODES = 6
m.options.SOLVER = 3
m.options.IMODE = 6
m.options.MAX_ITER = 500
m.options.MV_TYPE = 0
m.options.DIAGLEVEL = 0
# final time
tf = m.FV(value=1.0,lb=0.1,ub=100)
tf.STATUS = 1
# force
u = m.MV(value=0,lb=-1.1,ub=1.1)
u.STATUS = 1
u.DCOST = 1e-5
# variables
s = m.Var(value=0)
v = m.Var(value=0,lb=0,ub=1.7)
mass = m.Var(value=1,lb=0.2)
# differential equations scaled by tf
m.Equation(s.dt()==tf*v)
m.Equation(mass*v.dt()==tf*(u-0.2*v**2))
m.Equation(mass.dt()==tf*(-0.01*u**2))
# specify endpoint conditions
m.fix_final(s, 10.0)
m.fix_final(v, 0.0)
# minimize final time
m.Minimize(tf)
# Optimize launch
m.solve()
print('Optimal Solution (final time): ' + str(tf.value[0]))
# scaled time
ts = m.time * tf.value[0]
# plot results
plt.figure(1)
plt.subplot(4,1,1)
plt.plot(ts,s.value,'r-',linewidth=2)
plt.ylabel('Position')
plt.legend(['s (Position)'])
plt.subplot(4,1,2)
plt.plot(ts,v.value,'b-',linewidth=2)
plt.ylabel('Velocity')
plt.legend(['v (Velocity)'])
plt.subplot(4,1,3)
plt.plot(ts,mass.value,'k-',linewidth=2)
plt.ylabel('Mass')
plt.legend(['m (Mass)'])
plt.subplot(4,1,4)
plt.plot(ts,u.value,'g-',linewidth=2)
plt.ylabel('Force')
plt.legend(['u (Force)'])
plt.xlabel('Time')
plt.show()
There are a few problems that I fixed with your current solution:
w
andst
are not usedSTATUS
forp_s
ands_s
should be On (1) to be calculated by the solverm.options.TIME_SHIFT=1
) or multiple (m.options.TIME_SHIFT=10
) for eachm.solve()
command.APOPT
solver for a successful solution.With this script, I get a successful solution but I haven't investigated the objective function to see if it is giving a reasonable answer.
You may want to create plots to make sure that the equations and solver are giving a correct solution. Here is an animation and source code that shows how to set up a model predictive controller with a finite horizon and that advances in time (or space) for each solve command.
The finite horizon approach is used commonly in industrial control to ensure that the optimizer can finish within the required cycle time and balance that with the length of the horizon to "see" future constraints and opportunities for energy or production optimization.