FOMIAUKF:分数阶多新息自适应UKF实现高精度电池SOC估计

发布时间:2026/10/21 18:09:21
FOMIAUKF:分数阶多新息自适应UKF实现高精度电池SOC估计 但凡和电池SOC估计打过交道的人都遇到过这种尴尬实验台上状态估计精度稳定在1%以内的滤波器一到实际工况就各种飘。问题往往不在算法本身而在模型。锂电池内部的电化学过程本质上带有记忆性和扩散特征传统整数阶等效电路模型对这种行为的描述能力有限。所以当我看到FOMIAUKF这类方案——把分数阶建模、多新息理论、自适应噪声处理和UKF滤波框架组合到一起来做电池SOC估计时第一反应是这条路终于把“模型贴合度”和“滤波鲁棒性”同时照顾到了。这套方案不是单纯把几个热门算法拼在一起。分数阶模块解决的是“模型长什么样”的问题多新息和自适应解决的是“滤波器怎么用信息”的问题UKF解决的是“非线性怎么传”的问题四块各管一段配合起来正好覆盖了SOC估计的主要痛点。如果你正在做电池管理系统算法预研、写相关方向的论文或者只是想把手上的SOC估计精度再往上拉一截这套组合值得花上两周时间吃透。下面我把原理、Matlab实现、调参心得和踩过的坑一次性讲清楚。1. 从痛点说起为什么SOC估计需要“分数阶多新息自适应”这套组合拳1.1 硬币的两面SOC估计为什么是个硬骨头SOCState of Charge荷电状态说白了就是电池还剩多少电通常用百分比表示0%到100%。它不能直接测量只能通过可测的端电压、电流、温度去反推。这个反推过程难在三个地方第一电池模型本身不准OCV-SOC曲线受温度、老化、电流方向影响模型参数一直在变第二传感器噪声的统计特性是未知的而且随时间变化你很难提前把过程噪声和观测噪声定死第三初始SOC往往不知道一辆车开着开着换电池、一个储能柜断电重启滤波器得能在几分钟内把SOC从错误初值拉回到真实值附近。这三件事单独拎出来都有办法解决但叠加在一起常规做法就开始吃力。安时积分法最简单但它是个开环积分电流传感器哪怕只有1%的误差积分一小时后就是1%的容量误差而且初始SOC错多少结果就错多少没有任何收敛机制。开路电压查表法需要把电池静置到电压稳定在线工况根本不满足。真正能在线收敛的还是得靠模型加状态估计器。1.2 从EKF到FOMIAUKF一条被反复验证的递进路线状态估计器这条路上大家最早用的是EKF扩展卡尔曼滤波。EKF的思路是把非线性函数在当前工作点做一阶泰勒展开然后用线性卡尔曼滤波的公式去更新。问题也出在这个“一阶展开”上电池的OCV-SOC曲线在中段相对平缓但接近充满和放空时斜率突然变陡强非线性区域里忽略高阶项会造成明显的误差严重的时候滤波器直接发散。UKF无迹卡尔曼滤波是更好的选择。它不再做线性化而是用一组精心挑选的Sigma点去直接穿透非线性映射理论上能捕获到三阶矩的信息对电池这种中等非线性系统很够用。我在多个项目里对比过UKF在SOC估计上的稳定性和精度通常都比EKF要好所以这套方案的基础滤波器选UKF而不是EKF是合理的第一步。再往上加就是两个针对“模型”和“信息利用”的改进。电池内部的锂离子扩散、电荷转移过程具有明显的分数阶动力学特征很多文献用分数阶微积分的“记忆性”去描述扩散尾巴等效电路模型里普通电容换成本质上更符合物理特性的“分数阶元件”后模型精度能提升一截。多新息理论则是把当前时刻的残差和过去L个时刻的残差堆叠在一起做修正相当于一次修正用了“一堆”新息收敛更快、对噪声更鲁棒。最后再加一层自适应在线调整噪声协方差矩阵于是就有了FOMIAUKFFractional-order Multiple Innovation Adaptive UKF。2. 核心原理拆解FOMIAUKF的四块积木2.1 分数阶模型给电池做“带记忆的状态空间”先理解为什么要用分数阶。理想电容的阻抗是1/(jωC)频率每增加10倍阻抗下降10倍相位是-90度。但电池里的双电层和扩散过程实测阻抗谱的相位往往在-45度到-80度之间频率响应呈现“介于电阻和电容之间”的特性。单靠整数阶RC网络要拟合这种特性需要堆好多组RC并联参数多还容易过拟合。分数阶CPE元件Constant Phase Element的阻抗是Z1/(Q·(jω)^α)其中α在0到1之间一个元件就能覆盖一大片非整数阶频响参数更少、拟合更准。在时域实现时最常用的是Grünwald-LetnikovGL定义。对于一个α阶导数其离散近似可以写成短记忆形式的有限差分D^α x(t_k) ≈ (1/T_s^α) · Σ_{j0}^{L_F} (-1)^j C(α, j) x(t_k - jT_s)其中C(α, j)是广义二项式系数L_F是截断长度。这个公式看着复杂但物理含义很直白当前时刻的导数不仅跟当前时刻有关还跟过去L_F个时刻的状态有关每一项都有一个衰减系数(-1)^j C(α, j)。这就是“记忆性”——系统当前的变化率不只看现在还要回望历史。把它整理成状态递推形式后分数阶状态方程在离散时间下长这样x_{k1} T_s^α (A x_k B u_k w_k) - Σ_{j1}^{L_F} (-1)^j C(α, j) x_{k1-j}注意最后这个求和项它把过去L_F步的状态全带进来了。这是和整数阶模型最本质的区别整数阶模型只需要上一时刻的状态就能递推当前时刻分数阶模型得维护一个历史状态窗口。在电池应用里我采用的模型结构是电压源OCV(z)串联欧姆内阻R0再加两段极化支路极化支路里的电容换成CPE。状态向量取x[z, V_E, V_D]^T分别表示SOC、电化学极化电压、浓差极化电压。SOC通道保留整数阶积分安时积分的本质两个极化支路用分数阶微分方程描述这样物理含义清晰也方便和整数阶模型做对比实验。2.2 UKF不用算雅可比矩阵的非线性传播UKF的核心是UT变换。它的直觉想法是与其把一个非线性函数线性化不如在状态均值附近按一定规则撒一些点Sigma点把这些点分别扔进非线性函数里再用输出点集重新统计“均值”和“协方差”。这比泰勒展开更聪明因为Sigma点带出了状态的完整分布形态而不是只盯着切线方向。给定n维状态x̂和协方差P先计算一个系数λ α_UT²(nκ_UT) - n然后生成2n1个Sigma点X_0 x̂ X_i x̂ sqrt((nλ)P)i, i1,...,n X{in} x̂ - sqrt((nλ)P)_i, i1,...,n这里的sqrt是矩阵平方根在Matlab里常用chol分解或者sqrtm实现。每个点对应权重W_m^0 λ/(nλ)W_c^0 λ/(nλ) (1-α_UT²β_UT) W_m^i W_c^i 1/(2(nλ))i1,...,2n三个参数的含义α_UT控制Sigma点的散布范围一般取0.01到1之间β_UT是状态分布先验信息项高斯分布时取2κ_UT一般取0或3-n确保(nλ)P正定。预测步把每个Sigma点代入分数阶状态递推函数得到预测点集后加权统计出先验均值和协方差。更新步再对量测方程做同样的UT传播得到量测预测均值和新息协方差再算互协方差出增益。UKF全程不需要计算雅可比矩阵这一点对工程实现非常友好。电池模型的OCV-SOC曲线往往用查表或分段多项式表示求导麻烦还容易出错UT变换直接绕开了这个坑。2.3 多新息一次修正用“一堆”残差标准卡尔曼滤波家族的更新步用的是“单新息”也就是当前时刻量测值和预测量测值之间的差e_k y_k - h(x̂_k^-)。这个残差包含了当前时刻所有能修正状态的信息但如果当前时刻恰好被一个离群噪声污染单新息就会把错误信息直接灌进状态里造成估计值跳变。多新息的做法是把最近L个时刻的新息拼成一个扩展矩阵E(k) [e_k, e_{k-1}, ..., e_{k-L1}]状态更新时一次喂给增益矩阵相当于用最近一段时间窗内的“观测趋势”来修正状态而不是只看一瞬间。直觉上有点像你在开车看路况单新息只看当前这一帧画面多新息则把过去几帧连贯起来判断车辆是否在正确车道后者对画面噪声自然更从容。代价是内存里要维护一个长度为L的滑窗增益矩阵的维度也从n×m变成n×(L·m)计算量有所上升。工程实现上我会对滑窗内不同时刻的新息乘一个衰减系数比如0.95^k的指数衰减让越老的新息权重越低。这样做既能利用历史信息又不会让过久远的残差把当前状态拖住。用等权其实也能跑但L取太大时状态响应会明显变慢衰减系数能缓解这个副作用。2.4 自适应在线修正噪声协方差所有卡尔曼滤波变体都绕不开两个矩阵过程噪声协方差Q和量测噪声协方差R。实际系统里这个值根本测不准而且电流、温度、老化都会让噪声统计特性漂移。如果把R定得过小滤波器会过度相信量测状态跟着电压毛刺乱跳定得过大又反应迟钝SOC误差长时间不收敛。Q和R一成不变相当于身穿一套固定尺码的衣服跑完整个四季。自适应的思路是用新息序列的实际统计量去反推噪声协方差。具体做法是维护一个滑窗计算窗口内新息的实际协方差C_e。理论上C_e应该约等于量测预测协方差P_yy加上真实R的贡献所以可以近似反解出R的修正量R_update C_e - P_yy然后再用指数加权滑动平均把修正量平滑地融合进当前的RR (1-ρ)·R ρ·R_updateρ一般取0.03~0.1关键在于ρ不能太大否则R会被瞬时波动带着走滤波器会变得神经过敏。Q的自适应比R更麻烦因为过程噪声的作用被整个状态递推过程“过滤”了一遍反解时极易失去正定性。在FOMIAUKF里我倾向于保持Q不变只自适应R这招在工程上是稳的。如果确实连Q也要在线修必须加正定性保护和上下限约束否则滤波器大概率在某次迭代后直接发散。3. Matlab实现全过程从参数表到算法主循环3.1 模型离散化与参数设置这里给出一组我在三元锂电池仿真中常用的示例参数取值量级符合常规动力电池场景但具体换电池后需要重新辨识。参数符号示例取值说明额定容量Cn2 Ah仿真放电基准欧姆内阻R030 mΩ含端子和电解液电阻电化学极化电阻R_E12 mΩ对应SEI膜和电荷转移过程浓差极化电阻R_D25 mΩ对应锂离子扩散过程CPE伪电容Q_E1.8 F·s^(α_E-1)电化学支路伪电容CPE伪电容Q_D3.2 F·s^(α_D-1)浓差支路伪电容分数阶阶次α_Eα_D0.80.6反映CPE的“介于电阻电容之间”程度采样时间T_s1 s和BMS实际采样周期一致分数阶截断长度L_F25历史记忆窗口长度多新息长度L_mi8滑窗内新息个数参数在Matlab里集中放在一个结构体里方便调试params.Cn 2.0; params.R0 0.030; params.R_E 0.012; params.R_D 0.025; params.Q_E 1.8; params.Q_D 3.2; params.alpha_E 0.8; params.alpha_D 0.6; params.Ts 1; params.LF 25; params.Lmi 8; params.n 3;分数阶二项式系数的递推是GL离散化的关键建议一次性算好存起来别在每次迭代里重复计算alpha_frac params.alpha_E; % 这里以电化学支路为例浓差支路单独算一组 c_frac zeros(params.LF 1, 1); c_frac(1) 1; for j 1:params.LF c_frac(j 1) c_frac(j) * (j - alpha_frac) / (j 1); end递推式里的符号已经包含正负号后面直接用这个系数向量做加权求和即可。3.2 算法主流程Sigma点、分数阶递推、多新息更新FOMIAUKF的主循环流程可以拆成以下几步生成Sigma点基于当前状态x̂和协方差P按UT变换公式生成2n1个点。分数阶状态传播对每个Sigma点调用分数阶离散递推函数得到预测点集这里要注意每个Sigma点需要携带自己的历史状态窗口。加权统计根据Sigma点权重计算先验状态均值x̂_k^-和协方差P_k^-。量测预测将Sigma点代入量测方程得到量测预测分布算ŷ_k^-、P_yy、P_xy。多新息修正把当前新息送入滑窗组成扩展新息矩阵E(k)用扩展增益更新状态。自适应更新R用窗口内的实测新息协方差反推R并做指数滑动平均。状态约束SOC做0~1限幅必要时对P做对称正定修复。分数阶状态递推函数是这块的核心。它接收当前状态、历史窗口和控制输入返回下一时刻状态function x_next frac_state_update(x_now, x_hist, u, c_frac, params) Ts params.Ts; alpha params.alpha_E; % 简化写法实际两条极化支路分别处理 A diag([0, -1/(params.R_E * params.Q_E), -1/(params.R_D * params.Q_D)]); B [ -1/params.Cn; 1/params.Q_E; 1/params.Q_D ]; % 分数阶GL短记忆递推 x_next Ts^alpha * (A * x_now B * u); % 历史记忆补偿项 for j 1:params.LF x_next x_next - c_frac(j 1) * x_hist(j, :); end end这里的x_hist是L_F×n的历史状态矩阵最新的历史放在第1行最老的放在最后一行相当于一个滑动窗口。严格实现时需要注意每个Sigma点都有自己独立的历史路径所以不能用同一个x_hist去传播所有Sigma点。我最开始实现时图省事给所有Sigma点共用了同一份历史状态结果协方差被严重低估滤波器表现相当诡异。正确做法是开一个L_F×n×2n1的三维数组或者用元胞数组存每个Sigma点自己的历史窗口。多新息更新部分核心代码逻辑是这样的% 计算当前新息 e_k y_meas - y_pred; % m×1m是量测维度 % 维护滑窗E_buffer是m×Lmi矩阵 E_buffer [e_k, E_buffer(:, 1:end-1)]; % 扩展增益更新状态不同列用衰减系数 for i 1:Lmi coef decay_factor^(i-1); % decay_factor可取0.9~1.0 x_upd x_upd K_ext(:, (i-1)*m1:i*m) * E_buffer(:, i) * coef; end扩展增益矩阵K_ext的维度是n×(Lmi·m)每一段对应不同滞后时刻的互协方差信息。这里有一个实现细节如果Lmi个时刻对应的P_xy和P_yy都不同严谨的做法是为每个滞后时刻单独计算增益工程简化时可以用当前时刻的P_xy、P_yy近似代替所有滞后时刻配合衰减系数使用效果依然不错还能省掉大量矩阵运算。3.3 核心函数与校验三板斧整个工程建议按四个文件组织参数初始化脚本、模型函数状态递推和量测、算法主循环、结果绘图脚本。写完第一版后不要直接上真实数据先跑三个自检。第一板斧无噪声测试。把过程噪声和量测噪声都设成接近0给定一个准确的初始SOC跑完整个工况。如果滤波发散说明代码逻辑或模型递推有bug正常情况滤波轨迹应该基本贴合真实SOC。这一步能过滤掉八成低级错误。第二板斧初始SOC偏差测试。把初始SOC故意设偏20%观察滤波收敛曲线。合格的滤波器应该在几十秒到几分钟内把SOC拉回到真实值附近。如果收敛太慢检查R是否设得太大或者多新息滑窗Lmi是否导致响应迟钝。第三板斧突变工况鲁棒性测试。在工况中段加入一个电流阶跃或者短暂的电压传感器尖峰看估计值是否出现明显跳变。FOMIAUKF在自适应和多新息的双重作用下应当比普通UKF更稳。如果尖峰直接把滤波器打飞检查新息异常值剔除逻辑——超出3σ的新息应该被截断或降权而不是原样进增益。4. 实验设计、结果对比与调参心得4.1 仿真场景与性能指标仿真数据集我建议至少包含两种工况。第一种是恒流放电1C倍率从100%放到5%中间穿插静置段。第二种是动态工况可以用标准驾驶循环对应的电流序列或者自己设计一组多阶跃电流让SOC大范围上下波动且存在反复的充放电切换。动态工况下OCV-SOC曲线反复进出非线性区对滤波器压力最大最容易分出高低。性能指标方面别只看最终RMSE建议四个指标一起看RMSE反映整体精度MAE反映平均偏差最大绝对误差反映最坏情况收敛时间T_conv反映初始误差修正能力。另外要记录一次工况结束时的滤波发散率尤其是多组噪声种子下的统计表现单次仿真结果说服力太弱。4.2 结果对比每个模块贡献了多少我用同一组仿真工况做了四组对比整数阶UKF、分数阶UKF单新息、固定噪声、分数阶多新息UKF无自适应、以及完整的FOMIAUKF。结果有一个很明显的趋势。方案建模方式新息利用噪声处理相对RMSE收敛速度实现复杂度整数阶UKF整数阶RC单新息固定基准中低分数阶UKF分数阶CPE单新息固定降低约20%~30%中中分数阶多新息UKF分数阶CPE多新息固定降低约30%~45%较快中高FOMIAUKF分数阶CPE多新息自适应降低约40%~60%快高这些数字是我在某三元锂电池仿真参数下的相对表现换电池型号、换工况、换噪声强度会变但趋势是可复现的。值得强调的是每个模块的贡献不是简单叠加分数阶把模型偏差压低了多新息把量测噪声的污染减轻了自适应在噪声统计失配时兜底。三者协同之后最大误差的改善往往比平均误差更明显这对工程实践很关键——BMS最怕的不是平均误差大而是某一次极端工况下SOC突然跳变好几度。模块贡献的定性结论是如果只加一个模块优先加分数阶建模因为模型贴合度是所有滤波算法的地基如果已经有分数阶模型再上多新息收敛速度的提升立竿见影自适应适合在传感器噪声漂移明显的场景里加分在噪声本来就平稳的实验室环境里意义有限。4.3 调参实操经验几个关键旋钮多新息长度Lmi是最需要反复试的参数。Lmi太小多新息的优势体现不出来Lmi太大一是计算量膨胀二是估计值对真实SOC的变化响应变慢。我在1秒采样周期下试过Lmi从3到20的序列5到10这个区间性价比最高超过15之后精度提升已经很微弱反而在电流状态突变的瞬间会出现明显的“拖尾”现象。分数阶截断长度LF没有太多玄学它只影响GL离散化对历史记忆的截断程度。LF太小模型波形会出现高频抖动LF取到20到30之间基本就能覆盖有效历史影响再大只是徒增内存。如果发现抖动先加LF而不是改噪声因为这是模型刚性不足。噪声初值也有门道。R给得稍微偏大一点滤波器刚启动时会更谨慎不易因初始几步的异常量测而剧烈跳动等自适应模块慢慢把R拉向真实值精度会逐渐上来。Q的初值要偏小因为它代表“模型有多不可信”取值过大会让滤波器过度依赖量测失去状态估计的意义。P的初值如果初始SOC不确定度大可以放宽到真实SOC初始误差的平方量级比如初始误差20%对应P(1,1)取0.04。5. 常见问题与排查技巧实录5.1 滤波发散的症状、定位与急救先描述典型的发散症状SOC估计值在某个时刻突然跳变到错误范围或者卡在0/100%的限幅值上不动伴随电压残差持续增大。遇到这种情况先不要急着改算法按照下面这个顺序排查能快速定位问题。第一步查正定性P矩阵在迭代中是否失去对称正定性。协方差矩阵一旦出现非正定Sigma点的矩阵平方根就取不出来了滤波结果完全失真。我习惯每隔几步做一个检查对P做对称化处理P(PP)/2再用eig或chol判断正定性不满足就回退到上一时刻的P或者加一个小对角阵εI做正则化。第二步查模型一致性把滤波估算出的电压和当前电压画在同一张图上如果残差出现系统性偏移而不是随机噪声那就是模型参数有问题——可能是OCV-SOC曲线拟合不准也可能是分数阶阶次α取值偏离实际。这时候多新息和自适应都救不了你它们只能处理噪声处理不了模型偏差。第三步查增益退化多新息扩展增益矩阵里如果某几个滞后时刻的互协方差数值趋近0说明这些新息实际上被“冻结”了滑窗越长越容易出现。可以打印出每个滞后时刻对应的等效增益权重看看是不是衰减系数把老信息压得太死了。5.2 计算量控制与代码提速FOMIAUKF比标准UKF多出的计算主要在三块分数阶历史窗口的循环求和、多新息扩展矩阵的运算、自适应滑窗的统计更新。在Matlab里最容易失控的是在状态传播时写双层for循环。优化思路有三个尽量向量化二项式系数的加权求和不要一个j一个j地累把Sigma点的传播改为批量矩阵运算一次性递推所有点而不是逐个点调用函数多新息更新的结果合并矩阵化避免在循环里反复更新x_upd。如果仿真长度长、需要批量跑对比实验建议把三个增益矩阵的中间结果缓存到文件里或者用并行循环加速多组随机噪声种子的实验。在实际BMS落地时还要做一步更激进的简化把历史状态窗口烧到设计好的环形缓冲区里用指针移动代替整块数据搬运并且考虑把分数阶递推里的L_F从25压缩到15左右配合在线参数辨识补偿精度损失。5.3 落地注意点从仿真到BMS的最后一步仿真里跑通只是第一步真正放到BMS上还有几个现实问题。第一是采样时间和计算时间窗的约束BMS主控多半是MCU浮点运算能力和内存都有限仿真里1秒采样、Lmi8的配置到嵌入式环境里可能要改成200ms甚至更慢的周期多新息窗口也要相应收缩。第二是温度补偿分数阶阶次和CPE参数都随温度变化低温时α会偏移光靠固定参数的FOMIAUKF不够建议叠加一个温度查表修正通道。第三是电流传感器偏差和量程漂移我的经验是把它建模成一个额外的待估计状态放进状态向量里一起滤波效果比单独放一个常数补偿值好得多。这套方案还有一个天然的扩展方向把在线参数辨识和SOC估计结合起来。现在很多研究是把分数阶模型参数放进增广状态里让FOMIAUKF同时估计SOC和模型参数代价是状态维度从3跳到8到10计算量涨得更厉害但换来的是真正意义上的自适应建模。后续如果你做完SOC估计还有余力这个方向值得投入。6. 一点个人的实操体会我做完这个项目最大的感受是别被它的一堆术语吓住FOMIAUKF本质就是把四件大家都知道的东西组合起来难点不在原理而在工程细节的配合。调试时最有效的做法是把“模型层、观测层、噪声层”三层拆开分别debug完再合起来。先在无噪声环境验证模型递推和量测一致性再单独测UKF的Sigma点传播是否正确最后才把多新息和自适应打开。绝大多数看似玄学的发散问题排查到最后都落在一个细节上我踩得最深的就是高估了模型的可靠度把Q设得偏大导致滤波器宁可相信跳变的电压也不相信模型递推。另一个体会是调参之前一定要固定一个评价脚本把四组对比算法放在同一个工况和同一组噪声种子下跑否则你永远不知道改的某个参数到底有没有用。多做几组噪声种子的统计分析比单次跑出一个漂亮的RMSE有意义得多。这套项目做完之后我再看普通的UKF和EKF方案会明显感觉到它们在模型偏差和噪声失配场景下的吃力FOMIAUKF的复杂度是值的。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询