Если вы повторяете алгоритмы в схеме путем копирования и вставки блоков, и подсистемы, поддерживая модель могут стать трудными. Отдельные сигнальные линии и подсистемы могут переполнить схему, уменьшив удобочитаемость и делая простые изменения трудными. В то же время много переменных могут переполнить рабочие области, уменьшив мобильность модели. Модель может разработать эти проблемы эффективности, как вы добавляете к дизайну в зависимости от времени.
Чтобы повторить алгоритм, можно выполнить итерации алгоритма по сигналам, подсистемам и параметрам, которые сгруппированы в массивы и структуры. Этот пример показывает, как преобразовать неэффективно комплексный повторяющийся алгоритм в компактную форму, которой легче управлять.
Откройте модель в качестве примера ex_repeat_algorithm
. Модель создает приблизительно 30 переменных в базовом рабочем пространстве.
Осмотрите подсистему Burner_1_Analysis. Эта подсистема выполняет алгоритм при помощи переменных базового рабочего пространства как параметры в блоках, таких как Интегратор Дискретного времени и Констант.
Осмотрите подсистемы Burner_2_Analysis и Burner_3_Analysis. Все три подсистемы выполняют тот же алгоритм, но используют различные переменные рабочей области, чтобы параметризовать блоки.
Осмотрите три подсистемы Analysis_Delay. Эти подсистемы повторяют различный алгоритм от того в Аналитических подсистемах.
Возвратитесь к верхнему уровню модели. Блоки памяти задерживают входные сигналы, прежде чем они введут подсистемы Analysis_Delay.
Посмотрите на панель Импорта/Экспорта Данных диалогового окна Configuration Parameters. Модель использует переменные SensorsInput
и t
как входные параметры моделирования.
Во время моделирования каждый из этих девяти столбцов в матричном переменном SensorsInput
обеспечивает входные данные для блока Inport в верхнем уровне модели.
Можно использовать шины для связанных с группой сигналов в единственный структурированный сигнал, уменьшая плотность строки и улучшая удобочитаемость модели.
Каждая подсистема в модели в качестве примера требует трех входных параметров сигнала. Можно объединить каждую группу из трех сигналов в единственную шину.
Вы могли изменить все подсистемы в модели в качестве примера, чтобы использовать шины. Однако, потому что некоторые подсистемы идентичны, можно удалить их и позже заменить их на Для Каждой Подсистемы блоки.
Откройте редактор шины.
buseditor
Создайте тип шины SensorData
с тремя элементами сигнала: sensor1
, sensor2
и sensor3
.
Удалите блоки как показано в фигуре, оставив только блоки Burner_1_Sensor1 и Burner_1_Delay1 как входные параметры к двум остающимся подсистемам.
На вкладке Signal Attributes диалогового окна блока Burner_1_Sensor1 Inport, Типа данных набора к Bus: SensorData
.
Вывод блока является сигналом шины, который содержит три элемента сигнала sensor1
, sensor2
и sensor3
.
Откройте подсистему Burner_1_Analysis. Удалите выходные строки сигнала трех блоков Inport. Удалите блоки In3 Inport и In2.
Добавьте блок Селектора Шины справа от блока In1 Inport. Соедините блок Inport вывод с блоком Селектора Шины.
В Шине Селектор блокирует диалоговое окно, выбирает сигналы sensor1
, sensor2
и sensor3
.
Блок Селектора Шины извлекает три элемента сигнала от входной шины. Другие блоки в модели могут использовать извлеченные элементы сигнала.
В подсистеме соедините блоки как показано.
В подсистеме Burner_1_Analysis_Delay используйте блок Селектора Шины, чтобы извлечь сигналы в шине. Используйте тот же метод, как вы сделали в подсистеме Burner_1_Analysis.
Блок For Each Subsystem делит входной сигнал, и последовательно выполняет алгоритм на каждом разделе. Например, если входной параметр к подсистеме является массивом шести сигналов, можно сконфигурировать подсистему, чтобы выполнить тот же алгоритм на каждом из шести сигналов.
Можно использовать Для Каждого подсистемы, чтобы повторить алгоритм итеративным способом. Этот подход улучшает удобочитаемость модели и дает возможность изменять повторный алгоритм.
Добавьте два Для Каждой Подсистемы блоки к модели. Назовите одну из подсистем Burner_Analysis. Назовите другую подсистему Burner_Analysis_Delay.
Скопируйте содержимое подсистемы Burner_1_Analysis в подсистему Burner_Analysis. Прежде чем вы вставите блоки, удалите блоки Inport и Outport в Для Каждой подсистемы.
В диалоговом окне блока For Each в подсистеме Burner_Analysis установите флажок, чтобы разделить входной параметр In1
.
Скопируйте содержимое подсистемы Burner_1_Analysis_Delay в подсистему Burner_Analysis_Delay.
В диалоговом окне блока For Each в подсистеме Burner_Analysis_Delay установите флажок, чтобы разделить входной параметр In1
.
В верхнем уровне модели удалите подсистемы Burner_1_Analysis и Burner_1_Analysis_Delay. Соедините новое Для Каждой Подсистемы блоки в их месте.
На вкладке Signal Attributes диалогового окна блока Burner_1_Sensor1 Inport, размерностей Порта набора к 3
.
Блок вывод является трехэлементным массивом шин. Для Каждого подсистемы в модели повторяют алгоритм для каждой из трех шин в массиве.
Создайте объект Simulink.SimulationData.Dataset
, который блок Inport может использовать, чтобы импортировать данные моделирования. Можно использовать этот код, чтобы создать объект и сохранить его в переменном SensorsInput
.
% First, create an array of structures whose field values are % timeseries objects. for i = 1:3 % Burner number % Sensor 1 eval(['tempInput(1,' num2str(i) ').sensor1 = ' ... 'timeseries(t,SensorsInput(:,' num2str(3*(i-1)+1) '));']) % Sensor 2 eval(['tempInput(1,' num2str(i) ').sensor2 = ' ... 'timeseries(t,SensorsInput(:,' num2str(3*(i-1)+2) '));']) % Sensor 3 eval(['tempInput(1,' num2str(i) ').sensor3 = ' ... 'timeseries(t,SensorsInput(:,' num2str(3*(i-1)+3) '));']) end % Create the Dataset object. SensorsInput = Simulink.SimulationData.Dataset; SensorsInput = addElement(SensorsInput,tempInput,'element1'); clear tempInput t i
Код сначала создает переменный tempInput
, который содержит массив трех структур. Каждая структура имеет три поля, которые соответствуют элементам сигнала в типе шины SensorData
, и каждое поле хранит
объект MATLAB® timeseries
. Каждая объектно-ориентированная память timeseries
один из девяти столбцов данных от переменного SensorsInput
, который сохранил входные данные моделирования для каждого из датчиков.
Код затем перезаписывает SensorsInput
с новым объектом Simulink.SimulationData.Dataset
и добавляет tempInput
как элемент объекта.
Установите Входной параметр конфигурации на SensorsInput
.
Поскольку SensorsInput
обеспечивает входные данные моделирования в форме объектов timeseries
, вы не должны задавать переменную, которая содержит данные времени.
Создайте массив структур, который инициализирует блок объема оставшейся памяти, и сохраните массив в переменном initForDelay
. Задайте поля структуры со значениями существующих переменных инициализации, таких как initDelay_1_sensor1
.
for i = 1:3 % Burner number % Sensor 1 eval(['initForDelay(' num2str(i) ').sensor1 = ' ... 'initDelay_' num2str(i) '_sensor1;']) % Sensor 2 eval(['initForDelay(' num2str(i) ').sensor2 = ' ... 'initDelay_' num2str(i) '_sensor2;']) % Sensor 3 eval(['initForDelay(' num2str(i) ').sensor3 = ' ... 'initDelay_' num2str(i) '_sensor3;']) end
Чтобы просмотреть содержимое нового переменного initForDelay
, дважды кликните имя переменной в базовом рабочем пространстве. Переменная содержит массив трех структур, что у каждого есть три поля: sensor1
, sensor2
и sensor3
.
В диалоговом окне Блока памяти, установленном Начальном условии к initForDelay
.
Вывод Блока памяти является массивом шин, который требует инициализации. Каждый элемент сигнала в массиве шин получает начальное значение от соответствующего поля в массиве структур.
Базовое рабочее пространство содержит много переменных, которые модель в качестве примера использует для блочных параметров. Чтобы сократить количество переменных рабочей области, группируйте их в массивы структур и используйте отдельные поля структуры, чтобы задать блочные параметры.
Блок For Each Subsystem может разделить массив значений, которые вы задаете как параметр маски. Каждая итерация подсистемы использует единственный раздел массива, чтобы задать блочные параметры. Если вы задаете параметр как массив структур, каждая итерация подсистемы может использовать одну из структур в массиве.
Создайте массив структур, который параметризовал Burner_Analysis Для Каждой подсистемы, и сохраните массив в переменном paramsNormal
. Задайте поля структуры при помощи значений существующих переменных параметра, таких как gainNormal_1
, offsetNormal_1
и initDelayed_1
.
for i = 1:3 eval(['paramsNormal(' num2str(i) ').gain = gainNormal_' num2str(i) ';']) eval(['paramsNormal(' num2str(i) ').offset = offsetNormal_' num2str(i) ';']) eval(['paramsNormal(' num2str(i) ').init = initNormal_' num2str(i) ';']) end
Переменная содержит массив трех структур, что у каждого есть три поля: gain
, offset
и init
.
В модели щелкните правой кнопкой по Burner_Analysis Для Каждой подсистемы и выберите Mask> Create Mask.
На панели Parameters & Dialog диалогового окна, под Параметром, нажимают Edit. Для нового параметра маски, Подсказки набора к Parameter structure
и Имени к paramStruct
. Нажать ОК.
В маске для подсистемы Burner_Analysis, структуры Параметра набора к paramsNormal
.
Откройте подсистему. В диалоговом окне блока For Each, на панели Раздела Параметра, устанавливают флажок, чтобы разделить параметр paramStruct
. Установите размерность Раздела на 2
.
Для блоков в подсистеме, установленной эти параметры.
Блок | 'ParameterName' | Значение параметров |
---|---|---|
Усиление | Усиление | paramStruct.gain |
Интегратор дискретного времени | Начальное условие | paramStruct.init |
Постоянный | Постоянное значение | paramStruct.offset |
Создайте массив структур, который параметризовал Burner_Analysis_Delay Для Каждой подсистемы, и сохраните массив в переменном paramsForDelay
.
for i = 1:3 eval(['paramsForDelay(' num2str(i) ').gain = gainDelayed_' num2str(i) ';']) eval(['paramsForDelay(' num2str(i) ').offset = offsetDelayed_' num2str(i) ';']) eval(['paramsForDelay(' num2str(i) ').init = initDelayed_' num2str(i) ';']) end
В верхнем уровне модели щелкните правой кнопкой по Burner_Analysis_Delay Для Каждой подсистемы и выберите Mask> Create Mask.
На панели Parameters & Dialog диалогового окна, под Параметром, нажимают Edit. Для нового параметра маски, Подсказки набора к Parameter structure
и Имени к paramStruct
. Нажать ОК.
В маске для блока For Each Subsystem, структуры Параметра набора к paramsForDelay
.
Откройте подсистему. В диалоговом окне блока For Each, на панели Раздела Параметра, устанавливают флажок, чтобы разделить параметр paramStruct
. Установите размерность Раздела на 2
.
Для блоков в подсистеме, установленной эти параметры.
Блок | 'ParameterName' | Значение параметров |
---|---|---|
Усиление | Усиление | paramStruct.gain |
Интегратор дискретного времени | Начальное условие | paramStruct.init |
Постоянный | Постоянное значение | paramStruct.offset |
Очистите ненужные переменные от базового рабочего пространства.
% Clear the old parameter variables that you replaced % with arrays of structures clear -regexp _ % Clear the iteration variables clear i
Модель требует немногих переменных в базовом рабочем пространстве.
Чтобы просмотреть новый сигнал и организацию подсистемы, обновите схему.
Образцовый входной параметр является массивом трех сигналов шины. Модель использует два Для Каждого подсистемы, чтобы выполнить эти два алгоритма на каждом из трех сигналов шины во входном массиве.
В базовом рабочем пространстве массивы структур заменяют много переменных, которые использовала модель. Математически, измененная модель ведет себя тот же способ, которым она сделала, когда вы запустили, потому что массивы структур содержат значения всех старых переменных.
Чтобы просмотреть завершенную модель, откройте модель в качестве примера ex_repeat_algorithm_complete
.
Можно регистрировать сигналы нешины в Для Каждой подсистемы. Однако вы не можете использовать журналирование сигнала для шины или массива сигналов шин из Для Каждой подсистемы. Или используйте блок Селектора Шины, чтобы выбрать сигналы элемента шины, что вы хотите регистрировать или добавить блок Outport за пределами подсистемы и затем регистрировать тот сигнал. Для получения дополнительной информации смотрите Сигналы Журнала в Для Каждого Подсистемы.
Этот пример показывает, как упростить моделирование векторизованных алгоритмов. Используя Для Каждой Подсистемы блоки упрощают модель, где три входных сигнала отфильтрованы тремя идентичными Передачами блоки Fcn. Этот пример также показывает, как добавить больше управления к фильтрам путем изменения их коэффициентов для каждой итерации подсистемы.
Эта модель использует идентичную Передачу блоки Fcn, чтобы независимо обработать каждый элемент входного синусоидального сигнала. Блок Vector Concatenate конкатенирует получившиеся выходные сигналы. Этот повторяющийся процесс является графически комплексным и трудным поддержать. Кроме того, добавление другого элемента к сигналу требует значительной переделки модели.
Можно упростить эту модель, заменив повторяющиеся операции на единственный блок For Each Subsystem.
Для Каждого блока подсистемы содержит блок For Each и модель, представляющую алгоритм трех блоков, которые это заменяет посредством блока Transfer Fcn. Блок For Each задает, как разделить вектор входного сигнала в отдельные элементы и как конкатенировать обработанные сигналы сформировать вектор выходного сигнала. Каждый блок, который имеет состояние, поддерживает отдельный набор состояний для каждого входного элемента, обработанного во время данного шага выполнения.
Для этого примера входной сигнал выбран для разделения. Размерность Раздела и Раздел Widthparameters на блоке For Each оба установлены в 1
для входного параметра.
Можно увеличить этот подход, чтобы добавить больше сигналов, не имея необходимость значительно изменить модель. Этот подход рассматривается легко масштабируемым и графически более простым.
Изменение Параметра модели, Не Изменяя Образцовую Структуру. Этот пример показывает как изменению параметра модели в алгоритме. Это использует Для Каждой модели разделения Подсистемы от, Векторизуют Алгоритмы Используя Для Каждого Подсистемы, и создает различные фильтры для каждого входного сигнала в то время как сдерживающая простота модели. Вы подаете массив коэффициентов фильтра к Для Каждого блока подсистемы как параметр маски, отмеченный для разделения. В каждой итерации Для Каждого блока подсистемы, раздел коэффициентов фильтра питается к блоку Transfer Fcn.
Откройте модель ex_ForEachSubsystem_Partitioning. Создайте маску для блока For Each Subsystem и добавьте доступный для редактирования параметр маски. Определите имя к FilterCoeffs
и подсказку к Filter Coefficient Matrix
. Для получения информации о том, как добавить параметр маски, смотрите, Создают Простую Маску.
Откройтесь Для Каждого блока подсистемы. В подсистеме откройте диалоговое окно блока For Each.
Во вкладке Parameter Partition установите флажок рядом с параметром FilterCoeffs, чтобы позволить делить этого параметра. Сохраните параметры Размерности Ширины и Раздела Раздела в их значении по умолчанию 1.
Дважды кликните блок For Each Subsystem и введите свою матрицу коэффициентов фильтра, ссорение коэффициентов фильтра для каждого входного сигнала. Например, введите [0.0284 0.2370 0.4692 0.2370 0.0284; -0.0651 0 0.8698 0 -0.0651; 0.0284 -0.2370 0.4692 -0.2370 0.0284]
, чтобы реализовать различные фильтры четвертого порядка для каждого входного сигнала.
В блоке For Each Subsystem дважды кликните блок Transfer Fcn и введите FilterCoeffs
для Содействующего параметра Знаменателя. Эта установка заставляет блок, получают его коэффициенты от параметра маски.
Блок For Each Subsystem нарезает входной параметр в горизонтальные разделы ширины 1, который эквивалентен одной строке коэффициентов. Параметр коэффициентов преобразовывает от единого массива
в три строки параметров:
Повторное использование Улучшенного кода Используя Для Каждого Подсистемы. Этот пример показывает, как можно улучшить повторное использование кода, когда у вас есть два или больше идентичных Для Каждой Подсистемы блоки. Рассмотрите следующую модель, rtwdemo_foreachreuse.
Намерение для этих трех подсистем — Векторного SS1, Векторного SS2, и Векторного SS3 — чтобы применить ту же обработку к каждому скалярному элементу векторного сигнала в их соответствующих входных параметрах. Поскольку эти три подсистемы выполняют ту же обработку, желательно для них произвести единственный разделяемый Вывод (и Обновление) функция для всех трех подсистем в коде, сгенерированном для этой модели. Например, Векторная подсистема SS3 содержит эти блоки.
Чтобы сгенерировать единственную разделяемую функцию для этих трех подсистем, настройка разделения, которое они выполняют на их входных сигналах, должна быть тем же самым. Для Векторного SS1 и Векторного SS3, эта настройка является прямой, потому что можно установить размерность раздела и ширину к 1. Однако для Векторного SS2 к также делят его входной сигнал по измерению 1, необходимо вставить блок Math Function, чтобы транспонировать 1 8 вектор - строку в 8 1 вектор - столбец. Можно затем преобразовать вывод подсистемы назад к 1 8 вектору - строке с помощью второго набора блока Math Function для оператора transpose
.
Если вы нажимаете Ctrl+B, чтобы сгенерировать код, получившийся код использует единственную выходную функцию. Эта функция совместно используется всеми тремя Для Каждой Подсистемы экземпляры.
/* * Output and update for iterator system: * '<Root>/Vector SS1' * '<Root>/Vector SS2' * '<Root>/Vector SS3' */ void VectorProcessing(int32_T NumIters, const real_T rtu_In1[], real_T rty_Out1[], rtDW_VectorProcessing *localDW)
Функция имеет входной параметр NumIters
, который указывает на количество независимых скаляров, что каждый Для Каждой Подсистемы к процессам. Эта функция вызвана три раза с параметром набор NumIters
к 10, 8, и 7, соответственно.
Остающиеся две подсистемы на этом образцовом показе, как повторно используемый код может также быть сгенерирован для матричных сигналов, которые обрабатываются с помощью блока For Each Subsystem. Снова, нажатие Ctrl+B, чтобы сгенерировать код обеспечивает повторное использование кода единственной функции.
Для каждой подсистемы | Simulink.Bus