Повторите алгоритм Используя для каждой подсистемы

Если вы повторяете алгоритмы в схеме путем копирования и вставки блоков, и подсистемы, поддерживая модель могут стать трудными. Отдельные сигнальные линии и подсистемы могут переполнить схему, уменьшая удобочитаемость и делая простые изменения трудными. В то же время много переменных могут переполнить рабочие области, уменьшая мобильность модели. Модель может разработать эти проблемы эффективности, как вы добавляете в проект в зависимости от времени.

Чтобы повторить алгоритм, можно выполнить итерации алгоритма по сигналам, подсистемам и параметрам, которые сгруппированы в массивы и структуры. Этот пример показывает, как преобразовать неэффективно комплексный повторяющийся алгоритм в компактную форму, которой легче управлять.

Исследуйте модель в качестве примера

  1. Откройте модель ex_repeat_algorithm в качестве примера. Модель создает приблизительно 30 переменных в базовом рабочем пространстве.

  2. Осмотрите подсистему Burner_1_Analysis. Эта подсистема выполняет алгоритм при помощи переменных базового рабочего пространства как параметры в блоках, таких как Интегратор Дискретного времени и Констант.

  3. Осмотрите подсистемы Burner_2_Analysis и Burner_3_Analysis. Все три подсистемы выполняют тот же алгоритм, но используют различные переменные рабочей области, чтобы параметризовать блоки.

  4. Осмотрите три подсистемы Analysis_Delay. Эти подсистемы повторяют различный алгоритм от того в Аналитических подсистемах.

  5. Возвратитесь к верхнему уровню модели. Блоки памяти задерживают входные сигналы, прежде чем они введут подсистемы Analysis_Delay.

  6. Посмотрите на панель Data Import/Export диалогового окна Configuration Parameters. Модель использует переменные SensorsInput и t в качестве входных параметров симуляции.

    Во время симуляции каждый из этих девяти столбцов в матричной переменной SensorsInput обеспечивает входные данные для блока Inport в верхнем уровне модели.

Уменьшайте плотность сигнальной линии с шинами

Можно использовать шины для связанных с группой сигналов в один структурированный сигнал, уменьшая плотность строки и улучшая удобочитаемость модели.

Каждая подсистема в модели в качестве примера требует трех входных параметров сигнала. Можно объединить каждую группу из трех сигналов в одну шину.

Вы могли изменить все подсистемы в модели в качестве примера, чтобы использовать шины. Однако, потому что некоторые подсистемы идентичны, можно удалить их и позже заменить их на Для Каждого блоки Subsystem.

  1. Откройте редактор шины.

    buseditor

  2. Создайте тип шины SensorData с тремя элементами сигнала: sensor1, sensor2 и sensor3.

  3. Удалите блоки как показано в фигуре, оставив только блоки Burner_1_Sensor1 и Burner_1_Delay1 как входные параметры к двум остающимся подсистемам.

  4. На вкладке Signal Attributes диалогового окна блока Burner_1_Sensor1 Inport, набор Data type к Bus: SensorData.

    Вывод блока является сигналом шины, который содержит три элемента сигнала sensor1, sensor2 и sensor3.

  5. Откройте подсистему Burner_1_Analysis. Удалите выходные строки сигнала трех блоков Inport. Удалите блоки In3 Inport и In2.

  6. Добавьте блок Селектора Шины справа от блока In1 Inport. Соедините блок Inport вывод с блоком Селектора Шины.

  7. В Шине Селектор блокирует диалоговое окно, выбирает сигналы sensor1, sensor2 и sensor3.

    Блок Селектора Шины извлекает три элемента сигнала от входной шины. Другие блоки в модели могут использовать извлеченные элементы сигнала.

  8. В подсистеме соедините блоки как показано.

  9. В подсистеме Burner_1_Analysis_Delay используйте блок Селектора Шины, чтобы извлечь сигналы в шине. Используйте тот же метод, как вы сделали в подсистеме Burner_1_Analysis.

Повторите алгоритм

Для Каждого блока Subsystem делит входной сигнал, и последовательно выполняет алгоритм на каждом разделе. Например, если вход к подсистеме является массивом шести сигналов, можно сконфигурировать подсистему, чтобы выполнить тот же алгоритм на каждом из шести сигналов.

Можно использовать Для Каждого подсистемы, чтобы повторить алгоритм итеративным способом. Этот подход улучшает удобочитаемость модели и дает возможность изменять повторный алгоритм.

  1. Добавьте два Для Каждого блоки Subsystem к модели. Назовите одну из подсистем Burner_Analysis. Назовите другую подсистему Burner_Analysis_Delay.

  2. Скопируйте содержимое подсистемы Burner_1_Analysis в подсистему Burner_Analysis. Прежде чем вы вставите блоки, удалите блоки Inport и Outport в Для Каждой подсистемы.

  3. В диалоговом окне блока For Each в подсистеме Burner_Analysis установите флажок, чтобы разделить вход In1.

  4. Скопируйте содержимое подсистемы Burner_1_Analysis_Delay в подсистему Burner_Analysis_Delay.

  5. В диалоговом окне блока For Each в подсистеме Burner_Analysis_Delay установите флажок, чтобы разделить вход In1.

  6. В верхнем уровне модели удалите подсистемы Burner_1_Analysis и Burner_1_Analysis_Delay. Соедините новое Для Каждого блоки Subsystem в их месте.

  7. На вкладке Signal Attributes диалогового окна блока Burner_1_Sensor1 Inport, набор Port dimensions к 3.

    Блок вывод является трехэлементным массивом шин. Для Каждого подсистемы в модели повторяют алгоритм для каждой из трех шин в массиве.

  8. Создайте объект 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 как элемент объекта.

  9. Установите параметр конфигурации Input на SensorsInput.

    Поскольку SensorsInput обеспечивает входные данные симуляции в форме объектов timeseries, вы не должны задавать переменную, которая содержит данные времени.

  10. Создайте массив структур, который инициализирует блок объема оставшейся памяти, и сохраните массив в переменной 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.

  11. В диалоговом окне Блока памяти, набор Initial condition к initForDelay.

    Вывод Блока памяти является массивом шин, который требует инициализации. Каждый элемент сигнала в массиве шин получает начальное значение от соответствующего поля в массиве структур.

Организуйте параметры в массивы структур

Базовое рабочее пространство содержит много переменных, которые модель в качестве примера использует для параметров блоков. Чтобы сократить количество переменных рабочей области, группируйте их в массивы структур и используйте отдельные поля структуры, чтобы задать параметры блоков.

Для Каждого блока Subsystem может разделить массив значений, которые вы задаете как параметр маски. Каждая итерация подсистемы использует один раздел массива, чтобы задать параметры блоков. Если вы задаете параметр как массив структур, каждая итерация подсистемы может использовать одну из структур в массиве.

  1. Создайте массив структур, который параметризовал 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.

  2. В модели щелкните правой кнопкой по Burner_Analysis Для Каждой подсистемы и выберите Mask> Create Mask.

  3. На панели Parameters & Dialog диалогового окна, под Parameter, нажимают Edit. Для нового параметра маски, набор Prompt к Parameter structure и Name к paramStruct. Нажмите OK.

  4. В маске для подсистемы Burner_Analysis, набор Parameter structure к paramsNormal.

  5. Откройте подсистему. В диалоговом окне блока For Each, на панели Parameter Partition, устанавливают флажок, чтобы разделить параметр paramStruct. Установите Partition dimension на 2.

  6. Для блоков в подсистеме, установленной эти параметры.

    Блок'ParameterName' Значение параметров
    УсилениеGainparamStruct.gain
    Интегратор дискретного времениInitial conditionparamStruct.init
    ПостоянныйConstant valueparamStruct.offset

  7. Создайте массив структур, который параметризовал 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

  8. В верхнем уровне модели щелкните правой кнопкой по Burner_Analysis_Delay Для Каждой подсистемы и выберите Mask> Create Mask.

  9. На панели Parameters & Dialog диалогового окна, под Parameter, нажимают Edit. Для нового параметра маски, набор Prompt к Parameter structure и Name к paramStruct. Нажмите OK.

  10. В маске для Для Каждого блока Subsystem, набор Parameter structure к paramsForDelay.

  11. Откройте подсистему. В диалоговом окне блока For Each, на панели Parameter Partition, устанавливают флажок, чтобы разделить параметр paramStruct. Установите Partition dimension на 2.

  12. Для блоков в подсистеме, установленной эти параметры.

    Блок'ParameterName' Значение параметров
    УсилениеGainparamStruct.gain
    Интегратор дискретного времениInitial conditionparamStruct.init
    ПостоянныйConstant valueparamStruct.offset

  13. Очистите ненужные переменные из базового рабочего пространства.

    % 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 за пределами подсистемы и затем регистрировать тот сигнал. Для получения дополнительной информации смотрите Логарифмические Сигналы в Для Каждого Подсистемы.

Примеры Работы с для каждого подсистемы

Векторизуйте алгоритмы Используя для каждого подсистемы

Этот пример показывает, как упростить моделирование векторизованных алгоритмов. Используя Для Каждого блоки Subsystem упрощают модель, где три входных сигнала отфильтрованы тремя идентичными Передачами блоки Fcn. Этот пример также показывает, как добавить больше управления в фильтры путем изменения их коэффициентов для каждой итерации подсистемы.

Эта модель использует идентичную Передачу блоки Fcn, чтобы независимо обработать каждый элемент входного синусоидального сигнала. Блок Vector Concatenate конкатенирует получившиеся выходные сигналы. Этот повторяющийся процесс является графически комплексным и трудным поддержать. Кроме того, добавление другого элемента к сигналу требует значительной переделки модели.

Можно упростить эту модель, заменив повторяющиеся операции на сингл Для Каждого блока Subsystem.

Для Каждого блока подсистемы содержит блок For Each и модель, представляющую алгоритм трех блоков, которые это заменяет посредством блока Transfer Fcn. Блок For Each задает, как разделить вектор входного сигнала в отдельные элементы и как конкатенировать обработанные сигналы сформировать вектор выходного сигнала. Каждый блок, который имеет состояние, поддерживает отдельный набор состояний для каждого входного элемента, обработанного во время данного шага выполнения.

В данном примере входной сигнал выбран для разделения. Partition Dimension и параметры Partition Width на блоке For Each оба установлены в 1 для входа.

Можно увеличить этот подход, чтобы добавить больше сигналов, не имея необходимость значительно изменить модель. Этот подход рассматривается легко масштабируемым и графически более простым.

Изменение Параметра модели, Не Изменяя Образцовую Структуру.  Этот пример показывает как изменению параметра модели в алгоритме. Это использует Для Каждой модели разделения Подсистемы от, Векторизуют Алгоритмы Используя Для Каждого Подсистемы, и создает различные фильтры для каждого входного сигнала в то время как сдерживающая простота модели. Вы питаете массив коэффициентов фильтра к Для Каждого блока подсистемы как параметр маски отмеченным для разделения. В каждой итерации Для Каждого блока подсистемы, раздел коэффициентов фильтра питается блок Transfer Fcn.

  1. Откройте модель ex_ForEachSubsystem_Partitioning. Создайте маску для Для Каждого блока Subsystem и добавьте доступный для редактирования параметр маски. Определите имя к FilterCoeffs и подсказку к Filter Coefficient Matrix. Для получения информации о том, как добавить параметр маски, смотрите, Создают Простую Маску.

  2. Откройтесь Для Каждого блока подсистемы. В подсистеме откройте диалоговое окно блока For Each.

  3. Во вкладке Parameter Partition установите флажок рядом с параметром FilterCoeffs , чтобы позволить делить этого параметра. Сохраните параметры Размерности Ширины и Раздела Раздела в их значении по умолчанию 1.

  4. Дважды кликните Для Каждого блока 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], чтобы реализовать различные фильтры четвертого порядка для каждого входного сигнала.

  5. В Для Каждого блока Subsystem, дважды кликните блок Transfer Fcn и введите FilterCoeffs для Содействующего параметра Знаменателя. Эта установка заставляет блок получать свои коэффициенты от параметра маски.

Для Каждого блока Subsystem нарезает входной параметр в горизонтальные разделы ширины 1, который эквивалентен одной строке коэффициентов. Параметр коэффициентов преобразовывает от единого массива

в три строки параметров:

Повторное использование Улучшенного кода Используя Для Каждого Подсистемы.  Этот пример показывает, как можно улучшить повторное использование кода, когда у вас есть два или больше идентичных Для Каждого блоки Subsystem. Рассмотрите следующую модель, 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, соответственно.

Остающиеся две подсистемы в этой модели show, как повторно используемый код может также быть сгенерирован для матричных сигналов, которые обрабатываются с помощью Для Каждого блока Subsystem. Снова, нажатие Ctrl+B, чтобы сгенерировать код обеспечивает повторное использование кода одной функции.

Смотрите также

|

Связанные примеры

Больше о