Direct collocation involves 3 main components that define the type of direct collocation method,
Nonlinear program set up
Solve the nonlinear program to minimize the objective function subject to dynamics conctraints at collocation points, and any other problem constraints.
Minimize,
$$ J(u) = \Phi(X_f) + \int_{t=0}^{t_f} L(t,X,u) dt . $$Subject to,
$$ \dot{X} =f(x,u), $$with initial condition \( X(0) = X_0 \), under constraints,
$$ u_{min} \leq u \leq u_{max}, $$ $$ X_{min} \leq X \leq X_{max}, $$ $$ C_{eq}(X,u) = 0 , $$ $$ C(X,u) \leq 0 , $$We solve this problem using Hermite-Simpson collocation method.
Discretize time \( t_f \) into \( N \) intervals as,
$$ t_0 = 0 \leq t_1 \leq t_2 \leq \dots \leq t_{k} \leq t_{k+1} \dots \leq t_{N}=t_f $$The states between \( tk \) and \( t{k+1} \) can be written as,
$$ X(t) = a_{k,0} + a_{k,1} t + a_{k,2} t^2 + a_{k,3} t^3 , $$which gives
$$ \dot{X}(t) = a_{k,1} + 2 a_{k,2} t + 3 a_{k,3} t^2 , $$where \( a{k,0} \), \( a{k,1} \), \( a{k,2} \) and \( a{k,3} \) are coefficients of the polynomial approximation in \( k^{th} \) interval.
We redefine the constraint as,
$$ \Delta_k = \left[ \left( X_k - X_{k+1} \right) + \frac{h}{6} \left[ f(X_k,u_k) + 4 f(X_c, u_c)+ f(X_{k+1},u_{k+1}) \right] \right] $$Term in bracket is integral from Hermite-Simpson approximation when the dynamic constraints are satisfied. This technique results in implicit Hermite-Simpson integration.
The constraints on states and controls can be expressed as
$$ u_{min} \leq u_k \leq u_{max}, $$ $$ X_{min} \leq X_k \leq X_{max}, $$ $$ C{eq}(X_k,u_k) = 0 , $$ $$ C(X_k,u_k)\leq 0 , $$Subject to,
$$ \Delta_k = \left[ \left( X_k - X_{k+1} \right) + \frac{h}{6} \left[ f(X_k,u_k) + 4 f(X_c, u_c)+ f(X_{k+1},u_{k+1}) \right] \right] = 0 $$ $$ u_{min} \leq u_k \leq u_{max}, $$ $$ X_{min} \leq X_k \leq X_{max}, $$ $$ C{eq}(X_k,u_k) = 0 , $$ $$ C(X_k,u_k)\leq 0. $$%% Constraint function
function [C,Ceq]=cons_fn(X_opt)
N = (length(X_opt)-1)/3;
N_st = 2;
t_f = X_opt(1);
x = X_opt(N+2:end);
u = X_opt(2:N+1);
x = reshape(x,N,N_st);
t = linspace(0,1,N)'*t_f;
dt = t(2) - t(1);
tc = linspace (t(1)+dt/2,t(end)-dt/2,N-1);
xdot = innerFunc(t,x,u);
xll = x(1:end-1,:);
xrr = x(2:end,:);
xdotll = xdot(1:end-1,:);
xdotrr = xdot(2:end,:);
ull = u(1:end-1,:);
urr = u(2:end,:);
xc = .5*(xll+xrr)+ dt/8*(xdotll-xdotrr);
uc = (ull+urr)/2;
xdotc = innerFunc(tc,xc,uc);
Ceq = (xll-xrr)+dt/6*(xdotll +4*xdotc +xdotrr );
Ceq = Ceq(:);
Ceq = [Ceq ;
x(1,1)-10 ;
x(end,1);
x(1,2)
x(end,2);
];
C = [];
%% Cost function
function [cost,grad]= objfun(X_opt)
N = (length(X_opt)-1)/3;
t_f = X_opt(1);
cost = t_f;
grad = zeros(size(X_opt));
grad(1) = 1;
GPOPs II (pronounced GPOPs 2) is a general purpose optimal control software. GPOPs II stands for, General Purpose OPtimal Control Software version 2. GPOPs' development began in 2007, and the development of GPOPS-II continues today, with improvements that include the open-source algorithmic differentiation package ADiGator and continued development of \(hp\)-adaptive mesh refinement methods for optimal control. Detailed article on GPOPS II and its capibilites can be found here
%-------------------------------------------------------------------------%
%----------------- Provide All Bounds for Problem ------------------------%
%-------------------------------------------------------------------------%
t0min = 0; t0max = 0;
tfmin = 0; tfmax = 200;
x10 = +10; x1f = 0;
x20 = +0; x2f = 0;
x1min = -20; x1max = 20;
x2min = -20; x2max = 20;
umin = -1; umax = +1;
%-------------------------------------------------------------------------%
%----------------------- Setup for Problem Bounds ------------------------%
%-------------------------------------------------------------------------%
bounds.phase.initialtime.lower = t0min;
bounds.phase.initialtime.upper = t0max;
bounds.phase.finaltime.lower = tfmin;
bounds.phase.finaltime.upper = tfmax;
bounds.phase.initialstate.lower = [x10, x20];
bounds.phase.initialstate.upper = [x10, x20];
bounds.phase.state.lower = [x1min, x2min];
bounds.phase.state.upper = [x1max, x2max];
bounds.phase.finalstate.lower = [x1f, x1f];
bounds.phase.finalstate.upper = [x1f, x1f];
bounds.phase.control.lower = [umin];
bounds.phase.control.upper = [umax];
%-------------------------------------------------------------------------%
%---------------------- Provide Guess of Solution ------------------------%
%-------------------------------------------------------------------------%
tGuess = [0; 5];
x1Guess = [x10; x1f];
x2Guess = [x20; x2f];
uGuess = [umin; umin];
guess.phase.state = [x1Guess, x2Guess];
guess.phase.control = [uGuess];
guess.phase.time = [tGuess];
%-------------------------------------------------------------------------%
%----------Provide Mesh Refinement Method and Initial Mesh ---------------%
%-------------------------------------------------------------------------%
mesh.method = 'hp-PattersonRao';
mesh.tolerance = 1e-6;
mesh.maxiterations = 20;
mesh.colpointsmin = 4;
mesh.colpointsmax = 10;
mesh.phase.colpoints = 4;
%-------------------------------------------------------------------------%
%------------- Assemble Information into Problem Structure ---------------%
%-------------------------------------------------------------------------%
setup.mesh = mesh;
setup.name = 'Double-Integrator-Min-Time';
setup.functions.endpoint = @doubleIntegratorEndpoint;
setup.functions.continuous = @doubleIntegratorContinuous;
setup.displaylevel = 2;
setup.bounds = bounds;
setup.guess = guess;
setup.nlp.solver = 'ipopt';
setup.derivatives.supplier = 'sparseCD';
setup.derivatives.derivativelevel = 'second';
setup.method = 'RPM-Differentiation';
%% Dynamics
function phaseout = doubleIntegratorContinuous(input)
t = input.phase.time;
x1 = input.phase.state(:,1);
x2 = input.phase.state(:,2);
u = input.phase.control(:,1);
x1dot = x2;
x2dot = u;
phaseout.dynamics = [x1dot, x2dot];
%% Objective
function output = doubleIntegratorEndpoint(input)
output.objective = input.phase.finaltime;
%-------------------------------------------------------------------------% %----------------------- Solve Problem Using GPOPS2 ----------------------% %-------------------------------------------------------------------------%
output = gpops2(setup);
States for optimal control computed using GPOPS II.
States for optimal control computed using GPOPS II.