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 the- addModelAdvisorCheckFcnmethod for registering the custom check. The input to this method is a handle to the function- defineModelAdvisorChecks.- 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 is- com.mathworks.sample.detailStyle.- rec = ModelAdvisor.Check('com.mathworks.sample.detailStyle');
- Specify the - ModelAdvisor.Check.Titleand- ModelAdvisor.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. The- setCallbackFcnmethod arguments are a handle to the callback function and the- ModelAdvisor.Check.CallbackStyleproperty value. For this example, the- CallbackStyleproperty value is- DetailStyle. 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 the- ModelAdvisor.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 the- setCallbackFcnmethod 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 is- DetailStyleCallback. The inputs to this function are a- ModelAdvisor.CheckObjectand the path to the model or system that the Model Advisor analyzes.- function DetailStyleCallback(system, CheckObj)
- To create a - Simulink.ModelAdvisorobject, use the function- Simulink.ModelAdvisor.getModelAdvisor.- mdladvObj = Simulink.ModelAdvisor.getModelAdvisor(system); % get object
- To identify blocks that violate the check, use the - find_systemfunction. For each model element, this function creates a- ModelAdvisor.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 a- ModelAdvisor.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 each- ModelAdvisor.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. The- Simulink.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 is- sampleActionCB. The input to this function is a- ModelAdvisor.Taskobject.- function result = ActionCB(taskobj)
- Create handles to - Simulink.ModelAdvisorand- ModelAdvisor.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.mand- defineDetailStyleCheck.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 named- validate_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