This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Note: This page has been translated by MathWorks. Click here to see
To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

Customize Metrics Dashboard Layout and Functionality

Customize the Metrics Dashboard by using the model metric programming interface. Customizing the dashboard extends your ability to use model metrics to assess that your model and code comply with size, complexity, and readability requirements. You can perform these Metrics Dashboard customizations:

  • Configure compliance metrics to obtain compliance and issues metric data on your Model Advisor configuration.

  • Customize the dashboard layout by adding custom metrics, removing widgets, and configuring existing widgets.

  • Categorize metric data as compliant, warning, and noncompliant by specifying metric threshold values.

Configure Compliance Metrics

Use the Metrics Dashboard and metric APIs to obtain compliance and issues metric data on your Model Advisor configuration or on an existing check group such as the MISRA checks. To set up your own Model Advisor configuration, see Organize Checks and Folders Using the Model Advisor Configuration Editor. After you have set up your Model Advisor configuration, follow these steps to specify the check groups for which you want to obtain compliance and issues metric data:

  1. To open the model, at the MATLAB command prompt, enter this command:

    sf_car

  2. Open the default configuration (that is, the one that is shipped with the Metrics Dashboard). Add a corresponding slmetric.config.Configuration object to the base workspace.

    metricconfig=slmetric.config.Configuration.openDefaultConfiguration();
  3. Create a cell array consisting of the Check Group IDs that correspond to those check groups. Obtain a Check Group ID by opening the Model Advisor Configuration Editor and selecting the folder that contains the group of checks. The folder contains a Check Group ID parameter.

    values = {'maab', 'hisl_do178', '_SYSTEM_By Task_misra_c'};

    This cell array specifies MAAB, High-Integrity, and MISRA check groups. The values maab and hisl_do178 correspond to a subset of MAAB and High-Integrity System checks. To include all checks, specify the value for the Check Group ID parameter from the Model Advisor Configuration Editor.

  4. To set the configuration, pass the values cell array into the setMetricFamilyParameterValues method. The 'ModelAdvisorStandard' string is a standard string that you must supply to the setMetricFamilyParameterValues method.

    setMetricFamilyParameterValues(metricconfig,'ModelAdvisorStandard', values);
  5. Open the default configuration for the Metrics Dashboard layout (that is, the one that ships with the Metrics Dashboard).

    dashboardconfig = slmetric.dashboard.Configuration.openDefaultConfiguration();
  6. Obtain the slmetric.dashboard.Layout object from the slmetric.dashboard.Configuration object.

    layout = getDashboardLayout(dashboardconfig);
  7. Obtain widget objects that are in the layout object.

    layoutWidget = getWidgets(layout);
  8. The slmetric.dashboard.Layout object contains these objects:

    • An slmetric.dashboard.Container object that holds an slmetrics.dashboard.Widget object of type SystemInfo. The red number one in the diagram below indicates the SystemInfo widget.

    • An slmetric.dashboard.Group object that has the title SIZE.

    • An slmetrics.dashboard.Group object that has the title MODELING GUIDELINE COMPLIANCE.

    • An slmetrics.dashboard.Group object that has the title ARCHITECTURE.

    In the diagram, the red numbers 1, 2, 3, and 4 indicate their order in the layoutWidget array. Obtain the compliance group from the layout.

    complianceGroup = layoutWidget(3);

  9. The modeling guideline compliance group contains two containers. The top container contains the High Integrity and MAAB compliance and check issues widgets. The red numbers 3.1.1, 3.1.2, and 3.1.3 indicate the order of the three widgets in the first container. The second container contains the Code Analyzer Warnings and Diagnostic Warnings widgets.

    Remove the High Integrity compliance widget.

    complianceContainers = getWidgets(complianceGroup);
    complianceContainerWidgets = getWidgets(complianceContainers(1));
    complianceContainers(1).removeWidget(complianceContainerWidgets(1)); 
    
  10. Create a custom widget for visualizing MISRA check issues metrics.

    misraWidget = complianceContainers(1).addWidget('Custom', 1); 
    misraWidget.Title=('MISRA'); 
    misraWidget.VisualizationType = 'RadialGauge'; 
    misraWidget.setMetricIDs...
    ('mathworks.metrics.ModelAdvisorCheckCompliance._SYSTEM_By Task_misra_c'); 
    misraWidget.setWidths(slmetric.dashboard.Width.Medium);
  11. The bar chart widget visualizes the High Integrity and MAAB check groups. Point this widget to the MISRA and MAAB check groups.

    setMetricIDs(complianceContainerWidgets(3),...
    ({'mathworks.metrics.ModelAdvisorCheckIssues._SYSTEM_By Task_misra_c',...
    'mathworks.metrics.ModelAdvisorCheckIssues.maab'}));
    complianceContainerWidgets(3).Labels = {'MISRA', 'MAAB'};
  12. Save the configuration objects. These commands serialize the API information to XML files.

    save(metricconfig,'FileName','MetricConfig.xml');
    save(dashboardconfig,'Filename','DashboardConfig.xml');
  13. Set the active configurations.

    slmetric.config.setActiveConfiguration(fullfile(pwd,'MetricConfig.xml'));
    slmetric.dashboard.setActiveConfiguration(fullfile(pwd,'DashboardConfig.xml'));
  14. For your model, open the Metrics Dashboard.

    metricsdashboard sf_car
  15. Click the All Metrics button and run all metrics. The Metrics Dashboard displays results for the MISRA checks instead of the High Integrity checks.

  16. Close the Metrics Dashboard.

Add a Custom Metric to Dashboard

Create a custom metric that counts nonvirtual blocks. To display this metric on the Metrics Dashboard, specify a widget. Add it to the size group.

  1. Create a custom metric class.

    className = 'nonvirtualblockcount';
    slmetric.metric.createNewMetricClass(className);
    

  2. Create the nonvirtual block count metric by adding this code to the nonvirtualblockcount.m file.

    classdef nonvirtualblockcount < slmetric.metric.Metric
        %nonvirtualblockcount calculates number of nonvirtual blocks per level.
        % BusCreator, BusSelector and BusAssign are treated as nonvirtual.
        properties
            VirtualBlockTypes = {'Demux','From','Goto','Ground', ...
                'GotoTagVisiblity','Mux','SignalSpecification', ...
                'Terminator','Inport'};
        end
        
        methods
        function this = nonvirtualblockcount()
            this.ID = 'nonvirtualblockcount';
            this.Name = 'Nonvirtual Block Count';
            this.Version = 1;
            this.CompileContext = 'None';
            this.Description = 'Algorithm that counts nonvirtual blocks per level.';
            this.AggregatedValueName = 'Nonvirtual Blocks (incl. Descendants)';
            this.ValueName = 'Nonvirtual Blocks';
            this.ComponentScope = [Advisor.component.Types.Model, ...
                Advisor.component.Types.SubSystem];
            this.AggregationMode = slmetric.AggregationMode.Sum;
    	    this.AggregateComponentDetails = true;
            this.ResultChecksumCoverage = true;
            this.SupportsResultDetails = false;
                
        end
    
        function res = algorithm(this, component)
            % create a result object for this component
            res = slmetric.metric.Result();	
    
            % set the component and metric ID
            res.ComponentID = component.ID;
            res.MetricID = this.ID;
            
            % Practice
            D1=slmetric.metric.ResultDetail('identifier 1','Name 1');
            D1.Value=0;
            D1.setGroup('Group1','Group1Name');
            D2=slmetric.metric.ResultDetail('identifier 2','Name 2');
            D2.Value=1;
            D2.setGroup('Group1','Group1Name');
            
            
    
            % use find_system to get all blocks inside this component
            blocks = find_system(getPath(component), ...
                'SearchDepth', 1, ...
                'Type', 'Block');
    
            isNonVirtual = true(size(blocks));
    
            for n=1:length(blocks)
                blockType = get_param(blocks{n}, 'BlockType');
    
                if any(strcmp(this.VirtualBlockTypes, blockType))
                    isNonVirtual(n) = false;
                else
                    switch blockType
                        case 'SubSystem'
                            % Virtual unless the block is conditionally executed
                            % or the Treat as atomic unit check box is selected.
                            if strcmp(get_param(blocks{n}, 'IsSubSystemVirtual'), ...
                                    'on')
                                isNonVirtual(n) = false;
                            end
                        case 'Outport'
                            % Outport: Virtual when the block resides within
                            % SubSystem block (conditional or not), and 
                            % does not reside in the root (top-level) Simulink window.
                            if component.Type ~= Advisor.component.Types.Model
                                isNonVirtual(n) = false;
                            end
                        case 'Selector'
                            % Virtual only when Number of input dimensions 
                            % specifies 1 and Index Option specifies Select 
                            % all, Index vector (dialog), or Starting index (dialog).
                            nod = get_param(blocks{n}, 'NumberOfDimensions');
                            ios = get_param(blocks{n}, 'IndexOptionArray');
    
                            ios_settings = {'Assign all', 'Index vector (dialog)', ...
                                'Starting index (dialog)'};
    
                            if nod == 1 && any(strcmp(ios_settings, ios))
                                isNonVirtual(n) = false;
                            end
                        case 'Trigger'
                            % Virtual when the output port is not present.
                            if strcmp(get_param(blocks{n}, 'ShowOutputPort'), 'off')
                                isNonVirtual(n) = false;
                            end
                        case 'Enable'
                            % Virtual unless connected directly to an Outport block.
                            isNonVirtual(n) = false;
    
                            if strcmp(get_param(blocks{n}, 'ShowOutputPort'), 'on')
                                pc = get_param(blocks{n}, 'PortConnectivity');
    
                                if ~isempty(pc.DstBlock) && ...
                                        strcmp(get_param(pc.DstBlock, 'BlockType'), ...
                                        'Outport')
                                    isNonVirtual(n) = true;
                                end
                            end
                    end
                end
            end
    
            blocks = blocks(isNonVirtual);
    
            res.Value = length(blocks);
        end
        end
    end

  3. Register the new metric in the metric repository.

    [id_metric,err_msg] = slmetric.metric.registerMetric(className);
    
  4. Remove the widget that represents the Simulink block count metric. This widget is the first one in the size group. The size group is second in the layoutWidget array.

    sizeGroup = layoutWidget(2); 
    sizeGroupWidgets = sizeGroup.getWidgets(); 
    sizeGroup.removeWidget(sizeGroupWidgets(1));
  5. Add a widget that displays the nonvirtual block count metric. For custom widgets, the default visualization type is single value. If you want to use a different visualization type, specify a different value for the VisualizationType property.

    newWidget = sizeGroup.addWidget('Custom', 1);
    newWidget.Title=('Nonvirtual Block Count'); 
    newWidget.setMetricIDs('nonvirtualblockcount');
    newWidget.setWidths(slmetric.dashboard.Width.Medium);
    newWidget.setHeight(70);
    
  6. Specify whether there are lines separating the custom widget from other widgets in the group. These commands specify that there is a line to the right of the widget.

    s.top = false;
    s.bottom = false;
    s.left= false;
    s.right= true;
    newWidget.setSeparators([s, s, s, s]);

  7. Save the configuration objects. These commands serialize the API information to XML files.

    save(metricconfig,'FileName','MetricConfig.xml');
    save(dashboardconfig,'Filename','DashboardConfig.xml');
  8. Set the active configurations.

    slmetric.config.setActiveConfiguration(fullfile(pwd, 'MetricConfig.xml'));
    slmetric.dashboard.setActiveConfiguration(fullfile(pwd, 'DashboardConfig.xml'));
  9. For your model, open the Metrics Dashboard.

    metricsdashboard sf_car
  10. Click the All Metrics button and run all metrics. The Metrics Dashboard displays results for the nonvirtual block count metric instead of the Simulink block count metric.

  11. Close the Metrics Dashboard.

Add Metric Thresholds

For the nonvirtual block count and MISRA metrics, specify metric threshold values. Specifying these values enables you to access the quality of your model by categorizing your metric data as follows:

  • Compliant — Metric data that is in an acceptable range.

  • Warning — Metric data that requires review.

  • Noncompliant — Metric data that requires you to modify your model.

  1. Access the slmetric.config.ThresholdConfiguration object in the slmetric.config.Configuration object metricconfig. Create the corresponding slmetric.config.ThresholdConfiguration object (TC) in the base workspace.

    TC=getThresholdConfigurations(metricconfig);
  2. Add two slmetric.config.Threshold objects to TC. Each slmetric.config.Threshold object contains a default slmetric.config.Classification object that is compliant. Specify the compliant metric ranges.

    T1=addThreshold(TC,'mathworks.metrics.ModelAdvisorCheckIssues._SYSTEM_By Task_misra_c',...
     'AggregatedValue');
    C=getClassifications(T1); 
    C.Range.Start=-inf;
    C.Range.End=0;
    C.Range.IncludeStart=0;
    C.Range.IncludeEnd=1;
    
    T2=addThreshold(TC,'mathworks.metrics.ModelAdvisorCheckCompliance._SYSTEM_By Task_misra_c',...
     'AggregatedValue'); 
    C=getClassifications(T2); 
    C.Range.Start=1;
    C.Range.End=inf;
    C.Range.IncludeStart=1;
    C.Range.IncludeEnd=0;
    

  3. For each slmetric.config.Threshold object, specify the Warning ranges.

    C=addClassification(T1,'Warning');
    C.Range.Start=0;
    C.Range.End=inf;
    C.Range.IncludeStart=0;
    C.Range.IncludeEnd=1;
    
    C=addClassification(T2,'Warning');
    C.Range.Start=-inf;
    C.Range.End=1;
    C.Range.IncludeStart=0;
    C.Range.IncludeEnd=0;
    These commands specify that if the MISRA checks have issues, the model status is warning. If there are no issues, the model status is compliant.

  4. Add a third slmetric.config.Threshold object to TC. Specify compliant, warning, and noncompliant ranges for this slmetric.config.Threshold object.

    T3=addThreshold(TC,'nonvirtualblockcount', 'AggregatedValue');
    C=getClassifications(T3); 
    C.Range.Start=-inf;
    C.Range.End=20;
    C.Range.IncludeStart=1;
    C.Range.IncludeEnd=1;
    
    C=addClassification(T3, 'Warning');
    C.Range.Start=20;
    C.Range.End=30;
    C.Range.IncludeStart=0;
    C.Range.IncludeEnd=1;
    
    C=addClassification(T3, 'NonCompliant');
    C.Range.Start=30;
    C.Range.End=inf;
    C.Range.IncludeStart=0;
    C.Range.IncludeEnd=1;
     

    These commands specify that the compliant range is less than or equal to 20. The warning range is from 20 up to but not including 30. The noncompliant range is greater than 30.

  5. Save the configuration objects. These commands serialize the API information to XML files.

    save(metricconfig,'FileName','MetricConfig.xml');
    save(dashboardconfig,'Filename','DashboardConfig.xml');
  6. Set the active configurations.

    slmetric.config.setActiveConfiguration(fullfile(pwd, 'MetricConfig.xml'));
    slmetric.dashboard.setActiveConfiguration(fullfile(pwd, 'DashboardConfig.xml'));
  7. For your model, open the Metrics Dashboard.

    metricsdashboard sf_car

    For the MISRA check compliance issues, the gauge is yellow because 76% of the checks pass. Any percentage less than 100% is a warning. The bar chart also displays a yellow because the model contains three MISRA check issues. Any number greater than zero is a warning.

    The Nonvirtual Block Count widget is in the compliant range because there are 15 nonvirtual blocks.

  8. To reset the configuration and unregister the metric, execute these commands:

    slmetric.metric.unregisterMetric(className); 
    slmetric.dashboard.setActiveConfiguration(''); 
    slmetric.config.setActiveConfiguration('');

See Also

|

Related Topics