Inject Faults in Battery Models
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
Battery Builder | Module
| BatterySimulationChart