Повторите алгоритм Используя For Each Subsystem

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

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

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

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

  2. Смотрите подсистему Burner_1_Analysis. Эта подсистема выполняет алгоритм при помощи переменных базового рабочего пространства как параметры в блоках, таких как Constant и Discrete-Time Integrator.

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

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

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

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

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

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

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

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

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

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

    buseditor

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

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

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

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

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

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

  7. В диалоговом окне блока Bus Selector выберите сигналы sensor1, sensor2, и sensor3.

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

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

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

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

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

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

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

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

  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. Соедините новые блоки For Each Subsystem в их месте.

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

    Блок выход является трехэлементным массивом шин. For Each subsystem s в модели повторяет алгоритм для каждой из трех шин в массиве.

  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(SensorsInput(:,' num2str(3*(i-1)+1) '),t);'])
        
        % Sensor 2
        eval(['tempInput(1,' num2str(i) ').sensor2 = ' ...
            'timeseries(SensorsInput(:,' num2str(3*(i-1)+2) '),t);'])
        
        % Sensor 3
        eval(['tempInput(1,' num2str(i) ').sensor3 = ' ...
            'timeseries(SensorsInput(:,' num2str(3*(i-1)+3) '),t);'])
        
    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. Создайте массив структур, который инициализирует остающийся блок Memory, и сохраните массив в переменной 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. В диалоговом окне блока Memory, набор Initial condition к initForDelay.

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

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

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

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

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

  2. В модели щелкните правой кнопкой по Burner_Analysis For Each subsystem и выберите 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' Значение параметров
    GainGainparamStruct.gain
    Discrete-Time IntegratorInitial conditionparamStruct.init
    ConstantConstant valueparamStruct.offset

  7. Создайте массив структур, который параметрирует For Each subsystem 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 For Each subsystem и выберите Mask> Create Mask.

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

  10. В маске для блока For Each Subsystem, набор Parameter structure к paramsForDelay.

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

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

    Блок'ParameterName' Значение параметров
    GainGainparamStruct.gain
    Discrete-Time IntegratorInitial conditionparamStruct.init
    ConstantConstant valueparamStruct.offset

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

    % Clear the old parameter variables that you replaced 
    % with arrays of structures
    clear -regexp _
    
    % Clear the iteration variables
    clear i

    Модель требует немногих переменных в базовом рабочем пространстве.

Смотрите конвертированную модель

Чтобы просмотреть новый сигнал и организацию подсистемы, обновите схему.

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

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

Совет

Можно регистрировать сигналы нешины в Для Каждой подсистемы. Однако вы не можете использовать логгирование сигнала для шин или массивов шин из Для Каждой подсистемы. Или используйте блок Bus Selector, чтобы выбрать сигналы элемента шины, что вы хотите регистрировать или добавить блок Outport за пределами подсистемы и затем регистрировать тот сигнал. Для получения дополнительной информации смотрите Логарифмические Сигналы в Для Каждого Подсистемы.

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

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

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

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

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

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

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

screenshot of For Each Block Parameters dialog, Input Partition tab

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

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

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

  2. Откройте блок For Each subsystem. В подсистеме откройте диалоговое окно блока For Each.

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

    screenshot of For Each Block Parameters dialog, Parameter Partition tab

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

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

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

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

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

/*
 * 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 это указывает на количество независимых скаляров, что каждый For Each Subsystem к процессам. Эта функция вызвана три раза параметром NumIters установите на 10, 8, и 7, соответственно.

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

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

Объекты

Блоки

Похожие темы