In [13]:
%matplotlib inline

import numpy as np
import casadi as ca
import matplotlib.pyplot as plt

from operator import itemgetter

In [16]:
nk = 100    # Control discretization
tf = 10.0  # End time

# Declare variables (use scalar graph)
u  = ca.SX.sym( 'u' )     # control
x  = ca.SX.sym( 'x', 3 )  # states

This notebook will try to solve third order system in form of: $$ \dddot x + \ddot x + \dot x + x - u = 0 $$ Or alternatively in the 1st order form: $$\begin{cases} \dot x_0 = -x_0 - x_1 - x_2 + u \\ \dot x_1 = x_0 \\ \dot x_2 = x_1 \end{cases} $$ Subject to: $$ \min \int_{0}^{T}x_2^2 + u^2 \,dx $$


In [17]:
# ODE right hand side and quadratures
xdot = ca.vertcat( [-x[0] - x[1] - x[2] + u, x[0], x[1]] )
qdot = x[1]*x[1] + x[2]*x[2] + u*u

# DAE residual function
dae = ca.SXFunction("dae", ca.daeIn(x=x, p=u), ca.daeOut(ode=xdot, quad=qdot))

# Create an integrator
integrator = ca.Integrator("integrator", "cvodes", dae, {"tf":tf/nk})

# All controls (use matrix graph)
x = ca.MX.sym("x",nk) # nk-by-1 symbolic variable
U = ca.vertsplit(x) # cheaper than x[0], x[1], ...

# The initial state (x_0=0, x_1=1)
X  = ca.MX([0,1, 1])

In [18]:
# Objective function
f = 0

# Build a graph of integrator calls
for k in range(nk):
  X,QF = itemgetter('xf','qf')(integrator( {'x0':X, 'p':U[k] } ) )
  f += QF

# Terminal constraints: x_0(T)=x_1(T)=0
g = X

# Allocate an NLP solver
opts = {'linear_solver': 'ma27'}
nlp = ca.MXFunction("nlp", ca.nlpIn(x=x), ca.nlpOut(f=f,g=g))
solver = ca.NlpSolver("solver", "ipopt", nlp, opts)

# Solve the problem
sol = solver({"lbx" : -0.75,
              "ubx" : 1,
              "x0" : 0,
              "lbg" : 0,
              "ubg" : 0})


This is Ipopt version 3.11.4, running with linear solver ma27.

Number of nonzeros in equality constraint Jacobian...:      300
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:     5050

Total number of variables............................:      100
                     variables with only lower bounds:        0
                variables with lower and upper bounds:      100
                     variables with only upper bounds:        0
Total number of equality constraints.................:        3
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   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  2.5746930e+01 1.24e+00 8.37e-01  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  1.0687474e+01 3.74e-05 6.10e-01  -1.0 6.34e-01    -  5.78e-01 1.00e+00f  1
   2  9.9420668e+00 5.19e-06 9.38e-02  -1.7 1.24e-01    -  8.63e-01 1.00e+00f  1
   3  9.1737664e+00 4.61e-06 2.10e-02  -2.5 2.22e-01    -  8.74e-01 1.00e+00f  1
   4  8.9654181e+00 5.65e-06 1.83e-05  -2.5 1.41e-01    -  1.00e+00 1.00e+00f  1
   5  8.8993196e+00 8.79e-06 2.03e-03  -3.8 8.16e-02    -  9.46e-01 1.00e+00f  1
   6  8.8826049e+00 2.44e-06 2.56e-06  -3.8 3.69e-02    -  1.00e+00 1.00e+00f  1
   7  8.8772946e+00 4.53e-08 4.18e-04  -5.7 2.31e-02    -  9.47e-01 1.00e+00f  1
   8  8.8764249e+00 5.71e-08 1.94e-07  -5.7 1.19e-02    -  1.00e+00 1.00e+00f  1
   9  8.8763247e+00 1.78e-08 5.02e-07  -5.7 5.25e-03    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  8.8762906e+00 4.67e-09 9.35e-08  -8.6 1.44e-03    -  1.00e+00 1.00e+00h  1
  11  8.8762900e+00 1.40e-10 4.83e-10  -8.6 9.53e-05    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 11

                                   (scaled)                 (unscaled)
Objective...............:   8.8762900129608919e+00    8.8762900129608919e+00
Dual infeasibility......:   4.8340516312084247e-10    4.8340516312084247e-10
Constraint violation....:   1.3980010001366162e-10    1.3980010001366162e-10
Complementarity.........:   4.5201612662580193e-09    4.5201612662580193e-09
Overall NLP error.......:   4.5201612662580193e-09    4.5201612662580193e-09


Number of objective function evaluations             = 12
Number of objective gradient evaluations             = 12
Number of equality constraint evaluations            = 12
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 12
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 11
Total CPU secs in IPOPT (w/o function evaluations)   =      0.200
Total CPU secs in NLP function evaluations           =     13.000

EXIT: Optimal Solution Found.
                   proc           wall      num           mean             mean
                   time           time     evals       proc time        wall time
       eval_f     0.584 [s]      0.590 [s]    12      48.65 [ms]       49.20 [ms]
  eval_grad_f     1.562 [s]      1.578 [s]    13     120.17 [ms]      121.35 [ms]
       eval_g     0.651 [s]      0.663 [s]    12      54.27 [ms]       55.28 [ms]
   eval_jac_g     1.559 [s]      1.571 [s]    14     111.35 [ms]      112.20 [ms]
       eval_h    14.257 [s]     14.335 [s]    12    1188.08 [ms]     1194.60 [ms]
 all previous    18.613 [s]     18.737 [s]
        ipopt     0.060 [s]      0.061 [s]
    main loop    18.674 [s]     18.799 [s]

In [21]:
# Retrieve the solution
u_opt = np.array(sol["x"])

# Time grid
tgrid_x = np.linspace(0,10,nk+1)
tgrid_u = np.linspace(0,10,nk)

# Plot the results
plt.figure(1)
plt.clf()
plt.plot(tgrid_u,u_opt,'b-')
plt.title("third order system optimisation - single shooting")
plt.xlabel('time')
plt.legend(['u trajectory'])
plt.grid()



In [20]:
sol


Out[20]:
{'f': DMatrix(8.87629),
 'g': DMatrix([1.39746e-10, 1.09567e-10, -1.398e-10]),
 'lam_g': DMatrix([0.110401, 0.0226479, -0.131415]),
 'lam_p': DMatrix([]),
 'lam_x': DMatrix([-0.211563, -0.149845, -0.0893594, -0.0307915, -1.83113e-08, -4.56424e-09, -1.67147e-09, -5.72598e-11, 1.3693e-09, 3.11134e-09, 5.87477e-09, 1.17424e-08, 3.43192e-08, 0.00508942, 0.0198351, 0.0303988, 0.0369898, 0.03985, 0.0392519, 0.0354936, 0.0288924, 0.019779, 0.00849164, 1.12069e-07, 2.45207e-08, 1.27115e-08, 8.01601e-09, 5.49163e-09, 3.9009e-09, 2.78811e-09, 1.94607e-09, 1.26688e-09, 6.88711e-10, 1.73644e-10, -3.0261e-10, -7.55789e-10, -1.19523e-09, -1.62547e-09, -2.04678e-09, -2.45501e-09, -2.84231e-09, -3.19764e-09, -3.50827e-09, -3.76135e-09, -3.94615e-09, -4.05614e-09, -4.09002e-09, -4.05195e-09, -3.95044e-09, -3.79698e-09, -3.60426e-09, -3.38448e-09, -3.14846e-09, -2.90511e-09, -2.66138e-09, -2.42227e-09, -2.19131e-09, -1.97082e-09, -1.76221e-09, -1.56626e-09, -1.38336e-09, -1.21362e-09, -1.05701e-09, -9.13414e-10, -7.8268e-10, -6.64656e-10, -5.59179e-10, -4.66073e-10, -3.8515e-10, -3.16182e-10, -2.58898e-10, -2.12961e-10, -1.78005e-10, -1.53582e-10, -1.39183e-10, -1.34244e-10, -1.38166e-10, -1.50302e-10, -1.69981e-10, -1.96514e-10, -2.29216e-10, -2.67398e-10, -3.10399e-10, -3.57563e-10, -4.08255e-10, -4.61868e-10, -5.17816e-10, -5.75535e-10, -6.34481e-10, -6.94119e-10, -7.53929e-10, -8.13406e-10, -8.72036e-10, -9.2931e-10, -9.84707e-10, -1.0377e-09, -1.08774e-09, -1.13429e-09, -1.17677e-09, -1.21461e-09]),
 'x': DMatrix([-0.75, -0.75, -0.75, -0.75, -0.623784, -0.358954, -0.11166, 0.116255, 0.323424, 0.508838, 0.671879, 0.812237, 0.930014, 0.999999, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.976843, 0.903746, 0.824793, 0.741553, 0.655523, 0.5681, 0.480584, 0.394159, 0.309893, 0.228732, 0.151502, 0.0789003, 0.0114856, -0.0502627, -0.106006, -0.155535, -0.198708, -0.2355, -0.265963, -0.290241, -0.308539, -0.321124, -0.32832, -0.330494, -0.32805, -0.321408, -0.311015, -0.297332, -0.280816, -0.261924, -0.241105, -0.218798, -0.195416, -0.171355, -0.146982, -0.12264, -0.0986389, -0.0752588, -0.0527476, -0.0313196, -0.0111582, 0.00758744, 0.024796, 0.0403766, 0.0542661, 0.0664266, 0.0768451, 0.0855304, 0.0925123, 0.0978337, 0.101555, 0.103751, 0.104504, 0.103906, 0.102055, 0.099056, 0.0950151, 0.0900401, 0.08424, 0.0777206, 0.0705886, 0.062947, 0.054896, 0.0465324, 0.0379491, 0.0292351, 0.0204765, 0.0117557, 0.00315031, -0.00526355, -0.013413, -0.0212269, -0.028636, -0.0355726, -0.0419699, -0.0477612, -0.0528809])}

In [ ]: