Identifying equivalent circuits from pulse tests
An equivalent circuit parameter set is identified per cell, and the usual source is a pulse test: the hybrid pulse power characterization (HPPC) of the PNGV Battery Test Manual, or a series of constant-current pulses between rests at several states of charge and temperatures. The functions here turn such a record into the parameter sets of the Rint and the RCModel models, following the recipe of the batmodel tool of the ADVISOR vehicle simulator (extras/batmodel, ADVISOR 2003-00-r0116): cut the pulses out of the record, compute an analytic starting point, fit the model to each pulse by replaying the measured current through it, and tabulate the results over the state of charge and the temperature. The results are exactly the entries an EquivalentCircuitParameters set takes, and the tables are LookupTables.
| step | function | result |
|---|---|---|
| cut the pulses out of a record | hppc_pulses | HPPCPulses |
| Rint resistance of each pulse | rint_resistance | a resistance [Ω] |
| Rint tables | rint_tables | "discharge resistance", "charge resistance" |
| analytic starting point of the RC calibration | rc_initial_guess | the four impedance groups |
| RC calibration of each pulse | calibrate_rc (with using DyadModelOptimizer) | RCFits |
| RC tables | rc_tables | the five RCModel entries |
The rests between the pulses have to carry no current. The open-circuit voltage, the state of charge and the resistances are all read from them as the voltage of a cell through which no current flows, so hppc_pulses refuses a record whose rest next to a pulse carries more than rest_tolerance (by default 1e-4) of the pulse's current. Zero a rest current that is an offset of the measurement before cutting the record.
The Rint model
The Rint resistance of a pulse is the voltage the cell recovers once the current stops, over the current: the Rint model's own response to the pulse, whose voltage is OCV(SOC) - I R under load and OCV(SOC) at rest, exactly when the current steps between two samples. For a current that ramps down over an interval instead, rint_resistance gives the bias at the loaded state of charge and the further difference rint_tables takes on by placing the value at the state of charge after the pulse.
using BatteryComponents, Unitful
# time [s], current [A, positive while discharging] and voltage [V] of a pulse test at
# 25 °C, and the open-circuit voltage curve measured on the same cell
pulses = hppc_pulses(time, current, voltage; temperature = 25u"°C", ocv)
circuit = merge(Dict{String, Any}("open-circuit voltage" => ocv),
rint_tables(pulses; soc = 0.1:0.1:0.9))
set = EquivalentCircuitParameters(;
overall = Dict{String, Any}("nominal capacity" => 22.0u"A*hr"), circuit)Records at several temperatures are cut separately, each with its own temperature, and tabulated together, which gives the tables a temperature axis.
The RC model
using DyadModelOptimizer
fits = calibrate_rc(pulses)
circuit = merge(Dict{String, Any}("open-circuit voltage" => ocv),
rc_tables(fits; soc = 0.1:0.1:0.9))The calibration is a DyadModelOptimizer calibration, loaded as a package extension by using DyadModelOptimizer (a JuliaHub package): each pulse is an Experiment of the package's RC cell driven by the measured current, with the measured voltage as its data, and an InverseProblem over the four groups of the cell's impedance that the record determines (below), from which the model writes the five elements, solved with calibrate by a DyadModelOptimizer algorithm (alg, SingleShooting by default and the only one tested). Each fit keeps the InverseProblem and the CalibrationResult, for DyadModelOptimizer's own analysis and plots. Each pulse is replayed from a relaxed cell, so a pulse that starts before the cell has relaxed — the regenerative pulse 40 s after the discharge pulse of a PNGV HPPC profile, for a cell with a slow time constant — is calibrated together with the pulse before it by passing the two as one entry, calibrate_rc([[discharge, regen], ...]).
A current and voltage record does not determine all five elements of the RC circuit. Its terminal impedance is that of the PNGV model, four numbers, and the fifth degree of freedom — how the capacitance divides between the bulk and the surface capacitor — is free within the range that keeps every element positive. calibrate_rc explains the consequence and how the ratio is chosen; each RCFit carries the PNGV elements too, which the record does determine uniquely when it shows a polarization (A > 0 in calibrate_rc's notation).
On a measured record the total capacitance is often not determined either: the rest voltage an 18 s pulse leaves behind moves by the charge drawn over the capacitance, a fraction of a millivolt for a cell of tens of ampere-hours. The capacitance keyword of calibrate_rc fixes it from the cell's capacity and the slope of its open-circuit voltage instead, C = 3600 Q / (dOCV/dSOC).
Relation to ADVISOR
The workflow keeps ADVISOR's pulse segmentation and its definition of the Rint resistance, and reproduces the per-pulse resistances batmodel derives from its Evercel sample data (the test suite checks all 35 pulses of the 32 °C set). It differs where ADVISOR's choices were not the model's:
- the resistance is divided by the pulse current itself rather than by its mean rounded to whole amperes;
- the RC calibration replays the measured current, which the package's cells take, rather than the measured power ADVISOR's blocks take, minimizes the squared voltage error rather than the mean absolute percentage error, and runs a DyadModelOptimizer calibration over a search space two decades either side of the starting point rather than 30 evaluations of a global optimizer searching ±10% around it;
- the starting point is read off the pulse in the four quantities the pulse determines, rather than split into five elements with ADVISOR's fixed ratios (see
rc_initial_guess); - the capacitance ratio the record leaves free is chosen explicitly rather than by the search box;
- tables are least-squares fits of their own interpolant instead of cubic polynomials in the open-circuit voltage, and the RC capacitances are tabulated as calibrated rather than averaged over the state of charge.