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

Этот пример показывает, как сгенерировать и оптимизировать код для системы управления составом топливно-воздушной смеси с фиксированной точкой, разработанной с 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: Подсистема контроллера состава топливно-воздушной смеси

Система оценки всасываемого воздушного потока и коррекции замкнутого цикла содержит две интерполяционные таблицы, Pumping Constant и Ramp Rate 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.

Чтобы увидеть код для Pumping Constant, щелкните правой кнопкой мыши по блоку и выберите C/C + + Code > Navigate To C/C + + Code.

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

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

Фигура 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)));

Ramp Rate 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 и показывает отличное соответствие для равномерно распределенной степени двойки точек останова относительно исходных данных таблицы.

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;

Model Advisor по эффективности кода

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

Похожие примеры

Похожие темы