Представление исполнительных блоков источника и приемника в сгенерированном коде

Можно использовать Variant Source и Variant Sink блоки, чтобы воспринимать несколько реализаций модели в одной, унифицированной блок-схеме. Каждая реализация зависит от условий, которые вы устанавливаете для блоков Variant Source и Variant Sink. Simulink® распространяет эти условия на вышестоящие и нисходящие блоки, включая корневые входные и корневые выходные порты.

Можно сгенерировать:

  • Код из модели Simulink, содержащей Variant Sink и Variant Source блоки.

  • Код, который содержит предварительные условия процессора, которые управляют активацией каждого варианта выбора.

  • Предварительные условия, которые не допускают активного выбора варианта.

Представление источников вариантов и вариантов блоков приемника в Simulink

Этот пример показывает, как исходные блоки Variant Source делают элементы модели условными.

  1. Из библиотеки блоков Simulink добавьте 1 Sine Wave Function блок, два Add блока, три Gain блока, два Outports и два Variant Source блока в новую модель.

  2. Откройте Sine Wave Function блок. Для параметра Sine type выберите Sample based. Для параметра Time (t) выберите Use simulation time. Для параметра Sample time вставьте значение 0.2.

  3. Сделайте четыре копии блока Sine Wave Function.

  4. Соедините и назовите блоки как показано на рисунке.

  5. Вставьте значения 2, 3, и 4 в Gain2, Gain3, и Gain4 блоки, соответственно.

  6. Дайте модели имени inline_variants_example.

  7. Откройте диалоговое окно Параметров блоков для Variant Source.

  8. В Variant control столбце для порта 1 замените Choice_1 с V==1. Для порта 2 замените Choice_2 с V==2.

  9. Откройте диалоговое окно Параметров блоков для Variant Source1.

  10. В Variant control столбце замените Choice_1 с W==1. Для порта 2 замените Choice_2 с W==2.

  11. В Командном Окне MATLAB используйте эти команды для определения V и W как Simulink.Parameter объекты.

    V = Simulink.Parameter;
    V.Value = 1;
    V.DataType='int32';
    V.CoderInfo.StorageClass = 'custom';
    V.CoderInfo.CustomStorageClass = 'Define';
    V.CoderInfo.CustomAttributes.HeaderFile='inline_importedmacro.h'
    
    W = Simulink.Parameter;
    W.Value = 2;
    W.DataType='int32';
    W.CoderInfo.StorageClass = 'custom';
    W.CoderInfo.CustomStorageClass = 'Define';
    W.CoderInfo.CustomAttributes.HeaderFile='inline_importedmacro.h'

    В этом примере переменные управления вариантом Simulink.Parameter объекты. Для генерации кода, если вы используете Simulink.Variant объекты для задания вариантов управления, используйте Simulink.Parameter объекты или переменный MATLAB для определения их условий..

    Переменные управления вариантом, заданные как Simulink.Parameter объекты могут иметь один из следующих классов памяти:

    • Define с заданным файлом заголовка

    • ImportedDefine с заданным файлом заголовка

    • CompilerFlag

    • SystemConstant (AUTOSAR)

    • Пользовательский пользовательский класс памяти, который определяет данные как макрос в указанном заголовочном файле

    Если вы используете скалярные переменные управления вариантом для симуляции модели, можно преобразовать эти переменные в Simulink.Parameter объекты. См. «Преобразование переменных управления исполнениями в Simulink. Параметр объектов».

  12. Симулируйте модель.

    Input port 1 является активным вариантом для Variant Source потому что значение переменной управления вариантом V является 1. Input port 2 является активным вариантом для Variant Source1 потому что значение переменной управления вариантом W равен 2. Неактивные варианты удаляются из выполнения, и их пути выделяются серым цветом в схеме.

Задайте условия, которые управляют выбором варианта

Можно сгенерировать код, в котором каждый вариант выбора заключен в условия C препроцессора #if и #endif. Компилятор выбирает активный вариант во время компиляции, и предварительные условия процессора определяют, какие разделы кода выполнять.

  1. На вкладке Modeling панели инструментов Simulink нажмите Model Settings.

  2. На панели Code Generation и установите для System target file значение ert.tlc.

  3. На панели Solver установите значение параметра Type Fixed-step.

  4. В модели откройте диалоговое окно параметров блоков для Variant Source.

  5. Установите параметр Variant activation time равным code compile. Во время обновления схемы или симуляции, когда вы задаете это значение параметров, Simulink анализирует все варианты выбора. Этот анализ обеспечивает раннюю валидацию готовности генерации кода вариантов выбора. Во время генерации кода, когда вы устанавливаете это значение параметров, генератор кода генерирует предварительные условия, которые управляют активацией каждого варианта выбора.

  6. Очистите параметр Allow zero active variant controls.

  7. Откройте диалоговое окно Параметров блоков для Variant Source 1. Повторите шаги с 5 по 7.

  8. Создайте модель. Когда генерация кода завершена, сгенерированный код отображается в представлении кода.

Проверьте сгенерированный код

  1. В представлении кода выберите inline_variants_example.c файл.

  2. В inline_variants_example.c файл, вызов inline_variants_example_step функция условно скомпилирована как показано:

    /* Model step function */
    void inline_variants_example_step(void)
    {
      real_T rtb_VariantMerge_For_Variant_So;
      real_T rtb_VariantMerge_For_Variant__e;
    
      /* Sin: '<Root>/Sine2' incorporates:
       *  Sin: '<Root>/Sine3'
       *  Sum: '<Root>/Add'
       */
    #if V == 2
    
      rtb_VariantMerge_For_Variant_So = sin((real_T)
        inline_variants_example_DW.counter * 2.0 * 3.1415926535897931 / 10.0) + sin
        ((real_T)inline_variants_example_DW.counter_g * 2.0 * 3.1415926535897931 /
         10.0);
    
    #endif
    
      /* End of Sin: '<Root>/Sine2' */
    
      /* Sin: '<Root>/Sine4' incorporates:
       *  Sin: '<Root>/Sine5'
       *  Sum: '<Root>/Add1'
       */
    #if W == 2
    
      rtb_VariantMerge_For_Variant__e = sin((real_T)
        inline_variants_example_DW.counter_c * 2.0 * 3.1415926535897931 / 10.0) +
        sin((real_T)inline_variants_example_DW.counter_i * 2.0 * 3.1415926535897931 /
            10.0);
    
    #endif
    
      /* End of Sin: '<Root>/Sine4' */
    
      /* Sin: '<Root>/Sine1' */
    #if V == 1
    
      rtb_VariantMerge_For_Variant_So = sin((real_T)
        inline_variants_example_DW.counter_m * 2.0 * 3.1415926535897931 / 10.0);
    
    #endif
    
      /* End of Sin: '<Root>/Sine1' */
    
      /* Outport: '<Root>/Outport' incorporates:
       *  Gain: '<Root>/Gain1'
       */
      inline_variants_example_Y.Outport = 3.0 * rtb_VariantMerge_For_Variant_So;
    
      /* Gain: '<Root>/Gain' */
    #if W == 1
    
      rtb_VariantMerge_For_Variant__e = 2.0 * rtb_VariantMerge_For_Variant_So;
    
    #endif
    
      /* End of Gain: '<Root>/Gain' */
    
      /* Outport: '<Root>/Outport1' incorporates:
       *  Gain: '<Root>/Gain2'
       */
      inline_variants_example_Y.Outport1 = 4.0 * rtb_VariantMerge_For_Variant__e;
    
      /* Update for Sin: '<Root>/Sine2' incorporates:
       *  Sin: '<Root>/Sine3'
       */
    #if V == 2
    
      inline_variants_example_DW.counter++;
      if (inline_variants_example_DW.counter == 10) {
        inline_variants_example_DW.counter = 0;
      }
    
      inline_variants_example_DW.counter_g++;
      if (inline_variants_example_DW.counter_g == 10) {
        inline_variants_example_DW.counter_g = 0;
      }
    
    #endif
    
      /* End of Update for Sin: '<Root>/Sine2' */
    
      /* Update for Sin: '<Root>/Sine4' incorporates:
       *  Sin: '<Root>/Sine5'
       */
    #if W == 2
    
      inline_variants_example_DW.counter_c++;
      if (inline_variants_example_DW.counter_c == 10) {
        inline_variants_example_DW.counter_c = 0;
      }
    
      inline_variants_example_DW.counter_i++;
      if (inline_variants_example_DW.counter_i == 10) {
        inline_variants_example_DW.counter_i = 0;
      }
    
    #endif
    
      /* End of Update for Sin: '<Root>/Sine4' */
    
      /* Update for Sin: '<Root>/Sine1' */
    #if V == 1
    
      inline_variants_example_DW.counter_m++;
      if (inline_variants_example_DW.counter_m == 10) {
        inline_variants_example_DW.counter_m = 0;
      }
    
    #endif
    
      /* End of Update for Sin: '<Root>/Sine1' */
    }

Переменные rtb_VariantMerge_For_Variant_So и rtb_VariantMerge_For_Variant_e удерживайте входные значения в блоках Variant Source. Заметьте, что код для этих переменных является условным. Переменные inline_variants_example_Y.Outport и inline_variants_example_Y.Outport1 удерживать выходные значения блоков Variant Source. Заметьте, что код для этих переменных не является условным.

Сгенерируйте код с нулем активных элементов управления вариантом

Можно сгенерировать код, в котором блоки, соединенные с входом и выходом блока Variant Source, являются условными.

  1. Для Variant Sourceоткройте диалоговое окно Параметров блоков. Выберите Allow zero active variant controls параметра.

  2. Для Variant Source 1откройте диалоговое окно Параметров блоков. Выберите Allow zero active variant controls параметра.

Когда вы выбираете параметр Allow zero active variant controls, можно сгенерировать код для модели, содержащей Variant Source и Variant Sink блоки, даже когда вы задаете значение для переменной управления вариантом, которая не позволяет использовать активный вариант. Выбор значения для переменной управления вариантом, которая не позволяет использовать активный вариант и не выбирает параметр Allow zero active variant controls, приводит к ошибке.

Сгенерируйте код для inline_variants_example. Заметка в inline_variants_example.c файл, что код для переменных inline_variants_example_Y.Outport1 и inline_variants_example_Y.Outport2 является условным.

/* Model step function */
void inline_variants_example_step(void)
{
 ...
#if V == 1 || V == 2

  inline_variants_example_Y.Outport = 3.0 * rtb_VariantMerge_For_Variant_So;

#endif


 ...
#if (V == 1 && W == 1) || (V == 2 && W == 1) || W == 2

  inline_variants_example_Y.Outport1 = 4.0 * rtb_VariantMerge_For_Variant__e;

#endif
 
 ...

Похожие темы