TOMLAB /SOCS is a software package for advanced sparse optimal control.
An optimal control problem can be formulated as follows:
There is an objective function
|
where N is the number of phases, tI(p) ∈ ℝ, tF(p) ∈ ℝ, x(p)(t) ∈ ℝns(p), u(p)(t) ∈ ℝnc(p), q(p) ∈ ℝnp(p) are respectively the initial time, final time, state variables, control variables and parameter variables of phase p.
The optimal control problem consists of minimizing the objective function J subject to, for each phase p, with its set of state variables x, control variables u, parameter variables q and values of tI, tF the differential equations
| ẋ = f(x(t), u(t), t, q), t = [tI, tF], |
event (boundary) constraints
| ψlj ≤ ψj(tI, x(tI), u(tI), tF, x(tF), u(tF), q) ≤ ψuj, j = 1,…,ne, |
and path constraints
| glk ≤ gk(x(t), u(t), t, q) ≤ guk, t = [tI, tF], k = 1,…,ng |
There are also link constraints, used to link quantities between phases. One can link any quantity (x, u, t, q) at any endpoint (initial or final) of any phase with any other quantity at any endpoint of any phase.
Simple bounds can and should be set on all variables.
There are restrictions on the functions Φ and ψ. They must consist of a sum of terms, where a term depends on either the initial or final values of the time, state, control and parameter variables:
|
The following file illustrates how to solve an optimal control problem in TOMLAB. Also view the m-files specified for more information.
We want to solve the hypersensitive problem:
Minimize
| ∫ |
| (x2 + u2)dt, |
subject to
|
To formulate this problem in TOMLAB /SOCS, two callbacks need to be written, and a problem MATLAB structure needs to be populated. The callback functions contain the functions of the problem, while the problem structure contains static data, such as box bounds.
For this specific problem, we have two functions: (1) the integrand in the objective function, (2) the right-hand-side of the differential equation. These are defined in two separate callbacks. Let us name the integrand socsQGCost.m and the right-hand-side socsQGOde.m. These functions will be called by the solver to evaluate the functions, and it is important that they have the correct argument list. The functions are listed below.
File: tomlab/socs/quickguide/socsQGCost.m
% function [endpoint, integrand] = socsQGCost(phase_number, x, u, t, q, user) % % The following function computes the cost for the hyper sensitive % problem. function [f, iferr] = socsQGCost(phase_number, x, u, t, q, user) state = x; control = u; f = 0.5*(state.^2+control.^2); iferr = 0;
File: tomlab/socs/quickguide/socsQGOde.m
% function xdot = socsQGOde(phase_number, x, u, t, q, user) % % This function computes the right hand sides of the differential % equations for the hyper sensitive problem. function [xdot, iferr] = socsQGOde(phase_number, x, u, t, q, user) state = x; control = u; xdot = -state.^3+control; iferr = 0;
Once the callback functions names have been established the problem structure can be populated. In this example, it is completed in the MATLAB function socsQGMain.m. The problem structure always need to have all fields set, so a good idea is to use the newSocsProblem.m utility. It returns a new, empty problem structure.
Then the names of the callback functions will be set in the problem structure. In this case we have two functions to set: odefun and costfun_integrand.
Each phase in the problem has its own elements in the structure array problem.phases. This example consists of only one phase. The problem.phases structure also needs to have all fields set, so it is recommended first to get the empty predefined phases structure from the problem structure:
phases = problem.phases;
and then populate the phases structure. The phases structure should contain the lower and upper bounds of the variables, and also a value of the number of nodes the solver should have in the first grid for the specific phase. In this case, it is set to 50.
Then to solve the problem, solveSocsProblem.m is called. This yields a solution structure. From this solution structure a solution can be evaluated and this is done trhough evalSocsSolution.m.
The source code file for this, socsQGMain.m is listed below:
File: tomlab/socs/quickguide/socsQGMain.m
% script socsQGMain.m
problem = newSocsProblem;
% Set the callback functions. In this case, we have only two callbacks.
% (1) the right-hand-side of the ODE (hyperSensitiveSocsOde)
% (2) the integrand in the objective function (hyperSensitiveSocsCost)
problem.odefun = 'socsQGOde';
problem.costfun_integrand = 'socsQGCost';
problem.name = 'Hyper-Sensitive-Problem';
% Set initial state, final state and final time.
x0 = 1.5;
xf = 1;
t_f = 50;
% Use the predefined empty phases structure to make sure
% all fields are set.
phases = problem.phases;
% Number of nodes is the number of grid points used in the first
% mesh. If this value is too low to generate ac accurate enough
% solution, this will be refined.
phases(1).nodes = 50;
% Set lower and upper bounds of the time. The first element
% in the vector is the initial time, while the second is final
% time. The initial and final time are fixed.
phases(1).lower.time = [0 t_f];
phases(1).upper.time = [0 t_f];
% Set lower and upper bounds of the state variable. The first
% element is the bounds of the state at the initial point (at
% time == 0 in this case), while the last element is the bounds of
% the state at the final point (time == t_f = 50). The middle
% element is the bounds of the variable during the phase.
phases(1).lower.states = [x0 -10 xf];
phases(1).upper.states = [x0 10 xf];
% Set lower and upper bounds of the control variable.
phases(1).lower.controls = -50;
phases(1).upper.controls = 50;
% Reset the problem.phases structure.
problem.phases = phases;
% Solve the problem. Solution returned in sol
sol = solveSocsProblem(problem);
% Create a set of time points at which to evaluate the
% state and control variables.
t = linspace(sol.phases(1).initial_time, sol.phases(1).final_time);
% Evaluate. Information is added to the solution structure sol.
sol = evalSocsSolution(sol, 1, t);
% Plot the results.
plot(t, [sol.phases(1).states; sol.phases(1).controls]);
legend('State', 'Control');
title('Solution of hyper sensitive problem');
For more information about how to setup and solve an optimal control problem using TOMLAB /SOCS, see the TOMLAB /SOCS User’s Guide. It is available at http://tomopt.com/tomlab/download/manuals.php.