exponenta event banner

Установление владения данными в иерархии моделей

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

Можно создать глобальную переменную в сгенерированном коде, применив класс хранения к элементу данных в ссылочной модели (см. Настройка генерации кода C для элементов интерфейса модели). При определенных условиях генератор кода помещает определение переменной с кодом, созданным из верхней модели, в иерархию. Это размещение по умолчанию может затруднить определение модели, ответственной за данные, и управление изменениями кода в среде разработки на базе группы.

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

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

1. Копирование файла сценария 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');

2. Запустите копию сценария в текущей папке. Сценарий открывает модель 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.

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

open_system('airflow_calc')

4. На вкладке Моделирование (Modeling) щелкните Редактор данных модели (Model Data Editor).

5. В Редакторе данных модели (Model Data Editor) задайте в раскрывающемся списке Изменить вид (Change view) значение Code.

6. В airflow_calc модель, выберите est_airflow Блок аутпорта.

7. В редакторе данных модели проверьте значение в столбце «Класс хранилища». Сигнал, который представляет этот блок, est_airflow, использует класс хранения ExportToFile. При этой настройке сигнал отображается в сгенерированном коде как глобальная переменная. Блок Outport с меткой fb_correction также использует этот параметр.

8. В редакторе данных модели выберите вкладку Параметры (Parameters) и нажмите кнопку Показать/обновить дополнительную информацию (Show/refresh additional information). Редактор данных модели теперь показывает информацию о переменных и объектах рабочего пространства, таких как Simulink.Parameter , которые модель использует для задания значений параметров блока.

9. В поле Содержимое фильтра введите numerator. Simulink.Parameter объект numerator_param, который находится в базовом рабочем пространстве, устанавливает значение параметра «Числитель» в блоке «Дискретный фильтр» с меткой Throttle Transient. Объект использует класс хранения ExportToFile.

10. Выберите вкладку Signals (Сигналы). В поле Содержимое фильтра введите e0. Сигнал e0, которая является внутренней для airflow_calc ссылочная модель, также использует ExportToFile. Сигнал является внутренним, поскольку он не является входом или выходом модели на корневом уровне.

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

open_system('fuel_calc')

12. В редакторе данных модели для этой модели на вкладке Ввод/вывод (Inports/Outports) задайте для параметра Изменить вид (Change view) значение Code. Блоки ввода est_airflow и fb_correction использовать один и тот же класс хранения, ExportToFile, как соответствующие блоки Outport в airflow_calc. Блок Outport с меткой fuel_rate также использует ExportToFile.

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

Создать код из модели контроллера, sldemo_fuelsys_dd_controller.

evalc('slbuild(''sldemo_fuelsys_dd_controller'')');

В отчете о создании кода в разделе Ссылочные модели (Referenced Models) щелкните гиперссылку для проверки кода, созданного для 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;                           /* '<Root>/Sum1' */

В отчете о создании кода вернитесь к коду, созданному для 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;                  /* '<Root>/airflow_calc' */
real32_T fb_correction;                /* '<Root>/airflow_calc' */
real32_T fuel_rate;                    /* '<Root>/fuel_calc' */
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.

1. В airflow_calc на вкладке «Моделирование» в разделе «Модель» выберите «Инспектор свойств».

2. В Редакторе данных модели (Model Data Editor) выберите вкладку Ввод/вывод (Inports/Outports).

3. Выберите строку, соответствующую блоку Outport est_airflow. Инспектор свойств показывает свойства блока Outport.

4. В инспекторе свойств в разделе «Код» задайте для параметра «Владелец» значение airflow_calc. Генератор кода помещает определение глобальной переменной с кодом, сгенерированным для airflow_calc.

5. Для fb_correction, с помощью редактора данных модели и инспектора свойств задайте для параметра «Владелец» значение airflow_calc.

6. Выберите вкладку Параметры (Parameters).

7. Найдите строку, соответствующую объекту параметра, numerator_param. В строке дважды щелкните значок в левом столбце. Откроется Обозреватель моделей (Model Explorer), в котором отображаются свойства numerator_param.

8. На панели Иерархия модели (Model Hierarchy) разверните узел airflow_calc, чтобы можно было увидеть подчиненный узел Рабочая область модели (Model Workspace).

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

10. В fuel_calc на вкладке «Моделирование» в разделе «Модель» выберите «Инспектор свойств».

11. Для блоков ввода est_airflow и fb_correction, с помощью редактора данных модели и инспектора свойств задайте для параметра «Владелец» значение airflow_calc. При такой конфигурации fuel_calc код не определяет переменные.

12. Для блока «Outport» используйте редактор данных модели и инспектор свойств, чтобы задать для параметра «Owner» значение 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

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

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

14. Сохраните ссылочные модели.

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

Создать улучшенный код

Создать код из модели контроллера, sldemo_fuelsys_dd_controller.

evalc('slbuild(''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;                           /* '<Root>/Sum1' */
real32_T est_airflow;                  /* '<Root>/Sum' */
real32_T fb_correction;                /* '<Root>/Discrete Integrator' */
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;                    /* '<S2>/Merge' */

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

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

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

1. В редакторе данных модели для airflow_calc, на вкладке Inports/Outports найдите строку, соответствующую est_airflow. Для этой строки в столбце «Имя сигнала» щелкните ячейку.

2. В ячейке рядом с est_airflow нажмите кнопку действия (с тремя вертикальными точками). Выберите Создать и разрешить.

3. В диалоговом окне «Создание новых данных» задайте для параметра «Значение» значение Simulink.Signal и нажмите кнопку «Создать». A Simulink.Signal объект с именем est_airflow отображается в базовой рабочей области. В редакторе данных модели для est_airflow, флажок в поле Разрешить (Resolve) установлен, что означает, что блок Исходящий (Outport) получает настройки генерации кода из объекта сигнала в базовой рабочей области.

4. В est_airflow диалоговое окно свойств, задайте для класса Storage значение ExportToFile.

5. Задать для владельца значение airflow_calc.

6. Используйте Редактор данных модели (Model Data Editor) для создания аналогичного объекта сигнала для fb_correction.

В редакторе данных модели для fuel_calc, на вкладке Inports/Outports в столбце Resolve установите флажки для 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', 'StorageClass', 'Auto')
set_param('airflow_calc/est_airflow','MustResolveToSignalObject','on')

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

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

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

clear portHandles outportHandle

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

save_system('airflow_calc')
save_system('fuel_calc')
evalc('slbuild(''sldemo_fuelsys_dd_controller'')');

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