exponenta event banner

Система управления соотношением воздуха и топлива с фиксированными данными

В этом примере показано, как создать и оптимизировать код для системы управления соотношением воздуха и топлива с фиксированной точкой, разработанной с помощью Simulink ® и Stateflow ®. Подробное описание модели см. в:

В примере используется целевой файл Embedded Coder ® (ert.tlc).

Соответствующие части модели

На рис. 1-4 показаны соответствующие части sldemo_fuelsys модель, представляющая собой замкнутую систему, содержащую подсистему установки и подсистему контроллера. Установка позволяет инженерам проверить контроллер с помощью моделирования на ранних этапах проектного цикла. В этом примере создайте код для соответствующей подсистемы контроллера, fuel_rate_control. На рис. 1 показана модель моделирования верхнего уровня.

% Open |sldemo_fuelsys|, set the parameters and update the model diagram
% to view the signal data types.
close_system('sldemo_fuelsys',0)
load_system('sldemo_fuelsys');
rtwconfiguredemo('sldemo_fuelsys','ERT','fixed');
sldemo_fuelsys_data('sldemo_fuelsys','switch_data_type','fixed');
sldemo_fuelsys_data('sldemo_fuelsys','set_info_text','rtwdemo_fuelsys_fxp_script');
sldemo_fuelsys_data('sldemo_fuelsys','top_level_logging','on');
set_param('sldemo_fuelsys','ShowPortDataTypes','on');
set_param('sldemo_fuelsys','SampleTimeColors','on');
set_param('sldemo_fuelsys','Dirty','off');
sldemo_fuelsys([],[],[],'compile');
sldemo_fuelsys([],[],[],'term');

Рисунок 1: Модель верхнего уровня установки и контроллера

Система управления соотношением воздуха и топлива состоит из блоков Simulink ® и Stateflow ®. Это часть модели, для которой создается код.

open_system('sldemo_fuelsys/fuel_rate_control');

Рис. 2: Подсистема регулятора соотношения воздуха и топлива

Система оценки расхода всасываемого воздуха и коррекции по замкнутому контуру содержит две поисковые таблицы «Постоянная накачка» и «Скорость клина Ki».

open_system('sldemo_fuelsys/fuel_rate_control/airflow_calc');

Рис. 3: Подсистема airflow_calc

Логика управления представляет собой диаграмму Stateflow ®, которая определяет различные режимы работы.

open_system('sldemo_fuelsys/fuel_rate_control/control_logic');

Рис. 4: Логика контроллера соотношения топлива

Удалите загромождение окна.

close_system('sldemo_fuelsys/fuel_rate_control/airflow_calc');
close_system('sldemo_fuelsys/fuel_rate_control/fuel_calc');
close_system('sldemo_fuelsys/fuel_rate_control/control_logic');
hDemo.rt=sfroot;hDemo.m=hDemo.rt.find('-isa','Simulink.BlockDiagram');
hDemo.c=hDemo.m.find('-isa','Stateflow.Chart','-and','Name','control_logic');
hDemo.c.visible=false;
close_system('sldemo_fuelsys/fuel_rate_control');

Создать только систему регулирования соотношения воздух-топливо. После завершения процесса создания кода отображается HTML-отчет с подробным описанием созданного кода. Основной корпус кода расположен в fuel_rate_control.c.

rtwbuild('sldemo_fuelsys/fuel_rate_control');
### Starting build procedure for: fuel_rate_control
### Successful completion of build procedure for: fuel_rate_control

Build Summary

Top model targets built:

Model              Action                       Rebuild Reason                                    
==================================================================================================
fuel_rate_control  Code generated and compiled  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 15.844s

На фиг.5 показаны фрагменты сгенерированного кода для таблицы поиска Pumping Constant.

Для просмотра кода для константы накачки щелкните правой кнопкой мыши блок и выберите «Код C/C + +» > «Перейти к коду C/C + +».

rtwtrace('sldemo_fuelsys/fuel_rate_control/airflow_calc/Pumping Constant');

Код для константы накачки содержит два поиска точек останова и интерполяцию 2D. SpeedVect точка останова распределена неравномерно, и пока PressVect точка останова равномерно разнесена, ни имеют мощность двух интервалов. Текущий интервал приводит к дополнительному коду (ПЗУ), включая деление, и требует, чтобы все точки останова находились в памяти (ОЗУ).

Рис. 5: Сгенерированный код для поиска константы накачки (содержит неравномерно расположенные точки останова)

Оптимизация кода с равномерно распределенной мощностью двух точек останова

Производительность генерируемого кода можно оптимизировать, используя равномерно распределенную мощность двух точек останова. В этом примере повторно сопоставляют данные таблицы поиска в системе регулирования соотношения воздух-топливо на основе существующих измеренных данных.

При загрузке модели модель PostLoadFcn создал данные таблицы подстановки в рабочем пространстве модели. Извлечение исходных данных таблицы через sldemo_fuelsys_dataизмените его для равномерно распределенной мощности, равной двум, и переназначите его в рабочей области модели.

td = sldemo_fuelsys_data('sldemo_fuelsys', 'get_table_data');

Вычислите новые табличные данные для равномерно распределенной мощности двух точек останова.

ntd.SpeedVect   = 64 : 2^5 : 640;             % 32 rad/sec
ntd.PressVect   = 2*2^-5 : 2^-5 : 1-(2*2^-5); % 0.03 bar
ntd.ThrotVect   = 0:2^1:88;                   % 2 deg
ntd.RampRateKiX = 128:2^7:640;                % 128 rad/sec
ntd.RampRateKiY = 0:2^-2:1;                   % 0.25 bar

Перенастройка данных таблицы.

ntd.PumpCon  = interp2(td.PressVect,td.SpeedVect,td.PumpCon, ntd.PressVect',ntd.SpeedVect);
ntd.PressEst = interp2(td.ThrotVect,td.SpeedVect,td.PressEst,ntd.ThrotVect',ntd.SpeedVect);
ntd.SpeedEst = interp2(td.PressVect,td.ThrotVect,td.SpeedEst,ntd.PressVect',ntd.ThrotVect);
ntd.ThrotEst = interp2(td.PressVect,td.SpeedVect,td.ThrotEst,ntd.PressVect',ntd.SpeedVect);

Повторно вычислить данные таблицы скорости изменения.

ntd.RampRateKiZ = (1:length(ntd.RampRateKiX))' * (1:length(ntd.RampRateKiY)) * td.Ki;

Постоянная мощность накачки двух интервалов

figure('Tag','CloseMe');
mesh(td.PressVect,td.SpeedVect,td.PumpCon), hold on
mesh(ntd.PressVect,ntd.SpeedVect,ntd.PumpCon)
xlabel('PressVect'), ylabel('SpeedVect'), zlabel('PumpCon')
title(sprintf('Pumping Constant\nOriginal Spacing (%dx%d) vs. Power of Two Spacing (%dx%d)',...
    size(td.PumpCon,1),size(td.PumpCon,2),size(ntd.PumpCon,1),size(ntd.PumpCon,2)));

Расчетная мощность давления двух интервалов

clf
mesh(td.ThrotVect,td.SpeedVect,td.PressEst), hold on
mesh(ntd.ThrotVect,ntd.SpeedVect,ntd.PressEst)
xlabel('ThrotVect'), ylabel('SpeedVect'), zlabel('PressEst')
title(sprintf('Pressure Estimate\nOriginal Spacing (%dx%d) vs. Power of Two Spacing (%dx%d)',...
    size(td.PressEst,1),size(td.PressEst,2),size(ntd.PressEst,1),size(ntd.PressEst,2)));

Оценочная мощность скорости между двумя интервалами

clf
mesh(td.PressVect,td.ThrotVect,td.SpeedEst), hold on,
mesh(ntd.PressVect,ntd.ThrotVect,ntd.SpeedEst)
xlabel('PressVect'), ylabel('ThrotVect'), zlabel('SpeedEst')
title(sprintf('Speed Estimate\nOriginal Spacing (%dx%d) vs. Power of Two Spacing (%dx%d)',...
    size(td.SpeedEst,1),size(td.SpeedEst,2),size(ntd.SpeedEst,1),size(ntd.SpeedEst,2)));

Расчетная мощность дросселя с двумя интервалами

clf
mesh(td.PressVect,td.SpeedVect,td.ThrotEst), hold on
mesh(ntd.PressVect,ntd.SpeedVect,ntd.ThrotEst)
xlabel('PressVect'), ylabel('SpeedVect'), zlabel('ThrotEst')
title(sprintf('Throttle Estimate\nOriginal Spacing (%dx%d) vs. Power of Two Spacing (%dx%d)',...
    size(td.ThrotEst,1),size(td.ThrotEst,2),size(ntd.ThrotEst,1),size(ntd.ThrotEst,2)));

Скорость клина Ki Мощность двух интервалов

clf
mesh(td.RampRateKiX,td.RampRateKiY,td.RampRateKiZ'), hold on
mesh(ntd.RampRateKiX,ntd.RampRateKiY,ntd.RampRateKiZ'), hidden off
xlabel('RampRateKiX'), ylabel('RampRateKiY'), zlabel('RampRateKiZ')
title(sprintf('Ramp Rate Ki\nOriginal Spacing (%dx%d) vs. Power of Two Spacing (%dx%d)',...
    size(td.RampRateKiZ,1),size(td.RampRateKiZ,2),size(ntd.RampRateKiZ,1),size(ntd.RampRateKiZ,2)));

Конфигурация по умолчанию заставляет модель регистрировать данные моделирования для сигналов верхнего уровня. Эти результаты моделирования хранятся в переменной рабочей области. sldemo_fuelsys_output. Перед обновлением рабочего пространства модели новыми данными сохраните результат моделирования в hDemo.orig_data для более позднего сравнения с равномерно разнесенной мощностью моделирования двух таблиц.

set_param('sldemo_fuelsys','StopTime','8')
sim('sldemo_fuelsys')
hDemo.orig_data = sldemo_fuelsys_output;

Переназначить новые данные таблицы в рабочей области модели.

hDemo.hWS = get_param('sldemo_fuelsys', 'ModelWorkspace');
hDemo.hWS.assignin('PressEst',   ntd.PressEst);
hDemo.hWS.assignin('PressVect',  ntd.PressVect);
hDemo.hWS.assignin('PumpCon',    ntd.PumpCon);
hDemo.hWS.assignin('SpeedEst',   ntd.SpeedEst);
hDemo.hWS.assignin('SpeedVect',  ntd.SpeedVect);
hDemo.hWS.assignin('ThrotEst',   ntd.ThrotEst);
hDemo.hWS.assignin('ThrotVect',  ntd.ThrotVect);
hDemo.hWS.assignin('RampRateKiX',ntd.RampRateKiX);
hDemo.hWS.assignin('RampRateKiY',ntd.RampRateKiY);
hDemo.hWS.assignin('RampRateKiZ',ntd.RampRateKiZ);

Перенастройте таблицы поиска для равномерно разнесенных данных.

hDemo.lookupTables = find_system(get_param('sldemo_fuelsys','Handle'),...
    'BlockType','Lookup_n-D');

for hDemo_blkIdx = 1 : length(hDemo.lookupTables)
    hDemo.blkH = hDemo.lookupTables(hDemo_blkIdx);
    set_param(hDemo.blkH,'IndexSearchMethod','Evenly spaced points')
    set_param(hDemo.blkH,'InterpMethod','None - Flat')
    set_param(hDemo.blkH,'ProcessOutOfRangeInput','None')
end

Повторно запустите моделирование для равномерно распределенной мощности двух реализаций и сохраните результат моделирования в hDemo.pow2_data.

sim('sldemo_fuelsys')
hDemo.pow2_data = sldemo_fuelsys_output;

Сравните результат моделирования для расхода топлива и соотношения топлива воздуха. При моделировании использовались таблицы поиска Pumping Constant (постоянная накачка) и Ramp Rate Ki (скорость клина Ki), которые показывают превосходное соответствие для равномерно распределенной мощности двух точек останова относительно исходных данных таблицы.

figure('Tag','CloseMe');
subplot(2,1,1);
plot(hDemo.orig_data.get('fuel').Values.Time, ...
     hDemo.orig_data.get('fuel').Values.Data,'r-');
hold
plot(hDemo.pow2_data.get('fuel').Values.Time, ...
     hDemo.pow2_data.get('fuel').Values.Data,'b-');
ylabel('FuelFlowRate (g/sec)');
title('Fuel Control System: Table Data Comparison');
legend('original','even power of two');
axis([0 8 .75 2.25]);
subplot(2,1,2);
plot(hDemo.orig_data.get('air_fuel_ratio').Values.Time, ...
     hDemo.orig_data.get('air_fuel_ratio').Values.Data,'r-');
hold
plot(hDemo.pow2_data.get('air_fuel_ratio').Values.Time, ...
     hDemo.pow2_data.get('air_fuel_ratio').Values.Data,'b-');
ylabel('Air/Fuel Ratio');
xlabel('Time (sec)');
legend('original','even power of 2','Location','SouthEast');
axis([0 8 11 16]);
Current plot held
Current plot held

Перестроить систему регулирования соотношения воздух-топливо и сравнить разницу в сгенерированном коде таблицы поиска.

rtwbuild('sldemo_fuelsys/fuel_rate_control');
### Starting build procedure for: fuel_rate_control
### Successful completion of build procedure for: fuel_rate_control

Build Summary

Top model targets built:

Model              Action                       Rebuild Reason                   
=================================================================================
fuel_rate_control  Code generated and compiled  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 13.801s

На фиг.6 показаны те же фрагменты сгенерированного кода для таблицы поиска «Pumping Constant». Генерируемый код для равномерно распределенной мощности двух точек останова является значительно более эффективным, чем случай неравномерно разнесенной точки останова. Код состоит из двух простых вычислений точки останова и прямого индекса в данные таблицы поиска 2D. Дорогостоящее разделение устраняется, и данные точек останова не требуются в памяти.

rtwtrace('sldemo_fuelsys/fuel_rate_control/airflow_calc/Pumping Constant');

Рис. 6: Сгенерированный код для поиска константы накачки (равномерно распределенная мощность двух точек останова)

Закройте пример.

close(findobj(0,'Tag','CloseMe'));
clear hDemo* td ntd
close_system('sldemo_fuelsys',0);
rtwdemoclean;

Модельный консультант по эффективности кода

Повышение эффективности кода за счет использования равномерно распределенной мощности двух точек останова является одной из нескольких важных оптимизаций для генерации кода с фиксированной точкой. Simulink ® Model Advisor - это отличный инструмент для определения других методов повышения эффективности кода для моделей Simulink ® и Stateflow ®. Убедитесь, что проверки выполняются в папке Embedded Coder ® или Simulink Coder ®.

Связанные примеры

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