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('Local Multiple Models',LocalInputs);
% Select the best model using the AICc statistic.
L.Properties.SelectionStatistic = 'AICc';

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): 118 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)
    end

Accumulate 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;
end

Create 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,[]);
end

Inspect 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')
Was this topic helpful?