В этом примере показано, как логгирование траекторий состояния модели Simulink® в формате структуры может быть лучше, чем традиционный метод логгирования состояний в формате массивов. Упорядоченное расположение состояний вдоль столбцов в регистрируемой матрице зависит от блока отсортированный порядок, который программное обеспечение Simulink определяет во время компиляции модели. Различные факторы могут влиять на блок отсортированный порядок, который может изменить упорядоченное расположение состояний.
Этот пример иллюстрирует, как логгирование состояний в формате Структуры, который хранит имена блока траекториями состояния, может помочь предотвратить проблему упорядоченного расположения состояния.
По умолчанию программное обеспечение Simulink регистрирует траектории состояния в формате массивов, который является матрицей со столбцами N, где N является количеством состояний. Матрица имеет строки M с каждой строкой, соответствующей одному шагу времени симуляции. Этой матричной формой M на n легко управлять в MATLAB®. Однако упорядоченное расположение переменных состояния вдоль столбцов регистрируемой матрицы зависит от блока отсортированный порядок. Поэтому любой код MATLAB, который ожидает фиксированное отображение между состояниями блоков в модели и столбцах матрицы состояний, подвержен повреждению, когда блок отсортированный порядок изменяется из-за изменений в модели.
Например, рассмотрите следующие две блок-схемы:
mdl1 = 'sldemo_state_logging1'; mdl2 = 'sldemo_state_logging2'; open_system(mdl1); open_system(mdl2);
Две схемы имеют те же блоки, единственной разницей является упорядоченное расположение выходных портов. Симулируйте модели и регистрируйте состояния в формате массивов:
simOut1 = sim(mdl1, 'SaveFormat','Array'); simOut2 = sim(mdl2, 'SaveFormat','Array');
Извлеките векторы состояний из Simulink.SimulationOutput object, который содержит выходные журналы симуляции:
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');
Извлеките структуры, которые содержат журналы состояния от симуляции выходной объект:
x1s = simOut1.get('xout'); x2s = simOut2.get('xout');
Отобразите эти структуры. Обратите внимание на то, что эти структуры имеют два поля: время и сигналы. Поле 'время' пусто, потому что мы выбрали 'Structure' для параметра модели 'SaveFormat'. Мы, возможно, выбрали 'StructureWithTime', чтобы сохранить временной вектор в структуре состояний:
disp(x1s); disp(x2s);
time: [] signals: [1x2 struct] time: [] signals: [1x2 struct]
Программное обеспечение регистрирует траектории состояния в xs.signals(k).values
наряду с именами блоков xs.signals(k).blockName
это соответствует этим состояниям. Извлеките состояния в матрицу (как в формате массивов) как это:
x1a = [x1s.signals.values]; x2a = [x2s.signals.values];
Обратите внимание на то, что проблема упорядоченного расположения состояния все еще существует (x1a
и x2a
совпадают с x1
и x2
, полученный через формат массивов):
isequal(x1a, x2a)
ans = logical 0
Чтобы решить проблему упорядоченного расположения состояния, используйте имена блока, сохраненные наряду со значениями, чтобы сопоставить состояния с фиксированным порядком, например, алфавитным порядком имен блока:
[~, 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
Путем переупорядочения массивов сигналов в x1
и x2
в алфавитный порядок имен блока и извлечение полей значений, в том порядке, в матрицы x1
и x2
, у нас есть механизм для логгирования состояний в матрицу с фиксированным отображением состояний блока к столбцам регистрируемой матрицы.
Закройте модели и очистите переменные, которые использовались в этом примере:
close_system(mdl1); close_system(mdl2); clear ans idx1 idx2 mdl1 mdl2 simOut1 simOut2 x1 x1a x1s x2 x2a x2s