UI /

TrackingProblem

UI.TrackingProblem History

Hide minor edits - Show changes to markup

Changed line 204 from:

The delta-u formulation \Delta u(k) = u(k) - u(k-1) is activated with the "deltaPenalty" filter

to:

The delta-u formulation {$ \Delta u_k = u_k - u_{k-1} $} is activated with the "deltaPenalty" filter

August 15, 2013, at 12:48 PM by Martin Herceg -
Added lines 214-218:

Note that the partition of the explicit controller is defined in dimension three because the parametric variable is the current state {$x_k$}, the previous value of the input {$u_{k-1}$}, and the reference signal {$ r_k $}. This can be verified by plotting the partition of the controller

(:source lang=MATLAB -getcode:)
ectrl.partition.plot()
August 15, 2013, at 12:42 PM by Martin Herceg -
Changed lines 279-284 from:

and a closed form is created with the help of ClosedLoop object:

to:

and can be plotted with the help of fplot function

(:source lang=MATLAB -getcode:)
ectrl.feedback.fplot()

In the next step, the explicit controller is employed in the closed loop object

August 15, 2013, at 12:33 PM by Martin Herceg -
Added line 309:
August 15, 2013, at 12:29 PM by Martin Herceg -
Changed line 218 from:

Simulate the performance of the explicit controller in 20 samples and plot the closed loop trajectories

to:

Simulate the performance of the explicit controller in 20 samples

Deleted lines 226-227:

subplot(2, 1, 1); plot(1:Nsim, data.X(1:Nsim)); title('state') subplot(2, 1, 2); plot(1:Nsim, data.U); title('input')

Changed lines 228-233 from:

Tracking with builtin integrator

The tracking of a time-varying reference can be achieved by augmenting the state with an integrator state that predicts the steady state values. In MPT this can be achieved with the help of "integrator" filter that extends the model with an integrator state. Consider the unstable LTI system as in the previous example that operates under input and state constraints

to:

and plot the closed loop trajectories

Changed lines 230-234 from:

model = LTISystem('A', 1.5 , 'B', 1 ); model.x.min = -10; model.x.max = 10; model.u.min = -5; model.u.max = 5;

to:

subplot(2, 1, 1); hold on; plot(1:Nsim, data.X(1:Nsim), 'linewidth', 2 ); plot(1:Nsim, model.x.max*ones(1,Nsim), 'k--', 'linewidth', 2); plot(1:Nsim, model.x.min*ones(1,Nsim), 'k--', 'linewidth', 2); stairs(1:Nsim, xref, 'r--', 'linewidth', 2); axis([1, Nsim, -11, 11]); title('state') subplot(2, 1, 2); hold on; stairs(1:Nsim, data.U, 'linewidth', 2); plot(1:Nsim, model.u.max*ones(1, Nsim), 'k--', 'linewidth', 2); plot(1:Nsim, model.u.min*ones(1, Nsim), 'k--', 'linewidth', 2); axis([1, Nsim, -6, 6]); title('input')

Changed lines 244-249 from:

Activate the time-varying reference

to:

Tracking with builtin integrator

The tracking of a time-varying reference can be achieved by augmenting the state with an integrator state that predicts the steady state values. In MPT this can be achieved with the help of "integrator" filter that extends the model with an integrator state. Consider the unstable LTI system as in the previous example that operates under input and state constraints

Changed lines 251-252 from:

model.x.with('reference'); model.x.reference = 'free';

to:

model = LTISystem('A', 1.5 , 'B', 1 ); model.x.min = -10; model.x.max = 10; model.u.min = -5; model.u.max = 5;

Changed line 257 from:

To add the integrator, one need to active the "integrator" filter as follows.

to:

Activate the time-varying reference

Changed lines 259-260 from:

model.with('integrator');

to:

model.x.with('reference'); model.x.reference = 'free';

Changed line 262 from:

In the remainder of MPC set, the penalty on the predicted difference of the integrator state and the reference is provided

to:

To add the integrator, one need to active the "integrator" filter as follows.

Changed line 264 from:

model.x.penalty = QuadFunction( 5 );

to:

model.with('integrator');

Changed line 266 from:

as well as the penalty on the inputs

to:

In the remainder of MPC set, the penalty on the predicted difference of the integrator state and the reference is provided

Changed line 268 from:

model.u.penalty = QuadFunction( 1 );

to:

model.x.penalty = QuadFunction( 5 );

Changed line 270 from:

The resulting controller is exported to an explicit form

to:

as well as the penalty on the inputs

Changed lines 272-273 from:

ctrl = MPCController(model, 4); ectrl = ctrl.toExplicit();

to:

model.u.penalty = QuadFunction( 1 );

Changed line 274 from:

and a closed form is created with the help of ClosedLoop object:

to:

The resulting controller is exported to an explicit form

Changed lines 276-277 from:

loop = ClosedLoop( ectrl, model);

to:

ctrl = MPCController(model, 4); ectrl = ctrl.toExplicit();

Changed line 279 from:

The simulation results are the same as in the previous example, but this time obtained with the integrator state

to:

and a closed form is created with the help of ClosedLoop object:

Added lines 281-284:

loop = ClosedLoop( ectrl, model); @] The simulation results are the same as in the previous example, but this time obtained with the integrator state (:source lang=MATLAB -getcode:) [@

Deleted lines 291-292:

subplot(2, 1, 1); plot(1:Nsim, data.X(1:Nsim) ); title('state') subplot(2, 1, 2); plot(1:Nsim, data.U); title('input')

Changed lines 293-308 from:
to:

The simulated data can be plotted together with the reference signal and constraints

(:source lang=MATLAB -getcode:)
subplot(2, 1, 1); hold on;
plot(1:Nsim, data.X(1:Nsim), 'linewidth', 2 ); 
plot(1:Nsim, model.x.max*ones(1,Nsim), 'k--', 'linewidth', 2);
plot(1:Nsim, model.x.min*ones(1,Nsim), 'k--', 'linewidth', 2);
stairs(1:Nsim, xref, 'r--', 'linewidth', 2);
axis([1, Nsim, -11, 11]);
title('state')
subplot(2, 1, 2); hold on;
stairs(1:Nsim, data.U, 'linewidth', 2); 
plot(1:Nsim, model.u.max*ones(1, Nsim), 'k--', 'linewidth', 2);
plot(1:Nsim, model.u.min*ones(1, Nsim), 'k--', 'linewidth', 2);
axis([1, Nsim, -6, 6]);
title('input')
August 15, 2013, at 10:59 AM by Martin Herceg -
Changed line 49 from:

subplot(2, 1, 2); plot(1:30, data.U, 'linewidth', 2);

to:

subplot(2, 1, 2); plot(1:Nsim, data.U, 'linewidth', 2);

Changed lines 63-64 from:

subplot(2, 1, 1); plot(1:31, data.X); title('states') subplot(2, 1, 2); plot(1:30, data.U); title('inputs')

to:

subplot(2, 1, 1); hold on; grid on; plot(1:Nsim, data.X(:,1:Nsim), 'linewidth', 2); stairs(1:Nsim, xref(2,:), 'k--', 'linewidth', 2); axis([1, Nsim, -3, 4]); title('states') subplot(2, 1, 2); hold on; grid on; plot(1:Nsim, data.U, 'linewidth', 2); axis([1, Nsim, -1, 1]); title('inputs')

August 15, 2013, at 10:52 AM by Martin Herceg -
Changed lines 42-43 from:

subplot(2, 1, 1); plot(1:31, data.X); title('states') subplot(2, 1, 2); plot(1:30, data.U); title('inputs')

to:

@] The results of the simulation can be plotted nicely (:source lang=MATLAB -getcode:) [@ subplot(2, 1, 1); plot(1:Nsim, data.X(:,1:Nsim), 'linewidth', 2); axis([1, Nsim, -2, 2]); grid on; title('states'); subplot(2, 1, 2); plot(1:30, data.U, 'linewidth', 2); axis([1, Nsim, -1, 1]); grid on; title('inputs');

August 15, 2013, at 10:43 AM by Martin Herceg -
Changed lines 136-137 from:

subplot(2, 1, 1); plot(1:Nsim, data.Y); title('output') subplot(2, 1, 2); stairs(1:Nsim, data.U); title('input')

to:

subplot(2, 1, 1); plot(1:Nsim, data.Y, 'linewidth', 2); hold on; grid on; plot(1:Nsim, model.y.max*ones(1, Nsim), 'k--', 'linewidth', 2); plot(1:Nsim, model.y.min*ones(1, Nsim), 'k--', 'linewidth', 2); stairs(1:Nsim, yref, 'r--', 'linewidth', 2); axis([1, Nsim, -12, 12]); title('output') subplot(2, 1, 2); stairs(1:Nsim, data.U, 'linewidth', 2); hold on; grid on; plot(1:Nsim, model.u.max*ones(1, Nsim), 'k--', 'linewidth', 2); plot(1:Nsim, model.u.min*ones(1, Nsim), 'k--', 'linewidth', 2); axis([1, Nsim, -4, 4]); title('input')

August 15, 2013, at 10:33 AM by Martin Herceg -
Changed line 116 from:

The closed-loop simulation can be evaluated using the ClosedLoop object

to:

and plot the partition

Changed line 118 from:

loop = ClosedLoop(ectrl, model);

to:

ectrl.partition.plot()

Changed lines 120-121 from:

by providing the time varying reference signal yref

to:

The closed-loop simulation can be evaluated using the ClosedLoop object

Added lines 123-126:

loop = ClosedLoop(ectrl, model); @] by providing the time varying reference signal yref (:source lang=MATLAB -getcode:) [@

Changed line 137 from:

subplot(2, 1, 2); plot(1:Nsim, data.U); title('input')

to:

subplot(2, 1, 2); stairs(1:Nsim, data.U); title('input')

Added line 139:
Changed line 157 from:

subplot(2, 1, 2); plot(1:40, U); title('input')

to:

subplot(2, 1, 2); stairs(1:40, U); title('input')

August 15, 2013, at 10:25 AM by Martin Herceg -
Added line 45:
Added line 58:
Changed line 80 from:
to:
August 15, 2013, at 10:21 AM by Martin Herceg -
Changed line 78 from:
to:
August 05, 2013, at 11:37 AM by Martin Herceg -
Changed line 187 from:

u = 0;

to:

u0 = 0;

Deleted line 189:

xref = [repmat( xref1, 1, 10), repmat(xref2, 1, 10)];

Changed lines 191-192 from:

data = loop.simulate(x0, Nsim, 'u.previous', u, 'x.reference', xref);

to:

xref = [repmat( xref1, 1, Nsim/2), repmat(xref2, 1, Nsim/2)]; data = loop.simulate(x0, Nsim, 'u.previous', u0, 'x.reference', xref);

Changed line 231 from:

The simulation results are the same as in the previous example, but this time obtained with the integrator state

to:

and a closed form is created with the help of ClosedLoop object:

Changed lines 233-249 from:

x0 = 0; u = 0; X = []; U = []; model.initialize( x0 ); for i=1:20

   if i<10
      xref = 5;
   else 
      xref = -3;
   end
   X = [X, x0];
   u = ectrl.evaluate(x0, 'u.previous', u, 'x.reference', xref);
   U = [U, u];
   x0 = model.update(u);

end subplot(2, 1, 1); plot(1:20, X); title('state') subplot(2, 1, 2); plot(1:20, U); title('inputs')

to:

loop = ClosedLoop( ectrl, model);

Changed lines 235-246 from:
to:

The simulation results are the same as in the previous example, but this time obtained with the integrator state

(:source lang=MATLAB -getcode:)
x0 = 0;
u0 = 0;
xref1 = 5;
xref2 = -3;
Nsim = 20;
xref = [repmat( xref1, 1, Nsim/2), repmat(xref2, 1, Nsim/2)];
data = loop.simulate(x0, Nsim, 'u.previous', u0, 'x.reference', xref);
subplot(2, 1, 1); plot(1:Nsim, data.X(1:Nsim) ); title('state')
subplot(2, 1, 2); plot(1:Nsim, data.U); title('input')
August 05, 2013, at 11:31 AM by Martin Herceg -
Changed line 180 from:

Simulate the performance of the explicit controller in 20 samples

to:

For simulation purposes, the ClosedLoop object is created with the explicit controller and the same model that was used for MPC design

Changed lines 182-186 from:

x0 = 0;

to:

loop = ClosedLoop( ectrl, model); @] Simulate the performance of the explicit controller in 20 samples and plot the closed loop trajectories (:source lang=MATLAB -getcode:) [@ x0 = 0;

Changed lines 188-202 from:

X = []; U = []; model.initialize(x0); for i=1:20

   if i<10
      xref = 5;
   else 
      xref = -3;
   end
   X = [X, x0];
   u = ectrl.evaluate(x0, 'u.previous', u, 'x.reference', xref);
   U = [U, u];
   x0 = model.update(u);

end subplot(2, 1, 1); plot(1:20, X); title('state') subplot(2, 1, 2); plot(1:20, U); title('inputs')

to:

xref1 = 5; xref2 = -3; xref = [repmat( xref1, 1, 10), repmat(xref2, 1, 10)]; Nsim = 20; data = loop.simulate(x0, Nsim, 'u.previous', u, 'x.reference', xref); subplot(2, 1, 1); plot(1:Nsim, data.X(1:Nsim)); title('state') subplot(2, 1, 2); plot(1:Nsim, data.U); title('input')

Deleted line 195:
August 05, 2013, at 10:30 AM by Martin Herceg -
Changed line 130 from:

subplot(2, 1, 2); plot(1:Nsim, data.U); title('inputs')

to:

subplot(2, 1, 2); plot(1:Nsim, data.U); title('input')

Changed line 149 from:

subplot(2, 1, 2); plot(1:40, U); title('inputs')

to:

subplot(2, 1, 2); plot(1:40, U); title('input')

August 05, 2013, at 10:27 AM by Martin Herceg -
Changed lines 114-132 from:

The following simulation shows step-wise changes in the output reference over 30 samples that is obtained by evaluating the explicit controller

to:

The closed-loop simulation can be evaluated using the ClosedLoop object

(:source lang=MATLAB -getcode:)
loop = ClosedLoop(ectrl, model);

by providing the time varying reference signal yref

(:source lang=MATLAB -getcode:)
yref1 = 1;
yref2 = -2;
yref = [repmat(yref1, 1, 20), repmat(yref2, 1, 20)];
x0 = zeros(2,1); 
Nsim = 40;
data = loop.simulate(x0, Nsim, 'y.reference', yref);

The simulation results are stored in the output variable data and can be plotted

(:source lang=MATLAB -getcode:)
subplot(2, 1, 1); plot(1:Nsim, data.Y); title('output')
subplot(2, 1, 2); plot(1:Nsim, data.U); title('inputs')

In the next code sample you can find the manual decomposition of the simulation which shows the step-wise changes in the output reference over 30 samples and the input is obtained by evaluating the explicit controller

August 05, 2013, at 10:14 AM by Martin Herceg -
Changed lines 103-104 from:

model.y.penalty = OneNormFunction(3); model.u.penalty = OneNormFunction(0.5);

to:

model.y.penalty = OneNormFunction( 3 ); model.u.penalty = OneNormFunction( 0.5 );

Changed line 108 from:

ctrl = MPCController(model, 3)

to:

ctrl = MPCController(model, 3);

Changed lines 130-131 from:

subplot(2,1,1); plot(1:40,Y); title('output') subplot(2,1,2); plot(1:40,U); title('inputs')

to:

subplot(2, 1, 1); plot(1:40, Y); title('output') subplot(2, 1, 2); plot(1:40, U); title('inputs')

Changed lines 179-180 from:

subplot(2,1,1); plot(1:20,X); title('state') subplot(2,1,2); plot(1:20,U); title('inputs')

to:

subplot(2, 1, 1); plot(1:20, X); title('state') subplot(2, 1, 2); plot(1:20, U); title('inputs')

Changed line 223 from:

model.initialize(x0);

to:

model.initialize( x0 );

Changed lines 235-236 from:

subplot(2,1,1); plot(1:20,X); title('state') subplot(2,1,2); plot(1:20,U); title('inputs')

to:

subplot(2, 1, 1); plot(1:20, X); title('state') subplot(2, 1, 2); plot(1:20, U); title('inputs')

August 05, 2013, at 10:08 AM by Martin Herceg -
Changed lines 130-133 from:

subplot(2,1,1); plot(1:40,Y); title('output') subplot(2,1,2); plot(1:40,U); title('inputs')

to:

subplot(2,1,1); plot(1:40,Y); title('output') subplot(2,1,2); plot(1:40,U); title('inputs')

Changed lines 179-182 from:

subplot(2,1,1); plot(1:20,X); title('state') subplot(2,1,2); plot(1:20,U); title('inputs')

to:

subplot(2,1,1); plot(1:20,X); title('state') subplot(2,1,2); plot(1:20,U); title('inputs')

Changed line 216 from:

ectrl = ctrl.toExplicit;

to:

ectrl = ctrl.toExplicit();

Changed lines 235-238 from:

subplot(2,1,1); plot(1:20,X); title('state') subplot(2,1,2); plot(1:20,U); title('inputs')

to:

subplot(2,1,1); plot(1:20,X); title('state') subplot(2,1,2); plot(1:20,U); title('inputs')

August 05, 2013, at 10:04 AM by Martin Herceg -
Changed lines 28-29 from:

model.x.penalty = OneNormFunction(diag([0.5, 1, 0]) ); model.u.penalty = OneNormFunction(eye(2));

to:

model.x.penalty = OneNormFunction( diag([0.5, 1, 0]) ); model.u.penalty = OneNormFunction( eye(2) );

Changed line 37 from:

cl = ClosedLoop(ctrl,model);

to:

loop = ClosedLoop(ctrl, model);

Changed line 41 from:

data = cl.simulate(x0, Nsim, 'x.reference', xref)

to:

data = loop.simulate(x0, Nsim, 'x.reference', xref)

Changed line 53 from:

data = cl.simulate(x0, Nsim, 'x.reference', xref);

to:

data = loop.simulate(x0, Nsim, 'x.reference', xref);

Changed lines 75-78 from:

subplot(2,1,1); plot(1:30,X); title('states') subplot(2,1,2); plot(1:30,U); title('inputs')

to:

subplot(2,1,1); plot(1:30,X); title('states') subplot(2,1,2); plot(1:30,U); title('inputs')

August 05, 2013, at 08:51 AM by Michal Kvasnica -
Changed line 43 from:

subplot(2,1,2); plot(1:30, data.U); title('inputs')

to:

subplot(2, 1, 2); plot(1:30, data.U); title('inputs')

Changed lines 54-55 from:

subplot(2,1,1); plot(1:31, data.X); title('states') subplot(2,1,2); plot(1:30, data.U); title('inputs')

to:

subplot(2, 1, 1); plot(1:31, data.X); title('states') subplot(2, 1, 2); plot(1:30, data.U); title('inputs')

August 05, 2013, at 08:50 AM by Michal Kvasnica -
Changed line 18 from:

model.u.min = [-2;-3];

to:

model.u.min = [-2; -3];

Changed lines 41-45 from:

d = cl.simulate(x0, Nsim, 'x.reference', xref) subplot(2,1,1); plot(1:31,d.X); title('states') subplot(2,1,2); plot(1:30,d.U); title('inputs')

to:

data = cl.simulate(x0, Nsim, 'x.reference', xref) subplot(2, 1, 1); plot(1:31, data.X); title('states') subplot(2,1,2); plot(1:30, data.U); title('inputs')

Changed lines 53-57 from:

d = cl.simulate(x0, Nsim, 'x.reference', xref); subplot(2,1,1); plot(1:31,d.X); title('states') subplot(2,1,2); plot(1:30,d.U); title('inputs')

to:

data = cl.simulate(x0, Nsim, 'x.reference', xref); subplot(2,1,1); plot(1:31, data.X); title('states') subplot(2,1,2); plot(1:30, data.U); title('inputs')

August 05, 2013, at 08:43 AM by Michal Kvasnica -
Changed lines 38-41 from:

d = cl.simulate(zeros(3,1),30,'x.reference',[0; 1; 0])

to:

x0 = [0; 0; 0]; Nsim = 30; xref = [0; 1; 0]; d = cl.simulate(x0, Nsim, 'x.reference', xref)

Changed line 47 from:

For a time-varying referece, the simulation is decomposed into a for-loop and the reference is changing step-wise after 10 samples

to:

The simulate method also allows to provide time-varying profiles of references, e.g.

Added lines 49-62:

xref1 = [0; 1; 0]; xref2 = [0; 2; 0]; xref3 = [0; 3; 0]; xref = [repmat(xref1, 1, 10), repmat(xref2, 1, 10), repmat(xref3, 1, 10)]; x0 = [0; 0; 0]; Nsim = 30; d = cl.simulate(x0, Nsim, 'x.reference', xref); subplot(2,1,1); plot(1:31,d.X); title('states') subplot(2,1,2); plot(1:30,d.U); title('inputs') @] The same result can be obtained manually using a for-loop as follows: (:source lang=MATLAB -getcode:) [@

Changed line 69 from:
      yref = [0; 1; 0];
to:
      xref = [0; 1; 0];
Changed line 71 from:
      yref = [0; 2; 0];
to:
      xref = [0; 2; 0];
Changed line 73 from:
      yref = [0; 3; 0];
to:
      xref = [0; 3; 0];
Changed line 75 from:
   u = ctrl.evaluate(x0, 'x.reference', yref);
to:
   u = ctrl.evaluate(x0, 'x.reference', xref);
Changed line 118 from:

ectrl = ctrl.toExplicit;

to:

ectrl = ctrl.toExplicit();

Changed line 168 from:

ectrl = ctrl.toExplicit;

to:

ectrl = ctrl.toExplicit();

August 03, 2013, at 07:55 PM by Martin Herceg -
Added lines 180-232:

The tracking of a time-varying reference can be achieved by augmenting the state with an integrator state that predicts the steady state values. In MPT this can be achieved with the help of "integrator" filter that extends the model with an integrator state. Consider the unstable LTI system as in the previous example that operates under input and state constraints

(:source lang=MATLAB -getcode:)
model = LTISystem('A', 1.5 , 'B', 1 );
model.x.min = -10;
model.x.max = 10;
model.u.min = -5;
model.u.max = 5;

Activate the time-varying reference

(:source lang=MATLAB -getcode:)
model.x.with('reference');
model.x.reference = 'free';

To add the integrator, one need to active the "integrator" filter as follows.

(:source lang=MATLAB -getcode:)
model.with('integrator');

In the remainder of MPC set, the penalty on the predicted difference of the integrator state and the reference is provided

(:source lang=MATLAB -getcode:)
model.x.penalty = QuadFunction( 5 );

as well as the penalty on the inputs

(:source lang=MATLAB -getcode:)
model.u.penalty = QuadFunction( 1 );

The resulting controller is exported to an explicit form

(:source lang=MATLAB -getcode:)
ctrl = MPCController(model, 4);
ectrl = ctrl.toExplicit;

The simulation results are the same as in the previous example, but this time obtained with the integrator state

(:source lang=MATLAB -getcode:)
x0 = 0; 
u = 0;
X = []; U = [];
model.initialize(x0);
for i=1:20
   if i<10
      xref = 5;
   else 
      xref = -3;
   end
   X = [X, x0];
   u = ectrl.evaluate(x0, 'u.previous', u, 'x.reference', xref);
   U = [U, u];
   x0 = model.update(u);
end
subplot(2,1,1);
plot(1:20,X); title('state')
subplot(2,1,2);
plot(1:20,U); title('inputs')
August 03, 2013, at 07:39 PM by Martin Herceg -
Added lines 129-175:

Consider the following unstable LTI system subject to input and state constraints

(:source lang=MATLAB -getcode:)
model = LTISystem('A', 1.5 , 'B', 1);
model.x.min = -10;
model.x.max = 10;
model.u.min = -5;
model.u.max = 5;

The objective is to follow a time-varying state signal subject to delta-u formulation. The activation of the time-varying signal is achived via "reference" filter

(:source lang=MATLAB -getcode:)
model.x.with('reference');
model.x.reference = 'free';
model.x.penalty = QuadFunction(5);

The delta-u formulation \Delta u(k) = u(k) - u(k-1) is activated with the "deltaPenalty" filter

(:source lang=MATLAB -getcode:)
model.u.with('deltaPenalty');
model.u.deltaPenalty = QuadFunction(1);

The online MPCController object is created with a horizon 4 and exported to an explicit form

(:source lang=MATLAB -getcode:)
ctrl = MPCController(model, 4);
ectrl = ctrl.toExplicit;

Simulate the performance of the explicit controller in 20 samples

(:source lang=MATLAB -getcode:)
x0 = 0; 
u = 0;
X = []; U = [];
model.initialize(x0);
for i=1:20
   if i<10
      xref = 5;
   else 
      xref = -3;
   end
   X = [X, x0];
   u = ectrl.evaluate(x0, 'u.previous', u, 'x.reference', xref);
   U = [U, u];
   x0 = model.update(u);
end
subplot(2,1,1);
plot(1:20,X); title('state')
subplot(2,1,2);
plot(1:20,U); title('inputs')
August 03, 2013, at 07:08 PM by Martin Herceg -
Changed lines 69-70 from:

Input and output tracking

to:

Output tracking

Consider a simple PWA system that comprises of two modes and has one output

(:source lang=MATLAB -getcode:)
mode1 = LTISystem('A', [ 0.4 0.69; -0.69 0.4], 'B', [0;1], 'C', [1, 0]);
mode1.setDomain('x', Polyhedron('A', [1 0], 'b', 0) );
mode2 = LTISystem('A', [ 0.4 -0.69; 0.69 0.4], 'B', [0;1], 'C', [1, 0]);
mode2.setDomain('x', Polyhedron('A', [-1 0], 'b', 0) );
model = PWASystem([mode1, mode2]);

The model is subject to input/output constraints

(:source lang=MATLAB -getcode:)
model.u.min = -3;
model.u.max = 3;
model.y.min = -10;
model.y.max = 10;

The objective is to track the time varying output while satisfying the constraints. To incorporate a time varying signal one needs to active the appropriate reference filter and mark it as "free"

(:source lang=MATLAB -getcode:)
model.y.with('reference');
model.y.reference = 'free';

To finalize the MPC setup, penalty on inputs and outputs are provided

(:source lang=MATLAB -getcode:)
model.y.penalty = OneNormFunction(3);
model.u.penalty = OneNormFunction(0.5);

and the online MPCController object is constructed with horizon 3

(:source lang=MATLAB -getcode:)
ctrl = MPCController(model, 3)

After testing the performance of the online-controller, one can export it to the explicit form as follows:

(:source lang=MATLAB -getcode:)
ectrl = ctrl.toExplicit;

The following simulation shows step-wise changes in the output reference over 30 samples that is obtained by evaluating the explicit controller

(:source lang=MATLAB -getcode:)
x0 = zeros(2,1); 
Y = []; U = [];
model.initialize(x0);
for i=1:40
   if i<20
      yref = 1;
   else 
      yref = -2;
   end
   u = ectrl.evaluate(x0, 'y.reference', yref);
   U = [U, u];
   [x0, y] = model.update(u);
   Y = [Y, y];
end
subplot(2,1,1);
plot(1:40,Y); title('output')
subplot(2,1,2);
plot(1:40,U); title('inputs')
August 03, 2013, at 06:07 PM by Martin Herceg -
Added lines 12-70:

State tracking

Consider an LTI system with 3 states and 2 inputs subject to state and input constraints

(:source lang=MATLAB -getcode:)
model = LTISystem('A', [ -0.79  -0.3 -0.1; 0.5  0.82 1.23; 0.52 -0.3 -0.5], 'B', [ -2.04 -0.21; -1.28  2.75; 0.29 -1.41]);
model.x.min = [-10; -9; -8];
model.x.max = [10; 9; 8];
model.u.min = [-2;-3];
model.u.max = [2; 3];

The objective is to track the second state that varies in time. To provide a time-varying reference the reference filter is activated on the state signal and the value is set to "free", indicating a time-varying reference.

(:source lang=MATLAB -getcode:)
model.x.with('reference');
model.x.reference = 'free';

In the remainder of the MPC setup, the penalties on the states and inputs are provided.

(:source lang=MATLAB -getcode:)
model.x.penalty = OneNormFunction(diag([0.5, 1, 0]) );
model.u.penalty = OneNormFunction(eye(2));

and the online MPCController object is constructed with horizon 4:

(:source lang=MATLAB -getcode:)
ctrl = MPCController(model, 4)

For simulation purposes, a closed loop object is constructed and simulated for a constant reference value [0; 1; 0] over 30 samples

(:source lang=MATLAB -getcode:)
cl = ClosedLoop(ctrl,model);
d = cl.simulate(zeros(3,1),30,'x.reference',[0; 1; 0])
subplot(2,1,1);
plot(1:31,d.X); title('states')
subplot(2,1,2);
plot(1:30,d.U); title('inputs')

For a time-varying referece, the simulation is decomposed into a for-loop and the reference is changing step-wise after 10 samples

(:source lang=MATLAB -getcode:)
x0 = zeros(3,1); 
X = []; U = [];
model.initialize(x0);
for i=1:30
   X = [X, x0];
   if i<10
      yref = [0; 1; 0];
   elseif i<20
      yref = [0; 2; 0];
   else 
      yref = [0; 3; 0];
   end
   u = ctrl.evaluate(x0, 'x.reference', yref);
   U = [U, u];
   x0 = model.update(u);
end
subplot(2,1,1);
plot(1:30,X); title('states')
subplot(2,1,2);
plot(1:30,U); title('inputs')

Input and output tracking

August 03, 2013, at 05:14 PM by Martin Herceg -
Added lines 1-23:

Tracking problem


Tracking of time varying references

Tracking with delta u formulation

Tracking with builtin integrator

Back to MPC synthesis overview.