exponenta event banner

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

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

Можно создать:

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

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

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

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

В этом примере показано, как блоки источника исполнения делают элементы модели условными.

  1. В библиотеке блоков Simulink добавьте в новую модель 1 блок функции синусоидальной волны, два блока Add, три блока усиления, два блока Outports и два блока Variant Source.

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

  3. Создайте четыре копии блока функции синусоидальной волны.

  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. В столбце Элемент управления «Вариант» замените 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.Parameter.

  12. Моделирование модели.

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

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

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

  1. На вкладке «Моделирование» панели инструментов «Симуляция» выберите «Параметры модели».

  2. На панели Создание кода (Code Generation) установите для параметра Системный целевой файл (System target file) значение ert.tlc.

  3. На панели решателя задайте для параметра Тип значение Fixed-step.

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

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

  6. Снимите флажок Разрешить нулевой активный элемент управления исполнения.

  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откройте диалоговое окно «Параметры блока». Выберите параметр Разрешить нулевые активные элементы управления исполнения.

  2. Для Variant Source 1откройте диалоговое окно «Параметры блока». Выберите параметр Разрешить нулевые активные элементы управления исполнения.

При выборе параметра Разрешить нулевое активное исполнение можно создать код для модели, содержащей блоки Источник исполнения (Variant Source) и Получатель исполнения (Variant Sink), даже если указано значение переменной управления исполнением, не допускающее активное исполнение. При выборе значения переменной управления исполнениями, не разрешающего активное исполнение, а также при отсутствии параметра Разрешить нулевое активное исполнение возникает ошибка.

Создать код для 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
 
 ...

Связанные темы