Логгирование состояний с использованием Structure
формат может обеспечить преимущества перед Array
формат. Когда вы логгируете состояния используя Array
формат, упорядоченное расположение состояний вдоль столбцов в записанном массиве зависит от порядка сортировки блоков. Различные факторы могут повлиять на блок сортированный порядок, который может изменить упорядоченное расположение состояний от одной симуляции к следующей. Когда вы используете Structure
формат, имена блоков хранятся вместе с записанными данными о состоянии для этого блока, поэтому можно обрабатывать данные без учета порядка сортировки блоков.
Когда вы логгируете состояния используя Array
формат, записанные данные хранятся в массиве с N
столбцы, где N
количество состояний и M
строки, по одной для каждого временного шага симуляции. Этой M-на-N матричной формой легко манипулировать в MATLAB ®. Однако упорядоченное расположение переменных состояния вдоль столбцов записанной матрицы зависит от порядка сортировки блоков. Поэтому любой код MATLAB, который ожидает фиксированного отображения между состояниями блоков в модели и столбцами матрицы состояний, склонен к разрыву, когда порядок сортировки блоков изменяется из-за изменений в модели.
Для примера рассмотрим модели sldemo_state_logging1
и sldemo_state_logging2
.
mdl1 = 'sldemo_state_logging1'; mdl2 = 'sldemo_state_logging2'; open_system(mdl1); open_system(mdl2);
Две модели содержат одни и те же блоки, соединенные одинаково. Единственным различием является порядок выходных портов. Симулируйте модели и логгируйте состояния, используя Array
формат.
simOut1 = sim(mdl1, 'SaveFormat','Array'); simOut2 = sim(mdl2, 'SaveFormat','Array');
Извлеките векторы состояний из Simulink.SimulationOutput
объект, который содержит все данные, записанные в симуляцию.
x1 = simOut1.get('xout'); x2 = simOut2.get('xout');
Зарегистрированные данные о состояниях для x1
и x2
отличаются тем, что блоки упорядочены по-разному, поэтому отображение между столбцами в записанном массиве и блоками в модели отличается.
isequal(x1, x2)
ans = logical 0
Моделируйте модели снова, но на этот раз регистрируйте состояния в формате структуры.
simOut1=sim(mdl1,'SaveFormat','Structure'); simOut2=sim(mdl2,'SaveFormat','Structure');
Извлеките структуры, которые содержат записанные состояния, из SimulationOutput
объект.
x1s = simOut1.get('xout'); x2s = simOut2.get('xout');
Отобразите эти структуры, которые содержат два поля: time
и signals
. The time
поле пустое, поскольку данные были записаны с помощью Structure
формат, а не StructureWithTime
формат. Можно использовать StructureWithTime
формат, когда необходимо сохранить временные данные вместе с данными о состояниях.
disp(x1s); disp(x2s);
time: [] signals: [1x2 struct] time: [] signals: [1x2 struct]
Структура signals
поле является массивом структур с одной структурой для каждого блока в модели, который имеет данные о состоянии. Каждый блок структура данных в signals
поле содержит values
поле с данными о состояниях и blockName
поле с именем блока, который произвел эти данные о состоянии. Можно извлечь данные о состояниях в матрицу, которую можно обработать, подобно тому, как вы бы зарегистрировали состояния, используя Array
формат.
Чтобы исправить проблему упорядоченного расположения состояний, сначала используйте имена блоков, чтобы отсортировать данные о состояниях в фиксированный порядок. Например, можно отсортировать данные о состояниях так, чтобы блоки находились в алфавитном порядке, который останется неизменным от одной симуляции до следующей, независимо от порядка сортировки блоков.
[~, idx1] = sort({x1s.signals.blockName}); x1 = [x1s.signals(idx1).values]; [~, idx2] = sort({x2s.signals.blockName}); x2 = [x2s.signals(idx2).values]; isequal(x1, x2)
ans = logical 1
Если вы переупорядочиваете поля сигналов в алфавитном порядке по имени блока, если вы извлекаете данные поля значений в том же порядке, можно затем обработать данные так же, как и при использовании Array
формат, но порядок данных состояний блока не меняется от одной симуляции к следующей.