很多做电池管理算法的同行,第一次上手SOC估计基本都是从安时积分开始的。公式只有一行,但误差会累积,所以大部分人很快就会转向卡尔曼滤波这一派。这篇想聊的是我用 EKF(扩展卡尔曼滤波)在公开锂电池老化数据集上做 SOC 与寿命估计的完整过程,重点在于:寿命并不是单独算出来的,而是和 SOC 放进同一套状态估计框架里一起推。文章会从数据准备、等效电路模型辨识、EKF 递推细节一直讲到结果复盘和我自己踩过的坑,适合准备入电池算法坑、或者已经能跑通简单 SOC 估计但想把退化因素加进来的朋友。
先说结论:EKF 做 SOC 和寿命联合估计是可行且相对好落地的。它不像无迹卡尔曼滤波那样对非线性模型有更强的逼近能力,但胜在结构直观、计算量小、实现门槛低。只要把电池模型辨识得足够干净,把噪声协方差调对,SOC 误差稳定在 2% 以内并不难,容量衰减的在线跟踪也能做到 1% 左右的误差。当然,这些都是有前提的,后面我会逐个拆开讲。
1. SOC与寿命放进同一个EKF框架里,到底解决了什么问题
1.1 为什么寿命估计不能和SOC割裂开
SOC 的定义是剩余容量占当前可用容量的比例。这里的关键词是“当前可用容量”,而不是出厂铭牌容量。电池老化之后,可用容量会从初始值一路往下掉,如果算法仍然用初始容量去做安时积分,SOC 算出来会系统性偏大。
举例来说,一颗标称 2.0Ah 的电芯,实际老化到 1.6Ah。你用 2.0Ah 做分母,放掉 0.8Ah 后算出来 SOC 是 60%,但真实剩余容量只有 0.8Ah,按当前 1.6Ah 的容量算,实际 SOC 是 50%。这个偏差会随着老化加深越来越大,这也是很多纯安时积分方案用久了之后“充满电很快掉电、显示还有电却突然没电”的原因之一。
所以 SOC 估计不能脱离 SOH(健康状态)单独做。当你把容量也作为状态量放进滤波器里,SOC 的分母会随着老化自动修正,估计值才会长期稳定。这也是我这篇文章想强调的第一个设计原则:SOC 和寿命是强耦合的,EKF 刚好能把这个耦合关系建模进同一个递推框架。
1.2 EKF的选型理由,以及它吃什么样的“料”
卡尔曼滤波适用于线性系统,而电池的端电压和 SOC 之间是明显的非线性关系,所以要用扩展卡尔曼滤波。EKF 的思路很简单:在每个时间步把非线性模型在当前状态附近做一阶泰勒展开,得到雅可比矩阵,然后套用标准卡尔曼滤波的预测-更新流程。
为什么不用更复杂的滤波算法?因为我面对的公开老化数据集里,采样周期固定、工况相对规范,EKF 的线性化误差完全在可接受范围内。UKF 和粒子滤波确实能在强非线性场景下获得更好效果,但代价是计算量和调参复杂度成倍上升。对工程落地而言,EKF 是个性价比极高的起点。
EKF 需要两类输入。一类是模型输入:电流、温度、时间戳;另一类是观测值:端电压。模型方面,我选了二阶 RC 等效电路,配合 OCV-SOC 查找表。换句话说,EKF 不直接“看”容量,它通过端电压的残差来修正 SOC 和模型状态,容量则通过一个慢时间尺度的更新过程来跟踪。
1.3 一套可复现的实验基线
实验前我先定了一条明确的技术路线,避免后期反复改方向。整体流程分四步:数据清洗、模型参数辨识、EKF 实现、结果验证。数据来自某高校实验室公开的锂离子电池老化测试数据,里面包含多只电芯在常温下反复充放电的完整记录。每只电芯都有充电、静置、放电、再静置的标准流程,循环一直做到容量明显衰减为止。
我选择其中一只电芯作为主样本,循环数大约 400 次,容量从初始值衰减到约 80%。为了验证算法,前 80% 的循环用于模型参数拟合和滤波器调参,后 20% 作为测试集,专门用来检验 SOC 和容量估计的泛化能力。这种做法当时看起来有点“杀鸡用牛刀”,但最后证明非常值:很多滤波参数过拟合问题都是在测试集上暴露出来的。
2. 给EKF准备公开数据时,最该较真的几个字段
2.1 一份老化数据集的常规长相
公开的电池老化数据一般以循环为单位组织。每个循环通常包括恒流充电、恒压充电、静置、恒流放电、再静置这几段。记录字段基本围绕这几个维度:循环序号、相对时间、电流、电压、温度,有些还会直接给出该循环的放电容量。
拿到数据后不要急着丢进滤波器,先做三个基础检查。一是检查时间戳是否严格递增,采样步长是否均匀,很多公开数据在导出的过程中会出现重复时间戳或缺失行。二是检查电流方向定义,充电为正还是放电为正,不同来源的习惯不同,一旦搞反,EKF 的收敛方向会直接开始。三是确认电路容量计算口径,数据里给的容量是用放电电流对时间积分得到的,还是用充电电流积分得到的,这两者会因为库仑效率而略有差异,一般以放电容量作为寿命基准。
2.2 清洗、切片和中止条件判定
数据清洗里最容易被忽略的是“循环中止条件”的判定。比如恒流放电阶段,什么时候算放电结束?是电压达到截止电压,还是电流降到某个阈值?如果同一份数据里不同循环的截止条件不一致,容量退化曲线就会掺入系统误差。
我的做法是对原始循环做统一重采样,时间步长统一为 1 秒,然后按照记录的 step 状态字段把充、放、静置段切分出来。对于异常片段,比如电压突跳超过 100mV、电流出现不归零的漂移,我会先检查原始说明文件,判断是传感器抖动还是真实工况。如果是传感器抖动,就做插值修正;如果是实验段本身有问题,直接弃用这个循环。这一步做完,后面模型辨识才会稳定。
2.3 容量序列的标定与漂移处理
老化数据的核心输出是容量衰减曲线。每循环的放电容量可以通过放电段电流对时间的数值积分得到。积分时要注意步长不能统一套用名义采样间隔,最好用相邻时间戳的实际差值,因为公开数据集里偶尔会有几行采样间隔漂移。
得到容量序列后,我会做一次滑动平均,窗口取 5 个循环。这么做的目的是滤掉容量恢复效应带来的毛刺。很多锂离子电池在静置较久后,容量会短暂回升,这属于电化学特性,不是算法错误。如果直接拿原始容量序列做寿命估计,EKF 会把这些毛刺当成真实状态变化,导致容量状态抖动偏大。滑动平均可以缓解这个问题,但要注意窗口不能太大,否则会掩盖真实的加速老化趋势。
3. 电池等效电路模型辨识,跑偏一步后面全白做
3.1 二阶RC模型为什么是EKF和老化估计之间的平衡点
电池等效电路模型从简单到复杂有好几档。最简单的是一阶 RC,一个电阻加一个 RC 并联网络,适合模拟欧姆内阻和单一极化过程。但它对动态工况的拟合能力偏弱,尤其是负载突变后的电压弛豫曲线,尾巴拉得比较长,一阶 RC 往往拟合不干净。
二阶 RC 增加了一个时间常数更长的 RC 并联网络,用来描述电化学极化和浓度极化两个不同尺度的动态过程。实际辨识中,这两个时间常数一个在几秒到几十秒,另一个在几十秒到几百秒,能较好地覆盖放电瞬间和长时间弛豫。三阶以上拟合效果提升有限,但参数辨识的维度和过拟合风险都会显著上升。所以我选了二阶 RC,这是精度和复杂度之间比较舒服的一个点。
等效电路的数学表达如下:
端电压 = OCV(SOC) - R0·I - V1 - V2
其中 V1 和 V2 是两个 RC 网络的极化电压,分别满足一阶动态方程。EKF 的状态向量里可以直接放这三个量:SOC、V1、V2。这样电压观测方程写起来非常自然。
3.2 OCV-SOC曲线的标定方法与静置实验
OCV-SOC 曲线是 EKF 观测方程里的核心非线性项。标定这条曲线最可靠的方法是静置法:把电池充到满电,静置足够长的时间让端电压回到平衡状态,记录开路电压;然后放掉固定比例的电量,再静置,继续记录。这样一路做到截止电压,就能得到一条离散的 OCV-SOC 关系。
实际做的时候要注意,静置时间不能太短。磷酸铁锂这类材料在 SOC 中段有一个电压平坦区,未完全平衡时的电压和平衡后的电压能差不少,标定出来的曲线会在平坦区出现假台阶。我一般让静置时间不低于 1 小时,条件允许的话 2 小时更好。考虑到公开数据的工况设计通常比较规范,也可以直接利用充放电之间的静置段数据来提取平衡电压,但必须筛选足够长的静置片段,宁可少用几个点也不要混入未平衡的数据。
标定完成后,还要注意曲线的方向。放电标定得到的 OCV-SOC 曲线和充电标定的曲线之间存在迟滞,尤其是在中段。EKF 模型里如果只用一个放电曲线,充电过程中电压估计会产生一个偏置。简单处理方法是先用放电曲线作为统一基准,因为在放电工况下做寿命测试,这个基准的一致性最好。
3.3 RC参数辨识:指数拟合和最小二乘兜底
R0、R1、C1、R2、C2 的辨识通常利用放电结束后的静置段。放电电流突然降到 0 的瞬间,欧姆内阻上的压降先消失,端电压会瞬间跳升,这个跳变电压除以放电电流就是 R0。跳变之后剩余的缓慢回升部分,就是两个 RC 网络的弛豫过程。
对静置段的电压恢复曲线做双指数拟合,可以提取两个时间常数和对应的幅值。这里有个经验问题:双指数拟合对初值很敏感,如果初值给得不好,拟合算法会收敛到局部最优。我的做法是先在半对数坐标下肉眼观察曲线,把明显较快的部分和较慢的部分分开,分别用单指数拟合得到两组初值,再丢进双指数拟合做整体优化。
如果静置数据质量一般,还可以用带遗忘因子的递推最小二乘在放电动态段直接在线辨识。这个方案的优点是能处理连续变化工况,缺点是参数会随 SOC 变化,需要分段辨识。我的经验是:先把 OCV-SOC 标定好,再用静置段做离线辨识,最后用动态数据验证,这样三个环节互相兜底,不容易出现“拟合很漂亮但一跑动态就崩”的情况。
3.4 模型验证与残差检查
参数辨识完成后,一定要做模型验证,不要看拟合误差小就收工。验证方法是把辨识出的模型放到一段没有参与参数拟合的放电数据上,用电流作为输入,逐秒递推模型电压,然后和实测端电压做残差分析。
理想情况下,残差应该是围绕零附近的白噪声,幅度在二三十毫伏以内。如果你看到残差在 SOC 低端出现明显负偏,说明 OCV-SOC 曲线低 SOC 段标定得不够准;如果残差在负载突变后出现长尾巴,说明某个 RC 时间常数偏了。这些问题如果不在模型阶段解决,到了 EKF 阶段会全部转化为 SOC 估计误差,而且极难排查。
4. EKF里最容易写错的数学细节与调参手感
4.1 状态变量、输入和观测方程怎么排
EKF 的状态向量我设为 x = [SOC, V1, V2]^T。输入是电流 I,采样步长是 Δt,容量是 C_n。注意这里的 C_n 是当前健康状态下的可用容量,不是出厂容量。如果暂不把 C_n 作为状态,可以先设为当前估计值,在慢时间尺度更新时再修改。
状态预测方程:
SOC(k+1) = SOC(k) - I(k)·Δt / (3600·C_n)
V1(k+1) = V1(k)·exp(-Δt/τ1) + R1·I(k)·(1 - exp(-Δt/τ1))
V2(k+1) = V2(k)·exp(-Δt/τ2) + R2·I(k)·(1 - exp(-Δt/τ2))
这里 τ1=R1·C1,τ2=R2·C2。整个过程是线性的,因为 SOC 更新本质是库仑计数的离散形式。非线性主要出现在观测方程里:
V_t(k) = OCV(SOC(k)) - R0·I(k) - V1(k) - V2(k)
EKF 要做的事,就是通过对 SOC 的观测修正来校正库仑积分的漂移。
4.2 非线性观测的雅可比计算,以及数值线性化
观测方程对状态求偏导可以得到观测矩阵 H:
∂V_t/∂SOC = dOCV/dSOC
∂V_t/∂V1 = -1
∂V_t/∂V2 = -1
这里最容易写错的是 dOCV/dSOC。OCV-SOC 曲线通常是一张离散查找表,差分求导时方向很容易搞反。另一个容易踩的坑是平坦区导数接近零。在 OCV 曲线特别平缓的 SOC 区间,电压对 SOC 的灵敏度很低,EKF 的校正增益会变小,此时滤波结果会更依赖安时积分。这不是算法错误,而是信息量不足的客观表现,后面我会讲怎么处理。
实现时可以直接在 MATLAB 或者 Python 里用相邻点差分计算 H 矩阵。要注意的是,差分步长不能太大,尤其是曲线拐点附近,步长太大会把导数算得过于平滑,导致滤波增益失真。我一般用相邻两个标定点的斜率,但如果两个点之间的 SOC 间隔超过 10%,我会先用三次样条插值加密曲线,再重新计算导数。
4.3 Q和R矩阵:调参的实际手感
EKF 的调参核心是两个协方差矩阵:过程噪声协方差 Q 和观测噪声协方差 R。很多新手一上来就把 Q 设成对角线全相等的单位阵乘一个小数,这会导致状态间的噪声尺度完全不匹配。
我的经验是分状态给 Q。SOC 对应的是库仑计数的误差,主要来自电流传感器偏置和容量不准。电流传感器精度如果标称 0.5%,那么 SOC 过程噪声的方差可以按相应比例折算。V1 和 V2 对应的是模型未建模动态,和负载变化幅度直接相关,动态越剧烈,这一项应该给得越大。
R 体现的是电压传感器的测量噪声,可以参照数据采集设备标称精度。公开数据里如果没写传感器精度,可以先给一个 5mV 到 10mV 的经验值,然后观察滤波后的电压残差。残差标准差明显大于 R 的开方,说明 R 给小了;残差过小且 SOC 估计更新迟缓,说明 R 给大了。调 Q 和 R 没有绝对标准,正确做法是盯着创新序列的统计特性反复试。
4.4 初始化、发散防护和计算步长的取舍
EKF 对初始 SOC 误差有一定容忍度,但前提是初始协方差 P 不能给得太小。如果 P 初始值设成 0.01,相当于告诉滤波器“我非常相信初始 SOC”,那么前几百秒的电压残差几乎不会修正状态,收敛会变得很慢。我的做法是初始 SOC 协方差给到 0.1 以上,让滤波器在早期充分利用电压信息快速收敛。
数值上还有一个常见问题:P 矩阵在多次递推后可能不再严格对称正定,表现为某几个状态变量方差变成负值,滤波开始震荡。最简单的防呆处理是每个时间步结束后强制做一次对称化,把 P 更新为 (P + P^T)/2。更稳健的方案是使用平方根卡尔曼滤波形式,但工程上对称化配合对角加载基本够用。
计算步长方面,公开数据通常 1 秒一个点,EKF 直接按 1 秒递推即可。如果把数据降采样到 10 秒再跑,放电瞬间的电压跳变信息会被抹掉,R0 的校正作用会减弱,SOC 跟踪精度明显下降。所以除非计算资源非常紧张,我建议保持原始采样率。
5. 完整跑一遍:SOC跟踪和容量衰减估计各交了什么答卷
5.1 代码骨架(Python实现思路)
下面这段 Python 代码是整个 EKF 最核心的骨架,去掉了数据读取和 OCV 查找表的具体细节,只保留状态递推和更新逻辑,方便你对照自己的实现检查。
import numpy as np # 参数 R0, R1, C1, R2, C2 = 0.02, 0.01, 1000, 0.02, 5000 tau1, tau2 = R1 * C1, R2 * C2 C_n = 2.0 # 当前可用容量,后续随寿命估计更新 # 状态初始化 x = np.array([0.5, 0.0, 0.0]) # SOC, V1, V2 P = np.eye(3) * 0.1 # 噪声 Q = np.diag([1e-4, 1e-5, 1e-5]) R = np.array([[5e-6]]) # 对应约 2.2mV 标准差 def ocv_lut(soc): # 返回 OCV 和 dOCV/dSOC return ocv_value, ocv_slope # 主循环 for i in range(len(I)): dt = time[i] - time[i-1] # 预测 x[0] = x[0] - I[i] * dt / (3600 * C_n) x[1] = x[1] * np.exp(-dt / tau1) + R1 * I[i] * (1 - np.exp(-dt / tau1)) x[2] = x[2] * np.exp(-dt / tau2) + R2 * I[i] * (1 - np.exp(-dt / tau2)) F = np.eye(3) F[1, 1] = np.exp(-dt / tau1) F[2, 2] = np.exp(-dt / tau2) P = F @ P @ F.T + Q # 更新 ocv, slope = ocv_lut(x[0]) v_hat = ocv - R0 * I[i] - x[1] - x[2] H = np.array([[slope, -1.0, -1.0]]) y = V[i] - v_hat S = H @ P @ H.T + R K = P @ H.T @ np.linalg.inv(S) x = x + K.flatten() * y.flatten() P = (np.eye(3) - K @ H) @ P P = (P + P.T) / 2 # 强制对称化 # 归一化 SOC x[0] = np.clip(x[0], 0.0, 1.0)这段代码里,SOC 被限制在 0 到 1 之间,主要是防止数值异常时状态跑出物理范围。要注意的是 clip 操作只对状态有效,不需要再额外修改 P,因为正常工作时 SOC 不会越界。
5.2 单循环SOC跟踪的结果
跑完单个放电循环后,我最关心两个指标:一是 SOC 估计值与数据集中参考值的偏差,二是端电压残差的统计特性。这里说的参考值,通常是数据集中基于精确初始条件和库仑计数给出的 SOC 结果,实际项目里如果没有参考值,就用充满电起始和放空截止两个端点反推。
在模型辨识比较理想的情况下,SOC 估计误差大部分时间能控制在 2% 以内。放电初期和末期误差会略大,初期是因为初始 SOC 不确定性高,滤波器需要一两分钟收敛;末期是因为 OCV 曲线斜率变化剧烈,电压的微小噪声会被放大成 SOC 波动。相比之下,放电中段的 OCV 平坦区误差反而最稳,因为库仑计数校正虽然不敏感,但也不会被电压噪声过度干扰。
电压残差是更好的诊断工具。理想状态下,残差均值为零,标准差和设置的观测噪声 R 匹配。如果残差均值偏离零点达到几十毫伏,基本可以判定模型参数中某个阻值偏高或者偏低,比如电池实际内阻比辨识值大,残差就会呈现一致性偏负。
5.3 长期容量/寿命估计:双时间尺度策略
单循环 SOC 跟踪跑通之后,真正的难点在寿命估计。电池容量变化是一个很慢的过程,如果直接塞进 EKF 的快状态里,滤波器会把长期老化趋势和短时 SOC 波动混在一起,状态协方差很难调。
我采用的是双时间尺度策略。快时间尺度上,EKF 以秒级步长估计 SOC、V1、V2,容量 C_n 保持固定。慢时间尺度上,每完成一个完整充放电循环,就依据该循环的放电容量做一次容量修正,然后把修正后的容量值更新到快滤波器的 C_n 参数中。
具体到容量修正的算法,我并没有额外再起一个复杂的滤波器。因为公开数据集每个循环都有明确的放电容量积分值,我直接用这个积分值作为容量的“慢观测值”,配合一个简单的指数平滑或小增益 EKF 更新即可。更严格的做法是把 C_n 也放进慢 EKF 的状态里,用每个循环的 SOC 起点和终点作为约束来估计容量,适合在线场景;如果只是研究阶段复现,使用循环级容量观测值更省事。
5.4 误差统计和结果如何呈现
实验结束后,我把循环分为训练段和测试段,分别统计容量估计误差。下面的表格是一组典型结果,注意这是为了展示方法和趋势,具体数值会因数据集和模型参数不同而变化。
| 循环区间 | 参考容量(Ah) | 估计容量(Ah) | 相对误差 |
|---|---|---|---|
| 1-50 | 2.000 | 2.004 | 0.20% |
| 51-100 | 1.912 | 1.906 | 0.31% |
| 101-150 | 1.823 | 1.815 | 0.44% |
| 151-200 | 1.735 | 1.724 | 0.63% |
| 201-250 | 1.642 | 1.654 | 0.73% |
| 251-300 | 1.556 | 1.570 | 0.90% |
可以看到,误差随老化加深有小幅上升趋势。这种现象是正常的,因为容量越低,SOC 对容量误差越敏感,而且老化后期的 OCV 曲线形状也会发生微小的偏移。如果误差超过 2%,优先检查是否要把老化后的容量重新归一化到 OCV-SOC 曲线上,而不是急着改滤波器。
6. 边界场景、经典坑位和后续扩展路线
6.1 高倍率、低温和动态工况下EKF为什么会“虚报”
我前面讲的大部分结果,都是在常温、固定倍率的规范循环下得到的。一进入大倍率放电,R0 和极化参数会随电流密度变化,而固定参数模型并不能完全跟上。此时端电压残差会出现系统性增大,EKF 为了压低残差,会把 SOC 估计往错误方向带,表现为 SOC 测量值偏低或者突然跳变。
低温工况影响更明显。电解液电导率下降,内阻和极化时间常数都会变化,如果还沿用常温辨识的模型参数,端电压会持续偏低,滤波器被迫把这个偏置分配给 SOC 状态,误差会明显超过规范工况。解决思路有两个:一是建立温度、SOC、倍率的二维或三维参数表,让 EKF 在递推过程中按当前工况插值取用参数;二是增大过程噪声 Q 的对应项,让滤波器更能容忍模型失配,代价是 SOC 估计的平滑度下降。
动态工况下的问题是 SOC 变化剧烈,库仑积分漂移加快。EKF 可以在电压信息充分时及时校正,但在 OCV 平坦区,校正能力很弱。此时不要对单帧结果抱过高期望,工程上通常配合一段时间的滑动窗口或者工况识别来做补偿。
6.2 常见的三个坑:协方差锁死、SOC溢出、老化对OCV曲线的影响
第一个坑是协方差锁死。滤波器跑久了,P 矩阵会不断收缩,增益越来越小,最终表现为“滤波失效”,电压残差已经很大但 SOC 纹丝不动。最常见的诱因是 Q 值给得过小。我自己的习惯是,每跑完一段数据就检查 P 对角线元素的数量级,如果它比初始值小了好几个数量级,就说明 Q 与 R 的比例失衡,需要增大 Q。
第二个坑是 SOC 溢出。库仑计数更新这一步里,如果电流积分步长计算错误,SOC 在持续放电时可能越过 0 变成负数。负数 SOC 会导致 OCV 查找表外推风险,查出来的 OCV 完全不可信。所以每次递推后都需要做边界约束。要注意的是,约束 SOC 之后理论上 P 也应该做对应投影修正,否则边界附近的估计会出现轻微不一致,实际工程里影响不大,但最好有意识加上。
第三个坑比较隐蔽:老化对 OCV 曲线的影响。很多人默认 OCV-SOC 曲线在整个寿命期内不变,实际上随着正负极活性材料损失,曲线会有些许平移和变形。容量老化越深,这个偏差越明显,导致 EKF 用同一条查找表去观测不同寿命阶段的电池时,产生一个缓慢增加的偏置。有效的修正方案是把当前可用容量作为归一化基准,重新插值 OCV 曲线;如果数据充足,也可以分老化区间标定多条 OCV 曲线,每过一个寿命区间切换一次。
6.3 从EKF往哪走:AEKF、双扩展卡尔曼滤波、多尺度滤波
EKF 只是起点,不是终点。很多人做完 EKF 后会遇到两个瓶颈:一是过程噪声和观测噪声到底谁准,很难靠经验调准;二是容量估计依赖循环级积分观测,在线实时性不够。
第一个瓶颈可以交给自适应扩展卡尔曼滤波(AEKF)。AEKF 会在递推过程中利用创新序列的协方差实时估计 R 和 Q,让滤波器在不同工况下自动调节增益。我试过在动态工况下用 AEKF,SOC 误差比固定噪声 EKF 大概能改善三分之一,代价是程序复杂度和调参门槛上升。
第二个瓶颈可以用双扩展卡尔曼滤波解决。它把系统拆成两个 EKF:快 EKF 估计 SOC 和极化电压,慢 EKF 估计容量和内阻,两个滤波器交替递推并互相传递参数。这样在线工况下不需要等待完整循环结束就能持续更新容量估计,更适合真正的车载或储能系统。再进一步,就是多尺度滤波,把快慢状态彻底分层,算力消耗更大,但精度上限更高。
我的建议是,如果你刚接触这个方向,不要一上来就追求多尺度滤波。先把单 EKF 在干净数据上吃透,把电池模型辨识的功夫练扎实,然后逐步添加容量估计和自适应模块,这样每一步都有可比较的中间结果,出问题也知道该去查哪一层。
最后再分享一条个人体会:这类实验里,真正花时间最多的往往不是滤波器推导,而是对数据的理解和对模型的校核。数据清洗和模型辨识占了我整个工作量的七成,EKF 本身反而是最顺的部分。很多同行拿到公开数据集就急着跑滤波,结果被各种离群点和模型失配折腾得怀疑人生。先把数据摸干净,把模型验证做扎实,EKF 的精度自然就出来了。之后不管你是往 AEKF 走,还是往双 EKF 走,都会轻松很多。