Используйте подсистему вариантов для генерации кода, который использует условия препроцессора C

В этом примере показано, как использовать подсистемы варианта Simulink ® для генерации условий препроцессора C, которые управляют тем, какая дочерняя подсистема подсистемы варианта является активной в сгенерированном коде, произведенном Coder™ Simulink ®.

Обзор исполнительных подсистем

Блок Variant Subsystem содержит две или более дочерних подсистем, где один дочерний элемент активен во время выполнения модели. Активная дочерняя подсистема называется активным вариантом. Можно программно переключить активный вариант блока Variant Subsystem путем изменения значений переменных в базовом рабочем пространстве или путем переопределения выбора варианта вручную с помощью диалогового окна Variant Subsystem block. Активный вариант программно соединяется с блоками Inport и Outport Подсистемы вариантов Simulink ® во время компиляции модели.

Чтобы программно управлять выбором варианта, a Simulink.Variant связывается с каждой дочерней подсистемой в диалоговом окне блока «Variant Subsystem». Simulink.Variant объекты создаются в базовом рабочем пространстве MATLAB ®. Эти объекты имеют свойство с именем Condition, выражение, которое вычисляет логическое значение и используется для определения активной дочерней подсистемы варианта.

По умолчанию сгенерированный код содержит только активный вариант. Кроме того, можно параметризовать выбор активного варианта и сделать его зависимым от значений переменных и объектов в базовой рабочей области MATLAB ®. Когда вы генерируете код, можно сгенерировать код для всех вариантов и отложить выбор активного варианта, пока не наступит время скомпилировать этот код.

Определение вариантов для блока Subsystem

Открытие примера модели rtwdemo_preprocessor_subsys запустит PostLoadFcn, заданный в диалоговом окне «File: ModelProperties: Коллбэки». В базовом рабочем пространстве будут заполнены переменные для блоков Variant Subsystem.

open_system('rtwdemo_preprocessor_subsys')

Подсистема варианта LeftController содержит две дочерние подсистемы: Линейную и Нелинейную. Дочерняя подсистема LeftController/Linear выполняется, когда Simulink. Вариант объект LINEAR вычисляет true, и подсистема LeftController/Nonlinear child выполняется, когда Simulink. Вариант объект NONLINEAR оценивает как true.

Simulink. Варианты объекты заданы для подсистемы LeftController, щелкнув правой кнопкой мыши подсистему LeftController и выбрав Subsystem Parameters, который откроет диалоговое окно блока подсистемы LeftController.

open_system('rtwdemo_preprocessor_subsys/LeftController');

Диалоговое окно блока подсистемы LeftController создает связь между Линейной и Нелинейной подсистемами с этими двумя Simulink. Вариант объектов, LINEAR и NONLINEAR, которые существуют в базовом рабочем пространстве. Эти объекты имеют свойство с именем Condition, выражение, которое вычисляет логическое значение и определяет дочернюю подсистему активного варианта (линейную или нелинейную). Условие также показано в диалоговом окне блока подсистемы. В этом примере условия LINEAR и NONLINEAR 'VSSMODE = = 0' и 'VSSMODE = = 1', соответственно.

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

LINEAR = Simulink.Variant;
LINEAR.Condition = 'VSSMODE==0';
NONLINEAR = Simulink.Variant;
NONLINEAR.Condition = 'VSSMODE==1';

Определение переменной управления вариантом

Объекты варианта позволяют вам повторно использовать произвольно сложные условия во всей модели. Несколько Блоки Subsystem вариантов могут использовать одни и те же объекты Simulink .Variant, что позволяет переключать активацию вариантов как набора. Можно переключить набор перед симуляцией, изменив значение VSSMODE в среде MATLAB или при компиляции сгенерированного кода, как объяснено в следующем разделе. В этом примере LeftController и RightController ссылаются на одни и те же объекты варианта, так что можно переключать их одновременно.

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

Сгенерированный код обращается к переменной управления вариантом VSSMODE как пользовательский макрос. В этом примере rtwdemo_importedmacros.h поставляет VSSMODE. В рамках окружения MATLAB вы задаете VSSMODE использование Simulink.Parameter объект. Его значение будет проигнорировано при генерации кода, включая предварительные условия процессора. Однако значение используется для симуляции. Устаревший файл заголовка задает значение макроса, который будет использоваться при компиляции сгенерированного кода, что в конечном счете активирует один из двух заданных вариантов во встроенном исполняемом файле.

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

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

  • CompilerFlag

  • SystemConstant (AUTOSAR)

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

VSSMODE = Simulink.Parameter;
VSSMODE.Value = 1;
VSSMODE.DataType = 'int32';
VSSMODE.CoderInfo.StorageClass = 'Custom';
VSSMODE.CoderInfo.CustomStorageClass = 'ImportedDefine';
VSSMODE.CoderInfo.CustomAttributes.HeaderFile = 'rtwdemo_importedmacros.h';

Симуляция модели с различными вариантами

Потому что вы задаете значение VSSMODE 1, модель использует нелинейные контроллеры во время симуляции.

sim('rtwdemo_preprocessor_subsys')
youtnl = yout;

Если вы меняете значение VSSMODE 0, модель использует линейные контроллеры во время симуляции.

VSSMODE.Value = int32(0);
sim('rtwdemo_preprocessor_subsys')
youtl = yout;

Можно построить и сравнить реакцию линейного и нелинейного контроллеров:

figure('Tag','CloseMe');
plot(tout, youtnl.signals(1).values, 'r-', tout, youtl.signals(1).values, 'b-')
title('Response of Left Channel Linear and Nonlinear Controllers');
ylabel('Response');
xlabel('Time (seconds)');
legend('nonlinear','linear')
axis([0 100 -0.8 0.8]);

Использование условий предпроцессора C

Эта пример модели была сконфигурирована, чтобы сгенерировать предварительные условия C. Чтобы сгенерировать код для модели, на вкладке Код С панели инструментов выберите Build.

Чтобы активировать генерацию кода предварительных условий процессора, проверьте, верны ли следующие условия:

  • Выберите цель Embedded Coder ® в Генерация Кода > Системный целевой файл в диалоговом окне Configuration Parameters

  • В диалоговом окне блочного параметра Variant Subsystem установите параметр Variant activation time равным code compile.

В этом примере сгенерированный код включает ссылки на Simulink. Вариант объектов LINEAR и NONLINEAR, а также определения макросов, соответствующих этим вариантам. Эти определения зависят от значения VSSMODE, который передается во внешний заголовочный файл rtwdemo_importedmacros.h. Активный вариант определяется при помощи предварительных условий (# if) на макросах (# define) LINEAR и NONLINEAR.

Макросы LINEAR и NONLINEAR определяются в сгенерированных rtwdemo_preprocessor_subsys_types.h, заголовочный файл:

  #ifndef LINEAR
  #define LINEAR      (VSSMODE == 0)
  #endif
  #ifndef NONLINEAR
  #define NONLINEAR   (VSSMODE == 1)
  #endif

В сгенерированном коде код, относящийся к вариантам, охраняется условиями препроцессора С. Для примера, в rtwdemo_preprocessor_subsys.c, вызовы шага и функции инициализации каждого варианта скомпилированы по условию:

  /* Outputs for atomic SubSystem: '<Root>/LeftController' */
  #if LINEAR
      /* Output and update for atomic system: '<S1>/Linear' */
  #elif NONLINEAR
      /* Output and update for atomic system: '<S1>/Nonlinear' */
  #endif

Закройте переменные модели, рисунки и рабочей области из примера.

bdclose('rtwdemo_preprocessor_subsys')
close(findobj(0,'Tag','CloseMe'));
clear LINEAR NONLINEAR VSSMODE
clear tout yout youtl youtnl