☰
锂电池二阶RC模型MATLAB/Simulink仿真复现与参数辨识实践
2026/10/21 17:14:00 网站建设 项目流程

先交代一下背景。我之前接到一个活儿,要把一篇关于锂电池充放电模型的论文完整复现出来,工具是MATLAB/Simulink。这篇论文里既有等效电路模型的推导,又有参数辨识实验,最后还有仿真对比曲线。听上去不复杂,但真做起来,从读论文、选模型结构、做HPPC测试、辨识参数,到把方程变成Simulink模块,每一步都有坑。

这篇博文就把整条路重新走一遍,把我踩过的坑、试过的方案、最后稳定的做法都写出来。内容主要面向三类人:正在做电池方向毕业设计或课程设计的学生、刚接触电池管理系统仿真的工程师、以及想通过复现论文来掌握锂电池建模方法的研究者。我会尽量把每一步的操作细节都交代清楚,参数怎么定、模块怎么连、问题怎么查,不说废话。

1. 课题拆解:论文复现到底在复现什么

1.1 从标题里扒出三层信息

"论文复现---实现锂电池充放电模型,matlab/simulink仿真"这个标题,信息量其实非常大。拆开看就是三层:

第一层是"论文复现"。这个词意味着你面前有一篇具体的论文,里面有一个完整的电池模型,可能是等效电路模型,也可能是简化的电化学模型,还有一套实验方法。你要做的事情不是从零设计一个电池模型,而是把作者在论文里用文字、公式和曲线描述的内容,变成一份可以运行的仿真代码。

第二层是"锂电池充放电模型"。这决定了模型必须具备动态响应能力:电流变化时端电压怎么变、放电结束后电压怎么慢慢回升、SOC(荷电状态)怎么随着电流积分累加或减小。静态的电压源加内阻是不够的,必须能够在多种工况下复现电池的电压行为。

第三层是"MATLAB/Simulink仿真"。这限定了工具链和最终交付形式。也就是说,你不仅要把数学模型推导出来,还要把它落到Simulink的模块图上,跑出曲线,并且最好能和论文里的实验曲线对上。

这三层信息其实也框定了工作量:先读完论文把模型写出来,再做或找一批实验数据把参数估出来,最后在Simulink里搭出模型跑出结果。任何一个环节出问题,后面都会很痛苦。

1.2 我选的复现路线

我最后采用的是下面这条路线,也是我认为在日常复现中最稳的路径:

先不急着打开Simulink,而是把论文里的模型结构看明白。是Rint模型、一阶RC、二阶RC还是PNGV,这直接决定你后面写什么微分方程、辨识几个参数。模型结构一旦选错,后面所有工作全部白费。

确定结构之后,开始准备参数辨识数据。如果论文里没有公开原始实验数据,最现实的办法是自己找一块电池做HPPC混合脉冲功率特性测试,或者从课题组已有的测试数据里拿一段能用的放电静置曲线。数据质量决定了辨识结果的可靠程度。

接下来就是用MATLAB脚本拟合参数。这一步不涉及Simulink,主要用lsqcurvefit这类优化函数把内阻、极化电阻、极化电容这些值从电压曲线上扒出来。

最后才进入Simulink建模。按照状态方程把积分器、增益、查表模块连起来,接上一个电流工况输入,跑仿真,再拿真实数据和仿真曲线做对比。

这个顺序有一个好处:每一步都有明确的中间产物,模型的物理含义始终没有被那一堆模块连线掩盖掉。出现偏差时,也能快速定位是参数辨识的问题,还是模型本身的问题,还是仿真搭建的问题。

2. 模型选型:为什么我从一阶RC起步,最终停在二阶RC

2.1 Rint模型最大的问题不是太简单,而是解释不了电压回弹

先说说谁都能想到的最简单模型——Rint模型,就是一个开路电压源串联一个内阻R。公式很简单:

V(t) = OCV(SOC) - I(t) × R

OCV随SOC变化,放电时电流是正的,端电压等于开路电压减去电流乘内阻。

这个模型在恒定电流下的表现还不错,用来估SOC大概也能用,但它有一个天然的缺陷:一旦电流突然切断,端电压当场就跳回OCV。真实电池根本不是这样,你把放电电流撤掉,电池电压会先快速回升一小截,然后继续缓慢往上爬,可能要几十秒甚至几分钟才能接近开路电压。这个现象叫极化松弛,本质上是电池内部的极化效应需要一个缓冲过程才能消失。Rint模型完全没有这个机制,所以它无法反映充放电切换瞬间的电压行为,而论文里的充放电模型一般都要刻画这个过程。

2.2 一阶RC模型带来的"电容缓冲"

于是就有了RC等效电路模型。最常见的是一阶RC模型,结构是:OCV电压源、一个欧姆内阻R0、一个由R1和C1并联组成的RC网络串联在一起。数学表达为下面两个方程:

V(t) = OCV(SOC) - I(t)×R0 - U1(t)

dU1/dt = -U1/(R1×C1) + I/C1

这里的U1是RC并联网络两端的电压,也就是极化电压。这个RC环节最有意思的地方在于它对电流起了一个"缓冲"作用。电流突然消失时,C1上的电荷不会瞬间放光,而是通过R1慢慢泄放,所以U1是缓慢回落的,端电压也就出现了平滑回升。

理解RC可以打一个比方:电池内部的极化就像一块刚吸足水的海绵,放电时海绵被挤压吸收了一部分"电荷势能",当你停止挤压,海绵不会立刻弹回松软状态,而是慢慢释放。R1×C1这个乘积,也就是时间常数τ1,控制了这个回弹的快慢。τ1等于几秒,就表示电压回弹的前段大概在几秒内完成。

一阶RC模型的好处是参数少,只需要R0、R1、C1加上OCV-SOC关系,前三个参数都可以从一次脉冲放电静置实验里辨识出来。对很多简单工况仿真,一阶RC已经够用。

2.3 二阶RC模型解决多时间尺度极化问题

我最初图省事,直接用一阶RC搭了模型。但当我拿真实的脉冲实验数据去对比时,问题出现了:放电结束后电压回弹曲线的后半段,一阶RC模型明显跟不上实测,仿真曲线回弹得太快,后面平滑段差出几十毫伏。

原因很明确:电池里的极化现象不是单一时间尺度的。放电停止后的电压恢复,往往可以拆成两个叠加的指数过程,一个几秒到十几秒的快速过程,对应电荷转移极化;另一个几十秒到几分钟的慢速过程,对应浓度差极化。一条指数衰减曲线拟合不了两个时间尺度,必须再加一组RC。

二阶RC模型的方程变成:

V(t) = OCV(SOC) - I(t)×R0 - U1(t) - U2(t)

dU1/dt = -U1/(R1×C1) + I/C1

dU2/dt = -U2/(R2×C2) + I/C2

其中一组RC的时间常数小,负责刻画快速回弹段;另一组时间常数大,负责拖住后半段缓慢收敛的过程。你可以理解成电池里既有一块"快海绵"又有一块"慢海绵",放电结束后它们各自按自己的速度回弹,叠加在一起就是实测的那条完整的回升曲线。

复现论文模型时,只要论文里用的是二阶RC,就一定要老老实实把两个RC环节都做进去,不要嫌麻烦只搭一阶,否则和论文曲线对不上的时候,你会很难受。

2.4 阶数选择的工程权衡

为什么不干脆用三阶、四阶RC,或者直接上P2D电化学模型?

模型阶数越高,越能逼近真实的极化过程,但代价也很明显:参数辨识的难度直线上升。每增加一组RC,就多出一组R和C需要从曲线里分离出来,拟合时的初值敏感度会变高,稍微给一个差一点的初值,辨识结果就可能漂到物理上完全不可信的值。

P2D这种电化学模型虽然精度和可解释性都很高,但涉及十几个参数、大量偏微分方程耦合求解,计算量非常大,根本不适合在Simulink里做快速仿真复现。对于多数论文复现场景,二阶RC是精度和可操作性平衡得最好的选择。

3. 参数辨识实操:没有HPPC测试数据就别谈精度

3.1 HPPC测试的基本流程

参数辨识用的数据来自HPPC测试。简单说,就是在特定的SOC点,给电池施加一个"脉冲电流序列":先恒流放电一小段时间,静置,再恒流充电一小段时间,再静置。通过观察电流突变前后的电压变化,以及静置阶段电压的回弹曲线,就能把R0、R1、C1、R2、C2一个个挤出来。

我在复现时采用的流程是这样:

电池充满电后静置1到2小时,让电压回到真正的平衡态。然后放掉一部分容量,把SOC调整到目标点,比如90%、70%、50%、30%、10%这几个点,每个点都先静置足够长时间,再开始做脉冲。

脉冲式样的选型方面,我参考了电池测试里比较常见的做法:先以恒流放电10秒,然后静置40秒,再以相同的电流恒流充电10秒,接着静置40秒。放电倍率我取的是1C左右,这样信号幅度够大,电压响应明显,辨识出来的参数信噪比高。

3.2 从电压响应曲线上读取R0

脉冲测试曲线非常直观。放电电流刚加上去的那一瞬间,端电压会掉一截。这个瞬间的压降里几乎只有欧姆内阻的贡献,因为RC网络的电容还没来得及建立极化电压。读出这个电压跳变ΔV,再除以电流突变ΔI,就得到欧姆内阻R0。

R0 = ΔV / ΔI

实际操作中有两个小坑。

第一,电压跳变非常快,如果采样频率太低,比如一秒采一个点,往往捕捉不到完整的突降,导致R0偏大。我后面把采样频率调到了100Hz以上,每个脉冲段至少能拿到几十个点来确认突降幅度。

第二,放电瞬间的R0和充电瞬间的R0不完全一样,有时候差10%以上。因为正负极的反应路径和导电网络状态有差异。如果模型精度要求高,就分别辨识一个放电R0和一个充电R0,在Simulink里根据电流方向切换参数。

3.3 用最小二乘拟合RC极化参数

RC参数的辨识主要利用静置段。静置开始后,电流为零,端电压从放电结束点的电压慢慢回升。此时OCV基本不变,端电压和OCV的差值可以看作是两个RC电压U1、U2按各自时间常数衰减的叠加。

对应的拟合关系是:

V(t) = OCV - U1(0)×exp(-t/τ1) - U2(0)×exp(-t/τ2)

其中U1(0)和U2(0)是静置开始瞬间两个极化电压的初始值。

在MATLAB里,我直接用lsqcurvefit来做指数拟合。大致代码是这样:

t = t_rest; % 静置时间 V = V_rest; % 静置电压 ocv = V(end); % 静置末电压作为OCV近似 fun = @(x, t) ocv - x(1)*exp(-t./x(2)) - x(3)*exp(-t./x(4)); x0 = [0.15, 5, 0.05, 60]; % 初值:快极化电压0.15V/时间常数5s,慢极化电压0.05V/时间常数60s opts = optimset('Display', 'off'); x = lsqcurvefit(fun, x0, t, V, [], [], opts); U1_init = x(1); tau1 = x(2); U2_init = x(3); tau2 = x(4);

拟合出时间常数之后,还需要把R和C分开。这要用到静置开始瞬间的关系:

稳态下,放电未结束瞬间,U1满足U1_init = I×R1,U2同理。因此在电流I已知的情况下:

R1 = U1_init / I,C1 = tau1 / R1

R2 = U2_init / I,C2 = tau2 / R2

这个方法简单实用,前提是静置时间足够长,OCV那块取最后一点才靠谱。静置40秒对慢时间常数来说可能还不够,有些电池的慢极化过程长达几分钟,我在做的时候从40秒加到120秒,后半段拟合才稳定下来。

3.4 OCV-SOC曲线的建立

OCV和SOC的关系是电池建模的基础。获取方法很直接:在每个SOC点做完HPPC脉冲之后,静置足够长的时间,把最终的稳定电压记下来,就是该SOC下的OCV。

我拿到一组OCV-SOC散点后,把它整理成一个查表向量,存成数组后在Simulink里用一维查表模块输入。不建议只做一个低次多项式拟合,因为大倍率OCV-SOC曲线两端弯曲明显,多项式阶数不够会在低SOC段产生几十毫伏偏差,阶数太高又容易过拟合。

需要注意OCV迟滞:充电过程和放电过程测得的OCV-SOC曲线不完全重合,中间会有一个迟滞带。复现论文时一定要确认清楚作者用的是标准OCV、放电OCV还是充电OCV。如果论文没说,就用多次静置后取平均的标准OCV,然后在误差分析里提一下这个不确定性。

3.5 参数随SOC变化的处理

R1、C1、R2、C2在不同SOC点并不相同,尤其是在SOC低于20%的区间,慢极化时间常数会明显变大。如果全SOC范围都用一组固定参数,模型在两端会出明显偏差。

我的做法是:在每个SOC点都做一次完整的HPPC辨识,把R1、C1、R2、C2分别建立成关于SOC的查表数组,Simulink里的增益参数通过查表动态获取。这样模型在SOC从90%跌到10%的过程中,参数会跟着切换,精度整体可控。

如果时间和数据量有限,至少也要选SOC在50%附近的一组参数做单点标定,保证中间SOC区间精度,然后再说明两端误差较大的原因。

4. Simulink建模全流程:从积分器到子系统封装

4.1 模型总体的数据流

在Simulink里搭这个模型,我的原则是:不自找麻烦,每一个物理量都对应到一个明确的模块和信号线,让模型图本身就能讲清楚电池的工作原理。

整体数据流可以这样理解:电流I是整个模型唯一的输入信号。它同时走向三条路径:第一条路径对时间积分得到SOC;第二条路径经过一个查表得到当前SOC对应的OCV;第三条路径经过两组受控电压源或者说两个RC子系统,产生极化电压U1和U2。最后,把OCV减去欧姆压降I×R0,再减去U1和U2,就是端电压V。

信号流一旦清晰了,后面模块怎么连就非常自然。

4.2 SOC积分模块和单位换算

SOC是一个积分量,核心公式是:

SOC(t) = SOC0 - (1/(Qmax×3600)) × ∫ I dt

注意中间这个单位换算。电池容量Qmax通常以安时Ah为单位,而仿真里的时间单位是秒,电流单位是安培。1Ah等于3600安秒,所以计算时要把Qmax乘3600转成安秒,再放到分母上,积分结果才是无量纲的SOC。

因此我这里用了一个Gain模块,增益为-1/(Qmax*3600),接在电流信号后面,再进积分器。积分器初始值设成SOC0。比如初始SOC是90%,就在积分器初值一栏填0.9。

SOC是0到1之间的数,保险起见在积分器后面加一个Saturation模块把范围限死在0和1之间。如果积分器设置了输出上限,也把上限、下限分别设成1和0。

4.3 RC状态方程的Simulink接线方式

二阶RC模型有两个完全对称的RC子系统。我这里以一个RC环节为例说明接线,另外一个复制改参数即可。

方程是:

dU1/dt = -U1/(R1×C1) + I/C1

映射到Simulink里其实就三个运算:

电流I先乘一个增益1/C1,得到一个输入项。U1经过反馈路径乘一个增益-1/(R1*C1),得到另一个输入项。两项相加后进入一个积分器,积分器输出就是U1。

这里有一个很关键的细节:反馈增益要用U1本身来算,但U1又是积分器的输出,形成一条反馈回路。回路里因为有积分器这个状态存在,不会被判定为代数环,Simulink能正常处理,不需要额外加Memory模块。

完成两个RC子系统后,再用一个Sum模块把电压合成:

V = OCV查表输出 - I×R0 - U1 - U2

搭建时建议把OCV查表、两个RC子系统和端电压合成各放一个子系统层,不要全部摊在一个模型里。这样图面清楚,后面的参数调整也会方便很多。

4.4 用初始化脚本管理参数

模型里的电阻、电容、容量这些参数如果直接在模块里写数字,后面辨识完参数要改的时候,要翻到每个模块里去改,非常容易漏。更推荐的做法是:所有参数都写成变量名,通过一个MATLAB初始化脚本统一赋值。

我建立了一个init_battery.m脚本,大致结构是:

% 电池基础参数 Qmax = 2.0; % Ah SOC0 = 0.9; % 初始SOC % 欧姆内阻 R0 = 0.055; % 欧姆,放电方向 R0_chg = 0.060; % 欧姆,充电方向 % SOC断点 soc_break = [0, 0.1, 0.3, 0.5, 0.7, 0.9, 1]; % RC参数表 R1_table = [0.045 0.042 0.038 0.036 0.034 0.033 0.035]; C1_table = [1200 1500 2200 2600 2800 2500 1800]; R2_table = [0.08 0.06 0.038 0.03 0.026 0.024 0.03]; C2_table = [3800 5200 7500 9500 12000 11000 6000]; % OCV-SOC表 ocv_table = [3.20 3.35 3.60 3.72 3.85 4.0 4.18];

脚本放在模型同一目录,每次修改参数后运行一遍,Simulink再按新参数跑仿真,整个过程顺畅很多。

4.5 求解器选择与仿真步长设置

Simulink里求解器设置影响很大,特别是涉及脉冲工况的时候。

我用的方案是:变步长、代数求解器采用自动、最大步长设置在0.1秒或更小。纯恒流放电工况对步长不敏感,但脉冲放电的电流突跳瞬间,如果步长太大,电压跳变段会被平滑掉,和实验曲线对比时对不上。

如果模型里有查表模块,而且是分段线性的,建议使用ode45,一般能快速跑完。遇到代数环报错或数值发散,再切换到ode15s,这个刚性求解器在很多电池模型里都更稳。

另外,输出数据建议通过To Workspace模块存成结构体或者时间序列,方便在MATLAB里算RMSE和画图对比。

5. 充放电工况仿真与结果分析

5.1 恒流放电工况

先把最常用的恒流放电跑一遍。以2Ah电芯为例,用2A电流放电,大约1C倍率。预期SOC从90%开始线性下降,端电压也缓慢下降。

在实际仿真里,一阶RC和二阶RC在恒流放电中段差别不大,但到了末端,二阶RC因为慢极化环节的存在,压降更明显,也更接近真实电池的"电压悬崖"现象。

跑完之后把仿真端电压和实测端电压画到同一张图,就能直观看出模型准不准。我用均方根误差RMSE来量化:把仿真电压和实测电压都重采样到相同的时间网格,然后计算差值的均方根。对于我复现的电池,恒流工况下二阶RC的RMSE能控制在12毫伏左右,一阶RC则要到40毫伏以上。

5.2 脉冲充放电工况

脉冲工况是更苛刻的验证场景。把HPPC中的那段脉冲电流作为仿真输入,重点观察静置阶段的电压回弹曲线和突跳瞬间的落差是否和实验一致。

这一轮最能检验二阶RC的价值。实测曲线在放电停止后先快后慢地回升,二阶RC用两组时间常数叠加,能够把这个回升过程还原得很接近。一阶RC只会有一个时间常数,回升到后面就明显"对不上了"。

我复现后的典型精度对比大概是这样:

模型恒流放电RMSE脉冲工况RMSE
一阶RC42mV45mV
二阶RC12mV18mV

需要说明的是,脉冲工况误差的主要来源在低SOC区间,特别是SOC低于20%时,参数变化剧烈,慢极化时间常数和OCV曲线斜率的误差都会被放大。如果论文只给了全工况的整体精度,没有分区间讨论,复现报告里可以自己补充这部分分析。

5.3 模型泛化能力检验

有一个很常见的错误:用辨识参数的那组数据去验证模型,结果好得一塌糊涂,就以为模型已经完美了。实际上这只能证明模型"拟合"了那组数据,不能证明它能"预测"新的工况。

我在复现时把已有的充放电测试数据分成两份,一份专门用来辨识参数,另一份完全没参与过辨识,只用来看模型预测效果。这样做之后发现模型的预测精度比拟合精度差一截,但这是真实水平。

论文复现的底线是模型结构、参数辨识方法和验证结果三者自洽。与其为了曲线好看而过拟合,不如把真实误差摆在明面上。

6. 常见问题速查与排查记录

6.1 代数环错误

我在做带功率输入的工况仿真时,遇到过代数环。典型场景是当前时刻的电流由当前时刻的功率除以当前时刻的电压得到,而电压又反过来依赖电流,Simulink就会提示存在代数回路。

解决办法有三种:如果电流输入是外部给定的时序信号,就不要让它依赖端电压,从信号流上切断环路;如果必须依赖,在反馈回路上插入一个Memory模块或者Unit Delay,让当前时刻的电压用上一时刻的值计算;实在绕不开时,把求解器设置里的Algebraic Loop Solver打开,让Simulink自行迭代求解,但这种方式会增加仿真时间,而且遇到高速脉冲时容易不稳定。

6.2 仿真发散或NaN

刚把模型搭好时,仿真经常直接飘到上千伏或者输出NaN。这种问题十有八九是从参数单位上出的。最常见的是容量单位写错,把Ah当成了安秒,导致SOC积分量级错了1000倍还多;另一种是电容C1写了法拉数量级但实际该是千法拉级别,模型动态就变得极其敏感。

处理方法是先看积分器输出,确认SOC在合理范围;再查R、C的数量级。放电10秒引起的极化电压大致等于I×R,如果R是0.05欧姆、电流10A,极化电压应该在0.5伏这个量级,差太多就说明参数有误。

6.3 Lookup Table越界

如果SOC因为初始条件或者积分误差跑出了[0,1]区间,一维查表模块会报错或者给出错误的边界外推值。解决方法是给查表模块设置extrapolation方式为clip,让超出边界的SOC都按边界值处理。同时,给积分器加上输出饱和限制,双保险。

6.4 参数辨识拟合不收敛

用lsqcurvefit做指数拟合时,如果初值给得太离谱,容易收敛到一组物理上没有意义的参数。我的经验是:先直接从曲线上估算初值。放电结束瞬间的电压差大概就有几百毫伏,而纯欧姆压降只占一小部分,剩下的可以分配给两个RC初始电压。时间常数初值则可以直接按"回升曲线的快段大约5秒、慢段大约60秒"这个量级去设。

另外,静置时间不足、采样频率太低都会让拟合结果不稳定。遇到拟合结果一天一个样,就去检查数据采集质量,不要先怀疑算法。

快速诊断参考如下表:

现象最可能原因排查方向
电压突跳不对R0辨识不准采样频率低,或用了充电R0替代放电R0
回升前半段对不上快速RC参数有误检查电流脉冲段时长是否太短,快速极化没建立完全
回升后半段对不上慢速RC参数有误静置时间不够,OCV取点偏高,慢时间常数虚大
低SOC端模型失真参数表稀疏在SOC低端增加测试点,或改用更密的查表断点
仿真曲线毛刺多步长过大缩小最大步长或切换到固定步长+输出等间隔模式

7. 个人复盘和经验总结

复现论文这件事,难的地方从来不是"把模型跑起来"。搭一个能画出漂亮曲线的Simulink模型,半天就能搞定。真正花时间的是反复确认每一个参数的来源、每一个公式的前提条件,以及在误差不合理时判断到底该改参数还是该怀疑模型结构。

我在这次复现中体会最深的一点是:论文里的模型往往是在理想条件下推导的,作者省略了大量工程细节。比如温度恒定、SOC区间限制、充放电内阻差异等等。这些前提条件,论文可能只有一句话,甚至不提。复现者如果不意识到这些隐含边界,就很容易在高偏离条件下得到离谱结果,然后误以为论文有误。

如果再往后扩展,这个二阶RC模型还可以加温度依赖参数、老化循环修正,甚至接到一个简单的电池均衡策略里做系统级仿真。不过对于刚起步的人来说,先把充放电模型本身吃透,比追求复杂模型重要得多。

最后再分享一个小技巧:无论论文数据是否完整,都坚持把辨识数据和验证数据分开。模型在一个数据集上拟合精度再高都不算数,能在没有参与拟合的数据上依然保持稳定预测,才说明你这个复现是真的把模型做明白了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询