开篇先交代背景:做储能系统开发,仿真这一关迟早要过。我刚接触液流电池那会儿,想快速验证一套基础的储能管理逻辑,结果发现市面上资料大多停在“原理图+公式”层面,真正能把Simulink模型一步步搭起来、跑出充放电曲线的实操内容很少。后来我花半天时间,用Simulink搭了一个基础储能管理场景下的液流电池储能系统充放电特性仿真模型,跑通了充电、放电全周期,把SOC、端电压、极化电压都导出来分析了一轮。这篇就把整个建模过程掰开讲,包括等效电路怎么选、参数怎么定、模块怎么连、为什么要这么连,以及仿真发散、SOC漂移这些典型坑怎么排查。适合想用Simulink做电池储能仿真的入门学员,也适合想快速拿一个电池模型去验证BMS策略的工程师。
1. 为什么选液流电池和Simulink来做储能仿真
1.1 液流电池储能系统的特点
液流电池,尤其是全钒液流电池,跟日常接触的锂电池在储能管理上有明显差别。它把活性物质溶解在电解液里,电解液存在外部储罐,通过泵送进电堆发生反应。这意味着功率由电堆面积决定,容量由电解液体积决定,两者解耦,适合大规模长时储能。但也正因为有泵、有循环、有电堆流体分布,它的电气特性比锂电池更“软”:极化过程时间常数大,开路电压(OCV)对SOC的响应比较平缓,在SOC两端又会出现明显陡变。这些特性决定了一个好的液流电池仿真模型,不能简单拿锂电池的RC参数直接充数,而是要体现它的时间常数和电压平台特征。
本次仿真的价值在于:把液流电池最核心的外特性——充放电过程中端电压随SOC和电流的变化——先用一个可控、可调的Simulink模型复现出来。有了这个基础模型,后面无论是做电池管理系统(BMS)的SOC估算验证,还是做储能系统的功率调度,就有了一个不跑偏的“电源内核”。
1.2 Simulink做储能仿真的优势
很多人在“用什么工具搭电池模型”上犹豫,或者用Python手推方程,或者在Simscape Electrical里拉物理模型。我的建议是:如果你想快速验证控制策略,同时又能看清每一步信号流动,Simulink的模块化建模是效率最高的一种方式。
原因有三点。其一,Simulink天然把数学方程变成可视化信号流,不用写一大段求解代码,给谁看都能理解SOC积分、欧姆内阻、极化RC网络之间的因果关系。其二,它和MATLAB脚本无缝配合,参数写在脚本里,模型里所有Gain、Lookup Table直接引用工作区变量,改参数只需要改一处,不用满模型翻。其三,变步长求解器可以自动处理充电转放电时的电流跳变,比固定步长仿真稳定得多,这一点在后面排查问题时会深有体会。
1.3 建模范围与假设
我们要搭的是“特性仿真模型”,不是微观电化学模型。因此先明确边界,不碰电解液浓度场、不碰电堆流体动力学、不碰温度变化。模型采用一阶RC等效电路:一个受SOC控制的电压源,串一个欧姆内阻,再并联一个极化RC网络。电流作为输入,电压作为输出,SOC通过安时积分得到。
这样做能覆盖储能管理场景里最关心的三个量:SOC、端电压、充放电功率。它也足够解释为什么充电时电压会逐渐升高、放电时电压会逐渐下降,为什么电流突变后电压会有“弹跳”现象。实际工程中如果要加入泵损、自放电、温度系数,可以在当前模型上继续叠加,而不是推翻重来。
2. 模型的整体架构与参数设计
2.1 一阶RC等效电路原理
液流电池在电气上可以等效成下面这个结构:
- 受控电压源 (E_{ocv}),数值由SOC决定;
- 串联电阻 (R_0),代表电解液、隔膜和接触电阻引起的欧姆压降;
- 极化网络 (R_p) 和 (C_p) 并联,代表电化学反应过程中的浓度极化和电荷转移极化。
对应的电气方程是:
[ V_t = E_{ocv}(SOC) - I \cdot R_0 - V_p ]
其中极化电压 (V_p) 满足:
[ \frac{dV_p}{dt} = \frac{I}{C_p} - \frac{V_p}{R_p C_p} ]
而SOC的安时积分方程为:
[ SOC = SOC_0 + \int \frac{I}{3600 \cdot Q} dt ]
这里 (Q) 是额定容量,单位Ah,电流单位A,时间秒。注意约定:充电电流为正,放电电流为负。
用生活化的话说,欧姆内阻就像水管里的摩擦阻力,电流一上来立刻引起压降,没有延迟;RC网络就像一个大水池,电流变化后水位要慢慢涨或者慢慢落,反映到电池上就是极化电压的建立和消退需要时间。液流电池的“水池”特别大,所以极化时间常数通常比锂电池长得多,可能在几十秒到几分钟量级。这个特性必须体现在RC参数里。
2.2 OCV与SOC的关系
液流电池的开路电压和SOC不是线性关系。全钒体系下,接近SOC=50%时电压平台比较平,而SOC低于10%或高于90%时电压会快速跌落或爬升。在Simulink里最方便的建模方式是用一维Lookup Table,直接以SOC为输入、OCV为输出,中间线性插值。
我用的数据点是参考典型全钒液流电池单堆设定的,为了四舍五入把额定电压做成了48V左右:
| SOC | OCV / V |
|---|---|
| 0.0 | 42.0 |
| 0.1 | 43.0 |
| 0.2 | 44.5 |
| 0.5 | 48.0 |
| 0.8 | 51.5 |
| 0.9 | 52.5 |
| 1.0 | 54.0 |
在实际项目里,这些数据应该来自电池厂家的特性测试表,或者你自己做一次小电流恒流充放电实验,取静置后的端电压作为OCV。仿真时先用近似表验证逻辑,等拿到实测数据再替换即可。
这里有一个容易犯的错误:把充放电曲线直接用成OCV-SOC关系。真实液流电池存在充放电历史带来的“电压回滞”,同一个SOC下充电后的开路电压和放电后的开路电压可能差几伏。为了让入门模型简单,我暂时忽略回滞,用同一条曲线。这个假设会在6.3节说明如何扩展。
2.3 参数计算与模块化拆分
模型需要的参数如下表,全部放在MATLAB脚本里,Simulink模型通过变量名引用。
| 参数/模块 | 数值 | 说明 |
|---|---|---|
| 额定容量 (Q) | 20 Ah | 代表一个中等容量电堆模块 |
| 初始SOC (SOC_0) | 0.1 | 仿真从低电量开始充电 |
| 欧姆内阻 (R_0) | 0.08 Ω | 由直流阶跃响应的瞬时压降除以电流得到 |
| 极化电阻 (R_p) | 0.05 Ω | 反映极化稳态电压与电流的关系 |
| 极化电容 (C_p) | 1800 F | 极化时间常数 (R_p C_p=90s),符合液流电池慢极化 |
| 充电电流 | +5 A | 对应0.25C,常规储能倍率 |
| 放电电流 | -5 A | 4小时完放 |
| SOC积分系数 | (1/(3600 \cdot 20) = 1.3889\times10^{-5}) | 把安时积分变成SOC百分比 |
这里参数怎么来的做个简单解释。假设一个电堆在10A电流下,欧姆压降是0.8V,那 (R_0=0.08Ω)。极化电阻可以用“电流突变后电压稳态变化量减去欧姆压降,再除以电流”估算。极化电容则由实测电压响应时间常数反推,如果响应时间约90秒,而 (R_p=0.05Ω),那么 (C_p=1800F)。第一次建模可以先用这些估算值跑通,再根据实际曲线调整。
模块化方面,我建议把整个模型分成三层:信号输入层、电池本体层、测量输出层。输入层负责产生电流指令;本体层实现SOC积分、OCV查询、欧姆压降和RC极化;输出层记录数据并画曲线。这样后续要替换成锂电池模型,只需要改本体层,输入输出接口不变。
3. 手把手搭建Simulink充放电仿真模型
3.1 用脚本准备好电流输入信号
在Simulink里给电流源输入,我习惯用MATLAB脚本生成timeseries,再拖一个From Workspace模块读取。这样比在Simulink里手动定义信号更清晰,也方便批量改充放电时长。
% 液流电池仿真参数 Q = 20; % 额定容量,Ah SOC0 = 0.1; % 初始SOC R0 = 0.08; % 欧姆内阻,Ohm Rp = 0.05; % 极化电阻,Ohm Cp = 1800; % 极化电容,F K_soc = 1 / (3600 * Q); % SOC积分系数 % OCV-SOC 查找表 SOC_pts = [0 0.1 0.2 0.5 0.8 0.9 1.0]; OCV_vals = [42 43 44.5 48 51.5 52.5 54]; % 电流指令:前4h充电5A,后4h放电-5A % 注意Simulink时需要严格单调时间戳 t_i = [0, 4*3600, 4*3600, 8*3600]; i_vals = [5, 5, -5, -5]; i_bat = timeseries(i_vals, t_i);如果是老版本MATLAB,可能不支持timeseries直接作为From Workspace输入,可以用结构体:
i_bat.time = t_i; i_bat.signals.values = i_vals'; i_bat.signals.dimensions = 1;3.2 新建模型与基础配置
在MATLAB工具栏点Simulink,新建空白模型,保存为vrfb_model.slx。
打开模型设置(Model Settings),重点配置两个地方:
- 仿真时间:Start time填0,Stop time填
8*3600,也就是28800秒。 - 求解器:Solver选择
Variable-step和ode15s。虽然本模型本身不算刚性,但后续如果要加泵、加热、电力电子开关,ode15s的鲁棒性更好。更重要的是,把Max step size设置成20秒。
为什么要限制最大步长?因为电流在4小时那一点从+5A瞬间跳到-5A,如果求解器步长太大,可能直接跨过切换点,导致电压曲线在切换处出现明显畸变。设20秒,既能准确捕捉切换瞬间,也不至于像固定步长1秒那样跑得慢。对于RC时间常数90秒的极化网络,20秒步长可以保证每个时间常数至少采样4个点,足够描述极化响应。
3.3 搭建电池本体电路
进入模型编辑区,按下面顺序添加模块,我用的是纯Simulink基础模块,不依赖Simscape,因此任何带Simulink的版本都可以直接复现。
第一步,从Sources库拖一个From Workspace,模块参数里的Data填i_bat,输出就是电流信号。双击模块,确认Output data type选timeseries。
第二步,拖一个Gain,模块参数Gain填K_soc,把电流乘以SOC积分系数。再拖一个Integrator接在Gain后面,初始条件(Initial condition)填SOC0。这样积分器输出就是SOC。
第三步,拖一个Lookup Table (1-D)。双击打开,Breakpoints填SOC_pts,Table data填OCV_vals。输入端接Integrator的SOC输出,输出就是当前SOC对应的开路电压。
第四步,处理欧姆内阻压降。从From Workspace的电流输出再接一根线,经过Gain,Gain填R0,得到I*R0。稍后会在总电压里减去这一项。
第五步,搭极化RC网络。电阻(R_p)和电容(C_p)并联,在Simulink里的信号流实现是:电流(I)分流成两部分,一部分流经(R_p),另一部分给(C_p)充电。对应方程为(I = V_p/R_p + C_p dV_p/dt)。模块连接方式如下:
- 电流信号连接到第一个Gain,Gain填
1/Cp,进入一个Sum的第一个正端; - 电流信号同时连接到第二个Gain,Gain填
1/Rp,输出也进入同一个Sum的负端,作为反馈; - Sum的输入端还有一个项是
V_p经过Gain填1/(Rp*Cp)得到,也进负端; - Sum的输出经过Integrator得到
V_p,再把这个V_p引出,一路做反馈,一路送总电压减法。
用方程表示就是:
[ \frac{dV_p}{dt} = \frac{I}{C_p} - \frac{V_p}{R_pC_p} ]
第六步,计算端电压。拖一个Sum,输入符号设置为++-顺序:OCV正输入,V_p负输入,I*R0负输入。输出就是端电压V_t。
如果你想要一个更清爽的界面,可以把电池本体部分用Subsystem封装,外面只露出电流输入和两个输出:SOC和V_t。但首次搭建建议先不封装,直接把信号线放在顶层,方便看清每条信号走向。
3.4 配置充放电控制逻辑与负载
本次仿真的电流指令是开环恒流,没有闭环控制。实际上储能管理场景里,电流指令来自上层的充放电策略或者BMS。这里用From Workspace模拟这个外部指令,相当于我们把一个预设的恒流阶段表喂给了电池模型。
如果想增加“电压截止”逻辑,可以在输出端加一个Switch模块:当电池端电压超过上限(比如55V)时,电流指令切换为0;当低于下限(42V)时,停止放电。但入门阶段建议先不加,因为闭环逻辑引入后,不好判断是电池模型问题还是控制逻辑问题。我的做法是先用纯恒流跑出充放电特性曲线,确认模型对了,再叠加控制逻辑。
如果你实在想在同一个模型里看完整充放电周期,还可以用Signal Editor模块替代From Workspace,图形化编辑电流波形,从左边的Sources库拖入,双击打开界面,画出两段阶跃即可。这个操作更直观,适合不习惯写脚本的人。
3.5 添加测量与功率计算
为了分析充放电特性,除了电池本体,还要把测量和功率计算模块加上。
拖两个Scope,分别接V_t和SOC。如果想同时看电流、端电压、SOC,可以拖一个Mux,把三个信号合并进同一个Scope。
功率计算用Product模块,两个输入分别是V_t和电流I,输出就是瞬时功率(P=V_t \cdot I)。注意这个功率在充电时为正(吸收功率),放电时为负(放出功率)。储能管理场景中,“功率为正”代表处在充电状态,这点要和习惯上“负载耗电为正”区分开,否则SOC趋势会看反。
还需要拖两个To Workspace模块,一个记录电压,一个记录SOC,也可以把电流一起记录。变量名分别设为sim_Vt、sim_SOC、sim_I,Save format选Timeseries。这样仿真结束后,在MATLAB工作区可以直接用sim_Vt.Data取数据,用sim_Vt.Time取时间。
4. 充放电特性仿真结果分析与调参
4.1 恒流充电过程曲线解读
设置好参数后运行仿真,先看充电段(前4小时)。电流为+5A,初始SOC=0.1,查表得到OCV约43V。由于欧姆内阻R0=0.08Ω,模型施加电流的瞬间,端电压立刻比OCV高约0.4V((I \times R_0 = 0.4V)),这就是欧姆压降的瞬时响应。
随后极化电容开始充电,(V_p)从0上升,理想情况下会以时间常数90秒趋近于稳态值(I \times R_p = 0.25V)。于是端电压在电流施加后大约3到5分钟内又缓慢上升0.25V左右。这个“先跳变、后缓升”的曲线,正是电池模型中“欧姆极化+浓度极化”的直观体现。
随着SOC从0.1上升到0.9,OCV从43V逐渐爬到52.5V。整个充电阶段端电压由约43.5V缓慢升至54V上下,充电末端曲线明显变陡。这是因为OCV-SOC表在高SOC区斜率变大,相当于电池快满了,电压上升加速。
到了4小时电流指令从+5A变成0A(严格说,我的指令是直接跳到-5A,但先看中间时刻)。如果只是电流截止,端电压会先瞬间掉0.4V欧姆压降,剩下的极化电压再按90秒时间常数慢慢泄放,这就是“静置回弹”现象。做BMS的人经常拿这个回弹特性估计极化电阻,这里模型能完美复现。
4.2 恒流放电过程与端电压变化
4小时整,电流指令变为-5A,系统进入放电阶段。这里有一个很有意思的现象:由于切换瞬间极化电容上的电压不能突变,而电流方向突然反转,端电压可能先短暂上升一个台阶,然后再快速回落。原因是:
- 切换前(V_p)是正值(约0.25V);
- 切换瞬间电流变为-5A,欧姆压降变成(-(-5)\times0.08=+0.4V),因为电流为负,电压公式里减去负值等于加正值,所以端电压会先抬升;
- 随后(V_p)从+0.25V开始反向建立,逐渐趋向(-0.25V),这个反向过程导致端电压快速下降。
所以说,电池在充放电切换瞬间的电压尖峰/突降并不一定是模型错误,而是内阻和极化电容共同作用的结果。物理上也有这个现象,只是实际液流电池因为泵、管道延迟,会柔和一点。用仿真模型看这个细节,对后续设计过充放保护很有参考价值。
放电4小时进程中,SOC从0.9下降到0.1,OCV从52.5V降到43V,端电压随之下降。到了放电末端,由于SOC进入低平台区,电压快速下滑,低于42V以后就进入过放风险区间。此时BMS里一般会报低电压告警并限功率,这就是仿真模型的用途所在。
4.3 SOC-OCV滞回与效率计算
前面说过,我们的模型用了同一个OCV-SOC表,没有做充放电路径分离。因此在SOC=0.5处,无论充电还是放电,开路电压基础值都是48V。但端电压不同,因为电流方向导致欧姆压降和极化压降方向相反,所以充电端电压高于放电端电压。这个高出的量大约是两倍的过电位之和:(2 \times |I| \times (R_0 + R_p) = 2 \times 5 \times 0.13 = 1.3V)左右。这就是“充放电压差”,它直接决定了储能系统效率的主要来源——内阻热损耗和极化损耗。
仿真结束后,要计算效率,可以在MATLAB里写几行后处理脚本:
% 假设已经通过To Workspace得到 sim_Vt, sim_I Vt_data = sim_Vt.Data; I_data = sim_I.Data; t_data = sim_Vt.Time; P = Vt_data .* I_data; % 瞬时功率,充电为正,放电为负 % 充电能量(前4小时) idx_ch = find(I_data > 0.1); E_ch = trapz(t_data(idx_ch), P(idx_ch)) / 3600; % Wh % 放电能量(后4小时) idx_dis = find(I_data < -0.1); E_dis = -trapz(t_data(idx_dis), P(idx_dis)) / 3600; % Wh eta = E_dis / E_ch * 100;用我上面的参数跑下来,能量效率大致在82%左右。这个数值对液流电池来说是合理的,因为它的辅助损耗还没算进去。如果加上泵耗,系统效率还会再低几个百分点。
4.4 调参经验:电容值、最大步长与精度
在调模型时,我最常被人问到的就是“为什么曲线毛刺特别多”或“为什么仿真跑得特别慢”。这里有几个实际经验。
第一,极化电容(C_p)直接影响仿真步长和曲线平滑度。(C_p)越大,时间常数越大,Simulink变步长求解器可以用稍大的步长,跑得快;但(C_p)如果太小,比如只有10F,时间常数变成0.5秒,为了捕捉极化过程,求解器会把步长压到0.1秒以内,仿真8小时会变得非常慢。因此建议第一次仿真时把(C_p)设得偏大,让时间常数至少在60秒以上,模型容易收敛,也容易观察趋势。
第二,最大步长设置要与电流切换时刻配合。我在3.2节设了Max step size=20s,这样在4小时切换点附近,不会出现大步长跨越。如果你发现自己模型的电压在切换点出现“毛刺”,优先把最大步长改成2秒甚至1秒,看曲线是否变得正常,然后逐步放大,找到一个精度和速度的平衡点。
第三,ode15s vs ode45。很多人看到非刚性微分方程就选ode45,这个模型用ode45也能跑,但ode45在长时间仿真中会频繁调整步长,而且在电流阶跃处可能误差控制不好。我用ode15s后感觉更稳。如果你加了泵、电力电子开关等高频环节,ode15s几乎是必须的。建议从开始就用ode15s,养成习惯。
5. 常见问题与排查技巧实录
5.1 仿真发散、代数环和“NaN”问题
最常见的仿真失败现象是:一开始跑就报错,或者Scope里出现NaN、无限大电压。
排查优先级:
- 先看积分器初值。SOC初值如果是0,而查表表最左端也是0,没问题;但如果你把SOC初值写成负的,查表会外插出奇怪电压。建议SOC初值保持在0到1之间。
- 再看反馈路径。RC网络里的反馈信号如果符号接反,比如把负反馈接成正反馈,积分器就会发散。一个快速验证方法:单独给RC网络一个阶跃电流,看(V_p)是否趋向稳态值(I \times R_p)。
- 如果出现“Algebraic Loop”报错,说明某个Sum模块的输出直接或间接参与了自己的输入计算。最常见的是:你想用端电压去控制电流,又把电流用来计算端电压。打破代数环的有效办法是在反馈回路里加一个
Unit Delay(单位延迟),让信号延迟一个仿真步长。这样做虽然会引入一个步长的滞后,但不会影响整体结果的正确性。
有一个相关的小坑是总线信号报错。很多人习惯把SOC、V_t用Bus Creator打包,再用Bus Selector选信号,结果报“Bus Selector没有可选信号”。这个问题多半是Bus Creator的输出没有真正连接到Bus Selector的输入,或者总线里的信号名和选择器里写的不一致。如果只是为了看波形,直接用普通信号线和Mux就够,不必强行用总线。
5.2 SOC越界和积分漂移
安时积分法最大的毛病是SOC会一直积分,不封顶。如果电流方向给错,或者仿真时间过长,SOC可能跑到1.2或者-0.3。虽然物理上也可以过充过放,但在基础模型里,我们希望SOC控制在合理区间,不然查表外插会让OCV变得离谱。
解决办法是在SOC的Integrator后面加一个Saturation模块,上下限设为0和1。注意Saturation只是限制了SOC显示值,如果电流还在继续充,真实积分结果可能已经到了1.1,但显示卡在1.0,OCV也卡在54V。这样处理在策略仿真中可以接受,但如果你要分析过充过放行为,就不要加饱和,而是让SOC正常越过边界,用查表的外推行为去模拟电压突变。
另外,如果发现SOC在放电时反而增大,说明电流符号定义反了。我们的约定是充电电流为正,放电为负,SOC积分从初始值增加。检查From Workspace里的第二段值是不是负数。
5.3 查表外插导致电压异常、初始电压跳变
Lookup Table默认如果SOC超出Breakpoints范围,会做线性外插。如果你给的SOC初始值是0.1,没问题;但如果你把SOC初值设为0.02,查表会在0到0.1之间线性外插,得到42.4V左右,这也不是大问题。怕的是SOC初值设为0,而表里0到0.1区间斜率很大,外插可能让电压跌到40V以下。为避免这种异常,我会把表向两端扩充:
SOC_pts = [-0.5 0 0.1 0.2 0.5 0.8 0.9 1.0 1.5]; OCV_vals = [35 42 43 44.5 48 51.5 52.5 54 58];这样即使仿真中SOC因为积分溢出跑到1.2,电压也不会瞬间变成六七十伏。
初始电压跳变是正常的。电流从0变成5A的瞬间,欧姆内阻必然产生0.4V压降,所以端电压曲线会有个“台阶”。如果不想看到台阶,可以把电流指令从0到5A做成斜坡,比如10秒内爬升,这样更接近BMS限功率缓启动的逻辑。具体做法是在脚本里把5A前面加一个斜坡段,而不是纯阶跃。
5.4 常见问题速查表
| 现象 | 可能原因 | 排查思路 | 解决方案 |
|---|---|---|---|
| 仿真报代数环 | 输出信号直接参与输入计算且无延迟 | 沿信号链找闭环 | 在反馈回路加Unit Delay |
| 曲线出现NaN或发散 | RC负反馈符号接反,或SOC初值越界 | 单独测试RC网络阶跃响应 | 检查Sum符号和积分器初值 |
| SOC只升不降 | 放电电流方向给错 | 检查From Workspace第二段值 | 改为负值 |
| 电压在切换点毛刺 | 最大步长过大跨过阶跃点 | 缩小最大步长测试 | 设置Max step size=20s以内 |
| 查表电压异常高/低 | 表外插范围过大 | 看SOC是否超出区间 | 扩充表端点或加Satiration |
| Bus Selector没有可选信号 | Bus Creator/Selector不匹配 | 检查连接线和信号名 | 直接改用Mux或普通信号线 |
6. 从单体到系统:储能管理场景的扩展建议
6.1 加入泵损与自放电
液流电池储能系统有一个锂电池没有的问题:泵要一直转。即使不充不放,泵也要维持电解液循环,大概消耗系统额定功率的3%到10%。在仿真模型里,这个损耗最直接的表现是:电池放电时,一部分电流实际上被泵消耗了,真正对外供出的电流小于电堆电流。
建模时可以这样改:把电流指令拆成两路,一路是外部负载电流,一路是泵电流(常数或与流量相关)。电堆总电流 = 外部电流指令 + 泵电流。然后把这个总电流送入电池模型计算SOC和端电压,但对外报告的功率仍然按外部电流乘以端电压计算。这样系统层面看到的放电功率会小于电堆输出功率,多出来的部分就是泵耗。这个修改本身不难,关键是先要把单体模型逻辑弄明白,否则会弄混“电堆电流”和“系统电流”。
自放电也可以用一个小电流表示。液流电池自放电率低,但在长时间静置仿真中不可忽略。可以加一个恒定的负数电流(比如-0.05A)叠加到电流指令上,这样SOC在静置时也会缓慢下降。
6.2 与BMS、功率调度联调
当前模型只有电池本体和开环电流指令,要让它服务于储能管理场景,还需要把模型封装成带标准接口的子系统。封装的思路是:
- 输入端口:
I_cmd(电流指令,A)、enable(使能信号); - 输出端口:
SOC、V_t、P_est、max_charge_current、max_discharge_current。
在子系统内部,可以使用Saturation限制电流大小,再利用BMS给出的电压上下限,通过Switch把电流钳制到安全范围。这样在外面连一个简单的状态机(充电、放电、静置)或者PCS功率指令生成模块,就能模拟完整储能单元的功率响应。
这一步做完,就等于有了一个“虚拟电池”。后续接入Simulink的BMS模块,或者做车辆、微电网的功率调度联合仿真,都会自然很多。我见过很多项目把电池模型写得过细,导致联合仿真时每次步长极小,跑一天都跑不完,反而影响整系统验证。所以在储能管理场景下,一阶RC模型往往是性价比最高的选择。
6.3 更精细的液流电池模型方向
既然你已经把一阶RC模型搭出来了,后面想进阶可以试试下面几个方向:
- 充放电滞回模型:充电和放电分别建两个OCV-SOC表,切换时用历史状态变量过渡,解决单表无法表现回滞的问题。
- 温度对参数的影响:把R0、Rp和OCV都写成温度的函数,加上热容方程,形成电-热耦合模型。
- 多堆串并联:将单体模型作为子系统复制并连接,考虑汇流母线和各堆SOC不一致问题,这也是储能BMS的重要场景。
- 泵与流体网络:用Simscape Fluids或自建流体方程,把电解液流量与电流密度联系起来,更贴近液流电池实际运行。
这些方向每一条都可以单独展开成一篇长文。但基础都是今天这个模型:先把充放电特性仿真复现得准确、稳定、可调试,后面各种扩展才有牢固支点。
我自己在实际操作中最大的体会是:别一上来就追求“模型要和实测完全一致”,先保证趋势正确、逻辑清晰,再逐步增加复杂度。搭这个模型花的时间其实不长,真正花时间的是调参数和排查那些莫名其妙的问题。如果你照着这篇从头搭一遍,再跑一遍4小时充电和4小时放电,应该就能理解电池模型里的RC网络、SOC积分和求解器设置之间的关系了。等你亲手把Scope里的曲线调成预期形状,你对Simulink和液流电池特性的感觉都会完全不同。