function lkablock_utilParameterCheck(blk)
% Check mask dialog parameters for Lane Keeping Assist System Block.
%
%   Author: Meng Xia, Rong Chen

%   Copyright 2017-2018 The MathWorks, Inc.

%% get parameter values from mask workspace
maskWSVars = get_param(blk,'MaskWSVariables');
blkWSVarNames = {maskWSVars.Name};
% vehicle dynamics paras
m = maskWSVars(strcmp(blkWSVarNames,'VehicleMass')).Value;
Iz = maskWSVars(strcmp(blkWSVarNames,'VehicleYawInertia')).Value;
lf = maskWSVars(strcmp(blkWSVarNames,'LengthToFront')).Value;
lr = maskWSVars(strcmp(blkWSVarNames,'LengthToRear')).Value;
Cf = maskWSVars(strcmp(blkWSVarNames,'FrontTireStiffness')).Value;
Cr = maskWSVars(strcmp(blkWSVarNames,'RearTireStiffness')).Value;
lag = maskWSVars(strcmp(blkWSVarNames,'TransportLag')).Value;

% vehicle dynamics matrices
Av = maskWSVars(strcmp(blkWSVarNames,'EgoModelMatrixA')).Value;
Bv = maskWSVars(strcmp(blkWSVarNames,'EgoModelMatrixB')).Value;
Cv = maskWSVars(strcmp(blkWSVarNames,'EgoModelMatrixC')).Value;
% controller constraints
umax = maskWSVars(strcmp(blkWSVarNames,'MaxSteering')).Value;
umin = maskWSVars(strcmp(blkWSVarNames,'MinSteering')).Value;
% mpc design paras
Ts = maskWSVars(strcmp(blkWSVarNames,'Ts')).Value;
psteps = maskWSVars(strcmp(blkWSVarNames,'PredictionHorizon')).Value;
weightratio = maskWSVars(strcmp(blkWSVarNames,'ControllerBehavior')).Value;
maxiter = maskWSVars(strcmp(blkWSVarNames,'maxiter')).Value;
% initial conditions
Vx0 = maskWSVars(strcmp(blkWSVarNames,'InitialLongVel')).Value;

%% get default status of checkboxes
umin_ext = strcmp(get_param(blk,'umin_ext'),'on');
umax_ext = strcmp(get_param(blk,'umax_ext'),'on');
suboptimal = strcmp(get_param(blk,'suboptimal'),'off');

%% check parameters

%% check on system matrices
checkLinearModel(Av,Bv,Cv)

% check on vehicle paras: positive, finite, real, scalar
checkPositiveParam(m,getString(message('MPC:adasblocks:varnameLKAVehicleMass')))
checkPositiveParam(Iz,getString(message('MPC:adasblocks:varnameLKAVehicleInertia')))
checkPositiveParam(lf,getString(message('MPC:adasblocks:varnameLKAVehicleLengthToFront')))
checkPositiveParam(lr,getString(message('MPC:adasblocks:varnameLKAVehicleLengthToRear')))
checkPositiveParam(Cf,getString(message('MPC:adasblocks:varnameLKAVehicleFrontStiffness')))
checkPositiveParam(Cr,getString(message('MPC:adasblocks:varnameLKAVehicleRearStiffness')))
checkNonnegativeParam(lag,getString(message('MPC:adasblocks:varnameLKATransportLag')))

%% check controller constraints
% check on minimum steering angle umin: finite, real, scalar
if ~umin_ext && ~isempty(umin)
    checkFiniteParam(umin,getString(message('MPC:adasblocks:varnameLKAMinSteering')))
end

% check on maximum steering angle umax: finite, real, scalar
if ~umax_ext && ~isempty(umax)
    checkFiniteParam(umax,getString(message('MPC:adasblocks:varnameLKAMaxSteering')))
end

% check umin must be less than umax
if (~umax_ext && ~isempty(umax) && ~umin_ext && ~isempty(umin))
    checkLessThan(umin,umax,getString(message('MPC:adasblocks:varnameLKAMinSteering')),getString(message('MPC:adasblocks:varnameLKAMaxSteering')))
end

%% mpc
% check on sampling time Ts: non-negative, finite, real, scalar
checkPositiveParam(Ts,getString(message('MPC:adasblocks:varnameLKASampleTime')))

% check on prediction steps psteps: positive, finite, real, scalar
checkPositiveParam(psteps,getString(message('MPC:adasblocks:varnameLKAPSteps')))

% check on weight ratio weightratio: between zero and one, finite, real, scalar
checkInRangeParam(weightratio,getString(message('MPC:adasblocks:varnameLKAWeight')),0,1)

% check on maximum iteration number maxiter: positive, finite, real, scalar, integer
if ~suboptimal && ~isempty(maxiter)
    checkPositiveParam(maxiter,getString(message('MPC:adasblocks:varnameLKAMaxIter')))
end

%% initial conditions
% check on initial ego longitudinal velocity Vx0: non-negative, finite, real, scalar
checkPositiveParam(Vx0,getString(message('MPC:adasblocks:varnameLKAInitEgoVel')))



%% local functions
% Local function: non-negative, finite, real, scalar
function checkNonnegativeParam(var,varname)
if ~(isnumeric(var) && isscalar(var) && isreal(var) && isfinite(var) && (var>=0))
    error((message('MPC:adasblocks:errLKAParamNonNegScalarFiniteReal',varname)));
end
   
% Local function: positive, finite, real, scalar
function checkPositiveParam(var,varname)
if ~(isnumeric(var) && isscalar(var) && isreal(var) && isfinite(var) && (var>0))
    error((message('MPC:adasblocks:errLKAParamPosScalarFiniteReal',varname)));
end  

% Local function: less than
function checkLessThan(var1,var2,varname1,varname2)
if var1>=var2
    error((message('MPC:adasblocks:errLKAParamLessThan',varname1,varname2)));
end 
   
% Local function: finite, real, scalar
function checkFiniteParam(var,varname)
if ~(isnumeric(var) && isscalar(var) && isreal(var) && isfinite(var))
    error((message('MPC:adasblocks:errLKAParamScalarFiniteReal',varname)));
end 

% Local function: finite, real, scalar between min and max values
function checkInRangeParam(var,varname,varmin,varmax)
if ~(isnumeric(var) && isscalar(var) && isreal(var) && isfinite(var) && (var>=varmin) && (var<=varmax))
    error((message('MPC:adasblocks:errLKAParamRangeScalarFiniteReal',varname,num2str(varmin),num2str(varmax))));
end

% Local function: model has to be SISO and pass the mpc plant check (see mpcapp.util.checkPlant)
function checkLinearModel(A,B,C)
% number of states
NumStates = size(A,1);
% check matrices
if ~( ismatrix(A) && (size(A,2)==NumStates) && isreal(A) )
    error((message('MPC:adasblocks:errLKAEgoModelMatrixA')));
end
if ~( iscolumn(B) && isreal(B))
    error((message('MPC:adasblocks:errLKAEgoModelMatrixB')));
end
if ~( ismatrix(C) && isreal(C) && (size(C,1)==2) )
    error((message('MPC:adasblocks:errLKAEgoModelMatrixC')));
end
% check size mismatch
if ~( (size(B,1)==NumStates) && (size(C,2)==NumStates) )
    error((message('MPC:adasblocks:errLKAEgoModelMatrixSize')));
end
% check minimal realization
plant = ss(A,B,C,0);
sysr = minreal(plant);
if (size(sysr.A,1)~=NumStates)
    error((message('MPC:adasblocks:errLKAEgoModelMatrixMinimal')));
end





    
