做电池建模的人应该都经历过这个场景:项目要开始仿真了,手里只有一份电池规格书,里面有几组充放电曲线、容量、内阻,然后领导说“把电池模型建出来,明天仿真要用”。这时候最稳妥的选择之一,就是Simulink里的Battery (Table-Based)表格化电池模型——它是把实测数据直接做成查找表,用查表替代复杂公式的建模方式,上手快、精度可控,非常适合做系统级仿真和BMS算法验证。这篇是电池建模系列的第004篇,我会从原理、建模步骤、实验数据准备到常见坑位,把Table-Based模型的入门路线完整讲一遍,新手上手可以直接照着操作。
1. 表格化电池模型到底是个什么东西
1.1 一张表格代替一堆公式
Battery (Table-Based)的核心思路很简单:用开路电压(OCV)与SOC的关系表、内阻与SOC的关系表,把电池外特性描述出来。仿真时根据当前SOC查表得到开路电压和内阻,再按电路关系算出端电压和电流。
用公式表示大概是这样的:
V_terminal = OCV(SOC) - I_load × R_internal(SOC)
OCV(SOC)是一张表,R_internal(SOC)是另一张表,SOC通过安时积分实时更新,就这么简单。它不关心电池内部复杂的电化学过程,只看“外面表现出来是什么样”,所以也叫“黑箱模型”或者“行为模型”。
这个思路在工程里特别实用。锂电池尤其是磷酸铁锂,电压平台非常平,用传统的等效电路公式去拟合,拟合误差很容易超标。但只要你有一组实测的OCV-SOC数据,往表里一填,仿真结果基本就能贴合实际曲线,不用猜公式参数。
1.2 表格化模型与等效电路动态模型,差别在哪
很多人会问,Simulink里不是还有个Battery (Dynamic)吗?跟Table-Based有什么区别?这个必须说清楚,因为选错模型就会走弯路。
Battery (Dynamic)是基于受控电压源加内阻的等效电路模型,核心是一组根据Shepherd方程改进而来的公式,只需要额定电压、额定容量、内阻等几个参数就能跑。好处是参数少、上手快;缺点也很明显——公式的拟合能力有限,对磷酸铁锂这类平台电压特性非常平缓的电池,误差会比较大,而且很难模拟电池在温度和老化影响下的行为。
表格化模型恰好相反。它的精度不取决于公式形式,而取决于你喂给它的数据够不够好。只要OCV表、内阻表覆盖了你的工作范围,精度就能做得很好。当然代价是前期要准备数据,表格质量差,仿真结果也就差。
下面这个表是我在项目里常用的选型参考:
| 对比维度 | Battery (Dynamic) | Battery (Table-Based) |
|---|---|---|
| 数据依赖 | 只需额定参数 | 需要OCV/SOC/内阻实验数据 |
| 建模成本 | 起步快 | 前期数据准备耗时 |
| 电压平台拟合能力 | 弱,尤其铁锂 | 强,任意曲线可拟合 |
| 温度影响描述 | 相对粗糙 | 可通过二维/三维表描述 |
| 仿真速度 | 快 | 较快,查表开销不大 |
| 典型场景 | 快速概念仿真 | BMS算法验证、系统级精度仿真 |
一句话总结:能搞到数据就上Table-Based,搞不到数据就先用Dynamic顶一版再说。
1.3 什么项目适合用表格化模型
根据我自己的使用经验,下面这几类项目用Table-Based比较合适:
- BMS算法开发,特别是SOC估计、SOH估计、均衡策略验证。因为算法需要和“够真实的电池”交互,表格化模型能提供逐点对应的电压响应,比简化公式更接近台架数据。
- 整车能量管理、功耗估算这类系统级仿真,既要电池行为准确,又不想背负电化学模型的巨大计算量。
- 电池包级别的串并联仿真,每个电芯用一个表格化模型,仿真量可控,还能模拟不一致性。
- 数据驱动类课题,比如用实验数据建立数字孪生,Table-Based本身就是一条快捷路径。
反过来,如果是做电化学机理研究、析锂分析、寿命衰退机理分析,就不要用这个模型,那是P2D模型和微观模型的领域。表格化模型描述的是“外部行为”,不是“内部状态”。
2. 模型怎么选:同名模块的两个版本别搞混
2.1 同名模块的版本差异
新手开始用Table-Based时,最容易被绊倒的一点,是Simulink里有两个长得非常像的Battery (Table-Based)模块。
一个在Simscape Electrical库中,路径大约是Simscape > Electrical > Energy Storage,或者直接在库浏览器搜“Battery (Table-Based)”。这个模块面向系统级电气仿真,适合单电池或者电池组的外特性建模。
另一个在Simscape Battery工具箱中,是专门为电池包设计和仿真做的模块,支持电芯到模组再到电池包的多尺度建模,跟电池包热管理、均衡、BMS更贴近。
很多人不知道这俩模块的东西是不一样的:Simscape Electrical版本参数相对简单,适合快速上手;Simscape Battery版本参数层级多,数据输入可以面向大批量电芯,功能更全但学习曲线也更陡。
我的建议是,纯学习入门就选Simscape Electrical里的Battery (Table-Based),先把套路跑通。等到确实要做电池包级项目,再迁移到Simscape Battery。
2.2 参数设置面板里的关键选项
打开Battery (Table-Based)模块双击,主界面会看到几个关键区域,我逐个说明:
- Battery capacity (Ah):额定容量,单位是安时。这个参数决定SOC积分快慢,填错了整个模型时间尺度全错。
- Initial state of charge (%):初始SOC,注意有些版本填的是百分比,有些版本填的是0到1的小数,这个单位坑我后面细说。
- Nominal voltage (V):标称电压,主要用于模块内部输出和报表显示,不会直接参与计算,但还是得填准。
- Open-circuit voltage vs SOC table:OCV与SOC的查找表,这是表格化模型的核心。通常你需要给出两个向量,一个是SOC采样点(必须严格递增),一个是这些点对应的OCV电压值。
- Internal resistance vs SOC table:内阻与SOC的查找表,同理,给出SOC采样点和内阻值,单位是欧姆。
- 有些版本还支持温度相关的二维表,比如内阻与SOC和温度的二维表,需要额外提供温度采样向量。如果项目里有温度场景,强烈建议用这个选项。
参数对话框里可以直接填数值,也可以填工作区变量名——这个技巧很多人不知道。我一般用脚本生成数据,再在工作区里把变量名填进去,比如在SOC vector栏填SOC_vec,在OCV vector栏填OCV_vec,这样避免手动敲一大串数字。
还有个容易被忽略的点:内阻表的数据方向。有些版本要求内阻数据按行按列和SOC向量对应,一旦表格转置了,仿真结果看起来就是乱的。填完参数后建议先把模块输出放Scope里看几秒钟,确认曲线形状符合经验再继续往下做。
3. 从零搭建一个Table-Based电池仿真模型
3.1 模型库路径与最简单的仿真回路
下面把完整建模过程走一遍。以Simscape Electrical中的Battery (Table-Based)为例,其他版本大同小异。
第一步,打开MATLAB,在库浏览器搜索“Battery (Table-Based)”,把它拖到空白模型里。如果你搜出来多个结果,选Simscape Electrical分组下的那一个。
第二步,把Solver Configuration拖到模型中,这是Simscape物理模型的必备件,没有它仿真会报错。
第三步,拖入一个Electrical Reference,连接到电池负极。这个也很关键,物理网络必须要有一个参考地,否则电位没有参考点。
第四步,拖入一个可变负载。最推荐的是Simscape Electrical里的Ideal Current Source,因为它可以方便地用Simulink信号控制电流大小,模拟充放电工况。用法是先拖入一个带宽受限的理想电流源“Controlled Current Source”,再用Simulink-PS Converter把Step信号转成物理信号接上去。
第五步,观察信号。右键点击电池模块,看有没有SOC、Terminal voltage这类输出端口选项,有些版本需要在模块设置里手动勾选“Show SOC port”或者“Show terminal voltage port”。
第六步,连接成完整回路:电池正极连到电流源一端,电流源另一端连回电池负极,负极再接到Electrical Reference。
第七步,回到Battery (Table-Based)模块双击,填容量、初始SOC、OCV表、内阻表。可以先填几个点跑通,再用真实数据替换。
我习惯用下面这个最小回路的检查顺序:先不接任何外部控制信号,直接把电流源设为0,看电池端电压是不是等于初始SOC对应的OCV值。如果是,说明建表数据、初始SOC、单位都没大问题。然后再把电流源设成一个固定的放电电流,看SOC是不是按预期下降。这两步没问题了,后面的工况仿真基本不会出大幺蛾子。
3.2 用MATLAB脚本把实验数据做成查表数据
实验数据转到模块参数里,我强烈建议用脚本处理,不要手动填。下面这段脚本是我常用的模板:
% 构建OCV-SOC查找表 % SOC_vec单位是0~1小数 SOC_vec = linspace(0, 1, 21)'; % 这里用示例曲线,实际用实测数据替换 OCV_vec = 3.0 + 1.2 * SOC_vec.^0.6 + 0.1 * sin(pi * SOC_vec); % 构建内阻-SOC查找表,单位Ohm % 示例带了一点噪声,观察平滑效果 R_vec = 0.045 + 0.02 * exp(-8 * (SOC_vec - 0.3).^2) + 0.01 * randn(size(SOC_vec)); R_vec_smooth = smoothdata(R_vec, 'movmean', 5); % 画图检查 figure; subplot(2,1,1); plot(SOC_vec, OCV_vec, 'o-', 'LineWidth', 1.5); grid on; ylabel('OCV (V)'); xlabel('SOC'); subplot(2,1,2); plot(SOC_vec, R_vec, 'o-', SOC_vec, R_vec_smooth, 'x-', 'LineWidth', 1.5); grid on; legend('原始内阻','平滑内阻', 'Location', 'best'); ylabel('R (Ohm)'); xlabel('SOC'); % 将变量存入base workspace,供Simulink模块引用 assignin('base', 'SOC_vec', SOC_vec); assignin('base', 'OCV_vec', OCV_vec); assignin('base', 'R_vec', R_vec_smooth);运行完脚本后,回到模块参数对话框,把对应栏目里的数字删掉,直接填SOC_vec、OCV_vec、R_vec这几个变量名。Simulink会在仿真时自动去工作区找变量。
这里有个很关键的经验:内阻数据一定要平滑。实验测出来的内阻数据往往是毛糙的,直接用毛糙表进Simulink,会导致数值求导不稳定,仿真步长被压缩到极小,一个小时的工况可能要跑一下午。先用smoothdata或者filter把曲线清洗干净再进模型,效果立竿见影。
4. 实验数据怎么测,怎么处理成查表
4.1 OCV测试:慢充慢放法
表格化模型的精度上限,取决于OCV-SOC曲线的准确性。所以实验环节不能马虎。
最标准的OCV测试方法是分段静置法。大致流程是这样的:先把电芯用小电流放空,比如C/20电流放到截止电压,然后静置两个小时,记录此刻电压作为0%SOC对应的OCV。接着用C/20电流充入10%的容量,静置一小时,记录电压,就得到10%SOC对应的OCV。重复这个过程,直到充满到100%。
选C/20是有道理的:这个倍率下电流足够小,电池内阻产生的压降很小,静置后的端电压能近似认为是开路电压。如果你赶时间用C/10甚至C/5去测,测出来的“OCV”里混着极化电压,模型精度就会打折。
实测中还有一个细节。充电方向和放电方向的OCV往往有细微差别,这叫电压迟滞,磷酸铁锂电池尤其明显。如果你做的是高精度SOC估计,最好把充电OCV表和放电OCV表分开建,或者至少评估一下迟滞对你的工况影响大不大。入门阶段可以先不细化这个,但心里要有数。
4.2 脉冲法测内阻,别把单位搞错
内阻表的数据来源,最常用的是脉冲法,也就是HPPC(混合脉冲功率特性)测试。单个SOC点上的测试逻辑很直观:
先把电池调到某个SOC,比如50%。以1C电流恒流放电10秒,记录电压瞬间跌落量ΔV_d,那么放电内阻近似就是ΔV_d除以放电电流。然后静置40秒,让电池恢复。接着以0.75C电流恒流充电10秒,记录充电时的电压变化,同样算出充电内阻。
在每个SOC点上都做这么一轮,就得到了一条内阻随SOC变化的曲线。
这里有一个非常容易踩的坑:单位。规格书里内阻经常给毫欧(mOhm),比如20毫欧,但Simulink表格里单位是欧姆(Ohm),要填0.02。很多人的模型仿真结果对不上,查到最后就是单位写错了,一个小数点差出1000倍。
另外一个概念要拎清楚:脉冲法测出来的内阻是直流内阻,它包含了电池欧姆内阻和一部分极化内阻。如果你在模型中再额外串联一个RC极化网络,就等于把极化电阻重复计算了一次,动态响应会偏软。用Table-Based模型时,内阻表就代表了当下的所有电压损失,不需要画蛇添足。
5. 新手最容易踩的坑与排查经验
5.1 建表数据格式不对,报错信息提示了什么
表格化模型最常见的报错之一,是提示SOC数据不在查找表范围内,或者提示表格数据必须严格递增。遇到这种问题,先别慌,按顺序排查:
第一,SOC向量是不是严格递增且没有重复值?比如[0, 0.1, 0.1, 0.2]这种就肯定报错。
第二,SOC向量是否覆盖了你设置的初始SOC?如果表只做到0到0.9,初始SOC填了95%,仿真一启动就超范围了。
第三,初始SOC的单位对不对?如果SOC向量用的是0到1的小数,初始SOC却填了80(表示80%),会直接报错;反过来也一样。建议在模型里把单位统一:查找表里SOC统一用0到1小数,初始SOC单位如果默认是百分比,就填80;如果默认是小数,就填0.8。具体看模块上的标注。
第四,容量和SOC的关系有没有混淆?有些版本给的是Terminal voltage vs capacity表,第三列是累积容量,单位是Ah,不是SOC。如果你把SOC向量直接填进去,整个模型就跑飞了。用之前一定要看清楚表头写的是SOC还是Capacity。
5.2 内阻曲线太毛糙,查表查不住
这是我见过最多的问题。实测内阻数据一定是有噪声的,电池在不同SOC点的内阻本来就波动,再加上测量误差,整条曲线锯齿状很强。仿真时查找表一旦遇到这种剧烈变化的斜率,求解器会认为系统刚度过大,被迫把步长压到非常小,最终表现就是仿真慢如蜗牛。
处理办法就三步:先平滑,再检查边界,最后可视化确认。平滑用smoothdata或者移动平均都可以;边界检查是确认最低SOC点和最高SOC点的内阻值是否合理,如果边界上出现突然升高或下降,外推时结果会很离谱;可视化是最后人眼过一遍曲线,确认没有离谱的尖峰。
我自己一般会多做一个步骤:把平滑前后的曲线叠加对比,如果平滑后变化趋势还在,就说明没问题;如果连峰谷都被抹平了,说明窗口开太大,适当调小。
5.3 仿真不收敛、步长变小,先查这几处
仿真跑不起来,最常见的原因有三个,按优先级给新手提供的排查顺序是:
第一,Solver Configuration有没有放、参数合不合理。Simscape物理模型必须要有这个模块,里面可以启用Local solver,很多时候能让仿真稳定很多。
第二,信号域和物理域转换是否正常。Simulink-PS Converter的输入是从Simulink来的信号,输出是物理信号;PS-Simulink Converter反过来。两个接反了,系统直接在初始化阶段报错。
第三,负载突变太剧烈。如果你用Step信号把电流从0瞬间切到100A,Simscape求解器需要极高的精度去跟踪这个跳变,步长会被压得很小。解决办法是给Step增加斜率,用斜坡过渡几毫秒,或者直接用带宽受限的实际电流源模型。
如果是纯Simulink逻辑控制外加Simscape电池,建议把最大步长设小一点,比如1e-3秒,避免求解器跳过太快导致数值振荡。
5.4 热效应版本的一个经典坑
如果你用的是带热效应的Battery (Table-Based),比如“with thermal effects”版本,很容易出现一个现象:跑了半天仿真,电池温度纹丝不动。原因多半是热端口没接东西。
这个模块的热端口需要连接到热力学网络,比如一个Simscape Thermal的Thermal Mass,或者和环境温度源相连。如果不接,模块就认为自己处于绝热状态,温度自然不变。你要是想看电池发热升温,至少要接一个热容;要是想看散热,还得接热阻或者强制对流换热器。
热模型里的内阻数据注意了:这时的内阻表往往是SOC和温度二维的,很多新手只填了SOC方向的数据,温度方向只有一两个点。仿真中一旦温度超出表格范围,查表会触发外推,算出来的内阻可能变成负数,仿真结果直接崩掉。处理方法是把温度表范围做得比预期工作范围略宽,比如预计工作范围是-10到45摄氏度,就把表做到-20到55。
6. 表格化电池模型在项目里能拿来做什么
6.1 BMS算法验证
BMS算法开发是我用这个模型最多的场景。核心需求是:在算法接入真实硬件之前,能有一个“够真实”的电池来跑通整个逻辑。
比方说验证一个扩展卡尔曼滤波的SOC估计器。你需要在Simulink里搭一个电池模型模拟真实电池,再搭一套算法模型去估计这个电池的SOC,然后把“真值”和“估计值”放一起对比。如果电池模型太粗,SOC真值本身就不准,算法验证就失去了意义;如果电池模型太复杂,比如电化学模型,计算量又太大,跑一轮仿真要半天,不适合算法迭代。Table-Based正好卡在精度和速度的平衡点上。
我在实际项目中把电芯的实测HPPC数据做成Table-Based模型,再用它作为被控对象验证了一套安时积分加卡尔曼滤波的SOC估计算法。对比下来,端电压误差控制在毫伏级别,SOC估计误差在动态工况下不超过3%,整套流程的调试效率非常高。
6.2 电池包均衡策略开发
做电池包均衡仿真时,Table-Based模型有一个特别方便的地方:你可以把多个模型放在同一个回路里,给每个模型设置不同的初始SOC,模拟电芯不一致性。
比如搭一个由4节电芯串联组成的电池包,分别把初始SOC设为78%、80%、82%、85%,然后跑同一个充放电工况,观察各节电压和SOC的扩散情况。再在这个基础上开发被动均衡或者主动均衡策略,看均衡电流介入后,电池包容量利用率提升了多少。
用Table-Based模型做均衡仿真,还有一个隐性好处:内阻曲线是实测数据拟合的,各节电芯在不同SOC下的压降差异会自然体现出来,不会因为模型过于理想而低估了均衡难度。这个细节对均衡策略的鲁棒性验证非常重要。
6.3 整车能量管理仿真
在整车级别做能量管理策略验证,电池模型不需要太细,但一定要能真实反映电池的功耗和热量趋势。这时候Table-Based模型配上热效应版本,往整车模型里一挂,就能同时看到电流、电压、SOC、温度四个关键量的联动。
举个例子,我在一个混动能量管理策略的前期验证里,用Table-Based电池模型跑WLTC工况,把整个工况下的电池SOC轨迹、温升轨迹、充放电效率曲线都拉出来看。初步发现:某个策略在电池冷机状态下频繁大功率放电,导致电池温升过快,后期能量回收受限。如果不是电池模型里带了温度相关的内阻表,这个现象根本看不出来——因为用固定内阻模型算,冷态和热态的压降完全一样,策略的问题会被直接掩盖。
所以做整车能量管理,我强烈建议至少用带温度相关内阻的表格化模型,哪怕是二维表只有三五个温度点,也比固定内阻强得多。
上面这些场景,我自己都跑过不止一遍。如果你刚开始接触Table-Based模型,我给的最直接建议是:不要一上来就追求高精度大数据表,先用一个SOC点做十等分的表,哪怕OCV是随手画的、内阻是拍脑袋估的,只要能跑通“查表→算电压→更新SOC”这个闭环,你对这个模型的理解就到位了。然后再拿真实实验数据去替换,你会明显感觉到精度一步步逼近实测曲线,那个过程很有成就感。后面做BMS算法验证或者电池包均衡,心里就有底了。