Можно использовать Различный Источник и Различные блоки Приемника, чтобы чувствовать несколько реализаций модели в одной, объединенной блок-схеме. Каждая реализация зависит от условий, которые вы устанавливаете для Различного Источника и Различных блоков Приемника. Simulink® распространяет эти условия к восходящим и нисходящим блокам включая корневой вход и корневые выходные порты.
Можно сгенерировать:
Код из модели Simulink, содержащей Различный Приемник и Различные Исходные блоки.
Код, который содержит условные выражения препроцессора, которые управляют активацией каждого варианта.
Условные выражения препроцессора, которые не допускают активного варианта.
Этот пример показывает, как Различные Исходные блоки делают условное выражение элементов модели.
От Библиотеки блока Simulink добавьте, что 1 Функциональный блок Синусоиды, два Добавляют блоки, три блока Усиления, два Выходных порта и два Различных Исходных блока в новую модель.
Откройте Функциональный блок Синусоиды. Для параметра Sine type выберите Sample based
. Для параметра Time (t) выберите Use simulation time
. Для параметра Sample time вставьте значение 0.2
.
Сделайте четыре копии Функционального блока Синусоиды.
Соедините и назовите блоки как показано.
Вставьте значения 2
, 3
и 4
в Gain2
, Gain3
и блоках Gain4
, соответственно.
Дайте модели имя inline_variants_example
.
Откройте диалоговое окно Block Parameters для Variant Source
.
В столбце Variant control, для Порта 1, Variant_1
замены с V==1
. Для Порта 2, замените Variant_2
на V==2
.
Откройте диалоговое окно Block Parameters для Variant Source1
.
В столбце Variant control замените Variant_1
на W==1
. Для Порта 2, замените Variant_2
на W==2
.
В Окне Команды 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. Объекты параметра (Simulink).
Моделируйте модель.
Входной порт 1 является активным выбором для Variant Source
, потому что значением различной контрольной переменной V
является 1
. Входной порт 2 является активным выбором для Variant Source1
, потому что значение различной контрольной переменной W
равняется 2. Неактивный выбор удален из выполнения, и их пути отображаются серым в схеме.
Можно сгенерировать код, в который каждый вариант заключен в условных выражениях препроцессора C #if
и #endif
. Компилятор выбирает активный вариант во время компиляции, и условные выражения препроцессора определяют который разделы кода выполниться.
В редакторе Simulink выберите Simulation> Model Configuration Parameters.
Выберите панель Code Generation и установите System target file на ert.tlc
.
В панели Report выберите Create code generation report.
В вашей модели откройте диалоговое окно параметров блоков для Variant Source
.
Выберите параметр Analyze all choices during update diagram and generate preprocessor conditionals. Во время схемы обновления или симуляции, когда вы выбираете этот параметр, Simulink анализирует все варианты. Этот анализ обеспечивает раннюю валидацию готовности генерации кода вариантов. Во время генерации кода, когда вы выбираете этот параметр, генератор кода генерирует условные выражения препроцессора, которые управляют активацией каждого варианта.
Очистите параметр Allow zero active variant controls.
Откройте диалоговое окно Block Parameters для Variant Source 1
. Повторите шаги 5 - 7.
Создайте модель. Когда генерация кода завершена, Отчет Генерации кода отображен.
В отчете генерации кода выберите файл inline_variants_example.c
.
В файле inline_variants_example.c
вызовы функции inline_variants_example_step
и функций inline_variants_example_initialize
условно скомпилированы как показано:
/* Model step function */ void inline_variants_example_step(void) { real_T rtb_Sine4; real_T rtb_VariantMerge_For_Variant_So; /* Sin: '<Root>/Sine1' */ #if V == 1 rtb_Sine4 = sin((real_T)inline_variants_example_DW.counter * 2.0 * 3.1415926535897931 / 10.0); #endif /* V == 1 */ /* End of Sin: '<Root>/Sine1' */ /* Sin: '<Root>/Sine2' incorporates: * Sin: '<Root>/Sine3' * Sum: '<Root>/Add' */ #if V == 2 rtb_Sine4 = sin((real_T)inline_variants_example_DW.counter_i * 2.0 * 3.1415926535897931 / 10.0) + sin((real_T) inline_variants_example_DW.counter_f * 2.0 * 3.1415926535897931 / 10.0); #endif /* V == 2 */ /* End of Sin: '<Root>/Sine2' */ /* Outport: '<Root>/Out1' incorporates: * Gain: '<Root>/Gain3' */ inline_variants_example_Y.Out1 = 3.0 * rtb_Sine4; /* Gain: '<Root>/Gain2' */ #if W == 1 rtb_VariantMerge_For_Variant_So = 2.0 * rtb_Sine4; #endif /* W == 1 */ /* End of Gain: '<Root>/Gain2' */ /* Sin: '<Root>/Sine4' incorporates: * Sin: '<Root>/Sine5' * Sum: '<Root>/Add1' */ #if W == 2 rtb_VariantMerge_For_Variant_So = sin((real_T) inline_variants_example_DW.counter_fe * 2.0 * 3.1415926535897931 / 10.0) * 2.0 + sin((real_T)inline_variants_example_DW.counter_e * 2.0 * 3.1415926535897931 / 10.0); #endif /* W == 2 */ /* End of Sin: '<Root>/Sine4' */ /* Outport: '<Root>/Out2' incorporates: * Gain: '<Root>/Gain4' */ inline_variants_example_Y.Out2 = inline_variants_example_P.Gain4_Gain * rtb_VariantMerge_For_Variant_So; ... }
Переменные rtb_Sine4
и rtb_VariantMerge_For_Variant_So
содержат входные значения к Различным Исходным блокам. Заметьте, что код для этих переменных является условным выражением. Переменные inline_variants_example_Y.Out1
и inline_variants_example_Y.Out2
содержат выходные значения Различных Исходных блоков. Заметьте, что код для этих переменных не является условным выражением.
Можно сгенерировать код, в котором блоки, соединенные с входом и выводом Различного Исходного блока, являются условным выражением.
Для Variant Source
, открытого диалоговое окно Block Parameters. Выберите параметр Allow zero active variant controls.
Для Variant Source 1
, открытого диалоговое окно Block Parameters. Выберите параметр Allow zero active variant controls.
Когда вы выбираете параметр Allow zero active variant controls, можно сгенерировать код для модели, содержащей Различный Источник и Различные блоки Приемника, даже когда вы задаете значение для различной контрольной переменной, которая не допускает активный вариант. Выбор значения для различной контрольной переменной, которая не допускает активный вариант и не выбор параметра Allow zero active variant controls, производит ошибку.
Сгенерируйте код для inline_variants_example
. Заметьте в файле inline_variants_example.c
, что код для переменных inline_variants_example_Y.Out1
и inline_variants_example_Y.Out2
является условным выражением.
/* Model step function */ void inline_variants_example_step(void) { ... #if V == 1 || V == 2 inline_variants_example_Y.Out1 = 3.0 * rtb_Sine4; #endif /* V == 1 || V == 2 */ ... #if (V == 1 && W == 1) || (V == 2 && W == 1) || W == 2 inline_variants_example_Y.Out2 = 4.0 * rtb_VariantMerge_For_Variant_So; #endif /* (V == 1 && W == 1) || (V == 2 && W == 1) || W == 2 */ ...
Для внешних портов и большинства векторов DWork, сигналов и состояний, условные выражения препроцессора (#if
и #endif
) окружают объявления переменной глобальных данных. Для моделей, в которых вы включаете код API C для глобальных выходных сигналов блока, глобальных параметров блоков и дискретных и непрерывных состояний, условные выражения препроцессора не окружают объявления переменной глобальных данных. Для получения информации о API C смотрите, обмениваются Данными Между Сгенерированным и Внешним Кодом Используя API C (Simulink Coder).
Существуют некоторые редкие случаи, в которых условные выражения препроцессора не окружают структуры глобальных данных, которые содержат объявления переменной состояния. Для моделей, которые содержат Различные Исходные блоки или Различные блоки Приемника и также содержат блоки, которые поддерживают информацию состояния, такую как Единичная задержка, блокируется, исключение условных выражений препроцессора, окружающих объявления переменной состояния, может привести к несоответствию между результатами генерации кода и симуляцией.
Например, предположите, что модель имеет Различный Исходный блок с четырьмя вариантами. Один из этого выбора содержит блоки с информацией состояния. Если вы моделируете модель с активным вариантом, который отличается от варианта, который содержит информацию состояния, нет никаких регистрируемых данных состояния. В файле .h
model
сгенерированный код все еще инициализирует эти глобальные переменные состояния к 0
, потому что #if
и защита #endif
не окружают объявления переменной состояния. Если вы создаете файл .mat
model
из файла .exe
model
и сравниваете его с симуляцией вывод, результаты не соответствуют. В данном примере вывод симуляции пуст, потому что нет никаких регистрируемых данных состояния. Файл .mat
model
содержит несколько значений 0
.
Если активный вариант является вариантом, содержащим информацию состояния, результаты действительно соответствуют.