exponenta event banner

Переключение между наборами значений параметров во время моделирования и выполнения кода

Для хранения нескольких независимых наборов значений для одних и тех же параметров блока можно использовать массив структур. Чтобы переключиться между наборами параметров, создайте переменную, которая действует как индекс в массиве, и измените значение переменной. Значение переменной можно изменить во время моделирования и, если переменная настраивается, во время выполнения созданного кода.

Изучение примера модели

Откройте пример модели.

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'])

Блок дискретного фильтра фильтрует сигнал расхода топлива. В диалоговом окне блока параметр Числитель задает числительные коэффициенты фильтра.

Однородная подсистема rich_mode также содержит блок дискретного фильтра, который использует различные коэффициенты.

Обновите схему модели для отображения типов данных сигнала. Входные и выходные сигналы блока используют тип данных с одинарной точностью и плавающей запятой single.

В левом нижнем углу модели щелкните значок данных модели, затем щелкните ссылку «Словарь данных». Словарь данных для этой модели, sldemo_fuelsys_dd_controller.sldd, открывается в Обозревателе моделей (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 в диалоговом окне «Блок дискретного фильтра» задайте для параметра «Числитель» значение выражения 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';

Использовать перечисляемый тип для переключения переменных

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

Создание перечисляемого типа с именем FilterCoeffs. Создание элемента перечисления для каждой структуры в params. Задайте для базового целого значения каждого элемента перечисления соответствующий индекс в params.

Simulink.defineIntEnumType('FilterCoeffs',{'Weak','Aggressive'},[1 2])

Используйте перечисляемый тип в качестве типа данных переменной переключения. Задайте значение переменной как 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 для взаимодействия с моделью во время моделирования.

Начните выполнение моделирования и откройте диалоговое окно Блок области (Scope block). Объем показывает, что расход топлива ( fuel сигнал) колеблется со значительной амплитудой при нормальной работе двигателя.

В обозревателе моделей просмотрите содержимое словаря данных. sldemo_fuelsys_dd_controller.sldd. Установка значения Ctrl кому FilterCoeffs.Weak.

Обновить sldemo_fuelsys_dd схема модели. Объем показывает, что амплитуда колебаний расхода топлива уменьшается из-за менее агрессивных коэффициентов фильтра.

Остановите моделирование.

Создание и проверка кода

При наличии программного обеспечения Simulink Coder можно создать код, позволяющий переключаться между наборами параметров во время выполнения кода.

В обозревателе моделей просмотрите содержимое словаря данных. sldemo_fuelsys_dd_controller.sldd. На панели «Содержимое» задайте для параметра «Представление столбца» значение Storage Class.

Используйте столбец StorageClass для применения класса хранения ExportedGlobal кому params чтобы массив структур отображался как настраиваемая глобальная переменная в сгенерированном коде. Применить тот же класс хранения к Ctrl чтобы можно было изменить значение переменной переключения во время выполнения кода.

Кроме того, для настройки объектов используются следующие команды:

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 функция использует переменную переключения для индексирования в массив структур.

Для переключения между наборами параметров, хранящимися в массиве структур, измените значение Ctrl во время выполнения кода.

Закройте подключения к словарю данных. В этом примере отменяются несохраненные изменения. Для сохранения изменений используйте '-save' вариант.

Simulink.data.dictionary.closeAll('sldemo_fuelsys_dd_controller.sldd','-discard')

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