Fix a Model to Comply with Conditions that You Specify with the Model Advisor
This example shows how to create a customized Model Advisor pass/fail check with a fix action. When a model does not contain a check violation, the results contain the check description and result status. When a model contains a check violation, the results contain the check description, result status, and the recommended action to fix the issue. This example adds a custom check to a Model Advisor By Product > Demo subfolder.
For this example, the custom check identifies blocks whose names do not appear below the blocks. The fix action is to make the block names appear below the blocks.
When a check does not pass, the results include a hyperlink to each model element that
violates the check. Use these hyperlinks to easily locate areas in your model or
subsystem. The code for this example consists of an
sl_customization.m file and a
defineDetailStyleCheck.m file.
Create the sl_customization File
In your working folder, create an
sl_customization.mfile.To register the custom checks, create an
sl_customization(cm)function as shown here. This function accepts one argument, a customization manager object. The customization manager object includes theaddModelAdvisorCheckFcnmethod for registering the custom check. The input to this method is a handle to the functiondefineModelAdvisorChecks.defineModelAdvisorCheckscontains a call to the check definition function for custom Model Advisor pass/fail check.function sl_customization(cm) % SL_CUSTOMIZATION - Model Advisor customization demonstration. % Copyright 2019 The MathWorks, Inc. % register custom checks cm.addModelAdvisorCheckFcn(@defineModelAdvisorChecks); % ----------------------------- % defines Model Advisor Checks % ----------------------------- function defineModelAdvisorChecks defineDetailStyleCheck;
Create the Check Definition File
The check definition function defines the check and fix actions that the Model
Advisor takes when you run the check. For this example, the completed check
definition function file is defineDetailStyleCheck.m, and it
contains this
code:
function defineDetailStyleCheck mdladvRoot = ModelAdvisor.Root; % Create ModelAdvisor.Check object and set properties. rec = ModelAdvisor.Check('com.mathworks.sample.detailStyle'); rec.Title = 'Check whether block names appear below blocks'; rec.TitleTips = 'Check position of block names'; rec.setCallbackFcn(@DetailStyleCallback,'None','DetailStyle'); % Create ModelAdvisor.Action object for setting fix operation. myAction = ModelAdvisor.Action; myAction.setCallbackFcn(@ActionCB); myAction.Name='Make block names appear below blocks'; myAction.Description='Click the button to place block names below blocks'; rec.setAction(myAction); mdladvRoot.publish(rec, 'Demo'); % publish check into Demo group. end % ----------------------------- % This callback function uses the DetailStyle CallbackStyle type. % ----------------------------- function DetailStyleCallback(system, CheckObj) mdladvObj = Simulink.ModelAdvisor.getModelAdvisor(system); % get object % Find all blocks whose name does not appear below blocks violationBlks = find_system(system, 'Type','block',... 'NamePlacement','alternate',... 'ShowName', 'on'); if isempty(violationBlks) ElementResults = ModelAdvisor.ResultDetail; ElementResults.Description = 'Identify blocks where the name is not displayed below the block.'; ElementResults.Status = 'All blocks have names displayed below the block.'; mdladvObj.setCheckResultStatus(true); else for i=1:numel(violationBlks) ElementResults(1,i) = ModelAdvisor.ResultDetail; end for i=1:numel(ElementResults) ModelAdvisor.ResultDetail.setData(ElementResults(i), 'SID',violationBlks{i}); ElementResults(i).Description = 'Identify blocks where the name is not displayed below the block.'; ElementResults(i).Status = 'The following blocks have names that do not display below the blocks:'; ElementResults(i).RecAction = 'Change the location such that the block name is below the block.'; end mdladvObj.setCheckResultStatus(false); mdladvObj.setActionEnable(true); end CheckObj.setResultDetails(ElementResults); end % ----------------------------- % This action callback function changes the location of block names. % ----------------------------- function result = ActionCB(taskobj) mdladvObj = taskobj.MAObj; checkObj = taskobj.Check; resultDetailObjs = checkObj.ResultDetails; for i=1:numel(resultDetailObjs) % take some action for each of them block=Simulink.ID.getHandle(resultDetailObjs(i).Data); set_param(block,'NamePlacement','normal'); end result = ModelAdvisor.Text('Changed the location such that the block name is below the block.'); mdladvObj.setActionEnable(false); end
The following steps explain how to create the
defineDetailStyleCheck.m file.
Create a
ModelAdvisor.Rootobject.mdladvRoot = ModelAdvisor.Root;
Create a
ModelAdvisor.Checkobject and define the unique check ID. For this check, the ID iscom.mathworks.sample.detailStyle.rec = ModelAdvisor.Check('com.mathworks.sample.detailStyle');Specify the
ModelAdvisor.Check.TitleandModelAdvisor.Check.TitleTipsproperties.rec.Title = 'Check whether block names appear below blocks'; rec.TitleTips = 'Check position of block names';
Use the
setCallbackFcnmethod to call the callback function. ThesetCallbackFcnmethod arguments are a handle to the callback function and theModelAdvisor.Check.CallbackStyleproperty value. For this example, theCallbackStyleproperty value isDetailStyle. This style allows you to view results by block, subsystem, or recommended action. Applying this style produces default formatting, so that you do not have to use theModelAdvisor.FormatTemplateclass or the other Model Advisor formatting APIs to format the results that appear in the Model Advisor.rec.setCallbackFcn(@DetailStyleCallback,'None','DetailStyle');
To set the fix operation, create a
ModelAdvisor.Actionobject and define its properties. Use thesetCallbackFcnmethod to call the action callback function. The input to this method is a handle to the action callback function.myAction = ModelAdvisor.Action; myAction.setCallbackFcn(@ActionCB); myAction.Name='Make block names appear below blocks'; myAction.Description='Click the button to place block names below blocks';
Use the
setActionmethod to set the action for the check.rec.setAction(myAction);
Use the
publishmethod to publish the check to a folder within the By Product folder. For this example, the folder name is Demo.mdladvRoot.publish(rec, 'Demo'); % publish check into Demo group.
Create the Check Callback Definition Function
In the
defineDetailStyleCheck.mfile, create the check callback function. In this example, the function name isDetailStyleCallback. The inputs to this function are aModelAdvisor.CheckObjectand the path to the model or system that the Model Advisor analyzes.function DetailStyleCallback(system, CheckObj)To create a
Simulink.ModelAdvisorobject, use the functionSimulink.ModelAdvisor.getModelAdvisor.mdladvObj = Simulink.ModelAdvisor.getModelAdvisor(system); % get objectTo identify blocks that violate the check, use the
find_systemfunction. For each model element, this function creates aModelAdvisor.ResultDetailobject.violationBlks = find_system(system, 'Type','block',... 'NamePlacement','alternate',... 'ShowName', 'on');
Write code for the case when the
find_systemfunction does not identify blocks whose names do not appear below the block. In this case,ElementResultsis one instance of aModelAdvisor.ResultDetailobject and provides information content only. The method specifies that there is no check violation and displays Passed in the Model Advisor.if isempty(violationBlks) ElementResults = ModelAdvisor.ResultDetail; ElementResults.Description = 'Identify blocks where the name is not displayed below the block.'; ElementResults.Status = 'All blocks have names displayed below the block.'; mdladvObj.setCheckResultStatus(true);
Write code for the case when the
find_systemfunction returns a list of blocks whose names do not appear below the block (violationBlks).ElementResultsincludes eachModelAdvisor.ResultDetailobject that violates the check and provides a recommended action message for fixing the check violation.For this case, the
setCheckResultStatusmethod specifies the check violation and displays Warning or Failed in the Model Advisor. TheSimulink.ModelAdvisor.setActionEnable(true)method enables the ability to fix the check violation issue from the Model Advisor.else for i=1:numel(violationBlks) ElementResults(1,i) = ModelAdvisor.ResultDetail; end for i=1:numel(ElementResults) ModelAdvisor.ResultDetail.setData(ElementResults(i), 'SID',violationBlks{i}); ElementResults(i).Description = 'Identify blocks where the name is not displayed below the block.'; ElementResults(i).Status = 'The following blocks have names that do not display below the blocks:'; ElementResults(i).RecAction = 'Change the location such that the block name is below the block.'; end mdladvObj.setCheckResultStatus(false); mdladvObj.setActionEnable(true); end
To associate the results with a check object, use the
setResultDetailsmethod.CheckObj.setResultDetails(ElementResults); end
Create the Action Callback Definition Function
In the
defineDetailStyleCheck.mfile, create the action callback function. In this example, the function name issampleActionCB. The input to this function is aModelAdvisor.Taskobject.function result = ActionCB(taskobj)Create handles to
Simulink.ModelAdvisorandModelAdvisor.Checkobjects.mdladvObj = taskobj.MAObj; checkObj = taskobj.Check;
Create an array of
ModelAdvisor.ResultDetailobjects for storing the information for blocks that violate the check.resultDetailObjs = checkObj.ResultDetails;
Write code that changes the block name location to below the block.
for i=1:numel(resultDetailObjs) % take some action for each of them block=Simulink.ID.getHandle(resultDetailObjs(i).Data); set_param(block,'NamePlacement','normal'); end result = ModelAdvisor.Text('Changed the location such that the block name is below the block.');
Disable the Action box.
mdladvObj.setActionEnable(false);
Run the Check
Save the
sl_customization.manddefineDetailStyleCheck.mfiles.In the MATLAB command window, enter:
Advisor.Manager.refresh_customizations
Open the model
sldemo_fuelsysby typing this command in the MATLAB command prompt:openExample('sldemo_fuelsys')In the top model, select the block named
Engine Speed. In the toolstrip, on the Format tab, click Flip Name.Open the
fuel_rate_controlsubsystem. Select the block namedvalidate_sample_time. In the toolstrip, on the Format tab, click Flip Name.Return to the top model and save as
example_sldemo_fuelsys.In the Modeling tab, select Model Advisor. A System Selector ― Model Advisor dialog box opens. Click OK. The Model Advisor opens.
In the left pane, select By Product > Demo > Check whether block names appear below blocks.
Select Run Checks. The Model Advisor check produces a warning for the blocks that you changed.
Review the results by selecting either the Report or Result Detail tabs.
Both tabs provide a recommended action for each block that violates the check. You can click the hyperlink path to open the block in the model editor. For example:
Follow the recommended action for fixing the violating blocks by using one of these methods:
Update each violation individually by double-clicking the hyperlink to open the block. Select the block. In the toolstrip, on the Format tab, select Flip Name.
In the toolstrip, click Fix. The Model Advisor automatically fixes the issues in the model. Notice that the button is dimmed after the violations are fixed.
Rerun the Model Advisor check. The check passes.

See Also
ModelAdvisor.Check | ModelAdvisor.FormatTemplate | ModelAdvisor.FormatTemplate | ModelAdvisor.Check.CallbackContext | Simulink.ModelAdvisor | Simulink.ModelAdvisor.getModelAdvisor | Simulink.ModelAdvisor.openConfigUI | Simulink.ModelAdvisor.reportExists