Создать вашу собственную образцовую метрику:
Используйте функцию slmetric.metric.createNewMetricClass
, чтобы создать новый метрический класс, выведенный из базового класса slmetric.metric.Metric
.
Установите следующие свойства класса:
ID
: Уникальный метрический идентификатор, который получает новые метрические данные.
Имя:
Имя метрического алгоритма.
ComponentScope
: Компоненты модели, для которых вычисляется метрика.
CompileContext
: Скомпилируйте режим для метрического вычисления. Если ваша модель требует, чтобы образцовая метрика потребовала образцовой компиляции, задайте PostCompile
. Сбор метрических данных для скомпилированных моделей замедляет производительность.
ResultCheckSumCoverage
: Задайте, хотите ли вы метрические данные, регенерированные, если исходный файл и Version
не изменились.
AggregationMode
: Как метрический алгоритм агрегировал метрические данные.
AggregateComponentDetails
: Возвращает все подробные результаты или агрегировал подробные результаты компонента.
Опционально, установите эти дополнительные свойства:
Описание:
Описание метрики.
Версия:
Метрическая версия.
Напишите метрический алгоритм в метод slmetric.metric.Metric
, алгоритм. Алгоритм вычисляет метрические данные, заданные классом Advisor.component.Component
. Класс Advisor.component.Types
задает типы объектов модели, для которых можно вычислить метрические данные.
Этот пример показывает, как использовать образцовый метрический API, чтобы создать пользовательскую образцовую метрику для подсчета невиртуальных блоков в модели. После создания метрики можно собрать данные для метрики, получить доступ к результатам и экспортировать результаты.
Используя функцию createNewMetricClass
, создайте новый метрический класс named nonvirtualblockcount
. Функция создает файл, nonvirtualblockcount.m
, в текущей рабочей папке. Файл содержит конструктора и пустой метрический метод алгоритма. В данном примере убедитесь, что вы находитесь в перезаписываемой папке.
className = 'nonvirtualblockcount'; slmetric.metric.createNewMetricClass(className);
Чтобы написать метрический алгоритм, откройте файл nonvirtualblockcount.m
и добавьте метрику в файл. Например, чтобы отредактировать файл, используйте команду edit(className)
. В данном примере можно создать метрический алгоритм путем копирования этой логики в 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.ComponentScope = [Advisor.component.Types.Model, ... Advisor.component.Types.SubSystem]; this.AggregationMode = slmetric.AggregationMode.Sum; this.AggregateComponentDetails = true; this.ResultChecksumCoverage = true; this.SupportsResultDetails = true; 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
nonvirtualblockcount.m
, укажите новую метрику в метрическом репозитории.[id_metric,err_msg] = slmetric.metric.registerMetric(className);
Чтобы собрать метрические данные по моделям, используйте экземпляры slmetric.Engine
. Используя метод getMetrics
, задайте метрики, которые вы хотите собрать. В данном примере укажите, что невиртуальный блок считает метрику для модели sldemo_mdlref_bus
.
Загрузите модель sldemo_mdlref_bus
.
model = 'sldemo_mdlref_bus'; load_system(model);
Создайте метрический объект механизма и установите аналитический корень.
metric_engine = slmetric.Engine(); setAnalysisRoot(metric_engine,'Root',model,'RootType','Model');
Соберите метрические данные для невиртуальной метрики количества блока.
execute(metric_engine); rc = getMetrics(metric_engine,id_metric);
Чтобы получить доступ к метрикам для вашей модели, используйте экземпляры slmetric.metric.Result
. В этом примере отобразите невиртуальные метрики количества блока для sldemo_mdlref_busmodel
. Для каждого результата отобразите MetricID
, ComponentPath
и Value
.
for n=1:length(rc) if rc(n).Status == 0 results = rc(n).Results; for m=1:length(results) disp(['MetricID: ',results(m).MetricID]); disp([' ComponentPath: ', results(m).ComponentPath]); disp([' Value: ', num2str(results(m).Value)]); disp(' '); end else disp(['No results for:',rc(n).MetricID]); end disp(' '); end
Вот результаты.
MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_bus Value: 15 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_bus/More Info3 Value: 0 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_bus/More Info4 Value: 0 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_bus/More Info1 Value: 0 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_bus/More Info2 Value: 0 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_counter_bus Value: 2 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_counter_bus/COUNTER Value: 6 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_counter_bus/COUNTER/Counter Value: 3 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_counter_bus/COUNTER/Counter/ResetCheck Value: 4 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_counter_bus/COUNTER/Counter/ResetCheck/NoReset Value: 2 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_counter_bus/COUNTER/Counter/ResetCheck/Reset Value: 3 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_counter_bus/COUNTER/Counter/SaturationCheck Value: 5 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_counter_bus/COUNTER/LimitsProcess Value: 1 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_counter_bus/More Info1 Value: 0 MetricID: nonvirtualblockcount ComponentPath: sldemo_mdlref_counter_bus/More Info2 Value: 0
Чтобы экспортировать метрические результаты в XML-файл, используйте метод exportMetrics
. Для каждого метрического результата XML-файл включает ComponentID
, ComponentPath
, MetricID
, Value
, AggregatedValue
и Measure
.
filename='MyMetricData.xml'; exportMetrics(metric_engine,filename);
В данном примере не укажите невиртуальную метрику количества блока.
slmetric.metric.unregisterMetric(id_metric);
Закройте модель.
clear; bdclose('all');
Пользовательские метрические алгоритмы не поддерживают свойство path на объектах компонента:
Соединенные диаграммы Stateflow
Блоки MATLAB function
Пользовательские метрические алгоритмы не переходят по ссылкам библиотеки.
Advisor.component.Component
| Advisor.component.Types
| slmetric.Engine
| slmetric.metric.Metric
| slmetric.metric.Result
| slmetric.metric.createNewMetricClass