Main Content

Inject Faults in Battery Models

Since R2023b

This example shows how to inject faults in battery models during simulations using Simscape™ Battery™ and Simulink™ software. First, you explore the effect of disconnecting a battery cell from the other cells of a parallel assembly inside a battery module. A cell disconnection typically happens due to a weld failure or a failure in the cell current interruption device. Then, you add an internal short-circuit fault to a cell of a parallel assembly inside a battery module. The fault triggers a set of exothermic reactions, known as a thermal runaway. You activate both faults during the simulation by using a timed trigger at a simulation time of 30 seconds.

Fault injection is a powerful technique during the development of robust control software for safety critical systems such as lithium-ion batteries. This example generates a battery model, adds non-intrusive faults, and then displays the simulation results using a batterySimulationChart object.

Create Battery Module Object

To create a battery Module object, you must first design and create the foundational elements of the battery module.

Create Cell Object and Define Visualization Variables

Create and define the geometry of a battery cell. Use the batteryCylindricalGeometry function, which returns a CylindricalGeometry object. Then, to apply the geometry to the resulting Cell object, use the batteryCell function and specify the CylindricalGeometry object as the first argument.

cylindricalGeometry = batteryCylindricalGeometry;
cylindricalCell = batteryCell(cylindricalGeometry);

Change the fundamental cell model block of the Module object to use the Battery Equivalent Circuit block. Specify the CellModelBlockPath property of the CellModelOptions property inside the batterycell object.

cylindricalCell.CellModelOptions.CellModelBlockPath = "batt_lib/Cells/Battery Equivalent Circuit";

You can use the Cell object to simulate the thermal effects of the battery cell by using a simple 1-D model. To simulate the thermal effects of the battery cell, in the BlockParameters property of the CellModelOptions property of the Cell object, set the ThermalModel property to "LumpedThermalMass". You can add an exothermic reaction fault only if you set the ThermalModel property of the Cell object to "LumpedThermalMass". You can define the thermal boundary conditions for battery parallel assemblies and modules only if you first define a thermal model at the cell level.

cylindricalCell.CellModelOptions.BlockParameters.ThermalModel = "LumpedThermalMass";

Create ParallelAssembly Object

A parallel assembly comprises multiple battery cells connected electrically in parallel under a specific topological configuration or geometrical arrangement. In this example, you create a parallel assembly of nine cylindrical cells.

To create the ParallelAssembly object, use the batteryParallelAssembly function. Define the cell as the first argument and the number of parallel cells as the second argument.

parallelAssembly = batteryParallelAssembly(cylindricalCell, ...
    9, ...
    Rows=3, ...
    ModelResolution="Detailed", ...
    Topology="Square");

Create Module Object

You now have all the foundational elements to create your battery module. A battery module comprises multiple series-connected parallel assemblies. In this example, you create a battery module of three parallel assemblies with a detailed model resolution.

To create this Module object, use the batteryModule function. Define the parallel assembly as the first argument and the number of parallel assemblies in series as the second argument. To specify the additional module properties, use the optional name-value arguments.

module = batteryModule(parallelAssembly, ...
    3, ...
    AmbientThermalPath="CellBasedThermalResistance", ...
    CoolantThermalPath="CellBasedThermalResistance", ...
    ModelResolution="Detailed", ...
    InterCellThermalPath="on", ...
    InterParallelAssemblyGap=simscape.Value(0.005,"m"));

Visualize Battery Module and Check Model Resolution

To obtain the number of Battery Equivalent Circuit blocks used for the simulation, use the NumModels property of your Module object.

To visualize the battery module before you build the system model and to view its model resolution, create the figure where you want to visualize your module and then use the batteryChart function.

f = uifigure(Color="w");
tl = tiledlayout(1,2,Parent=f,TileSpacing="Compact");
nexttile(tl)
moduleChart1 = batteryChart(tl,module);
nexttile(tl)
moduleChart2 = batteryChart(tl,module,SimulationStrategyVisible="On");

Build Simscape Model of Module Object

After you create your battery objects, you need to convert them into Simscape models to use them in block diagrams. You can then use these models as references for system integration and requirement evaluation, cooling system design, control strategy development, hardware-in-the-loop, and many more applications.

To create a library that contains the Simscape Battery model of the Module object, use the buildBattery function. To create a script where you can individually define all battery parameters, set the MaskParameters argument of the buildBattery function to "VariableNamesByType". To include the initial targets as part of the script, set the MaskInitialTargets argument of the buildBattery function to "VariableNamesByInstance".

Create the packVisualization_lib and packVisualization SLX library files in your working folder. The packVisualization_lib library contains the Modules and ParallelAssemblies sublibraries. This function also creates a packVisualization_param script with the .m extension, which creates all of the necessary parameters for running the battery simulation.

libraryname = "moduleFaults";
buildBattery(module, ...
    "LibraryName",libraryname, ...
    "MaskParameters","VariableNamesByType");

Create and Simulate Battery Model

After you create your battery library with the required battery models, you must create a Simulink model. You then simulate this model to obtain the logged simulation data.

Create Simulink Model

Create and open a Simulink model. Define the name of your model and use the open_system function.

modelname = "batteryFaultsModel";
open_system(new_system(modelname));

This example programmatically adds all the blocks required to simulate the battery module model. To add these blocks, define their block paths as variables in your workspace.

batteryBlockPath = strcat(modelname,"/","Module1");
electricalRefBlockPath = strcat(modelname,"/","ElectricalReference");
solverConfigBlockPath = strcat(modelname,"/","Solver");
currentSourceBlockPath = strcat(modelname,"/","Controlled Current Source");
ambientTemperatureSourceBlockPath = strcat(modelname,"/","Temperature Source");
coolantTemperatureSourceBlockPath = strcat(modelname,"/","Temperature Source Clnt");

Add the blocks to the model using the add_block function.

add_block(strcat(libraryname,"_lib/",module.Name),batteryBlockPath,position=[150,100,300,250]);
add_block("fl_lib/Electrical/Electrical Elements/Electrical Reference",electricalRefBlockPath,position=[215,320,235,340],orientation="down");
add_block("nesl_utility/Solver Configuration",solverConfigBlockPath,position=[-80,280,-30,320]);
add_block("fl_lib/Electrical/Electrical Sources/DC Current Source",currentSourceBlockPath,position=[-30,150,0,200],orientation="down",i0=num2str(-400),ShowName="off");
add_block("fl_lib/Thermal/Thermal Sources/Temperature Source",ambientTemperatureSourceBlockPath,position=[80,195,120,235],ShowName="off",orientation="left");
add_block("fl_lib/Thermal/Thermal Sources/Temperature Source",coolantTemperatureSourceBlockPath,position=[80,120,120,160],ShowName="off",orientation="left");

Get the handles to the block ports and connect all blocks.

batteryBlockPortHandles = get_param(batteryBlockPath,"PortHandles");
electricalRefBlockPortHandles = get_param(electricalRefBlockPath,"PortHandles");
solverConfigBlockPortHandles = get_param(solverConfigBlockPath,"PortHandles");
currentSourceBlockPortHandles = get_param(currentSourceBlockPath,"PortHandles");
ambientTemperatureSourceBlockPortHandles = get_param(ambientTemperatureSourceBlockPath,"PortHandles");
coolantTemperatureSourceBlockPortHandles = get_param(coolantTemperatureSourceBlockPath,"PortHandles");

add_line(modelname,batteryBlockPortHandles.RConn,currentSourceBlockPortHandles.RConn,autorouting="smart");
add_line(modelname,batteryBlockPortHandles.LConn(3),currentSourceBlockPortHandles.LConn,autorouting="smart");
add_line(modelname,batteryBlockPortHandles.RConn,electricalRefBlockPortHandles.LConn,autorouting="smart");
add_line(modelname,batteryBlockPortHandles.RConn,solverConfigBlockPortHandles.RConn,autorouting="smart");
add_line(modelname,batteryBlockPortHandles.LConn(2),ambientTemperatureSourceBlockPortHandles.LConn,autorouting="smart");
add_line(modelname,batteryBlockPortHandles.LConn(1),coolantTemperatureSourceBlockPortHandles.LConn,autorouting="smart");

This figure shows the resulting battery model:

Prepare Model for Simulation

To visualize the battery simulation outputs in the BatterySimulationChart object, you must first enable the Simscape signal logging. To enable logging, set the SimscapeLogType property to "all" in the Simulink model.

set_param(modelname,"SimscapeLogType","all")

To run the simulation, you must first run the parameterization script.

run(strcat(libraryname,"_param.m"))

Simulate Disconnected Cell in Module Fault

To create a new fault, first save the model using the save_system function and use the name of the model as input.

save_system(modelname)

In this example, you model a fault that disconnects a cell from its corresponding parallel assembly by adding a large electrical resistance to that particular cell. To determine the index to use for activating the fault, display the CellNumbering property of the module.

module.CellNumbering.Cells
ans = 3×3

     1     4     7
     2     5     8
     3     6     9

ans = 3×3

     1     4     7
     2     5     8
     3     6     9

ans = 3×3

     1     4     7
     2     5     8
     3     6     9

Use the Simulink.fault.addFault function to add an additional resistance fault to the fifth cell of the second parallel assembly. To add this fault to the fault model, use the addBehavior function.

additionalResistanceFault = Simulink.fault.addFault(strcat(batteryBlockPath,"/ParallelAssembly1(2)/Cell1(5)/Additional resistance"));
faultModel = strcat(modelname,"_FaultModel");
addBehavior(additionalResistanceFault,faultModel);

Now edit and activate the fault. Change the trigger type and the fault event time by changing the TriggerType and StartTime properties, respectively, of the additionalResistanceFault object.

additionalResistanceFault.TriggerType = "Timed";
additionalResistanceFault.StartTime = 30;

To activate the fault, use the activate function of the additionalResistanceFault object.

additionalResistanceFault.activate;

To run the simulation, use the sim function and define the StartTime and StopTime arguments.

out = sim(modelname,StartTime="0",StopTime="600");

Visualize Battery Fault

To select the variable to plot in the BatterySimulationChart and the variable unit, you must first create a batterySimulationLog object with the batterySimulationLog function. Specify the battery object you use to create the battery model library as the first argument and the simulation output data of that battery block from the Simulink model as the second argument. By default, the variable for plotting is the temperature.

batterySimLog = batterySimulationLog(module,out.simlog.Module1);

To display which variables you can plot, query the ModelVariables property of the BatterySimulationLog object. These variables correspond to the public variables in the fundamental cell model block.

disp(batterySimLog.ModelVariables)
    "batteryVoltage"    "batteryTemperature"    "socCell"    "numCycles"    "batteryCurrent"

To select another variable, specify the SelectedVariable property. The software automatically selects the default unit for a variable. You can then define a commensurate unit in the SelectedVariableUnit property.

batteryCurrentSimLog = batterySimLog;
batteryCurrentSimLog.SelectedVariable = "batteryCurrent";

To visualize the value of the temperature variable, use the batterySimulationChart function.

f = uifigure(Color="w");
g = uigridlayout(f,[2 1]);
packChart = batterySimulationChart(g, ...
    batterySimLog);
packChartColorBar = colorbar(packChart);
ylabel(packChartColorBar,strcat("Cell temperature"," (",batterySimLog.SelectedVariableUnit,")"),FontSize=14);

Visualize the current and the state of charge.

packCurrentChart = batterySimulationChart(g, ...
    batteryCurrentSimLog);
packCurrentChart.colormap("parula")
packCurrentChartColorBar=colorbar(packCurrentChart);
ylabel(packCurrentChartColorBar,strcat("Cell current"," (",batteryCurrentSimLog.SelectedVariableUnit,")"),FontSize=14);

The faulted cell causes a decrease in the terminal voltage and differences in state of charge between the parallel assemblies inside the module.

To eliminate the effect of this fault, set the AddedResistance fault element to off.

Simulink.fault.enable(additionalResistanceFault.ModelElement,false);

Simulate Short-Circuit with Exothermic Reactions Fault

In this scenario, you add a fault that triggers a thermal runaway event and observe how the heat spreads throughout the module. In real life applications, thermal runaway events have many initiation mechanisms, including short-circuit, over-charge, and high temperatures. In this example, an internal short circuit triggers the exothermic reactions.

Use the addFault function to add an internal short-circuit fault to the fifth cell of second parallel assembly. To add this fault to the fault model, use the addBehavior function.

internalShortFault = Simulink.fault.addFault(strcat(batteryBlockPath,"/ParallelAssembly1(2)/Cell1(5)/Internal short"));
addBehavior(internalShortFault,faultModel);

Edit and activate the fault. Change the trigger type and the fault event time by specifying the TriggerType and StartTime properties, respectively, of the internalShortFault object.

internalShortFault.TriggerType = "Timed";
internalShortFault.StartTime = 30;

To activate the fault, use the activate function of the internalShortFault object.

internalShortFault.activate

Now add an exothermic reactions fault to fifth cell in the second parallel assembly using the addFault function. To add this fault to the fault model, use the addBehavior function.

exothermicReactionsFault = Simulink.fault.addFault(strcat(batteryBlockPath,"/ParallelAssembly1(2)/Cell1(5)/Exothermic reactions"));
addBehavior(exothermicReactionsFault,faultModel);

Edit and activate the fault. By default, the trigger type of an exothermic reaction fault is "Always On".

To activate the fault, call the activate function of the exothermicReactionsFault object.

exothermicReactionsFault.activate

You can enable the exothermic reactions for all the cells in your module to view a cascade of exothermic reactions that the heat transfer induces. Enabling the possibility of exothermic reactions for every cell results in a more accurate simulation of a real-life battery system. In this example, you do not modify the inter-cell heat transfer and only one cell at a time has an exothermic reactions fault. If all cells can undergo exothermic reactions, the solver can encounter issues solving the equations due to use of the ideal Current Source (Simscape Electrical) block. You can fix this instability by connecting a five ohm resistance in parallel with the battery module.

To run the simulation, use the sim function and define the StartTime and StopTime arguments.

out = sim(modelname,StartTime="0",StopTime="600");

Visualize Battery Fault

To select the variable to plot in the BatterySimulationChart and the variable unit, you must first create a BatterySimulationLog object with the batterySimulationLog function. Specify the battery object you use to create the battery model library as the first argument and the simulation output data of that battery block from the Simulink model as the second argument. By default, the variable selected for plotting is the temperature.

batterySimLog = batterySimulationLog(module,out.simlog.Module1);

To display which variables you can plot, query the ModelVariables property of the BatterySimulationLog object. These variables correspond to the public variables in the fundamental cell model block.

disp(batterySimLog.ModelVariables)
    "batteryVoltage"    "batteryTemperature"    "socCell"    "numCycles"    "batteryCurrent"

To select another variable, specify the SelectedVariable property. The software automatically selects the default unit for a variable. You can define a commensurate unit in the SelectedVariableUnit property.

batteryCurrentSimLog = batterySimLog;
batteryCurrentSimLog.SelectedVariable = "batteryCurrent";

To visualize the value of the temperature variable, use the batterySimulationChart function.

f = uifigure(Color="w");
g = uigridlayout(f,[2,1]);
packChart = batterySimulationChart(g, ...
    batterySimLog);
packChartColorBar=colorbar(packChart);
ylabel(packChartColorBar,strcat("Cell temperature"," (",batterySimLog.SelectedVariableUnit,")"),FontSize=14);

Visualize the current and the state of charge.

packCurrentChart = batterySimulationChart(g, ...
    batteryCurrentSimLog);
packCurrentChart.colormap("parula")
packCurrentChartColorBar=colorbar(packCurrentChart);
ylabel(packCurrentChartColorBar,strcat("Cell current"," (",batteryCurrentSimLog.SelectedVariableUnit,")"),FontSize=14);

See Also

| |

Related Topics