ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

电动汽车BMS核心状态量SOH与SOP的估算策略与工程落地

电动汽车BMS核心状态量SOH与SOP的估算策略与工程落地

简介:电动汽车BMS中SOH与SOP估算策略的系统总结,内容面向动力电池工程师、整车电池管理系统开发人员及高校相关专业学习者,旨在梳理电池健康状态与功率状态的估计方法,帮助读者快速建立算法选型与联合估计的整体框架。文档共1个docx文件,压缩包约787KB,篇幅精炼而体系完整。正文从IEEE标准中SOH定义出发,依次展开SOH估算的开环与闭环方案,覆盖基于耐久性模型、基于电池模型、基于开路电压等主流路径;随后介绍SOP估算中基于电池模型与基于电池内阻的两类方法,并进一步对比SOH与SOP联合估算的卡尔曼滤波双时间尺度和多时间尺度策略,给出SOC与SOH同步估计的模型思路。文中还结合具体老化实验流程,演示了利用充电能量、放电能量计算内阻并标定内阻与SOH线性关系的完整步骤,对实际工况下的参数识别具有直接参考价值。目前已有3661人学习,适合需要系统掌握BMS核心算法、开展电池老化研究或进行SOH/SOP联合仿真的工程师与研究人员。

1. 电动汽车BMS里最容易被低估的两个状态量:SOH与SOP

实测过某混动车型的冬季标定,仪表显示剩余输出功率还有80kW,拿到试驾车上爬一个高架匝道,油门踩到一半就被BMS限扭,实际给到车轮的功率不到50kW。售后反馈清一色是“动力不足”,但电池本身没有故障码。另一台纯电车,SOH标定还有92%,用户却反复投诉快充电流被限制,换了好几个充电桩都一样。这类问题的根子都不在电芯,而在BMS里SOH和SOP估算策略——SOH负责回答“这电池还剩下多少寿命和底气”,SOP负责回答“此刻到底能放出或吸收多大功率”。两份策略拿到同一份数据,算出的数字却能差出十万八千里。这篇文章就是把这些策略拆开讲清楚:它们是什么、怎么落地、参数怎么定、坑在哪,给做BMS算法、电池系统集成或整车性能标定的从业者一条可以照着复现的路。

2. SOH估算:容量派与内阻派的取舍,以及我能直接落地的估计框架

2.1 先别急看算法:SOH的定义分歧决定你后面所有的标定

SOH,State of Health,电池健康状态。这个定义在学术界和工程界都没有统一标准。最常见的是容量型SOH,拿当前最大可用容量除以额定容量,得到“这电池还能装多少电”。另一条线是功率型SOH,拿当前峰值功率能力除以出厂时的峰值功率能力,反映“这电池还能不能扛住大电流”。

这两个定义在同一个电芯上往往给出不同的结论。举例说,一块磷酸铁锂电池跑了8万公里,容量SOH还有90%,但内阻比出厂时涨了30%以上,低温下功率SOH可能只剩75%。所以做策略的第一步不是选算法,而是想清楚这个SOH输出给谁用。给整车做剩余续航,你必须用容量型SOH;给VCU做动力性能预测、给充电桩做功率协商,你更需要功率型SOH。

量产BMS里常见的做法是容量为主、内阻为辅。也就是说,对外报SOH时以容量法为准,维持用户对“衰减”的直观理解;对内做SOP限制时用“容量SOH”和“内阻增量”同时参与计算。这个混合结构不是最优解,但它是工程上最不容易扯皮的方案——至少售后看数字时不会说“我容量还有90%,凭什么限制我充电功率”。

2.2 容量法落到代码:OCV-SOC标定、安时积分与有效片段更新

容量法的核心难点在于“当前最大可用容量”是个不可直接测量的量。你不能在车上做一次完整的标准放电,所以只能靠日常运行数据里的“有效片段”去推算。所谓有效片段,指的是SOC从一个已知点可靠地变化到另一个已知点的时间段。OCV-SOC曲线就是给这个过程提供“已知点”的标尺。

# 容量型SOH的简化估计器(Python示意实现) class CapacitySoHEstimator: def __init__(self, q_rated_ah, smoothing=0.03): self.q_rated_ah = q_rated_ah # 额定容量,单位Ah self.q_max_ah = q_rated_ah # 当前最大可用容量估计 self.ah_integrated = 0.0 # 窗口内安时积分 self.last_soc_ocv = None # 上一次可靠OCV对应的SOC self.smoothing = smoothing # 滑动平均系数,0.01~0.05为宜 def feed(self, current_a, dt_s, soc_ocv=None): # 安时积分:current为正表示放电 self.ah_integrated += current_a * dt_s / 3600.0 # 仅当外部给入可靠的OCV-SOC值时进行窗口闭合 if soc_ocv is not None and self.last_soc_ocv is not None: delta_soc = soc_ocv - self.last_soc_ocv if abs(delta_soc) >= 0.05: # 用窗口内安时与SOC变化量反推容量 q_est = self.ah_integrated / delta_soc if q_est > 0: self.q_max_ah = (1 - self.smoothing) * self.q_max_ah \ + self.smoothing * q_est # 闭合窗口后清零 self.ah_integrated = 0.0 if soc_ocv is not None: self.last_soc_ocv = soc_ocv return self.q_max_ah / self.q_rated_ah

这段逻辑里最关键的参数是delta_soc阈值和smoothing。阈值我一般设到5%以上,小于这个值,OCV查表误差和传感器噪声会被放大成容量估计误差;smoothing设到0.03左右,代表新估计只贡献3%的权重,保证SOH不会因为一次异常片段就跳变。真正常用的做法是把这个估计器挂在充电结束或长时静置结束的事件上触发,而不是在行驶中高频更新。行驶中电流传感器零点漂移、温度分布不均、极化未恢复,都会让“可靠OCV”变成“不可靠OCV”,这是容量法最容易翻车的地方。

2.3 内阻法落到代码:R0+R1辨识与温度修正

功率型SOH的实践落点则是内阻辨识。直流内阻不能直接测,但可以用电压变化量除以电流变化量来近似。真正的难度在于“电流变化”要足够大,且要区分欧姆内阻和极化内阻。我的做法是维护一个滑动窗口,只提取电流跳变瞬间的电压响应来计算欧姆内阻,再把稳态极化后的压差用于辨识极化电阻。

def estimate_r0_from_step(dv_mv, di_a, min_di=5.0): # 输入:一个采样周期内的电压变化量(mV)、电流变化量(A) # 输出:欧姆内阻(mOhm),无效时返回None if abs(di_a) < min_di: return None # 电流跳变太小,信噪比不足 r0_mohm = dv_mv / di_a # R = dV / dI if 0.2 <= abs(r0_mohm) <= 20.0: # 物理合理范围过滤 return r0_mohm return None

这个函数本身很简单,工程上的工作量全在数据筛选上。电流跳变前后需要各取若干点的平均电压来消除纹波干扰;跳变方向要区分充电和放电,因为负极过电位在充放电时不对称;数据还要同步到温度通道。

内阻的温补公式是另一个必调项。我一般把实测内阻折算到25℃基准:R25 = Rt * exp(Ea * (1/T25 - 1/Tt)),Ea按电芯材料体系取,磷酸铁锂大致在25到45kJ/mol之间,三元略小。参数不匹配的表现很典型:夏天SOH偏高、冬天SOH偏低,且偏差与季节强相关,而不是随真实衰减缓慢变化。如果看到这种规律,先回去查温补系数,别急着改算法结构。

3. SOP估算:从标定表到电压约束的功率极限计算

3.1 先定义清楚:SOP算的是“多久不越界的最大功率”

SOP,State of Power,功率状态。很多人把它理解成一个“当前能输出的最大功率”的固定值,这是误区。SOP的本质是一族带时间标签的极限,它回答的是“在当前温度、当前SOC、当前SOH下,持续10秒放电的最大功率是多少”“持续30秒馈电的最大功率是多少”。时间维度不写清楚,SOP就没有意义。

工程上SOP至少区分两个时间档:峰值功率(通常取10s,用于超车、爬坡)和持续功率(通常取30s或60s,用于长坡道维持、高速持续行驶)。做再生制动时还要额外考虑充电SOP,因为电机回馈功率可能远大于电池当前能接受的充电功率,出现“想刹但电池不让”的危险情况。

SOP要满足的约束从电芯侧看有四类:电压上下限、电流上下限、SOC边界、温度边界。功率本身不是约束,它是电压、电流、SOC约束共同作用下的结果。所以SOP估算策略好不好,看的是“约束之间怎么协调”。

3.2 一张SOP标定矩阵的组成:温度、SOC、时间常数与SOH修正

当前量产方案里,查表法仍然占主流。原因是它简单、可审计、标定流程成熟。SOP查表不是查一个二维矩阵,而是查一组多维度曲面:横轴是SOC,纵轴是温度,第三维是持续时间,再加上SOH修正系数。

温度 / SOC-20℃-10℃0℃25℃40℃
80%32 kW58 kW110 kW180 kW165 kW
50%25 kW46 kW95 kW160 kW145 kW
30%12 kW22 kW50 kW95 kW80 kW
SOH=80%修正×0.85×0.88×0.90×0.92×0.90

上表是10秒放电SOP的示意。注意常温段和低温段的差异比例:25℃到-20℃,SOP掉了超过80%,这主要来自电解液电导率下降和负极界面阻抗上升。SOH修正系数不是线性的,越低温、SOH权重越大,因为老化电芯的低温功率衰减更剧烈。

标定这张表的数据源是HPPC(混合功率脉冲特性)测试。一个常见坑是脉冲电流取得偏小。我见过标定文档里用1C脉冲电流做出来的一张表,常温看起来没问题,低温段全虚高。原因是低压平台区,大电流和小电流导致的极化差异不是按比例放大的。建议脉冲电流至少按2C或按整车最大需求功率折算到电芯级别去标定,低温段甚至可以做到3C以上。

3.3 一阶RC约束下SOP的代码实现与参数调整

查表法最大的短板是无法响应瞬态工况,尤其是冷启动后电池温度快速上升的过程。模型法则可以弥补这一点:用一个一阶RC等效电路,在线预测持续dt秒后的端电压,再反推最大允许电流。

import math def compute_discharge_sop(ocv, r0, r1, tau, dt, v_min, soc, soc_min, q_rated_ah, soh_scale, c_rate_max): # ocv: 当前开路电压(V) # r0, r1: 欧姆内阻与极化内阻(Ohm) # tau: 极化时间常数(s),典型值 5~30s # dt: SOP持续时间(s),比如10s # v_min: 放电截止电压(V) # soc_min: 允许最低SOC,通常0.05~0.10 # q_rated_ah: 额定容量(Ah) # soh_scale: SOH折算系数,SOH低则功率能力衰减 # c_rate_max: 电芯允许最大放电倍率 # 1) 电压约束:一阶RC模型预测dt秒后端电压,反推电流上限 # V(t) = OCV - I * [R0 + R1 * (1 - exp(-dt/tau))] factor = r0 + r1 * (1.0 - math.exp(-dt / tau)) if factor <= 1e-9: return 0.0 i_voltage_limit = (ocv - v_min) / factor # 2) SOC约束:dt秒内SOC不能低于下限 # I = (SOC - SOC_min) * Q_rated * 3600 / dt,单位A i_soc_limit = (soc - soc_min) * q_rated_ah * 3600.0 / dt # 3) 倍率约束:电芯厂商给出的短时倍率极限 i_crate_limit = c_rate_max * q_rated_ah # 取三者最小值,再乘以SOH折算 i_limit = min(i_voltage_limit, i_soc_limit, i_crate_limit) # 保守起见,功率用端电压预测值而非OCV v_predict = ocv - i_limit * factor return max(v_predict, v_min) * i_limit * soh_scale

这个函数里要调的核心参数是tau和c_rate_max。tau不能设置为固定值,它随温度和电流方向变化很大,低温下可以到30s以上,常温只有5到10s。我常在实车上用“大电流阶跃后的电压恢复曲线”去在线拟合tau,比用标定值效果更好。

还要提醒一点:当dt远大于tau时,factor接近R0+R1,SOP趋向“持续功率”;当dt远小于tau时,极化来不及建立,factor接近R0,SOP就是“峰值功率”。很多标定问题恰恰是这两个极限没分清,把持续功率当作峰值功率限制去控制,导致整车动力性永久性被低估。

4. SOH与SOP协同:双向耦合与多时间尺度状态机

4.1 SOH怎么实时收缩SOP边界

SOH和SOP不是两个独立计算完再拼在一起的输出,它们之间存在强耦合。最直接的一条线是:SOH下降 => 可用容量减少 => 同样的SOC数值下,实际可用能量变少 => SOP矩阵整体收缩;同时SOH下降通常伴随内阻上升 => 相同电流下端电压降落更大 => 电压约束项提前触发 => SOP进一步收紧。

所以在SOP查表里做SOH修正时,不能只对功率数值乘一个系数,还要注意“可用SOC窗口收缩”。一块SOH=80%的电池,表上50%SOC的SOP值不能直接按原表乘0.9处理,因为50%SOC折算到绝对容量后,已经是“老电池”的62%额定SOC位置的功率能力。常见做法是把SOH修正拆成两项:一项是容量衰减导致的SOC平移修正,一项是内阻上升导致的功率折算修正。前者用容量SOH,后者用内阻型SOH。

4.2 用SOP观测反过来修正SOH:功率维持率统计法

反向耦合往往被忽略,但它对缺少完整充放电片段的运营车辆特别有价值。很多营运车辆长期浅充浅放,SOC始终在40%到70%之间活动,容量型SOH根本没有机会通过大SOC摆幅去更新。这时可以统计SOP的“功率维持率”:在相同温度、相同SOC条件下,当前实测可输出的峰值功率与出厂基准值的比值。

这个比值的本质是内阻型SOH的一个代理量。做法是每触发一次SOP限制事件时就记录当时的温度、SOC、请求功率、实际限制功率,累积一段时间后做分仓统计。比如按SOC每10%一档、温度每10℃一档,把每档内“功率维持率”的中位数提取出来,与模型预测值比对。偏差持续超过3%时,就触发内阻型SOH的修正。

这个统计方法有两个前提:一是SOP限制事件要足够多,二是限制发生时电池确实接近了边界条件。所以它更适合做“辅助修正”而不是“主更新路径”,否则容易把偶发故障当作真实衰减。

4.3 多时间尺度状态机:1秒级、分钟级、周月级各干各的

这是整套策略里最值得先画出来的一张表。先明确每个状态量该在哪个时间尺度上更新,再决定用什么滤波器和什么触发条件。

时间尺度更新对象输入信息输出用途
1~100ms控制周期SOP电流/功率限制电流、电压、温度、SOC、SOH缓存值直接给VCU的扭矩限制与回馈功率限制
分钟级极化内阻R1、时间常数tau大电流阶跃事件、温度变化修正SOP查表结果的瞬态修正量
周/月级容量型SOH有效充放电片段、OCV静置点输出给仪表显示、SOP表基线SOH索引

这个状态机的核心原则是:不要让慢变量参与快变量的噪声传递,也不要让快变量的波动反过来扰动慢变量。我见过一个项目把SOH和SOP放进同一个离散卡尔曼滤波器里,结果车辆每次急加速,SOP限制触发后SOH估值也跟着抖一下。问题不在卡尔曼本身,而在时间尺度混叠。分开滤波后,两边的稳定性都好了。

5. BMS估算落地的6个坑:现象、原因、解决

5.1 SOH数字跳变:把慢变量快算的典型翻车

现象:用户在某次OTA后看到SOH从92%掉到88%,开了一周又回到91%。仪表上的衰减“忽忽悠悠”,售后又解释不清楚。 原因:容量型SOH被过快更新。一次有效片段中,OCV-SOC查表误差叠加电流传感器零漂,导致估算容量大幅偏离。 解决:给SOH更新加两个闸门。一是“新鲜度闸门”,只有停车静置超过2小时以上的OCV点才允许作为片段端点;二是“平滑闸门”,滑动平均系数降到0.02以下,且单次修正量超过2%时直接丢弃。SOH宁可更新慢,不可乱跳。

5.2 低温SOP虚高:传感器滞后与极化时间常数不匹配

现象:-15℃冷启动后,SOP表给出120kW,驾驶员一踩油门,实际功率不到60kW,整车没有故障码但体感“肉”。 原因:标定表按温箱“体表温度”标定,实车上温度传感器贴在模组表面,电芯芯部温度高于表面;更关键的是低温极化时间常数可能超过30s,而SOP算法里用的是常温标定的10s。 解决:对温度索引做一阶滞后补偿,估算芯部温度后再查表;同时让SOP表里低温档的持续时间改到与实测tau匹配。低温的SOP宁可给低,也不能虚高,因为后果不只是体感差,还可能是析锂。

5.3 电压下限没留线束压降:功率限制总是比预期早触发

现象:BMS采样点显示电压还在2.9V以上,但功率限制已经触发,整车动力性明显低于标定曲线。 原因:采样点在电池管理单元端,电芯极柱到采样点之间有连接排、线束和接触电阻。大电流时线束压降可能达到50~100mV,这个压降没进标定表。 解决:在不增加硬件的条件下,用标定时的线束电阻值乘当前电流,对电压下限做动态修正;或者在HPPC数据采集时保留“电芯端电压”和“采样点电压”两路,把差值做成电流的补偿表。这步是最容易被当成“算法bug”实际却是“工程细节”的坑。

5.4 充电SOP与放电SOP共用一套矩阵

现象:车辆在高功率直流充电时,请求功率被限制到明显低于充电桩能力,但电芯温度适中、SOC也不高。 原因:充电SOP与放电SOP采用了同一套标定表和同一个内阻模型。实际上充电时负极电位和析锂风险是主要约束,其极化特性与放电完全不同;而且充电持续时间通常以分钟计,比10s放电档大得多。 解决:充放电SOP必须分开标定,充电表的时间档至少覆盖10s、60s和“持续到充满”三档。尤其是快充场景,SOP输出要直接参与充电桩功率协商,而不是只做保护判断。

5.5 SOH与SOP共用同一个滤波器:误差互相放大

现象:车辆在长坡道连续爬坡后,SOP数值持续下降,同时SOH也出现同步下降,等到坡道结束,SOH又恢复。 原因:SOP受温度和内阻影响是正常的,但SOH滤波器误把SOP限制事件当作衰减证据,或者说两者共用了一个观测信号,导致误差沿“限制—衰减—更限制”的环路放大。 解决:SOH和SOP的观测信息可以共享,但滤波器必须独立,且SOH的更新权重不应包含短时功率事件。我在每个更新周期里加了一个“事件标签”,只有高置信度的长时片段才能进SOH滤波器,短时SOP触发一律只修正R0/R1,不碰容量SOH。

6. 进阶方向:查表+在线修正的融合结构,以及验证指标

6.1 融合修正函数的最小实现

查表法和模型法各有所长,量产里最优解是二者融合:查表提供基准,一阶RC模型提供瞬态修正。下面的函数把这个结构压缩成一个最小实现,适合作为算法框架的起点。

def fused_sop_estimation(soh, soc, temp_sensor, dt, ocv, r0, r1, tau, lookup_base_power): # 1) 查表得到基准功率,SOC和温度做主索引 base_power = lookup_base_power(soc, temp_sensor) # 2) 温度传感器滞后补偿:估算芯部温度 # tau_thermal取100~300s,传感器越大滞后越大 temp_core = temp_sensor + (core_temp_prev - temp_sensor) * \ math.exp(-dt / tau_thermal) # 3) SOH对基准值收缩 # 0.5+0.5*soh 保证SOH=0.8时还有90%的功率 soh_factor = 0.5 + 0.5 * soh # 4) 电压约束动态修正:用一阶RC模型计算电压项 v_limit_factor = (ocv - v_min) / \ (r0 + r1 * (1 - math.exp(-dt / max(tau, 1.0)))) # 5) 基准、SOH、动态电压约束三者取交集,再限幅 power_limit = min(base_power * soh_factor, v_limit_factor * ocv) return max(power_limit, 0.0)

这段代码真正需要标定的参数只剩tau_thermal、v_min和查表数据。我的建议是:先离线把查表法测准,再叠加RC修正,不要同时调太多参数。一次只动一个环节,你才知道哪个参数在拖后腿。

6.2 这类策略验证看什么:三个关键指标

SOH和SOP策略好不好,不能只看算法仿真曲线,要放到整车和台架上用三个指标卡。

第一个是SOP预测功率与实际可输出功率的误差:把整车实测的功率限制值与离线重算的SOP预测值作差,95%分位误差控制在5kW以内,低温段放宽到10kW。第二个是电压越限事件率:统计每千公里行驶中电芯端电压越过Vmin/Vmax的次数,这个指标考察SOP是否“过度乐观”。第三个是SOH收敛带宽:同一块电池在三个月内的SOH估值波动不超过2%,且与参考容量衰减趋势一致。这三个指标同时满足,策略才算真正落地。

我在做某车型的三高标定时常说一句话:SOH和SOP是BMS里最不像算法的模块,因为它们一半靠算法、一半靠标定。数据少的时候先别急着加模型复杂度,把查表做准、时间尺度分开,比什么都管用。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进