Чтобы хранить несколько независимых множества значений для тех же параметров блоков, можно использовать массив структур. Чтобы переключиться между наборами параметров, создайте переменную, которая действует как индекс в массив, и измените значение переменной. Вы можете изменить значение переменной во время симуляции и, если переменная настраивается, во время выполнения сгенерированного кода.
Откройте пример модели.
open_system('sldemo_fuelsys_dd_controller')
Эта модель представляет систему заправки бензинового двигателя. Выходом модели является скорость потока топлива к двигателю.
Перейдите к switchable_compensation
вложенная подсистема.
open_system(['sldemo_fuelsys_dd_controller/fuel_calc/',... 'switchable_compensation'])
Эта подсистема корректирует и фильтрует шум из сигнала расхода топлива. Подсистема использует различные коэффициенты фильтра на основе режима заправки, который логика управления изменяется на основе отказов датчика в двигателе. Для примера алгоритм управления активирует low_mode
подсистема при нормальной операции. Он активирует rich_mode
подсистема в ответ на отказ датчика.
Откройте low_mode
подсистема.
open_system(['sldemo_fuelsys_dd_controller/fuel_calc/',... 'switchable_compensation/low_mode'])
Блок Discrete Filter фильтрует сигнал расхода топлива. В диалоговом окне блока Numerator наборов параметров коэффициенты числителя фильтра.
Подсистема одноуровневого rich_mode
также содержит блок Дискретного Фильтра, который использует различные коэффициенты.
Обновите диаграмму модели, чтобы отобразить типы данных сигнала. Входной и выходной сигналы блока используют тип данных с одной точностью и плавающей точкой single
.
В левом нижнем углу модели щелкните значок данных моделей, а затем щелкните ссылку Data Dictionary. Словарь данных для этой модели, sldemo_fuelsys_dd_controller.sldd
, откроется в Model Explorer.
На панели иерархии модели Model Explorer выберите узел Данные.
На панели «Содержимое» просмотрите свойства Simulink.NumericType
объекты, такие как s16En15
. Все эти объекты в настоящее время представляют тип данных с одной точностью и плавающей точкой single
. Модель использует эти объекты, чтобы задать типы данных сигнала, включая входные и выходные сигналы блоков Дискретного Фильтра.
Предположим, что во время симуляции и выполнения сгенерированного кода вы хотите, чтобы каждая из этих подсистем переключалась между различными коэффициентами числителя на основе переменной, значение которой вы управляете.
Сохраните существующий набор коэффициентов числителя в Simulink.Parameter
объект, значение которого является структурой. Каждое поле структуры хранит коэффициенты для одного из дискретных блоков фильтра.
lowBlock = ['sldemo_fuelsys_dd_controller/fuel_calc/'... 'switchable_compensation/low_mode/Discrete Filter']; richBlock = ['sldemo_fuelsys_dd_controller/fuel_calc/'... 'switchable_compensation/rich_mode/Discrete Filter']; params.lowNumerator = eval(get_param(lowBlock,'Numerator')); params.richNumerator = eval(get_param(richBlock,'Numerator')); params = Simulink.Parameter(params);
Скопируйте значение params
во временную переменную. Измените значения полей в этой временной структуре и присвойте измененную структуру второму элементу params
.
temp = params.Value;
temp.lowNumerator = params.Value.lowNumerator * 2;
temp.richNumerator = params.Value.richNumerator * 2;
params.Value(2) = temp;
clear temp
Значение params
- массив из двух структур. Каждая структура хранит один набор коэффициентов фильтра.
Создайте Simulink.Parameter
объект с именем Ctrl
.
Ctrl = Simulink.Parameter(2);
Ctrl.DataType = 'uint8';
В low_mode
подсистема в диалоговое окно блока Дискретного Фильтра устанавливает параметр Numerator в выражение params(Ctrl).lowNumerator
.
set_param(lowBlock,'Numerator','params(Ctrl).lowNumerator');
В блоке Дискретный Фильтр в rich_mode
подсистема, установите значение параметра Numerator равным params(Ctrl).richNumerator
.
set_param(richBlock,'Numerator','params(Ctrl).richNumerator');
В выражениях выбирается одна из структур в params
при помощи переменной Ctrl
. Выражения затем выходят из одного из полей в структуре. Значение поля устанавливает значения коэффициентов числителя.
Чтобы переключиться между наборами коэффициентов, вы изменяете значение Ctrl
к соответствующему индексу в массиве структур.
Вы можете создать Simulink.Bus
объект для использования в качестве типа данных массива структур. Вы можете:
Управление формой конструкций.
Для каждого поля управляйте такими характеристиками, как тип данных и физические единицы измерения.
Управляйте именем struct
введите в сгенерированный код.
Используйте функцию Simulink.Bus.createObject
чтобы создать объект и переименовать его как paramsType
.
Simulink.Bus.createObject(params.Value)
paramsType = slBus1;
clear slBus1
Можно использовать Simulink.NumericType
объекты из словаря данных для управления типами данных полей структуры. В объекте шины используйте имя объекта типа данных, чтобы задать DataType
свойство каждого элемента.
paramsType.Elements(1).DataType = 's16En15'; paramsType.Elements(2).DataType = 's16En7';
Используйте объект шины как тип данных массива структур.
params.DataType = 'Bus: paramsType';
Опционально используйте перечисленный тип как тип данных переменной switching. Можно связать каждый из наборов параметров со значимым именем и ограничить допустимые значения переменной switching.
Создайте перечисленный тип с именем FilterCoeffs
. Создайте представителя перечисления для каждой из структур в params
. Установите базовое целое значение каждого представителя перечисления в соответствующий индекс params
.
Simulink.defineIntEnumType('FilterCoeffs',{'Weak','Aggressive'},[1 2])
Используйте перечисленный тип в качестве типа данных переменной switching. Установите значение переменной равным Aggressive
, что соответствует индексу 2
.
Ctrl.Value = FilterCoeffs.Aggressive;
Добавьте объекты, которые вы создали, в словарь данных sldemo_fuelsys_dd_controller.sldd
.
dictObj = Simulink.data.dictionary.open('sldemo_fuelsys_dd_controller.sldd'); sectObj = getSection(dictObj,'Design Data'); addEntry(sectObj,'Ctrl',Ctrl) addEntry(sectObj,'params',params) addEntry(sectObj,'paramsType',paramsType)
Перечисленные типы можно также хранить в словарях данных. Однако вы не можете импортировать перечисленный тип в этом случае, потому что вы не можете сохранить изменения в sldemo_fuelsys_dd_controller.sldd
. Дополнительные сведения о хранении перечисленных типов в словарях данных см. в разделе Перечисления в словаре данных.
Откройте пример модели sldemo_fuelsys_dd
, который ссылается на модели контроллеров sldemo_fuelsys_dd_controller
.
open_system('sldemo_fuelsys_dd')
Установите время остановки симуляции равным Inf
чтобы можно было взаимодействовать с моделью во время симуляции.
Начните запуск симуляции и откройте Возможности диалогового окна блока. Эти возможности показывают, что топливо скорости потока жидкости (fuel
сигнал) колеблется со значительной амплитудой при нормальной операции двигателя.
В Model Explorer просмотрите содержимое словаря данных sldemo_fuelsys_dd_controller.sldd
. Установите значение Ctrl
на FilterCoeffs.Weak
.
Обновление sldemo_fuelsys_dd
диаграмма модели. Возможности показывают, что амплитуда колебаний скорости топлива уменьшается из-за менее агрессивных коэффициентов фильтра.
Остановите симуляцию.
Если у вас есть программное обеспечение Simulink Coder, можно сгенерировать код, который позволяет вам переключаться между наборами параметров во время выполнения кода.
В Model Explorer просмотрите содержимое словаря данных sldemo_fuelsys_dd_controller.sldd
. На панели «Содержимое» установите для представления столбца значение Storage Class
.
Используйте столбец StorageClass, чтобы применить класс памяти ExportedGlobal
на params
так, что массив структур появляется как настраиваемая глобальная переменная в сгенерированном коде. Применить тот же класс памяти к Ctrl
таким образом можно изменить значение переменной switching во время выполнения кода.
Кроме того, чтобы сконфигурировать объекты, используйте следующие команды:
tempEntryObj = getEntry(sectObj,'params'); params = getValue(tempEntryObj); params.StorageClass = 'ExportedGlobal'; setValue(tempEntryObj,params); tempEntryObj = getEntry(sectObj,'Ctrl'); Ctrl = getValue(tempEntryObj); Ctrl.StorageClass = 'ExportedGlobal'; setValue(tempEntryObj,Ctrl);
Сгенерируйте код из моделей контроллеров.
slbuild('sldemo_fuelsys_dd_controller')
### Starting build procedure for: sldemo_fuelsys_dd_controller ### Successful completion of code generation for: sldemo_fuelsys_dd_controller Build Summary Top model targets built: Model Action Rebuild Reason ================================================================================================ sldemo_fuelsys_dd_controller Code generated Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 25.82s
В отчете о генерации кода просмотрите заголовочный файл sldemo_fuelsys_dd_controller_types.h
. Код определяет тип перечисленных данных FilterCoeffs
.
file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw',... 'sldemo_fuelsys_dd_controller_types.h'); rtwdemodbtype(file,'#ifndef DEFINED_TYPEDEF_FOR_FilterCoeffs_',... '/* Forward declaration for rtModel */',1,0)
#ifndef DEFINED_TYPEDEF_FOR_FilterCoeffs_ #define DEFINED_TYPEDEF_FOR_FilterCoeffs_ typedef enum { Weak = 1, /* Default value */ Aggressive } FilterCoeffs; #endif
Код также определяет тип структуры paramsType
, что соответствует Simulink.Bus
объект. В полях используется тип данных с одной точностью с плавающей точкой из модели.
rtwdemodbtype(file,'#ifndef DEFINED_TYPEDEF_FOR_paramsType_',... '#ifndef DEFINED_TYPEDEF_FOR_FilterCoeffs_',1,0)
#ifndef DEFINED_TYPEDEF_FOR_paramsType_ #define DEFINED_TYPEDEF_FOR_paramsType_ typedef struct { real32_T lowNumerator[2]; real32_T richNumerator[2]; } paramsType; #endif
Просмотрите исходный файл sldemo_fuelsys_dd_controller.c
. Код использует перечисленный тип, чтобы задать переменную переключения Ctrl
.
file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw',... 'sldemo_fuelsys_dd_controller.c'); rtwdemodbtype(file,'FilterCoeffs Ctrl = Aggressive;',... '/* Block signals (default storage) */',1,0)
FilterCoeffs Ctrl = Aggressive; /* Variable: Ctrl * Referenced by: * '<S12>/Discrete Filter' * '<S13>/Discrete Filter' */
Код также определяет массив структур params
.
rtwdemodbtype(file,'/* Exported block parameters */',... '/* Variable: params',1,1)
/* Exported block parameters */ paramsType params[2] = { { { 8.7696F, -8.5104F }, { 0.0F, 0.2592F } }, { { 17.5392F, -17.0208F }, { 0.0F, 0.5184F } } } ; /* Variable: params
Алгоритм кода в модели step
функция использует переменную switching для индекса в массив структур.
Чтобы переключиться между наборами параметров, хранящимися в массиве структур, измените значение Ctrl
во время выполнения кода.
Закройте соединения со словарем данных. Этот пример отбрасывает несохраненные изменения. Чтобы сохранить изменения, используйте '-save'
опция.
Simulink.data.dictionary.closeAll('sldemo_fuelsys_dd_controller.sldd','-discard')