使用matlab编写m脚本,编写无迹卡尔曼滤波算法(UKF)估计电池SOC,注释清晰
使用matlab编写m脚本,编写无迹卡尔曼滤波算法(UKF)估计电池SOC,注释清晰。 卡尔曼滤波算法(EKF)锂电池SOC估计,噪声系数自适应 Matlab程序 无迹卡尔曼,粒子滤波,状态估计,噪声,信号提取
最近在折腾锂电池状态估计,发现无迹卡尔曼(UKF)比传统EKF省事不少——不用算雅可比矩阵真是救命!今天拿Matlab撸了个基础版SOC估计脚本,实测数据跑起来效果还行,分享下实现思路和踩坑记录。
先看核心状态方程和观测方程。假设电池模型用二阶RC等效电路,状态变量选SOC和极化电压。这里偷个懒直接用简化模型,重点放在UKF实现上:
% 状态方程(离散化)
function x_next = stateFcn(x,current,dt,Q)
R0 = 0.01; % 内阻
Cn = 2.5*3600; % 额定容量
x_next = [x(1) - dt*current/Cn; % SOC递推
x(2)*exp(-dt/10)]; % 极化电压衰减
x_next = x_next + sqrt(Q).*randn(2,1); % 过程噪声
end
% 观测方程
function voltage = measFcn(x,current,R0)
OCV = 3.7 + 0.6*x(1); % 简化OCV-SOC关系
voltage = OCV - current*R0 - x(2);
end
重点来了——UKF的实现。和EKF不同,UKF用确定性采样点(Sigma点)传播统计特性,避免了线性化误差。核心步骤分三块:生成Sigma点、预测步、更新步。
使用matlab编写m脚本,编写无迹卡尔曼滤波算法(UKF)估计电池SOC,注释清晰。 卡尔曼滤波算法(EKF)锂电池SOC估计,噪声系数自适应 Matlab程序 无迹卡尔曼,粒子滤波,状态估计,噪声,信号提取
生成Sigma点的代码看着简单其实有门道,注意chol分解可能失败的情况:
function X = sigmaPoints(x,P,lambda)
n = length(x);
X = zeros(n,2*n+1);
sqrtP = chol((n+lambda)*P,'lower'); % 可能需处理非正定矩阵
X(:,1) = x;
for k=1:n
X(:,k+1) = x + sqrtP(:,k);
X(:,k+n+1) = x - sqrtP(:,k);
end
end
预测步里有个容易翻车的点——权重计算。注意参数α影响Sigma点分布范围,β用于先验分布信息(对高斯过程β=2最优):
alpha = 1e-3;
kappa = 0;
lambda = alpha^2*(n+kappa) - n;
Wm = [lambda/(n+lambda), 0.5/(n+lambda)+zeros(1,2*n)]; % 均值权重
Wc = Wm;
Wc(1) = Wc(1) + (1-alpha^2+beta); % 协方差权重
实际跑数据时发现过程噪声Q和观测噪声R对结果影响极大。这里用了个讨巧的方法——根据新息(观测残差)动态调整R:
% 在更新步中加入自适应逻辑
delta_z = z - z_pred;
R = R_base * (0.9 + 0.1*abs(delta_z)); % R随残差变化
完整循环结构长这样:
for k = 2:length(current_data)
% 生成Sigma点
X = sigmaPoints(x_est, P_est, lambda);
% 预测步
X_pred = zeros(2,2*n+1);
for i=1:2*n+1
X_pred(:,i) = stateFcn(X(:,i), current_data(k), dt, Q);
end
x_pred = X_pred * Wm';
P_pred = (X_pred - x_pred) * diag(Wc) * (X_pred - x_pred)' + Q;
% 观测更新
Z_pred = measFcn(X_pred, current_data(k), R0);
z_pred = Z_pred * Wm';
Pzz = (Z_pred - z_pred) * diag(Wc) * (Z_pred - z_pred)' + R;
Pxz = (X_pred - x_pred) * diag(Wc) * (Z_pred - z_pred)';
K = Pxz / Pzz; % 卡尔曼增益
x_est = x_pred + K*(voltage_data(k)-z_pred);
P_est = P_pred - K*Pzz*K';
soc_est(k) = x_est(1); % 记录SOC估计值
end
实测发现几个调参经验:
- 初始协方差P0别设太小,否则收敛慢
- 过程噪声Q中SOC分量要远小于电压分量
- OCV-SOC曲线的精度直接影响最终结果
- 采样频率过高反而会放大噪声影响
最后放个效果对比图(假装有图)。蓝色真值,红色估计曲线,在5%噪声水平下SOC估计误差能压在1.5%以内。想要更精确的话得把温度效应、滞回特性这些加进去,不过那就是另一个悲伤的故事了...
代码完整版扔在Github了(地址虚构),注意数据要做归一化处理,不同电池的参数记得改配置文件。下次可能会试试把UKF和粒子滤波结合起来搞事情,有坑再分享。

更多推荐
所有评论(0)