What is the built-in Kalman filter mean in the MPC Controller block?

8 views (last 30 days)
Can any specialist answer my quesiton?
The inside M code is as follows, and I cannot figure out the relationship between the Kalman filter and MPC controller, can anyone help me ?
///////////
function [xk1, u, cost, useq, xseq, yseq, status, xest, iAout] = fcn(...
xk, old_u, ym, ref, md, umin, umax, ymin, ymax, E, F, G, S, switch_in, ext_mv, MVtarget, isQP, nx, nu, ny, degrees, Hinv, Kx, Ku1, Kut, Kr, Kv, Mlim, ...
Mx, Mu1, Mv, z_degrees, utarget, p, uoff, voff, yoff, maxiter, ...
CustomSolver, CustomSolverCodeGen, UseWarmStart, UseSuboptimalSolution, nxQP, openloopflag, ...
no_umin, no_umax, no_ymin, no_ymax, no_cc, switch_inport, no_switch, enable_value, ...
return_cost, H, return_mvseq, return_xseq, return_ovseq, Linv, Ac, ...
ywt, uwt, duwt, rhoeps, iA, ...
no_ywt, no_uwt, no_duwt, no_rhoeps,...
Wy, Wdu, Jm, SuJm, Su1, Sx, Hv, Wu, I1, ...
A, Bu, Bv, C, Dv, Mrows, nCC, Ecc, Fcc, Scc, Gcc, ...
nv, no_md, no_ref, no_uref, no_mv, RYscale, RMDscale, myindex, ...
myoff, xoff, CustomEstimation, M, L)
%#codegen
coder.extrinsic('mpcblock_optimizer_double_mex');
coder.extrinsic('mpcblock_optimizer_single_mex');
coder.extrinsic('mpcblock_refmd_double_mex');
coder.extrinsic('mpcblock_refmd_single_mex');
% Parameters
isSimulation = coder.target('Sfun') && ~coder.target('RtwForRapid') && ~coder.target('RtwForSim');
isAdaptive = false;
isLTV = false;
isDouble = isa(ref,'double');
ZERO = zeros('like',ref);
ONE = ones('like',ref);
% Pre-allocate all the MEX block outputs for the simulation mode
%#ok<*NASGU>
%#ok<*PREALL>
if isSimulation
rseq = zeros(p*ny,1,'like',ref);
vseq = zeros((p+1)*nv,1,'like',ref);
v = zeros(nv,1,'like',ref);
xk1 = zeros(nx,1,'like',ref);
u = zeros(nu,1,'like',ref);
cost = ZERO;
useq = zeros(p+1,nu,'like',ref);
status = ONE;
xest = zeros(nx,1,'like',ref);
iAout = iA;
end
% Get reference and MD signals -- accounting for previewing
if isSimulation
% When doing normal simulation in SL, use MEX for better compilation speed
if isDouble
[rseq, vseq, v] = mpcblock_refmd_double_mex(ref,md,nv,ny,p,yoff,voff,no_md,no_ref,openloopflag, RYscale, RMDscale);
else
[rseq, vseq, v] = mpcblock_refmd_single_mex(ref,md,nv,ny,p,yoff,voff,no_md,no_ref,openloopflag, RYscale, RMDscale);
end
else
% When doing code generation, use M code directly
[rseq, vseq, v] = mpcblock_refmd(ref,md,nv,ny,p,yoff,voff,no_md,no_ref,openloopflag, RYscale, RMDscale);
end
% External MV override.
% NOTE: old_u and ext_mv input signals are dimensionless but include offset
old_u = old_u - uoff;
if no_mv==ONE
delmv = zeros(nu,1,'like',ref);
else
ext_mv = ext_mv - uoff; % Bias correction
delmv = ext_mv - old_u;
old_u = ext_mv;
end
% Obtain x[k|k]
xk = xk - xoff; % Remove offset
if CustomEstimation==ONE
% Input state is x(k|k)
xest = xk;
else
% Default state estimation.
% Scale measured output and remove offset.
ym = ym.*RYscale(myindex) - myoff;
% Correct x(k|k-1) for possible external mv override.
% NOTE: Offset was removed from x[k|k-1] at k=0.
xk = xk + Bu*delmv;
% Measurement upate to x(k|k)
ym_est = C(myindex,:)*xk + Dv(myindex,:)*v;
y_innov = ym - ym_est;
xest = xk + M*y_innov;
end
% Real-time MV target override
% Note: utargetValue is a vector length p*nu.
if no_uref==ONE
% no external utarget
utargetValue = utarget;
else
% utarget is a vector length p*nu. Define constant targets for the
% entire horizon.
MVtarget = MVtarget - uoff; % Bias correction
utargetValue = reshape(MVtarget(:,ones(p,1)),nu*p,1);
end
% Real-time custom constraint override (scaled E/F/S)
if no_cc~=ONE
Ecc = E;
Fcc = F;
Gcc = G;
if nv>1
Scc = S;
end
end
return_sequence = (return_mvseq || return_xseq || return_ovseq)*ONE;
if isSimulation
% When doing normal simulation in SL, use MEX for better compilation speed
if isDouble
[u, cost, useq, status, iAout] = mpcblock_optimizer_double_mex(...
rseq, vseq, umin, umax, ymin, ymax, switch_in, xest, old_u, iA, ...
isQP, nu, ny, degrees, Hinv, Kx, Ku1, Kut, Kr, Kv, Mlim, ...
Mx, Mu1, Mv, z_degrees, utargetValue, p, uoff, voff, yoff, maxiter, ...
CustomSolver, false, UseWarmStart, UseSuboptimalSolution, nxQP, openloopflag, ...
no_umin, no_umax, no_ymin, no_ymax, no_cc, switch_inport, ...
no_switch, enable_value, return_cost, H, return_sequence, Linv, Ac, ...
ywt, uwt, duwt, rhoeps, no_ywt, no_uwt, no_duwt, no_rhoeps,...
Wy, Wdu, Jm, SuJm, Su1, Sx, Hv, Wu, I1, ...
isAdaptive, isLTV, A, Bu, Bv, C, Dv, ...
Mrows, nCC, Ecc, Fcc, Scc, Gcc);
else
[u, cost, useq, status, iAout] = mpcblock_optimizer_single_mex(...
rseq, vseq, umin, umax, ymin, ymax, switch_in, xest, old_u, iA, ...
isQP, nu, ny, degrees, Hinv, Kx, Ku1, Kut, Kr, Kv, Mlim, ...
Mx, Mu1, Mv, z_degrees, utargetValue, p, uoff, voff, yoff, maxiter, ...
CustomSolver, false, UseWarmStart, UseSuboptimalSolution, nxQP, openloopflag, ...
no_umin, no_umax, no_ymin, no_ymax, no_cc, switch_inport, ...
no_switch, enable_value, return_cost, H, return_sequence, Linv, Ac, ...
ywt, uwt, duwt, rhoeps, no_ywt, no_uwt, no_duwt, no_rhoeps,...
Wy, Wdu, Jm, SuJm, Su1, Sx, Hv, Wu, I1, ...
isAdaptive, isLTV, A, Bu, Bv, C, Dv, ...
Mrows, nCC, Ecc, Fcc, Scc, Gcc);
end
else
% When doing code generation, use M code directly
[u, cost, useq, status, iAout] = mpcblock_optimizer(...
rseq, vseq, umin, umax, ymin, ymax, switch_in, xest, old_u, iA, ...
isQP, nu, ny, degrees, Hinv, Kx, Ku1, Kut, Kr, Kv, Mlim, ...
Mx, Mu1, Mv, z_degrees, utargetValue, p, uoff, voff, yoff, maxiter, ...
false, CustomSolverCodeGen, UseWarmStart, UseSuboptimalSolution, nxQP, openloopflag, ...
no_umin, no_umax, no_ymin, no_ymax, no_cc, switch_inport, ...
no_switch, enable_value, return_cost, H, return_sequence, Linv, Ac, ...
ywt, uwt, duwt, rhoeps, no_ywt, no_uwt, no_duwt, no_rhoeps,...
Wy, Wdu, Jm, SuJm, Su1, Sx, Hv, Wu, I1, ...
isAdaptive, isLTV, A, Bu, Bv, C, Dv, ...
Mrows, nCC, Ecc, Fcc, Scc, Gcc);
end
if return_xseq || return_ovseq
[yseq, xseq] = mpc_computeSequence(isLTV, xest, useq, vseq, uoff, yoff, xoff, p, ny, nxQP, nv, A, Bu, Bv, C, Dv);
else
yseq = zeros(p+1,ny,'like',rseq);
xseq = zeros(p+1,nxQP,'like',rseq);
end
if CustomEstimation==ONE
xk1 = xk;
else
% update x[k+1|k], assuming that above u and v will be applied.
xk1 = A*xk + Bu*(u - uoff) + Bv*v + L*y_innov;
end
xk1 = xk1 + xoff; % Updated state must include offset
% return xest in original value
xest = xest + xoff;

Answers (1)

Pratheek Punchathody
Pratheek Punchathody on 12 Feb 2021
By default, MPC uses a static Kalman filter (KF) to update its controller states that derives from the state observer. Refer to the documemntation on State Estimation and Adaptive MPC.
Also refer to the documentation Adaptive MPC Controller for further details.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!