Установите владение данных в системе компонентов

Этот пример показывает, как установить владение глобальных данных в коде, сгенерированном от системы компонентов (модели, на которые ссылаются).

Когда вы создаете глобальную переменную в сгенерированном коде путем применения класса памяти к элементу данных в модели, на которую ссылаются (см., Применяют Классы памяти к Отдельному Сигналу, состоянию и Элементам данных Параметра), при определенных обстоятельствах, генератор кода помещает определение переменной с кодом, сгенерированным от топ-модели в иерархии. Это размещение по умолчанию может сделать более трудным определить, какой компонент ответственен за данные и управлять изменениями кода в основанной на команде среде разработки.

Чтобы установить владение глобальной переменной путем размещения определения с кодом, сгенерированным от соответствующего компонента, примените класс памяти, такой как ExportToFile и задайте пользовательский атрибут Владельца. Также для объектов параметра, таких как Simulink.Parameter, который вы используете только в одном компоненте, можно установить владение, храня объект в рабочем пространстве модели вместо базового рабочего пространства или словаря данных.

Исследуйте модель в качестве примера

Скопируйте файл скрипта prepare_sldemo_fuelsys_dd_ctrl.m в вашу текущую папку.

[~, ~] = copyfile(fullfile(matlabroot,'examples','ecoder','main','prepare_sldemo_fuelsys_dd_ctrl.m'),...
    'prepare_sldemo_fuelsys_dd_ctrl.m','f');

Запустите копию скрипта в вашей текущей папке. Скрипт открывает модель sldemo_fuelsys_dd_controller и готовит ее к этому примеру.

prepare_sldemo_fuelsys_dd_ctrl
open_system('sldemo_fuelsys_dd_controller')

Эти модели контроллеров содержат две модели компонента, airflow_calc и fuel_calc. Два выходных параметров airflow_calc, est_airflow и fb_correction, являются входными параметрами fuel_calc.

Откройте модель airflow_calc.

open_system('airflow_calc')

В этой модели выберите View> Model Data Editor.

В Model Data Editor, набор представление Change выпадающий список к Code.

В модели выберите верхний блок Outport.

В Model Data Editor осмотрите значение в столбце Класса памяти. Сигнал, что этот блок представляет, est_airflow, использует класс памяти ExportToFile. С этой установкой сигнал появляется в сгенерированном коде как глобальная переменная. Блок Outport маркировал fb_correction, также использует эту установку.

В Model Data Editor выберите вкладку Parameters и нажмите кнопку дополнительной информации Show/refresh. Model Data Editor теперь показывает, что информация о переменных рабочей области и объектах, таких как Simulink.Parameter возражает, что образцовое использование, чтобы установить значения параметров блоков.

В поле содержимого Фильтра введите numerator. Объект Simulink.Parameter numerator_param, который находится в базовом рабочем пространстве, устанавливает значение параметра Числителя в блоке Discrete Filter, маркировал Throttle Transient. Объект использует класс памяти ExportToFile.

Выберите вкладку Signals.

В поле содержимого Фильтра введите e0. e0 сигнала, который является внутренним к компоненту airflow_calc, также использует ExportToFile. Сигнал является внутренним, потому что это не ввод или вывод корневого уровня модели.

Откройте модель fuel_calc.

open_system('fuel_calc')

В Model Data Editor для этой модели, на вкладке Inports/Outports, представлении Change набора к Code. Inport блокирует est_airflow, и fb_correction используют тот же класс памяти, ExportToFile, как соответствующие блоки Выходного порта в airflow_calc. Блок Outport маркировал fuel_rate, также использует ExportToFile.

Сгенерируйте и осмотрите код

Сгенерируйте код от моделей контроллеров, sldemo_fuelsys_dd_controller.

rtwbuild('sldemo_fuelsys_dd_controller')
### Starting build procedure for model: airflow_calc
### Successful completion of build procedure for model: airflow_calc
### Starting build procedure for model: fuel_calc
### Successful completion of build procedure for model: fuel_calc
### Starting build procedure for model: sldemo_fuelsys_dd_controller
### Successful completion of build procedure for model: sldemo_fuelsys_dd_controller

В отчете генерации кода, в соответствии с Моделями, на которые Ссылаются, кликают по гиперссылке, чтобы осмотреть код, сгенерированный для airflow_calc.

airflow_calc.c файла задает глобальную переменную, которая представляет e0 сигнала. Поскольку блоки, которые пишут в и читают из e0, существуют только в airflow_calc, генератор кода принимает, что этот компонент владеет сигналом.

file = fullfile('slprj','ert','airflow_calc','airflow_calc.c');
rtwdemodbtype(file,'/* Definition for custom storage class: ExportToFile */',...
    'real32_T e0;',1,1)
/* Definition for custom storage class: ExportToFile */
real32_T e0;

В отчете генерации кода возвратитесь к коду, сгенерированному для sldemo_fuelsys_dd_controller.

Файл sldemo_fuelsys_dd_controller.c задает другие глобальные переменные.

file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw',...
    'sldemo_fuelsys_dd_controller.c');
rtwdemodbtype(file,...
    '/* Definition for custom storage class: ExportToFile */',...
    'real32_T numerator_param[2] = { 0.01F, -0.01F } ;',1,1);
/* Definition for custom storage class: ExportToFile */
real32_T est_airflow;
real32_T fb_correction;
real32_T fuel_rate;
real32_T numerator_param[2] = { 0.01F, -0.01F } ;

Поскольку сигналы est_airflow и передача fb_correction между этими двумя компонентами и через модели контроллеров верхнего уровня, генератор кода принимает, что sldemo_fuelsys_dd_controller владеет сигналами. Генератор кода делает подобное предположение о fuel_rate. Поскольку объект параметра, numerator_param существует в базовом рабочем пространстве, любой модели в иерархии, может использовать объект. Поэтому генератор кода принимает, что sldemo_fuelsys_dd_controller владеет параметром.

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

Сконфигурируйте владение данных

В этом примере вы конфигурируете настройки генерации кода так, чтобы:

  • Код, сгенерированный для модели airflow_calc, задает сигналы что передача между этими двумя компонентами, est_airflow и fb_correction.

  • Код, сгенерированный для airflow_calc, задает данные о параметре, numerator_param.

  • Код, сгенерированный для fuel_calc, задает выходной сигнал, который это вычисляет, fuel_rate.

В модели airflow_calc выберите View> Property Inspector.

В Model Data Editor выберите вкладку Inports/Outports.

Найдите строку, которая соответствует блоку Outport est_airflow.

В строке кликните по значку в левом столбце. Property Inspector показывает свойства блока Outport.

В Property Inspector, в соответствии с Кодом, устанавливает CoderInfo. CustomAttributes. Владелец к airflow_calc. Генератор кода помещает определение глобальной переменной с кодом, сгенерированным для airflow_calc.

Для fb_correction используйте Model Data Editor и Property Inspector к владельцу набора к airflow_calc.

Выберите вкладку Parameters.

Найдите строку, которая соответствует объекту параметра, numerator_param.

В строке дважды кликните значок в левом столбце. Model Explorer открывает и отображает свойства numerator_param.

В панели Иерархии модели расширьте airflow_calc узел так, чтобы вы видели зависимый узел Рабочего пространства модели.

Используйте Model Explorer, чтобы переместить numerator_param от базового рабочего пространства до рабочего пространства модели airflow_calc. Например, в панели Иерархии модели, выберите Base Workspace. Затем перетащите numerator_param от панели Содержимого до узла Рабочего пространства модели в панели Иерархии модели. С этим изменением генератор кода принимает, что airflow_calc владеет numerator_param и помещает определение переменной в код, сгенерированный для airflow_calc.

В модели fuel_calc выберите View> Property Inspector.

Поскольку Inport блокирует est_airflow и fb_correction, используйте Model Data Editor и Property Inspector к владельцу набора к airflow_calc. С этой настройкой код fuel_calc не задает переменные.

Для блока Outport используйте Model Data Editor и Property Inspector к владельцу набора к fuel_calc.

Также, чтобы сконфигурировать данные в моделях, используйте эти команды в командной строке:

temp = Simulink.Signal;
temp.CoderInfo.StorageClass = 'Custom';
temp.CoderInfo.CustomStorageClass = 'ExportToFile';
temp.CoderInfo.CustomAttributes.Owner = 'airflow_calc';

set_param('airflow_calc/est_airflow','SignalName','est_airflow')
set_param('airflow_calc/est_airflow','SignalObject',copy(temp))

set_param('airflow_calc/fb_correction','SignalName','fb_correction')
set_param('airflow_calc/fb_correction','SignalObject',copy(temp))

mdlwks = get_param('airflow_calc','ModelWorkspace');
assignin(mdlwks,'numerator_param',copy(numerator_param));

portHandles = get_param('fuel_calc/est_airflow','portHandles');
outportHandle = portHandles.Outport;
set_param(outportHandle,'Name','est_airflow')
set_param(outportHandle,'SignalObject',copy(temp))

portHandles = get_param('fuel_calc/fb_correction','portHandles');
outportHandle = portHandles.Outport;
set_param(outportHandle,'Name','fb_correction')
set_param(outportHandle,'SignalObject',copy(temp))

temp.CoderInfo.CustomAttributes.Owner = 'fuel_calc';

set_param('fuel_calc/fuel_rate','SignalName','fuel_rate')
set_param('fuel_calc/fuel_rate','SignalObject',copy(temp))

clear temp portHandles outportHandle numerator_param

В каждой из этих трех моделей выберите Configuration Parameters> владелец Use от объекта данных для размещения определения данных. С этой очищенной установкой (значение по умолчанию), генератор кода игнорирует значения, которые вы задаете для Владельца.

set_param('fuel_calc','EnableDataOwnership','on')
set_param('airflow_calc','EnableDataOwnership','on')
set_param('sldemo_fuelsys_dd_controller','EnableDataOwnership','on')

Сохраните модели компонента.

save_system('fuel_calc')
save_system('airflow_calc')

Сгенерируйте улучшенный код

Сгенерируйте код от моделей контроллеров, sldemo_fuelsys_dd_controller.

rtwbuild('sldemo_fuelsys_dd_controller')
### Starting build procedure for model: airflow_calc
### Successful completion of build procedure for model: airflow_calc
### Starting build procedure for model: fuel_calc
### Successful completion of build procedure for model: fuel_calc
### Starting build procedure for model: sldemo_fuelsys_dd_controller
### Successful completion of build procedure for model: sldemo_fuelsys_dd_controller

Теперь, файл sldemo_fuelsys_dd_controller.c не задает ни одной из глобальных переменных.

В отчете генерации кода осмотрите код, сгенерированный для airflow_calc.

airflow_calc.c файла теперь задает глобальные переменные, которые принадлежат airflow_calc.

file = fullfile('slprj','ert','airflow_calc','airflow_calc.c');
rtwdemodbtype(file,'/* Definition for custom storage class: ExportToFile */',...
    'real32_T numerator_param[2] = { 0.01F, -0.01F } ;',1,1)
/* Definition for custom storage class: ExportToFile */
real32_T e0;
real32_T est_airflow;
real32_T fb_correction;
real32_T numerator_param[2] = { 0.01F, -0.01F } ;

Осмотрите код, сгенерированный для fuel_calc. Файл fuel_calc.c задает глобальную переменную fuel_rate.

file = fullfile('slprj','ert','fuel_calc','fuel_calc.c');
rtwdemodbtype(file,'/* Definition for custom storage class: ExportToFile */',...
    'real32_T fuel_rate;',1,1)
/* Definition for custom storage class: ExportToFile */
real32_T fuel_rate;

Создайте одну точку спецификации для сигналов та передача между компонентами

Элементы данных сигнала est_airflow и fb_correction представлены блоками Выходного порта в airflow_calc и блоками Inport в fuel_calc. Если вы хотите изменить настройку одного из этих сигналов, необходимо внести изменение в обеих моделях. Например, если вы хотите изменить класс памяти est_airflow от ExportToFile до Volatile, необходимо изменить класс памяти дважды: однажды для блока Outport в airflow_calc и снова для блока Inport в fuel_calc.

Чтобы сделать обслуживание каждого сигнала легче, сохраните настройки генерации кода в объекте Simulink.Signal, который может существовать в базовом рабочем пространстве или словаре данных.

В Model Data Editor для airflow_calc, на вкладке Inports/Outports, находят строку, которая соответствует est_airflow.

Для той строки, в столбце Имени Сигнала, кликают по ячейке.

В ячейке, рядом с текстом est_airflow, кликают по кнопке действий (с тремя вертикальными точками). Выберите Create и Resolve.

В диалоговом окне Create New Data, установленном Значении к Simulink.Signal и нажимают Create. Объект Simulink.Signal под названием est_airflow появляется в базовом рабочем пространстве. В Model Data Editor, для est_airflow, устанавливается флажок во флажке Resolve, что означает, что блок Outport получает настройки генерации кода от объекта сигнала в базовом рабочем пространстве.

В диалоговом окне свойства est_airflow, Классе памяти набора к ExportToFile.

Владелец набора к airflow_calc.

Используйте Model Data Editor, чтобы создать подобный объект сигнала для fb_correction.

В Model Data Editor для fuel_calc, на вкладке Inports/Outports, в столбце Твердости, устанавливают флажки для est_airflow и fb_correction. Теперь, каждый блок Inport получает настройки генерации кода от соответствующего объекта сигнала.

Также, чтобы создать объект сигнала и сконфигурировать блоки и строки в модели, в командной строке, используют эти команды:

est_airflow = Simulink.Signal;
est_airflow.CoderInfo.StorageClass = 'Custom';
est_airflow.CoderInfo.CustomStorageClass = 'ExportToFile';
est_airflow.CoderInfo.CustomAttributes.Owner = 'airflow_calc';

fb_correction = Simulink.Signal;
fb_correction.CoderInfo.StorageClass = 'Custom';
fb_correction.CoderInfo.CustomStorageClass = 'ExportToFile';
fb_correction.CoderInfo.CustomAttributes.Owner = 'airflow_calc';

set_param('airflow_calc/est_airflow','MustResolveToSignalObject','on')

set_param('airflow_calc/fb_correction','MustResolveToSignalObject','on')

portHandles = get_param('fuel_calc/est_airflow','portHandles');
outportHandle = portHandles.Outport;
set_param(outportHandle,'MustResolveToSignalObject','on')

portHandles = get_param('fuel_calc/fb_correction','portHandles');
outportHandle = portHandles.Outport;
set_param(outportHandle,'MustResolveToSignalObject','on')

clear portHandles outportHandle

Сохраните модели компонента и сгенерируйте код от sldemo_fuelsys_dd_controller. Код эквивалентен, это было, прежде чем вы создали объекты Simulink.Signal. Теперь, можно внести изменения в объекты сигнала вместо соответствующих блоков и строк в моделях.

save_system('airflow_calc')
save_system('fuel_calc')
rtwbuild('sldemo_fuelsys_dd_controller')
### Starting build procedure for model: airflow_calc
### Successful completion of build procedure for model: airflow_calc
### Starting build procedure for model: fuel_calc
### Successful completion of build procedure for model: fuel_calc
### Starting build procedure for model: sldemo_fuelsys_dd_controller
### Successful completion of build procedure for model: sldemo_fuelsys_dd_controller

Похожие темы