主要内容

Simulate Five-Cycle Energy Consumption Tests Using Virtual Vehicle Model

This example shows you how to use the Virtual Vehicle Composer app to configure an electric vehicle model and run drive cycles that generate energy data for the five- and two-cycle energy tables used in the SAE J1634 [1] adjustment factor calculations. See Calculate Five-Cycle Electric Vehicle Range Adjustment Factor.

This example uses the first of four testing options listed in SAE J1634 Appendix B.3.6 to generate five-cycle data by simulating these standalone drive cycle tests:

  • Federal test procedure (FTP-75)

  • Highway fuel economy test (HWFET)

  • Supplemental Federal Test Procedure (SFTP) US06

  • Supplemental Federal Test Procedure (SFTP) SC03

The FTP-75 drive cycle is available in the Drive Cycle Source block by default. To install the additional drive cycles, see Install Drive Cycle Data.

Note that this example uses a representative one-motor electric vehicle model. Adjust the configured model to fit your vehicle specifications.

Add Example Folder to Path

Add the example folder to the MATLAB® path.

addpath(genpath(pwd));

Build Virtual Vehicle Model

Open a working copy of the Electric Vehicle (EV) Reference Application. For more information, see Build Full Electric Vehicle Model.

autoblkEvStart

Set Up Simulation Inputs

Specify the drive cycles to run and get the simulation length of each drive cycle. The simulation lengths are needed to configure the simulations at a later step. The cold FTP test is not simulated in this example.

mdlName = "ConfiguredEv1EmVirtualVehicle";
cyclesToRun = ["FTP75", "HWFET", "US06", "SC03"];
cycleSrcBlk = mdlName + "/Scenarios/Reference Generator/Drive Cycle/Drive Cycle Source";
battBlkName = mdlName + "/Vehicle/ConfiguredSimulinkPlantModel/Battery/BatteryMapped/Lithium Ion Battery Pack";

numSims = length(cyclesToRun);
load_system(mdlName)
cycleSimTime = strings(numSims, 1);
for i = 1:numSims
    set_param(cycleSrcBlk, "cycleVar", cyclesToRun(i))
    simLengthTime = split(get_param(cycleSrcBlk, "tfinal"));
    cycleSimTime(i) = string(simLengthTime{1});
end
close_system(mdlName, 1);

Create Simulink.SimulationInput Object

To create a set of simulation configurations to simulate each drive cycle, initialize a Simulink.SimulationInput object for the model.

simIn = Simulink.SimulationInput(mdlName);

Define a presimulation function to run before each simulation using the setPreSimFcn function. The presimulation function uses the function setPwrLogging to turn on data logging for each power accounting bus.

simIn = setPreSimFcn(simIn, @(simIn) setPwrLogging(simIn.ModelName, "on"));

Define a postsimulation function to run after each simulation using the setPostSimFcn function. The postsimulation function uses the function getBattPwrInfo to turn off data logging and constructs the power analysis.

simIn = setPostSimFcn(simIn, @(simOut) getBattPwrInfo(simOut, battBlkName));

Enable data logging for the vehicle speed signal VehSpd.

Simulink.sdi.markSignalForStreaming('ConfiguredEv1EmVirtualVehicle/Visualization/Signal Specification6',1,'on');
speedph = get_param('ConfiguredEv1EmVirtualVehicle/Visualization/Signal Specification6','PortHandles');
speedlh = get_param(speedph.Outport,'Line');
set_param(speedlh,'Name','VehSpd')
save_system('ConfiguredEv1EmVirtualVehicle');

Configure Simulations

Duplicate the simulation object to create one object for each drive cycle to simulate.

simIn = repmat(simIn, 5, 1);

Specify the drive cycle and simulation time for each simulation object.

for i = 1:numSims
    simIn(i) = setBlockParameter(simIn(i), cycleSrcBlk, "cycleVar", cyclesToRun(i));
    simIn(i) = setModelParameter(simIn(i), "StopTime", cycleSimTime(i));
end

Run Simulations

Run the simulations in parallel using the parsim function.

simOut = parsim(simIn);
[09-Oct-2025 11:41:38] Checking for availability of parallel pool...
Starting parallel pool (parpool) using the 'Processes' profile ...
09-Oct-2025 11:43:17: Job Queued. Waiting for parallel pool job with ID 2 to start ...
Connected to parallel pool with 10 workers.
[09-Oct-2025 11:43:51] Starting Simulink on parallel workers...
[09-Oct-2025 11:44:43] Loading project on parallel workers...
[09-Oct-2025 11:44:44] Configuring simulation cache folder on parallel workers...
[09-Oct-2025 11:45:11] Loading model on parallel workers...
[09-Oct-2025 11:46:41] Running simulations...
[09-Oct-2025 12:02:42] Cleaning up parallel workers...

Save Simulation Data

Extract the simulation data and save the data to the variable CycleSimData.

simData = dictionary(string.empty, struct);
for i = 1:numSims
    
    vehSpdSignal = simOut(i).logsout.find("VehSpd");
    dataStruct = struct("VehSpd", vehSpdSignal.Values, ...
        "BattPwr", simOut(i).BattPwr);
    simData(cyclesToRun(i)) = dataStruct;
end
save("CycleSimData", "simData");

Plot Drive Cycles

Plot the drive cycles to view the simulation results.

for i = 1:length(cyclesToRun)
    cycleData = simData(cyclesToRun(i));
    figure; % Create a new figure for each cycle
    plot(cycleData.VehSpd)
    title("Simulated Vehicle Speed for Cycle " + num2str(cyclesToRun(i)))
    ylabel("Vehicle Speed (" + cycleData.VehSpd.DataInfo.Units.Name + ")")
    legend(cyclesToRun(i))
end

References

[1] SAE J1634. "Battery Electric Vehicle Energy Consumption and Range Test Procedure". Warrendale, PA: SAE International, revised April 2021, issued May 1993. https://doi.org/10.4271/J1634_202104.

See Also

External Websites