Point-by-Point Modeling for a Diesel Engine
This example shows how to use the Model-Based Calibration Toolbox™ command-line functionality for point-by-point engine modeling projects.
Multiple injection diesel engines and gasoline direct-injection engines can often only be modeled with point-by-point models. You can use point-by-point models to build a model at each operating point of an engine with the necessary accuracy to produce an optimal calibration. Point-by-point command-line functionality is necessary to handle the complexity of developing designs for each operating point.
Why are point-by-point models necessary? Engine actuators and sensors are continually being added to Engine Management Systems (EMS) in response to ever-increasing engine emissions, fuel economy, and performance requirements. In some cases, optimal engine calibration development processes that rely on two-stage modeling may no longer be able to model engine performance responses with sufficient accuracy across the engine operating range. Point-by-point models can provide the necessary model accuracy at measured operating points. However, point-by-point models do not provide estimated responses at other operating points.
This example uses the two-stage models generated in the diesel case study as a surrogate for an engine dynamometer or CAE engine model, in order to generate the point-by-point data for this example. The example shows you how to:
Generate local designs at each operating point. If insufficient design points can be collected, you can augment the local design using Sobol sequences.
Create local multiple models to model each of the responses at each operating point.
Build a point-by-point boundary model to define the data boundary at each operating point for later use in calibration optimization.
Finally, you must visually inspect the fitted models to verify that the model quality is acceptable. You usually need to identify and remove outliers. You can use the command-line to plot diagnostics and remove outliers, but it is easier to use the graphical and statistical tools in the Model Browser (mbcmodel) provided in the Model-Based Calibration Toolbox.
Load Models from Diesel Project
This example uses engine data generated from the models in the diesel case study.
The inputs are MAINSOI, SPEED, BASEFUELMASS, FUELPRESS, VGTPOS, EGRPOS.
DieselProject = mbcmodel.LoadProject(... fullfile(mbcpath,'mbctraining','Diesel_project.mat')); % Store the models in a structure for convenience DieselResponses = DieselProject.Testplans.Responses; Models.BTQ = DieselResponses(1); Models.VGTSPEED = DieselResponses(2); Models.EQREXH = DieselResponses(3); Models.PEAKPRESS = DieselResponses(4); Models.NOX = DieselResponses(6); Models.EGRMF = DieselResponses(7);
Define Inputs for Point-by-Point Models and Create Local Model
The operating point variables are speed (SPEED) and brake torque (BTQ).
The local inputs are main start of injection (MAINSOI), fuel pressure (FUELPRESS), variable gate turbo position (VGTPOS), and exhaust gas recirculation position (EGRPOS).
OperatingPointInputs = mbcmodel.modelinput('Symbol',{'SPEED','BTQ'},... 'Name',{'SPEED','BTQ'},... 'Units',{'rpm','Nm'},... 'Range',{[1600 2200],[0 1600]}); LocalInputs = mbcmodel.modelinput(... 'Symbol',{'MAINSOI','FUELPRESS','VGTPOS','EGRPOS'},... 'Name',{'MAINSOI','FUELPRESS','VGTPOS','EGRPOS'},... 'Units',{'deg','MPa','ratio','mm'},... 'Range',{[-9 3],[90 160],[0.2 0.9],[0.5 5]}); % Create a local multiple model L = mbcmodel.CreateModel('Point-by-Point',LocalInputs); % Select the best model using the PRESS RMSE statistic. L.Properties.SelectionStatistic = 'PRESS RMSE';
Define Engine Operating Points
The design for the operating points is a 7 point drive cycle.
Xg = [2200.0 1263.0
2200.0 947.0
2200.0 632.0
2200.0 126.0
1600.0 1550.0
1600.0 1163.0
1600.0 775.0];
OperatingPointDesign = CreateDesign(OperatingPointInputs);
OperatingPointDesign.Points = Xg;
OperatingPointDesign.Name = 'Drive cycle';Create a Local Design for Each Operating Point
For each operating point, adjust limits for main injection, fuel pressure and VGTPOS, and generate a 128 point Sobol design.
localDesign = CreateDesign(LocalInputs,'Type','Sobol Sequence'); localDesignGenerator = localDesign.Generator; NumLocalPoints = 128; localDesignGenerator.NumberOfPoints = NumLocalPoints; DList = mbcdoe.design.empty( 0, 1); data = []; for i = 1:OperatingPointDesign.NumberOfPoints OperatingPoint = OperatingPointDesign.Points(i,:); speed = OperatingPoint(1); TQDemand = OperatingPoint(2);
Name the Local Design by Operating Point
localDesign.Name = sprintf('Test %2d (%s=%4.0f,%s=%3.0f)', i,... OperatingPointInputs(1).Symbol,OperatingPoint(1),.... OperatingPointInputs(2).Symbol,OperatingPoint(2));
Set Up Limits Depending on Speed for Local Inputs
When you use the Limits property to specify the input range, you generate a Sobol design with exactly NumLocalPoints points.
f = (speed-1600)/(2200-1600);
% The main soi range varies from [-3,3] at 1600 rpm to
% [-9,-3] at 2200 rpm.
localDesignGenerator.Limits(1,:) = (1-f)*[-3,3] + f*[-9,-3];
% The fuel pressure range varies from [90,130] at 1600 rpm to
% [120,160] at 2200 rpm.
localDesignGenerator.Limits(2,:) = (1-f)*[90 120] + f*[110,160];
% The VGTPOS range varies from [0.2,0.4] at 1600 rpm to
% [0.6,0.9] at 2200 rpm.
localDesignGenerator.Limits(3,:) = (1-f)*[0.2 0.4] + f*[0.6 0.9];
% set design properties and generate local design
localDesign.Generator = localDesignGenerator;Collect Engine Data for Local Design
Find the fuel required to obtain the demanded torque for each point in the local design.
[Xlocal,XTS] = mbcSolveTQ(Models,localDesign.Points,speed,TQDemand);
Augment Designs If Necessary
Check that enough points have been collected after running the 128 point DOE (design of experiment). Collect extra points by augmenting the Sobol Sequence with the next N points in the sequence if necessary.
N = NumLocalPoints;
count = 1;
while size(Xlocal,1) < NumLocalPoints*0.75 && count<10
localDesign = Generate(localDesign,...
'Skip',N,...
'NumberOfPoints',N);
N = N*2;
% Find the fuel required to obtain the demanded torque for each point in
% the augmented local design
[Xlocalaug,XTSaug] = mbcSolveTQ(Models,localDesign.Points,speed,TQDemand);
Xlocal = [Xlocal; Xlocalaug]; %#ok<AGROW>
XTS = [XTS; XTSaug]; %#ok<AGROW>
end
% Update points in the local design
localDesign.Points = Xlocal;
fprintf('%s: %d points\n',localDesign.Name,localDesign.NumberOfPoints);Test 1 (SPEED=2200,BTQ=1263): 127 points Test 2 (SPEED=2200,BTQ=947): 128 points Test 3 (SPEED=2200,BTQ=632): 128 points Test 4 (SPEED=2200,BTQ=126): 128 points Test 5 (SPEED=1600,BTQ=1550): 116 points Test 6 (SPEED=1600,BTQ=1163): 119 points Test 7 (SPEED=1600,BTQ=775): 128 points
Collect Response Data
Calculate response data from the diesel case study models.
BTQ = TQDemand*ones(size(Xlocal,1),1);
AFR = 14.46./Models.EQREXH.PredictedValue(XTS);
EGRMF = Models.EGRMF.PredictedValue(XTS);
BSNOX = 3600*Models.NOX.PredictedValue(XTS)/159.5573;
PEAKPRESS = Models.PEAKPRESS.PredictedValue(XTS)/1e6;
VGTSPEED = Models.VGTSPEED.PredictedValue(XTS);
BSFC = 5400.*XTS(:,3)./(BTQ*pi);Check Fit for BSFC
Check RMSE < 2.
[stats,Lbsfc] = Fit(L,Xlocal,BSFC);
if stats(5)>2
fprintf('Poor fit for test %d.\n',i)
endAccumulate Data and Local Designs
You can ensure tests are automatically defined by defining a variable 'logno'.
data = [data ;
Xlocal XTS(:,2:3) ...
BTQ BSFC AFR EGRMF BSNOX PEAKPRESS VGTSPEED i*ones(size(Xlocal,1),1)]; %#ok<AGROW>
DList(i) = localDesign;
endCreate Project and Test Plan
Create an mbcmodel project and build models
project = mbcmodel.CreateProject('DieselPointByPoint'); % Create test plan TP = CreateTestplan( project, {LocalInputs,OperatingPointInputs} ); TP.Name = 'Point-by-point'; % Assign list of local designs to test plan TP.Designs{1} = DList; % Set as best design in test plan TP.BestDesign{2} = OperatingPointDesign;
Make and Import Data Structure
D = project.CreateData();
s = D.ExportToMBCDataStructure;
s.varNames = {LocalInputs.Name ...
'SPEED', 'MAINFUEL','BTQ' 'BSFC' 'AFR' 'EGRMF' 'BSNOX' 'PEAKPRESS' 'VGTSPEED','logno'};
s.varUnits = {'deg','MPa','mm','ratio',...
'rpm','mg/stroke','Nm','g/kWhr','ratio','ratio','g/kWhr','MPa','rpm',''};
s.data = data;
D.BeginEdit;
D.ImportFromMBCDataStructure(s);
D.CommitEdit;
TP.AttachData(D);Build Point-by-Point Boundary Model
Use a convex hull for local boundaries.
B = TP.Boundary.Local.CreateBoundary('Point-by-Point'); B.LocalModel = CreateBoundary(B.LocalModel,'Convex hull'); % Add point-by-point boundary model to project. TP.Boundary.Local.Add(B);
Build Response Models
Use a local multiple model and no global model.
Responses = {'BSFC','BSNOX','AFR','EGRMF','PEAKPRESS','VGTSPEED','MAINFUEL'};
for i = 1:length(Responses)
TP.CreateResponse(Responses{i},L,[]);
endInspect and Refine Models
Finally, you must visually inspect the fitted models to verify that the model quality is acceptable. You usually need to identify and remove outliers. You can use the command-line to plot diagnostics and remove outliers, but it is easier to use the graphical and statistical tools in the Model Browser (mbcmodel) provided in the Model-Based Calibration Toolbox.
You must save the project to a file before loading it into the Model Browser.
project.Save('DieselPointByPoint.mat');
mbcmodel('DieselPointByPoint.mat')