Main Content

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

  1. In your working folder, create an sl_customization.m file.

  2. 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 addModelAdvisorCheckFcn method for registering the custom check. The input to this method is a handle to the function defineModelAdvisorChecks. defineModelAdvisorChecks contains 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.

  1. Create a ModelAdvisor.Root object.

    mdladvRoot = ModelAdvisor.Root;
  2. Create a ModelAdvisor.Check object and define the unique check ID. For this check, the ID is com.mathworks.sample.detailStyle.

    rec = ModelAdvisor.Check('com.mathworks.sample.detailStyle');
    
  3. Specify the ModelAdvisor.Check.Title and ModelAdvisor.Check.TitleTips properties.

    rec.Title = 'Check whether block names appear below blocks';
    rec.TitleTips = 'Check position of block names';
  4. Use the setCallbackFcn method to call the callback function. The setCallbackFcn method arguments are a handle to the callback function and the ModelAdvisor.Check.CallbackStyle property value. For this example, the CallbackStyle property 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.FormatTemplate class or the other Model Advisor formatting APIs to format the results that appear in the Model Advisor.

    rec.setCallbackFcn(@DetailStyleCallback,'None','DetailStyle');
  5. To set the fix operation, create a ModelAdvisor.Action object and define its properties. Use the setCallbackFcn method 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';
  6. Use the setAction method to set the action for the check.

    rec.setAction(myAction);
  7. Use the publish method 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

  1. In the defineDetailStyleCheck.m file, create the check callback function. In this example, the function name is DetailStyleCallback. The inputs to this function are a ModelAdvisor.CheckObject and the path to the model or system that the Model Advisor analyzes.

    function DetailStyleCallback(system, CheckObj)
  2. To create a Simulink.ModelAdvisor object, use the function Simulink.ModelAdvisor.getModelAdvisor.

    mdladvObj = Simulink.ModelAdvisor.getModelAdvisor(system); % get object
    
  3. To identify blocks that violate the check, use the find_system function. For each model element, this function creates a ModelAdvisor.ResultDetail object.

    violationBlks = find_system(system, 'Type','block',...
                               'NamePlacement','alternate',...
                               'ShowName', 'on');
  4. Write code for the case when the find_system function does not identify blocks whose names do not appear below the block. In this case, ElementResults is one instance of a ModelAdvisor.ResultDetail object 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);  
  5. Write code for the case when the find_system function returns a list of blocks whose names do not appear below the block (violationBlks). ElementResults includes each ModelAdvisor.ResultDetail object that violates the check and provides a recommended action message for fixing the check violation.

    For this case, the setCheckResultStatus method 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    
  6. To associate the results with a check object, use the setResultDetails method.

    CheckObj.setResultDetails(ElementResults);
    end

Create the Action Callback Definition Function

  1. In the defineDetailStyleCheck.m file, create the action callback function. In this example, the function name is sampleActionCB. The input to this function is a ModelAdvisor.Task object.

    function result = ActionCB(taskobj)
  2. Create handles to Simulink.ModelAdvisor and ModelAdvisor.Check objects.

    mdladvObj = taskobj.MAObj;
    checkObj = taskobj.Check;
  3. Create an array of ModelAdvisor.ResultDetail objects for storing the information for blocks that violate the check.

    resultDetailObjs = checkObj.ResultDetails;
  4. 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.');
  5. Disable the Action box.

    mdladvObj.setActionEnable(false);

Run the Check

  1. Save the sl_customization.m and defineDetailStyleCheck.m files.

  2. In the MATLAB command window, enter:

    Advisor.Manager.refresh_customizations
  3. Open the model sldemo_fuelsys by typing this command in the MATLAB command prompt:

    openExample('sldemo_fuelsys')

  4. In the top model, select the block named Engine Speed. In the toolstrip, on the Format tab, click Flip Name.

  5. Open the fuel_rate_control subsystem. 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.

  6. In the Modeling tab, select Model Advisor. A System Selector ― Model Advisor dialog box opens. Click OK. The Model Advisor opens.

  7. In the left pane, select By Product > Demo > Check whether block names appear below blocks.

  8. Select Run Checks. The Model Advisor check produces a warning for the blocks that you changed.

  9. 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:

    The Model Advisor showing a table of blocks with violations and the hyperlinks to the block paths

  10. 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.

  11. Rerun the Model Advisor check. The check passes.

    The Model Advisor with a passing result

See Also

| | | | | | |

Related Topics