Optimal Control Problems
Table of Contents
- ocp. A object of class ode is a structure that contains a all information of a ordinary differential equation. This have a dynamic equation, initial condition, time span, etc. $$ \min_{u \in \mathcal{U}} \bigg[ \psi(x(T)) + \int_0^T L(t,x(t),u(t)) dt \bigg] \\ \text{subject to:} \\ \dot{x} = f(t,x,u)$$
Methods
Class:: ocp
A object of class ode is a structure that contains a all information of a ordinary differential equation. This have a dynamic equation, initial condition, time span, etc. $$ \min_{u \in \mathcal{U}} \bigg[ \psi(x(T)) + \int_0^T L(t,x(t),u(t)) dt \bigg] \\ \text{subject to:} \\ \dot{x} = f(t,x,u)$$
Method::ocp of Class::ocp
Syntax
iocp = ocp(idynamics,PathCostFcn,FinalCostFcn)
Interface
INPUTS | ||
---|---|---|
Name | Class | Description |
idynamics | {ode,pde1d,pde2d,pdefem} | This is a object { |
PathCostFcn | casadi function | it is a casadi function that $ L:\mathbb{R}^+ \times \mathcal{X} \times \mathcal{U} \rightarrow \mathbb{R}$ |
FinalCostFcn | casadi function | it is a casadi function that $ \psi:\mathcal{X} \rightarrow \mathbb{R}$ |
OUTPUTS | ||
---|---|---|
Name | Class | Description |
iocp | ode |
ocp object that contain all information of optimal control problem. |
Example
clear all;close all
import casadi.*
Xs = SX.sym('x',2,1);
Us = SX.sym('u',2,1);
ts = SX.sym('t');
%
A = [ -2 +1;
+1 -2];
B = [1 0;
0 1];
EvolutionFcn = Function('f',{ts,Xs,Us},{ A*Xs + B*Us });
%
tspan = linspace(0,2,10);
iode = ode(EvolutionFcn,Xs,Us,tspan);
SetIntegrator(iode,'RK4')
iode.InitialCondition = [1;2];
epsilon = 1e4;
PathCost = Function('L' ,{ts,Xs,Us},{ Us'*Us });
FinalCost = Function('Psi',{Xs} ,{ epsilon*(Xs'*Xs) });
iocp = ocp(iode,PathCost,FinalCost)
iocp =
ocp with properties:
DynamicSystem: [1x1 ode]
CostFcn: [1x1 CostFcn]
VariableTime: 0
constraints: [1x1 constraints]
TargetState: []
Hamiltonian: [0x0 casadi.Function]
AdjointStruct: [1x1 AdjointStruct]
ControlGradient: [1x1 casadi.Function]
Method::ArmijoGradient of Class::ocp
Syntax
[uopt,xopt] = ArmijoGradient(iocp,uguess)
[uopt,xopt] = ArmijoGradient(iocp,uguess,'MaxIter',MaxIter)
Interface
Example
import casadi.*
A = [-2 1;
1 -2];
B = [1;0];
%
tspan = linspace(0,1,7);
idyn = linearode(A,B,tspan);
idyn.InitialCondition = [1;2];
ts = idyn.ts;
Xs = idyn.State.sym;
Us = idyn.Control.sym;
%
epsilon = 1e4;
PathCost = Function('L' ,{ts,Xs,Us},{ Us'*Us });
FinalCost = Function('Psi',{Xs} ,{ epsilon*(Xs'*Xs) });
iocp = ocp(idyn,PathCost,FinalCost);
uguess = tspan;
[uopt,xopt] = ArmijoGradient(iocp,uguess);
===================================================================================================
| iter | norm(dJ/du) | abs(Jc-Ja)/Jc | LengthStep | J | Distance2Target |
===================================================================================================
| 008 | 2.017e+03 | 1.780e-01 | 2.50e-04 | 1.13750e+03 | NaN |
| 012 | 1.651e+03 | 2.549e-01 | 2.50e-04 | 6.18609e+02 | NaN |
| 016 | 2.011e+03 | 1.540e-01 | 1.00e-03 | 4.12580e+02 | NaN |
| 020 | 3.068e+03 | 4.962e-02 | 1.00e-03 | 3.26251e+02 | NaN |
| 024 | 8.769e+02 | 8.368e-02 | 1.00e-03 | 2.07381e+02 | NaN |
| 028 | 8.176e+02 | 1.259e-01 | 1.00e-03 | 1.28015e+02 | NaN |
| 032 | 1.172e+03 | 7.778e-02 | 1.00e-03 | 1.02105e+02 | NaN |
| 036 | 3.997e+02 | 1.316e-01 | 2.50e-04 | 8.07760e+01 | NaN |
| 040 | 4.187e+02 | 2.306e-02 | 1.00e-03 | 6.74948e+01 | NaN |
===================================================================================================
| iter | norm(dJ/du) | abs(Jc-Ja)/Jc | LengthStep | J | Distance2Target |
===================================================================================================
| 048 | 1.864e+02 | 3.809e-02 | 2.50e-04 | 5.13924e+01 | NaN |
| 052 | 1.509e+02 | 3.159e-02 | 2.50e-04 | 4.71590e+01 | NaN |
| 056 | 1.803e+02 | 1.423e-02 | 1.00e-03 | 4.55183e+01 | NaN |
| 060 | 8.734e+01 | 8.959e-03 | 1.00e-03 | 4.47686e+01 | NaN |
| 064 | 7.475e+01 | 1.117e-02 | 2.50e-04 | 4.39292e+01 | NaN |
| 068 | 5.289e+01 | 3.286e-04 | 2.50e-04 | 4.35600e+01 | NaN |
| 072 | 9.023e+01 | 2.091e-03 | 1.00e-03 | 4.32197e+01 | NaN |
| 076 | 3.367e+01 | 1.155e-03 | 1.00e-03 | 4.31266e+01 | NaN |
| 080 | 2.741e+01 | 3.512e-05 | 2.50e-04 | 4.30802e+01 | NaN |
===================================================================================================
| iter | norm(dJ/du) | abs(Jc-Ja)/Jc | LengthStep | J | Distance2Target |
===================================================================================================
Mininum Length Step have been achieve !!
uopt
uopt =
-7.9370 -8.1077 -7.8352 -6.7968 -4.4915 -0.1483 7.4126
xopt
xopt =
1.0000 -0.0772 -0.9118 -1.4622 -1.6301 -1.2395 -0.0019
2.0000 1.4904 1.0038 0.5701 0.2238 0.0129 0.0094
Method::IpoptSolver of Class::ocp
Syntax
[uopt,xopt] = IpoptSolver(iocp,uguess)
[uopt,xopt] = IpoptSolver(iocp,uguess,'Integrator',Integrator)
Interface
Example
import casadi.*
A = [-2 1;
1 -2];
B = [1;0];
%
tspan = linspace(0,1,7);
idyn = linearode(A,B,tspan);
idyn.InitialCondition = [1;2];
ts = idyn.ts;
Xs = idyn.State.sym;
Us = idyn.Control.sym;
%
epsilon = 1e4;
PathCost = Function('L' ,{ts,Xs,Us},{ Us'*Us });
FinalCost = Function('Psi',{Xs} ,{ epsilon*(Xs'*Xs) });
iocp = ocp(idyn,PathCost,FinalCost);
uguess = tspan;
[uopt,xopt] = IpoptSolver(iocp,uguess);
This is Ipopt version 3.12.3, running with linear solver mumps.
NOTE: Other linear solvers might be more efficient (see Ipopt documentation).
Number of nonzeros in equality constraint Jacobian...: 62
Number of nonzeros in inequality constraint Jacobian.: 0
Number of nonzeros in Lagrangian Hessian.............: 9
Total number of variables............................: 21
variables with only lower bounds: 0
variables with lower and upper bounds: 0
variables with only upper bounds: 0
Total number of equality constraints.................: 14
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.0000338e+04 1.00e+00 1.33e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 2.1420978e+01 3.33e-16 1.66e-14 -1.0 5.90e+00 - 1.00e+00 1.00e+00f 1
Number of Iterations....: 1
(scaled) (unscaled)
Objective...............: 1.0710489227567338e-01 2.1420978455134676e+01
Dual infeasibility......: 1.6577017536434369e-14 3.3154035072868737e-12
Constraint violation....: 3.3306690738754696e-16 3.3306690738754696e-16
Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00
Overall NLP error.......: 1.6577017536434369e-14 3.3154035072868737e-12
Number of objective function evaluations = 2
Number of objective gradient evaluations = 2
Number of equality constraint evaluations = 2
Number of inequality constraint evaluations = 0
Number of equality constraint Jacobian evaluations = 2
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations = 1
Total CPU secs in IPOPT (w/o function evaluations) = 0.006
Total CPU secs in NLP function evaluations = 0.001
EXIT: Optimal Solution Found.
t_proc [s] t_wall [s] n_eval
nlp_f 3.3e-05 3.4e-05 2
nlp_g 5.8e-05 5.8e-05 2
nlp_grad_f 0.000101 0.0001 3
nlp_hess_l 0.00807 6.2e-05 1
nlp_jac_g 0.000236 0.00024 3
solver 0.0208 0.00761 1
Elapsed time is 0.022389 seconds.
uopt
uopt =
-5.5768 -5.6623 -5.5679 -4.7070 -2.4409 2.3186 5.4928
xopt
xopt =
1.0000 0.1623 -0.5028 -0.9714 -1.1358 -0.7915 -0.0010
2.0000 1.5116 1.0554 0.6485 0.3127 0.0857 0.0046
Method::SteptestGradientDescent of Class::ocp
Syntax
[uopt,xopt] = SteptestGradientDescent(iocp,uguess)
[uopt,xopt] = SteptestGradientDescent(iocp,uguess,'MaxIter',MaxIter)
[uopt,xopt] = SteptestGradientDescent(iocp,uguess,'InitialLengthStep',InitialLengthStep)
Interface
Example
import casadi.*
A = [-2 1;
1 -2];
B = [1;0];
%
tspan = linspace(0,1,7);
idyn = linearode(A,B,tspan);
idyn.InitialCondition = [1;2];
ts = idyn.ts;
Xs = idyn.State.sym;
Us = idyn.Control.sym;
%
epsilon = 1e4;
PathCost = Function('L' ,{ts,Xs,Us},{ Us'*Us });
FinalCost = Function('Psi',{Xs} ,{ epsilon*(Xs'*Xs) });
iocp = ocp(idyn,PathCost,FinalCost);
uguess = tspan;
[uopt,xopt] = SteptestGradientDescent(iocp,uguess);
iteration: 005 | error: 3.672e+03 | LengthStep: 8.705e-04 | J: 1.234e+03 | Distance2Target: NaN
iteration: 010 | error: 2.642e+02 | LengthStep: 2.640e-04 | J: 5.972e+01 | Distance2Target: NaN
iteration: 015 | error: 1.706e+02 | LengthStep: 1.358e-04 | J: 5.118e+01 | Distance2Target: NaN
iteration: 020 | error: 3.506e+01 | LengthStep: 1.806e-04 | J: 4.304e+01 | Distance2Target: NaN
iteration: 025 | error: 2.688e+01 | LengthStep: 2.964e-06 | J: 4.304e+01 | Distance2Target: NaN
iteration: 030 | error: 2.658e+01 | LengthStep: 3.377e-07 | J: 4.304e+01 | Distance2Target: NaN
iteration: 035 | error: 2.655e+01 | LengthStep: 4.453e-08 | J: 4.304e+01 | Distance2Target: NaN
Mininum Length Step have been achive !!
uopt
uopt =
-7.9333 -8.1012 -7.8269 -6.7884 -4.4855 -0.1486 7.3999
xopt
xopt =
1.0000 -0.0763 -0.9101 -1.4598 -1.6275 -1.2375 -0.0019
2.0000 1.4905 1.0041 0.5706 0.2245 0.0137 0.0100
Method::ClassicalGradient of Class::ocp
Syntax
[uopt,xopt] = ArmijoGradient(iocp,uguess)
[uopt,xopt] = ArmijoGradient(iocp,uguess,'MaxIter',MaxIter)
Interface
Example
import casadi.*
A = [-2 1;
1 -2];
B = [1;0];
%
tspan = linspace(0,1,7);
idyn = linearode(A,B,tspan);
idyn.InitialCondition = [1;2];
ts = idyn.ts;
Xs = idyn.State.sym;
Us = idyn.Control.sym;
%
epsilon = 1e4;
PathCost = Function('L' ,{ts,Xs,Us},{ Us'*Us });
FinalCost = Function('Psi',{Xs} ,{ epsilon*(Xs'*Xs) });
iocp = ocp(idyn,PathCost,FinalCost);
uguess = tspan;
[uopt,xopt] = ClassicalGradient(iocp,uguess);
iteration: 005 | error: 2.525e+03 | LengthStep: 1.000e-04 | J: 1.981e+03 | Distance2Target: NaN
iteration: 010 | error: 2.253e+03 | LengthStep: 1.000e-04 | J: 1.688e+03 | Distance2Target: NaN
iteration: 015 | error: 2.086e+03 | LengthStep: 1.000e-04 | J: 1.453e+03 | Distance2Target: NaN
iteration: 020 | error: 1.933e+03 | LengthStep: 1.000e-04 | J: 1.252e+03 | Distance2Target: NaN
iteration: 025 | error: 1.790e+03 | LengthStep: 1.000e-04 | J: 1.079e+03 | Distance2Target: NaN
iteration: 030 | error: 1.658e+03 | LengthStep: 1.000e-04 | J: 9.315e+02 | Distance2Target: NaN
iteration: 035 | error: 1.536e+03 | LengthStep: 1.000e-04 | J: 8.046e+02 | Distance2Target: NaN
iteration: 040 | error: 1.423e+03 | LengthStep: 1.000e-04 | J: 6.957e+02 | Distance2Target: NaN
iteration: 045 | error: 1.318e+03 | LengthStep: 1.000e-04 | J: 6.024e+02 | Distance2Target: NaN
iteration: 050 | error: 1.221e+03 | LengthStep: 1.000e-04 | J: 5.223e+02 | Distance2Target: NaN
uopt
uopt =
[[-4.66594, -4.75716, -4.63036, -4.11885, -2.96299, -0.762059, 3.09807]]
xopt
xopt =
[[1, 0.354971, -0.164069, -0.534352, -0.705436, -0.587689, -0.0341006],
[2, 1.54437, 1.13777, 0.786533, 0.501721, 0.302829, 0.222859]]
Method::ConjugateGradient of Class::ocp
Syntax
[uopt,xopt] = ArmijoGradient(iocp,uguess)
[uopt,xopt] = ArmijoGradient(iocp,uguess,'MaxIter',MaxIter)
Interface
Example
import casadi.*
A = [-2 1;
1 -2];
B = [1;0];
%
tspan = linspace(0,1,7);
idyn = linearode(A,B,tspan);
idyn.InitialCondition = [1;2];
ts = idyn.ts;
Xs = idyn.State.sym;
Us = idyn.Control.sym;
%
epsilon = 1e4;
PathCost = Function('L' ,{ts,Xs,Us},{ Us'*Us });
FinalCost = Function('Psi',{Xs} ,{ epsilon*(Xs'*Xs) });
iocp = ocp(idyn,PathCost,FinalCost);
uguess = tspan;
[uopt,xopt] = ConjugateGradient(iocp,uguess);
iteration: 005 | error: 2.473e+03 | norm(dJ): 2.473e+03 | LengthStep: +2.762e-07 | beta: 1.093e+00 | J: 1.9944e+03 | Distance2Target: NaN
iteration: 010 | error: 2.997e+03 | norm(dJ): 2.997e+03 | LengthStep: +1.976e-07 | beta: 1.073e+00 | J: 1.9937e+03 | Distance2Target: NaN
iteration: 015 | error: 3.521e+03 | norm(dJ): 3.521e+03 | LengthStep: +1.609e-07 | beta: 1.063e+00 | J: 1.9930e+03 | Distance2Target: NaN
iteration: 020 | error: 4.065e+03 | norm(dJ): 4.065e+03 | LengthStep: +1.405e-07 | beta: 1.057e+00 | J: 1.9922e+03 | Distance2Target: NaN
iteration: 025 | error: 4.638e+03 | norm(dJ): 4.638e+03 | LengthStep: +1.278e-07 | beta: 1.053e+00 | J: 1.9913e+03 | Distance2Target: NaN
iteration: 030 | error: 5.248e+03 | norm(dJ): 5.248e+03 | LengthStep: +1.195e-07 | beta: 1.049e+00 | J: 1.9902e+03 | Distance2Target: NaN
iteration: 035 | error: 5.897e+03 | norm(dJ): 5.897e+03 | LengthStep: +1.138e-07 | beta: 1.047e+00 | J: 1.9889e+03 | Distance2Target: NaN
iteration: 040 | error: 6.586e+03 | norm(dJ): 6.586e+03 | LengthStep: +1.098e-07 | beta: 1.044e+00 | J: 1.9874e+03 | Distance2Target: NaN
iteration: 045 | error: 7.312e+03 | norm(dJ): 7.312e+03 | LengthStep: +1.070e-07 | beta: 1.042e+00 | J: 1.9855e+03 | Distance2Target: NaN
iteration: 050 | error: 8.066e+03 | norm(dJ): 8.066e+03 | LengthStep: +1.049e-07 | beta: 1.039e+00 | J: 1.9833e+03 | Distance2Target: NaN
uopt
uopt =
-2.6217 -2.6272 -2.5285 -2.2421 -1.6369 -0.5107 1.4475
xopt
xopt =
1.0000 0.6188 0.3006 0.0606 -0.0738 -0.0560 0.1892
2.0000 1.5773 1.2206 0.9230 0.6830 0.5053 0.4026