MIMO with MPC

474 views
Skip to first unread message

D Duda

unread,
Apr 6, 2017, 11:31:16 AM4/6/17
to YALMIP
Hi,

In short, how I would need to modify the MPC conroller code, to be compatible with multiple inputs and outputs?

What I am trying to do, is by using MPC based controller for simulink, I want it to modify code, so it can compute multiple Inputs and multiple outputs.
In strict 3 inputs and 6 outputs.
I was able to have 1, 2, or 3 inputs, converging the output to the solution, but seams failing on having multiple outputs with inputs.

Trying simple, I have modified the code, from simulink example, and modified the ABCD, for 2 inputs and 2 outputs (2 by 2 matrices).
But I think, I completely lost track, as any attempt to run code fails. 
I know, I am missing something simple, but not necessary obvious for me tho.
So I am asking for hopefully short help.

Current modified code after number of attempts, based on simulink with MPC controller, looks as following (I have commented out original line of code):

% function uout = MPCController(currentx,currentr,t)
function uout = MPCController(t, inXY, oX )

persistent Controller

if t == 0
    % Compute discrete-time dynamics
    
    % MIMO
    % 3 in 6 out
    % Numerator = {[1 -1 0], 1, 1; 1, [1 -1 0], 1; 1, 1, [1 -1 0] };
    % Denominator = {[1 2 0], 1, 1; 1, [1 -1 0], 1; 1, 1, [1 -1 0] };

    % 2 in 2 out
    Numerator = {[1 -1], 2; [1 0], 1};
    Denominator = {[1 2], 2; [1 0], 1};

    H = tf(Numerator,Denominator) ;

    % Plant = ss(tf(1,[1 0 0]));
    Plant = ss(H);

    A = Plant.A;
    B = Plant.B;
    C = Plant.C;
    D = Plant.D;
    Ts = 0.1;
    Gd = c2d(Plant,Ts);
    Ad = Gd.A;
    Bd = Gd.B;
    
    % Define data for MPC controller
    N = 10;
    Q = 10;
    R = 0.1;
    
    % Avoid explosion of internally defined variables in YALMIP
    yalmip('clear')
    
    % Setup the optimization problem
    % u = sdpvar(repmat(1,1,N),repmat(1,1,N));
    u1 = sdpvar(repmat(1,1,N),repmat(1,1,N));
    u2 = sdpvar(repmat(1,1,N),repmat(1,1,N));
    
    % x = sdpvar(repmat(2,1,N+1),repmat(1,1,N+1));
    x1 = sdpvar(repmat(2,1,N+1),repmat(1,1,N+1));
    x2 = sdpvar(repmat(2,1,N+1),repmat(1,1,N+1));
    
    % sdpvar r
    sdpvar r1
    sdpvar r2
    
    % Define simple standard MPC controller
    % Current state is known so we replace this
    constraints = [];
    objective = 0;
    for k = 1:N
        %objective = objective + (r-C*x{k})'*Q*(r-C*x{k})+u{k}'*R*u{k};
        objective = objective + (r1-C*x1{k})'*Q*(r1-C*x1{k})+u1{k}'*R*u1{k};
        objective = objective + (r2-C*x2{k})'*Q*(r2-C*x2{k})+u2{k}'*R*u2{k};
        %constraints = [constraints, x{k+1} == Ad*x{k}+Bd*u{k}];
        constraints = [constraints, -5 <= u1{k}<= 5];
        constraints = [constraints, -5 <= u2{k}<= 5];
    end
    
    % Define an optimizer object which solves the problem for a particular
    % initial state and reference
    % Controller = optimizer(constraints,objective,[],{x{1},r},u{1});
    
    inXY_2optimizer = [{x1{1},r1}, {x2{1},r2}] ;
    oX_2optimizer = [u1{1}, u2{1}] ;
    
    Controller = optimizer(constraints, objective, [], inXY_2optimizer, oX_2optimizer );
    
    % And use it here too
    % uout = Controller{{currentx, currentr}};
    % uout = Controller{{inX, inY, currentx}};
    uout = Controller{{inXY', oX'}};
    
else    
    % Almost no overhead
    % uout = Controller{{currentx, currentr}};
    % uout = Controller{{inX, inY, currentx}};
    uout = Controller{{inXY, oX}};
end

I suspect that I need put variables r1, r2, in x array, u1, u2, in u array and x1, x2 in x array. 
This seams worked for multiple inputs. But I get lost, trying replicate and do it for multiple inputs and outputs. 

When run current code, I got error:

 Simulation  1 Clear Save
4:16:05 PM Apr 6, 2017 Elapsed: 0.886 sec

 An error occurred while running the simulation and the simulation was terminated

Error due to multiple causes.

The number of cell elements in input does not match OPTIMIZER declaration

Error in 'MPCSimulation/MPC1' while evaluating expression.
Component: Simulink | Category: Model error


The simulink model has been modified to have following form (hope picture allow to help understand the case better)


And ziped project with 3 files is attached.

Most appreciated for the support.
MIMO_2in2Out.zip

Johan Löfberg

unread,
Apr 6, 2017, 1:27:03 PM4/6/17
to YALMIP
Yes, you seem to be generally lost. You define a model which has two states, two inputs and two outputs. Hence,  x = sdpvar(repmat(2,1,N+1),repmat(1,1,N+1));,u = sdpvar(repmat(2,1,N),repmat(1,1,N)), and r=sdpvar(2,1). Your definition of x1,2,u1,u2,r1,r2 makes everything messy and strange. The code should look exactly like the scalar case, with the simple change of dimension when defining x,r,u

D Duda

unread,
Apr 10, 2017, 10:37:20 AM4/10/17
to YALMIP
Man thx Johan for a guidance
Investigating solution now.

D Duda

unread,
Apr 11, 2017, 7:00:24 AM4/11/17
to YALMIP
Hi Johan. 

Unfortunately I am back with no resolution yet to 2in 2out system. I was attempting different approaches, but failing measurably.


First simulink, what I got:

Minimum of changes, in comparison to the web example. 
Added second input and updating MPC and SS blocks.
Commenting out Gain for now.

Values seams showing right dimensions. But simulation is failing on controller code (please see below).



I have setup ABCD matrices as following:

A = [0 1;0 -1] ;
B
= [1 0;0 1] ;
C
= [0 1;1 0] ;
D
= [0 0;0 0] ;

Plant = ss (A,B,C,D) ;

% Global sampling-time
Ts = 0.1;

% Initial state for simulation
x0
= [1;1];

Then simulink control code, with aim of 2 inputs and 2 outputs. Also 2 states.
Tried reuse again code from the example.

function uout = MPCController(currentx,currentr,t)

persistent Controller

if t == 0

        A = [0 1;0 -1] ;
    B = [1 0;0 1] ;
    % B = sdpvar(2,2); % I tried that too, from one of examples, just in case
    C = [0 1;1 0] ;
    D = [0 0;0 0] ;

     Plant = ss (A,B,C,D) ;

    Ts = 0.1;
    Gd = c2d(Plant,Ts);
    Ad = Gd.A;
    Bd = Gd.B;
    
    % Define data for MPC controller
    N = 10;
    Q = 10;
    R = 0.1;
    
    % Avoid explosion of internally defined variables in YALMIP
    yalmip('clear')
    
    nu = 2; % Number of inputs
    nx = 2; % Number of states   
    ny = 2; % Number of outputs ?
    
    % Setup the optimization problem
   
    u = sdpvar(repmat(nu,1,N),repmat(1,1,N));
    x = sdpvar(repmat(nx,1,N+1),repmat(1,1,N+1));
   
    % tried differen definitions of r, but either failing with some errors

    r = sdpvar( repmat(ny,1,N+1), repmat(1,1,N+1) ); % example
    % r = sdpvar( repmat(ny,1,N+1) )
    % r = sdpvar( repmat(ny,1,N) )
    
    % Define simple standard MPC controller
    % Current state is known so we replace this
    constraints = [];
    objective = 0;
    
    for k = 1:N
        objective = objective + (r{k}-C*x{k})'*Q*(r{k}-C*x{k})+u{k}'*R*u{k};
        constraints = [constraints, x{k+1} == Ad*x{k}+Bd*u{k}];
        constraints = [constraints, -5 <= u{k}<= 5];
    end
    
    parameters_in = {x{:},r{:}} ;
   
    solutions_out = {u{:}};
    
    % Define an optimizer object which solves the problem for a particular
    % initial state and reference
    
    ops = sdpsettings('verbose',2);
    
    Controller = optimizer(constraints, objective, ops, parameters_in, solutions_out );
    
    % And use it here too
    uout = Controller{{currentx,currentr}};
    
else    
    % Almost no overhead
    uout = Controller{{currentx,currentr}};
end


And the latest simulink error

References to the optimizer and cell issue

An error occurred while running the simulation and the simulation was terminated
Caused by:
Error due to multiple causes.
The number of cell elements in input does not match OPTIMIZER declaration
Error in 'MPCSimulationV4/MPC yalmipsimulinkAdapt5' while evaluating expression.
Component: Simulink | Category: Model error

I had number of different errors in simulink, but now I think they resolved, assumed I got other stuff right. Specially MPC block.


What I also tried

I have tried to run MPC basics examples and  was able to increase number of inputs.This was for me, to better understand method.
So at least I know, I got right approach, as it also uses optimizer () ;


Cells

The problem I think I am facing, is misunderstanding cells application for optimizer?

I believe, I followed correctly your guidance. At least partially.

But I need to ask you kindly again, what I am missing? It must be something trivial, but not obvious for me.

Would you be able to point out the issue and solution please? 

I feel I really stuck on that case.


Best Regards

Johan Löfberg

unread,
Apr 11, 2017, 7:06:05 AM4/11/17
to YALMIP
You are only sending the currently measured 2x1 reference r to the controller. However, the controller code magically uses different reference values for future predictions. Hence, r should be 2x1, and you should use that vector in all terms in the objective, and as a parameter in the controller definition

D Duda

unread,
Apr 11, 2017, 7:37:15 AM4/11/17
to YALMIP
Thats great.

I was looking for a problem and solution in completely different area.

Finally starting getting something. 
Feasibility issue, but neither objective, nor constrains were setup correctly.
At least I go no errors. :)

Many thx again.

But it may happen that I will come back at some point to this topic.

Reply all
Reply to author
Forward
0 new messages