Этот пример показывает, как журналирование траекторий состояния модели 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, который содержит выходные журналы симуляции:
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