TomSym MPC example with TomSym.

From TomWiki
Revision as of 09:33, 8 November 2011 by Mbot (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Notice.png

This page is part of the TomSym Manual. See TomSym Manual.

This is an example of MPC for a linear, time-invariant system, illustrating how to use sym2prob and setParameter with tomSym for repeatedly solving the same optimization problem.

Note: This example code contains two alternative ways of setting up the problem. If you use this code as a basis for your own MPC controller, then you should probalby delete the "if 0" statement, and only keep the "else" part.

Reference: The problem definition is taken from the "Standard MPC" example in the YALMIP documentaion by Johan Löfberg. http://users.isy.liu.se/johanl/yalmip/pmwiki.php?n=Examples.StandardMPC


% Model data
A = [2 -1;1 0];
B = [1;0];
nx = size(A,2); % Number of states
nu = size(B,2); % Number of inputs

% MPC data
Q = eye(2);
R = 1;
N = 4; % Number of time-steps

% Make the initial state a symbol, so that we can use it as a parameter
% later.
x0 = tom('x0',nx,1);

Problem Setup

This example shows two ways of setting up the model. Change "if 0" to "if 1" to try the other one.

if 0
    % The more intuitive way to write the model involves a for-loop:

    u = cell(N,1); % Preallocate empty cell array.
    constraints = cell(N,1);

    objective = 0;
    x = x0;

    for k = 1:N
        u{k} = tom(['u' num2str(k)], nu, 1);

        % The symbolic expressions for x and the objective will grow inside
        % the loop, so at the last iteration, they will be quite large.
        % Remove the semicolons from the following lines to see how the
        % expressions grow.
        x = A*x + B*u{k};
        objective = objective + norm(Q*x,1) + norm(R*u{k},1);

        constraints{k} = { -1 <= u{k} <= 1, -5 <= x <=5 };
    end
else
    % A better way to solve the same problem:

    % Making all x(k) a decsion variables is numerically more sound, even
    % though it makes the number of unknowns larger.
    x = tom('x',nx,N);

    % Make the first column of u a separate symbol for compatibility with
    % the above variation of the code.
    u1 = tom('u1',nu,1);
    uk = tom('uk',nu,N-1);
    u = [u1 uk];

    % Matrix-matrix multiplication is equivalent to looping over the
    % columns of the second matrix and doing matrix-vector multiplication.
    constraints = {
        x == A*[x0 x(:,1:N-1)] + B*u
        -1 <= u <= 1
        -5 <= x <= 5
        };

    objective = sum(vec(abs(Q*x))) + sum(vec(abs(R*u)));
end

Compile the sybolic problem into a Prob structure

[objective, constraints] = rewriteV(objective, constraints);
ptype = tomDiagnose(objective, constraints);
Prob = sym2prob(ptype, objective, constraints);

Simulate a trajectory

Now that a Prob structure has been created, we can run the optimizatino multiple times without the overhead of processing symbols.

Ns = 5; % Number of steps to simulate
xt = zeros(nx,Ns+1);
xt(:,1) = [2;1];
ut = zeros(nu,Ns);
for i = 1:Ns
    Prob = setParameter(Prob, x0 == xt(:,i));
    Result = tomRun('snopt',Prob,0);
    solution = getSolution(Result);
    ut(:,i) = solution.u1;
    xt(:,i+1) = A*xt(:,i) + B*ut(:,i);
end

subplot(2,1,1);
plot(0:Ns,xt');
title('states');
legend({'x_0','x_1'});

subplot(2,1,2);
plot(0:Ns,[ut NaN(nu,1)]');
title('control');

Tomsym mpc 01.png

Get rid of any temporary m-files created.

This example results in a linear programming, so no m-files are created. Cleanup is therefore striclty not needed, but we include it in case we want to modify the code to use a nonlinear model later. (Remove these lines if you want to keep the Prob structure after the script has finished.)

tomCleanup(Prob)
clear Prob