В этом примере показано, как создать и оптимизировать код для системы управления соотношением воздуха и топлива с фиксированной точкой, разработанной с помощью 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)));

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 ®.
Конструкция с фиксированной точкой: Система регулирования расхода топлива с фиксированной точкой (Конструктор с фиксированной точкой)
Генерация производственного кода C/C + +: система управления соотношением воздуха и топлива с картами статофлоу