I want to implement a battery management system that simulates the internal behaviour of a cell (ECM), and controls the incoming current based on a voltage limit (here 3.8V). I’m trying to do this using ModelingToolkit.jl
and callbacks, but i always get the same error: ERROR: KeyError: key cell1₊i(t) not found
at prob = ODEProblem(sys, Pair[], tspan)
. Here’s the code:
using OrdinaryDiffEq
using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D
using Plots: plot, plot!
using DataFrames
using CSV
using DataInterpolations
using LinearAlgebra
using CairoMakie
using ModelingToolkitStandardLibrary.Electrical
using ModelingToolkitStandardLibrary.Blocks
using DiffEqCallbacks
soc_vec = range(0, 1.0; length=1000)
ocv_vec = range(2.5, 4.2; length=1000)
focv = LinearInterpolation(ocv_vec, soc_vec, extrapolation=ExtrapolationType.Constant)
t_vec = range(0.0, 24*3600; length=1000)
i_vec = rand(-10.0:10.0, 1000)
fi = ConstantInterpolation(i_vec, t_vec)
@mtkmodel ECM begin
@extend OnePort()
@parameters begin
Q
R0
R1
τ1
R2
τ2
end
@structural_parameters begin
focv
end
@variables begin
vr(t)
v1(t) = 0
v2(t) = 0
ocv(t)
soc(t) = 0.5
test(t)
end
@equations begin
D(soc) ~ i / (Q * 3600.0)
D(v1) ~ -v1 / τ1 + i * (R1 / τ1)
D(v2) ~ -v2 / τ2 + i * (R2 / τ2)
vr ~ i * R0
ocv ~ focv(soc)
v ~ ocv + vr + v1 + v2
test ~ ifelse(v > 3.8, 0, i)
end
@discrete_events begin #BMS
(v >= 3.8) => [i ~ 0]
(v < 3.8) => [i ~ i]
end
end
@mtkmodel Series_Connection begin
@components begin
cell1 = ECM(
Q=4.8,
R0=15e-3,
R1=15e-3,
τ1=60.0,
R2=15e-3,
τ2=600.0,
focv=focv,
)
source = Current()
ground = Ground()
end
@structural_parameters begin
fi
end
@equations begin
connect(cell1.p, source.p)
connect(source.n, cell1.n, ground.g)
source.i ~ -fi(t)
end
#= @discrete_events begin
(cell1.v >= 3.8) => [source.i ~ 0]
(cell1.v < 3.8) => [source.i ~ -fi(t)]
end=#
end
@mtkbuild sys = Series_Connection(; fi)
tspan = (0, 24 * 3600)
prob = ODEProblem(sys, Pair[], tspan)
sol = solve(prob; saveat=1.0)
I also tried implementing the callback in the Series_Connection
block but I get the same error.
I’d rather use @continuous_events but I can’t find a way to set the conditional v>=3.8V other than with @discrete_events.
In general, I need the current of the ECM model to behave as the test
variable. Any ideas on how can I make it work?