function [blk,Ts,A,Cm,Bu,Bv,Dvm,isQP,strmoorx,nmoorx,nmv,nv,ny,nx,nmy,...
    degrees,L,M,H,Hinv,Linv,iA,Ac,Kx,Ku1,Kut,Kr,Kv,...
    Mlim,Mx,Mu1,Mv,utarget,...
    lastx,lastu,p,xoff,mvoff,yoff,mdoff,myoff,no_md,no_ref,...
    CustomSolver,CustomSolverCodeGen,UseSuboptimalSolution,...
    UseActiveSetSolver,ASOptions,IPOptions,ADOptions,...
    MIQPOptions,isHyb,Mdis,Vdis,Ndis,numdis,maxdis,...
    nxQP,openloopflag,no_ym,no_mv,no_uref,...
    no_umin,no_umax,no_ymin,no_ymax,no_cc,...
    no_switch,CustomEstimation,...
    no_ywt,no_uwt,no_duwt,no_rhoeps,...
    Wy,Wdu,Jm,SuJm,Su1,Sx,Hv,Wu,I1,...
    isDouble,isAdaptive,C,Dv,Mrows,nCC,E,F,S,G,...
    nxp,nxindist,mvindex,mdindex,udindex,myindex,...
    Uscale,Yscale,MVscale,MDscale,...
    RYscale,RMYscale,RMVscale,RMDscale,no_p,no_m,p0,m] = impcblock_MaskInitFcnParameter(return_cost,return_mvseq,return_xseq,return_ovseq)
% MPC block uses three functions in the following order to initialize:
%
%   InitFcn: collect data from @mpc and @mpcstate objects specified in the
%   block dialog.  Obtain additional inport and outport connection
%   information (i.e. optional ports on/off status, whether an inport is
%   connected to a source block), special mmpc settings, and some scaling
%   data.  Save the structure to block "UserData".
%
%   MaskInitFcn: split into two functions: Parameter and Resize.
%
%       Parameter: when "UserData" is empty (i.e. model opens or no @mpc),
%       initialize the block with correct information for compilation.
%       Otherwise, create mask variables from "UserData" with additional
%       sanity check and memory optimization.
%
%       Resize: modify the block I/O based on dialog settings.  Each
%       constant block (when an optional inport is off) is initialized with
%       correct dimension.
%
%   StartFcn: check signal connectivity to MPC Controller block.  Signal
%   dimensions are already checked in the C S-function blocks connected to
%   the inports.  This function is called after compilation is done.
%
%   When using fixed horizon, parameter "p" = mpcobj.p and "p0" is irrelevant.
%   When using online horizon, parameter "p" = maximum p, "p0" = mpcobj.p.

%   Authors: A. Bemporad, N. L. Ricker, R. Chen
%   Copyright 1986-2021 The MathWorks, Inc.

% MPC block parameter "UserData" can have the following values:
%   []          - when SL model is open/loaded or design from scratch
%   MPCstruct   - generated from block InitFcn

blk = gcb;
root = bdroot(blk);
MPCstruct = get_param(blk,'Userdata');
DataType = get_param(blk,'BlockDataType');
ONE = ones(DataType);
ZERO = zeros(DataType);
ONE32 = ones('int32');
ZERO32 = zeros('int32');
isDouble = strcmp(DataType,'double');
isAdaptive = false;     
%% When open SL model or design from scratch, MPCstruct is empty
if isempty(MPCstruct)
    %% Non-required parameters for this operation
    [H,Hinv,Linv,Ac,Kx,Ku1,Kut,Kr,Kv,...
        Mlim,Mx,Mu1,Mv,utarget,xoff,yoff,mdoff,...
        Wy,Wdu,Jm,SuJm,Su1,Sx,Hv,Wu,I1,E,F,S,G] = deal(ZERO);
    [degrees,nxp,nxindist,mvindex,mdindex,udindex,Mrows,nCC,p0] = deal(int32(0));
    [no_md,no_ref,no_ym,no_umin,no_umax,no_ymin,no_ymax,no_switch, ...
        no_ywt, no_uwt, no_duwt, no_rhoeps, no_uref, no_p, no_m] = deal(false);
    %% Sample time (must be in double precision)
    Ts = double(slResolve(get_param(blk,'n_ts'), root));
    if Ts==ZERO
        Ts = ONE;
    end
    %% no_mv must be true for letting last_u pass through
    no_mv = true;
    %% no_cc must be true for sizing
    no_cc = true;
    %% Key dimensions
    p = int32(max(ONE,slResolve(get_param(blk,'n_p'),root)));
    % # of MV: make sure default n_mv is valid
    defaultNMV = int32(slResolve(get_param(blk,'n_mv'),root));
    if defaultNMV==ZERO32
        set_param(blk,'n_mv','1');
        defaultNMV = ONE32;
    end
    nmv = defaultNMV;
    % # of MO: make sure default n_mo is valid
    defaultNMO = int32(slResolve(get_param(blk,'n_mo'),root));
    if defaultNMO==ZERO32
        set_param(blk,'n_mo','1');
        defaultNMO = ONE32;
    end
    nmy = defaultNMO;
    % # of MD + 1
    n_md = int32(slResolve(get_param(blk,'n_md'),root));
    nv = n_md + ONE32;
    % # of inputs 
    n_ud = int32(slResolve(get_param(blk,'n_ud'),root));
    nu = nmv + n_md + n_ud;
    % # of states set to #MO + #MD
    nx = nmy + n_md; 
    nxQP = nx;
    % # of outputs set to #MO + #UO
    n_uo = int32(slResolve(get_param(blk,'n_uo'),root));
    ny = nmy + n_uo; 
    %% Required parameters
    openloopflag = true;            % open loop or not
    isQP = false;                   % unconstrained or not
    CustomEstimation = false;
    UseSuboptimalSolution = false;
    CustomSolver = false;
    CustomSolverCodeGen = false;
    lastu = zeros(nmv,1,DataType);   % unit delay - Last MVs
    iA = false;                     % memory block
    lastx = zeros(nx,1,DataType);   % memory block
    mvoff = zeros(nmv,1,DataType);    % bias - mv_bias
    C = zeros(ny,nx,DataType);      % state estimator subsystem
    Dv = zeros(ny,nv,DataType);     % state estimator subsystem
    myoff = zeros(nmy,1,DataType);  % state estimator subsystem
    Cm = zeros(nmy,nx,DataType);    % state estimator subsystem
    Dvm = zeros(nmy,nv,DataType);   % state estimator subsystem
    M = zeros(nx,nmy,DataType);     % state estimator subsystem
    L = zeros(nx,nmy,DataType);     % state estimator subsystem
    A = zeros(nx,nx,DataType);      % state estimator subsystem
    Bu = zeros(nx,nmv,DataType);    % state estimator subsystem
    Bv = zeros(nx,nv,DataType);     % state estimator subsystem
    myindex = (1:nmy)';                 % must be a column vector
    Uscale = ones(nu,1,DataType);           % scale factors for all inputs
    Yscale = ones(ny,1,DataType);           % scale factors for all outputs and references
    MVscale = ones(nmv,1,DataType);         % scale factors for manipulated variables
    MDscale = ones(max(n_md,1),1,DataType); % scale factors for measured disturbances
    RMVscale = ones(nmv,1,DataType);        % inverse of scale factors for manipulated variables
    RMDscale = ones(max(n_md,1),1,DataType);% inverse of scale factors for measured disturbances
    RYscale = ones(ny,1,DataType);          % inverse of scale factors for all outputs and references
    RMYscale = ones(nmy,1,DataType);        % inverse of scale factors for measured outputs
    m = ONE32;                              % dummy control moves
    UseActiveSetSolver = int32(1);
    ASOptions = toStruct(mpc.solver.options.qp.ActiveSet('DataType',class(ONE),'MaxIterations',int32(10)));
    IPOptions = toStruct(mpc.solver.options.qp.InteriorPoint('DataType',class(ONE)));
    ADOptions = toStruct(mpc.solver.options.qp.ADMM('DataType',class(ONE)));
    MIQPOptions = toStruct(mpc.solver.options.miqp.BranchBound('DataType',class(ONE)));
    isHyb = false; 
    Mdis=ZERO;
    Ndis=ZERO32;
    Vdis=ZERO;    
    numdis=ZERO32;
    maxdis=ZERO32;
else
    %% Update mask parameters
    set_param(blk,'n_ts',num2str(MPCstruct.Ts),...
                 'n_p',num2str(MPCstruct.p),...
                 'n_mv',num2str(MPCstruct.nmv),...
                 'n_md',num2str(MPCstruct.nmd),...
                 'n_ud',num2str(MPCstruct.nud),...
                 'n_mo',num2str(MPCstruct.nmy),...
                 'n_uo',num2str(MPCstruct.nuy));
    %% If snap time is used in findop or linearize, "openloop" is false, otherwise it is the same as "AnalyticLinearization".
    if isempty(find_system(root,'MatchFilter', @Simulink.match.allVariants, 'FirstResultOnly', 'on', 'MaskType', 'Time Operating Condition Snapshot'))
        openloopflag = strcmp(get_param(root,'AnalyticLinearization'),'on');
    else
        openloopflag = false;
    end
    %% Check start time
    StartTimeExpression = get_param(root,'StartTime');
    try
        t0 = slResolve(StartTimeExpression, root);
    catch %#ok<CTCH>
        ctrlMsgUtils.error('MPC:utility:InvalidStartTime');
    end
    if ~isreal(t0) || ~isscalar(t0) || t0<0
        ctrlMsgUtils.error('MPC:utility:InvalidStartTime');
    end
    %% get MPC parameters from MPCstruct
    % convert them into correct data type for ISO/MISRA support
    names = fieldnames(MPCstruct);
    for i = 1:length(names)
        % get each field value from MPCstruct
        field = names{i};
        % force data type
        if isstruct(MPCstruct.(field))
            % ASOptions or IPOptions or MIQPOptions
            subnames = fieldnames(MPCstruct.(field));
            for j = 1:length(subnames)
                out = mpc_forceDataType(MPCstruct.(field).(subnames{j}),subnames{j},isDouble); %#ok<*NASGU> 
                eval(sprintf('%s.%s = out;',field,subnames{j}));
            end
        else
            out = mpc_forceDataType(MPCstruct.(field),field,isDouble);
            eval(sprintf('%s = out;',field));
        end
    end    
    %% EML block doesn't like empty parameters
    % even if they are not used in computation at all. Transform any of
    % them to zero matrices with correct size.
    %#ok<*NODEF>
    if isempty(mdoff) % [inf 1]
        mdoff = ZERO;
    end
    if isempty(Mlim) % [inf 1]
        Mlim = ZERO;
    end
    if isempty(Mu1) % [inf inf]
        Mu1 = zeros(1,nmv,DataType);
    end
    if isempty(Mv) % [inf inf]
        Mv = zeros(1,nv,DataType);
    end
    if isempty(Mx) % [inf inf]
        Mx = zeros(1,nxQP,DataType);
    end
    if isempty(Ac) % [inf inf]
        Ac = zeros(1,degrees,DataType);
    end
    if isempty(iA) % [inf 1]
        iA = false(size(Ac,1),1);
    end
    if isempty(Linv) % [inf inf]
        Linv = zeros(degrees,degrees,DataType);
    end
    if isempty(Mrows)
        Mrows = zeros(degrees,1,'int32');
    end
    if isempty(mdindex)
        mdindex = ZERO32;
    end
    if isempty(udindex)
        udindex = ZERO32;
    end
    if nCC == ZERO32
        E = zeros(1,nmv,DataType);
        F = zeros(1,ny,DataType);
        G = ZERO;
        S = zeros(1,nv,DataType);
    end
    if isempty(S)
        % has custom constraint
        if nv>ONE32
            % has MD signal but it is not involved in custom constraint
            S = zeros(nCC,nv-1,DataType);
        else
            % no MD signal at all (avoid empty, not used in QP formulation)
            S = zeros(nCC,1,DataType);
        end
    end
    if isempty(M) % [inf inf]
        M = ZERO;
    end
    if isempty(L) % [inf inf]
        L = ZERO;
    end
    %% Zero matrices not needed in MPC computations
    is_pmvarying = strcmp(get_param(blk,'pm_inport'),'on');
    if no_ywt && no_uwt && no_duwt && ~return_cost && ~return_mvseq && ~return_xseq && ~return_ovseq && no_cc && ~is_pmvarying
        % no online tuning of YWT, UWT, DUWT and no cost returned, 
        % not adaptive, then
        % we can set all matrices = scalar 0 in order to save memory space
        [Wy, Wu, Wdu, Jm, SuJm, Su1, Sx, Hv] = deal(ZERO);
    end
end
%% Extra mask variables
% state estimation
if CustomEstimation
    nmoorx = nx; %#ok<UNRCH>
    strmoorx = 'x[k|k]';
else
    nmoorx = nmy;
    strmoorx = 'mo';
end
%% Override Ts for inherited sample time
if strcmp(get_param(blk,'SampleTimeInherited'),'on')
    Ts = -1;
else
    Ts = double(Ts);
end
if strcmp(get_param(blk,'pm_inport'),'on')
    set_param(blk,'HorizonChoice','VariableHorizon');
else
    set_param(blk,'HorizonChoice','FixedHorizon');
end
