Free initial and final times

In this tutorial, we consider an optimal control problem with the initial and final times as free variables, that is there are parts of the variable to be optimized. The required packages for the tutorial are:

using OptimalControl
using NLPModelsIpopt
using Plots

The problem we consider is the following:

@def ocp begin

    v = (t0, tf) ∈ R², variable # the initial and final times are free variables

    t ∈ [t0, tf], time
    x ∈ R², state
    u ∈ R, control

    -1 ≤ u(t) ≤ 1

    x(t0) == [0, 0]
    x(tf) == [1, 0]

    0.05 ≤ t0 ≤ 10
    0.05 ≤ tf ≤ 10
    0.01 ≤ tf - t0 ≤ Inf

    ẋ(t) == [x₂(t), u(t)]

    t0 → max

end

We now solve the problem using a direct method.

sol = solve(ocp; grid_size=100)
▫ This is OptimalControl version v1.1.6 running with: direct, adnlp, ipopt.

▫ The optimal control problem is solved with CTDirect version v0.17.4.

   ┌─ The NLP is modelled with ADNLPModels and solved with NLPModelsIpopt.
   │
   ├─ Number of time steps⋅: 100
   └─ Discretisation scheme: midpoint

▫ This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.1.

Number of nonzeros in equality constraint Jacobian...:     1104
Number of nonzeros in inequality constraint Jacobian.:        2
Number of nonzeros in Lagrangian Hessian.............:      402

Total number of variables............................:      304
                     variables with only lower bounds:        0
                variables with lower and upper bounds:      102
                     variables with only upper bounds:        0
Total number of equality constraints.................:      204
Total number of inequality constraints...............:        1
        inequality constraints with only lower bounds:        1
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  1.0000000e-01 9.00e-01 5.00e-01   0.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  5.0499990e-02 8.82e-01 6.09e+02  -6.0 4.98e+00    -  1.98e-03 2.00e-02h  1
   2  1.0404841e-01 8.82e-01 5.56e+02   2.0 8.62e+02    -  1.18e-03 5.49e-04h  2
   3  1.4249759e-01 8.81e-01 4.79e+02   2.0 7.04e+02    -  3.71e-03 4.41e-04h  2
   4  2.1711471e-01 8.80e-01 6.66e+02   2.0 1.69e+02    -  1.32e-01 1.04e-03h  3
   5  3.4950960e-01 8.76e-01 1.85e+03   2.0 5.04e+01    -  1.03e-02 5.01e-03h  3
   6  3.5415551e-01 8.76e-01 2.13e+03   2.6 2.11e+02    -  1.37e-02 5.47e-05h  7
   7  3.4480150e-01 8.76e-01 2.40e+03   2.2 8.44e+01    -  3.86e-03 3.24e-04h  6
   8  3.2656066e-01 8.75e-01 2.39e+03   1.1 1.36e+02   4.0 3.53e-03 2.69e-04h  5
   9  4.8729676e-01 8.73e-01 3.40e+05   2.0 1.20e+02   4.4 7.04e-03 2.69e-03f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  8.2352816e-01 8.72e-01 3.05e+05   3.0 1.04e+03    -  2.99e-04 1.61e-03f  1
  11  9.7605472e-01 8.71e-01 3.38e+05   3.0 1.68e+03    -  2.63e-04 7.98e-04f  1
  12  1.0054530e+00 8.71e-01 3.38e+05   3.0 6.91e+02    -  1.13e-03 1.62e-04h  1
  13  1.0485140e+00 8.71e-01 3.38e+05   3.0 4.38e+03    -  2.87e-04 2.52e-04h  1
  14  1.2784861e+00 8.69e-01 3.37e+05   3.0 9.04e+02    -  8.27e-04 1.38e-03f  1
  15  1.4055028e+00 8.69e-01 3.37e+05   3.0 1.17e+03    -  8.52e-04 8.43e-04h  1
  16  1.5065746e+00 8.68e-01 3.37e+05   3.0 1.17e+03    -  9.80e-04 7.22e-04h  1
  17  1.5921300e+00 8.67e-01 3.36e+05   3.0 1.15e+03    -  1.09e-03 6.56e-04h  1
  18  1.6707461e+00 8.67e-01 3.35e+05   3.0 1.04e+03    -  1.29e-03 6.45e-04h  1
  19  1.7508952e+00 8.66e-01 3.35e+05   3.0 8.11e+02    -  1.49e-03 7.08e-04h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20  1.8552431e+00 8.65e-01 3.33e+05   3.0 7.83e+02    -  1.59e-03 9.97e-04h  1
  21  1.9590742e+00 8.64e-01 3.31e+05   3.0 5.79e+02    -  2.14e-03 1.08e-03h  1
  22  2.0816525e+00 8.63e-01 3.28e+05   3.0 4.68e+02    -  2.73e-03 1.42e-03h  1
  23  2.2254455e+00 8.62e-01 3.24e+05   3.0 3.38e+02    -  3.71e-03 1.88e-03h  1
  24  2.3959758e+00 8.59e-01 3.18e+05   3.0 2.45e+02    -  5.52e-03 2.60e-03h  1
  25  2.6082820e+00 8.56e-01 3.12e+05   3.0 1.57e+02    -  9.03e-03 3.97e-03h  1
  26  2.8918007e+00 8.50e-01 3.07e+05   3.0 7.39e+01    -  2.37e-02 7.03e-03h  1
  27  3.5161394e+00 8.25e-01 3.02e+05   3.0 2.63e+01    -  1.00e+00 2.98e-02h  1
  28  3.7122772e+00 7.88e-01 3.05e+05   2.7 3.73e+00    -  4.05e-01 4.47e-02F  1
  29  3.5543669e+00 7.63e-01 1.42e+05   3.0 1.16e+01    -  3.44e-04 3.09e-02h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30  3.5352460e+00 7.32e-01 6.42e+04   3.0 9.76e+00    -  3.48e-01 4.16e-02f  1
  31  3.6243659e+00 4.54e-01 6.18e+05   3.0 4.55e+00    -  2.20e-01 3.79e-01f  1
  32  3.3466591e+00 1.39e-01 3.69e+05  -3.1 1.34e+00    -  3.00e-01 6.95e-01h  1
  33  3.1699893e+00 3.01e-04 2.49e+04   1.5 3.50e-01   4.9 1.00e+00 1.00e+00f  1
  34  3.1651535e+00 2.43e-07 2.31e+02   0.7 9.74e-03   4.4 1.00e+00 1.00e+00f  1
  35  4.3398281e+00 2.32e-04 1.31e+01   0.2 1.31e+00    -  9.93e-01 1.00e+00f  1
  36  6.8831800e+00 1.46e-03 8.21e-01  -0.4 2.75e+00    -  9.92e-01 1.00e+00f  1
  37  7.1092224e+00 2.15e-04 7.90e-02  -6.4 2.65e-01    -  9.53e-01 8.54e-01f  1
  38  7.5792654e+00 1.92e-03 8.16e-02  -2.7 4.70e-01    -  9.99e-01 1.00e+00f  1
  39  7.9125868e+00 2.09e-03 4.20e-02  -3.2 6.31e-01    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  40  7.9766429e+00 4.59e-04 3.95e-03  -3.7 7.22e-01    -  1.00e+00 1.00e+00h  1
  41  7.9932350e+00 9.79e-05 1.93e-04  -4.2 5.95e-01    -  9.52e-01 1.00e+00h  1
  42  7.9996775e+00 3.65e-05 2.85e-05  -5.6 5.72e-01    -  8.66e-01 1.00e+00h  1
  43  7.9999898e+00 1.59e-07 6.35e-08  -7.0 5.13e-02    -  1.00e+00 1.00e+00h  1
  44  8.0000001e+00 7.25e-11 7.52e-11 -11.0 7.11e-04    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 44

                                   (scaled)                 (unscaled)
Objective...............:  -8.0000001087846737e+00    8.0000001087846737e+00
Dual infeasibility......:   7.5173978350256311e-11    7.5173978350256311e-11
Constraint violation....:   7.2495676128880859e-11    7.2495676128880859e-11
Variable bound violation:   9.9990002055960758e-08    9.9990002055960758e-08
Complementarity.........:   4.1892313538509210e-11    4.1892313538509210e-11
Overall NLP error.......:   7.5173978350256311e-11    7.5173978350256311e-11


Number of objective function evaluations             = 75
Number of objective gradient evaluations             = 45
Number of equality constraint evaluations            = 75
Number of inequality constraint evaluations          = 75
Number of equality constraint Jacobian evaluations   = 45
Number of inequality constraint Jacobian evaluations = 45
Number of Lagrangian Hessian evaluations             = 44
Total seconds in IPOPT                               = 3.172

EXIT: Optimal Solution Found.
• Solver:
  ✓ Successful  : true
  │  Status     : first_order
  │  Message    : Ipopt/generic
  │  Iterations : 44
  │  Objective  : 8.000000108784674
  └─ Constraints violation : 7.249567612888086e-11

• Variable: v = (t0, tf) = [8.000000108784674, 10.000000099990002]
  │  Var dual (lb) : [-4.129997128438849e-12, -3.3227298185429468e-12]
  └─ Var dual (ub) : [-1.7008970342252067e-11, -0.999999999990444]

• Boundary duals: [-0.9999999955938075, -1.0022059561717027, 0.9999999955938075, -0.9977940261700856, 5.267600719122683e-12]

And plot the solution.

plot(sol)
Example block output