锂电池SOC估计 UKF && EKF

该文通过UKF(UnscentedKalmanFilter)和EKF(ExtendedKalmanFilter)算法对二阶RC等效电路模型的电池进行状态估计,包括端电压和SOC(StateofCharge)。文中详细展示了两个算法的实现步骤,包括系统矩阵、观测矩阵的设定,以及状态更新和误差分析。通过比较两种方法的估计结果,评估其性能。
摘要由CSDN通过智能技术生成

UKF

对于一个非线性系统:

在这里插入图片描述
其中,w是系统噪声值,是v测量噪声值。
UKF算法过程如下:
1)确定状态值初始值和后验状态误差协方差初始值;
2)计算采样点。

在这里插入图片描述

其中,L为状态向量的长度,本文中状态向量长度为3,权重值计算如下所示:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
代码如下:

模型代码

load('R0.mat');
load('R1.mat');
load('C1.mat');
load('discharge.mat');%放电数据
load('OCV_SOC.mat');%OCV-SOC关系

系统矩阵

A=[1-1*Ts/R1/C1 0;0 1];%系统矩阵
B=[1*Ts/C1;-1*Ts/Qn];
C=[-1  0];
D=0;

初始值

Q=0.00000001*eye(2);
R=1;
P0=0.01*[0.01 0;0 1];%状态误差协方差初始值

赋值

tm=discharge(1,:)';
Cur=-discharge(2,:)';
Vot=discharge(3,:)';
RSOC=discharge(4,:)';
T=length(tm);

模型估计得到的电压值

Xekf=[0;0.8];%[U1,U2,SOC]初始值
L=length(Xekf);
Uoc(1)=p(1)*Xekf(2)^8+p(2)*Xekf(2)^7+p(3)*Xekf(2)^6+p(4)*Xekf(2)^5+p(5)*Xekf(2)^4+p(6)*Xekf(2)^3+p(7)*Xekf(2)^2+p(8)*Xekf(2)+p(9);%OCV
Vekf(1)=Uoc(1)+C*Xekf-Cur(1)*R0;%估计得到的端电压值
m=length(Vekf);
alpha=0.01;
ki=0;
beta=2;
lamba=alpha^2*(L+ki)-L;

迭代

for i=1:T-1
    delta=c*chol(P0)';
    Xekf_i=Xekf(:,i);
    Y=Xekf_i(:,ones(1,numel(Xekf_i)));
    X=[Xekf_i Y+delta Y-delta];
    LL=length(X);
    xx=zeros(2,1);
    XX=zeros(2,LL);
    for k=1:LL
        XX(:,k)=A*X(:,k)+B*Cur(i);
        xx=xx+Wm(k)*XX(:,k);
    end
    Xekf(:,i+1)=xx;
    X1=XX-xx(:,ones(1,LL));
    P_xx=X1*diag(Wc)*X1'+Q;
    LL_y=length(XX);
    yy=zeros(1,1);
    YY=zeros(1,LL_y);
    for k=1:LL_y
        Uoc(i+1)=p(1)*XX(2,k)^8+p(2)*XX(2,k)^7+p(3)*XX(2,k)^6+p(4)*XX(2,k)^5+p(5)*XX(2,k)^4+p(6)*XX(2,k)^3+p(7)*XX(2,k)^2+p(8)*XX(2,k)+p(9);
        YY(k)=Uoc(i+1)+C*XX(:,k)-Cur(i+1)*R0;
        yy=yy+Wm(k)*YY(k);
    end
    Vekf(i+1)=yy;
    Y1=YY-yy(:,ones(1,LL_y));
    P_yy=Y1*diag(Wc)*Y1'+R;
    P_xy=X1*diag(Wc)*Y1';
    K(:,i)=P_xy*inv(P_yy);
    Xekf(:,i+1)=Xekf(:,i+1)+K(:,i)*(Vot(i+1)-Vekf(i+1));
    P0=P_xx-K(:,i)*P_xy';
end

画图

t=0:0.1:length(tm)/10-0.1;
figure(1);
plot(t,Vot,'-k',t,Vekf,'-r','lineWidth',2); grid on
legend('真实值','估计值-UKF');
ylabel('端电压','Fontsize', 16)
xlabel('时间(s)', 'Fontsize', 16)
figure(2);
plot(t,RSOC,'-k',t,Xekf(2,:),'-r','lineWidth',2); grid on
legend('真实值','估计值-UKF');
ylabel('SOC','Fontsize', 16)
xlabel('时间(s)', 'Fontsize', 16)
    V_error=Vot-Vekf';
    SOC_error=RSOC-Xekf(2,:)';
SOC_error_mean=mean(abs(SOC_error(5000:end)));
SOC_error_max=max(abs(SOC_error(5000:end)));
figure(3);
plot(t,V_error,'-k','lineWidth',2); grid on
legend('端电压误差');
ylabel('端电压误差','Fontsize', 16)
xlabel('时间(s)', 'Fontsize', 16)
figure(4);
plot(t,SOC_error,'-k','lineWidth',2); grid on
legend('SOC误差');
ylabel('SOC误差','Fontsize', 16)
xlabel('时间(s)', 'Fontsize', 16)
SOC_UKF=Xekf(2,:);
SOC_error_UKF=SOC_error;
save SOC_UKF.mat SOC_UKF
save SOC_error_UKF.mat SOC_error_UKF
save RSOC.mat RSOC

EKF

二阶RC等效电路模型的等效电路模型框图如下。
在这里插入图片描述

其中,Uoc表示理想电压源,与SOC存在非线性关系;R0表示欧姆内阻, R1 R2是极化电阻,C1 C2是极化电容,Ut表示电池的端电压。根据基尔霍夫定律,可以得到系统方程和观测方程如下。定义放电电流方向为正,充电电流为负。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

代码如下

load('R0.mat');
load('R1.mat');
load('C1.mat');
load('discharge.mat');%放电数据
load('OCV_SOC.mat');%OCV-SOC关系
Qn=30.23*3600;%容量,单位:A*S

矩阵

A=[1-1*Ts/R1/C1 0;0 1];%系统矩阵
B=[1*Ts/C1;-1*Ts/Qn];
C=[-1  0];
D=0;

赋值

%% 赋值
tm=discharge(1,:)';%时间
Cur=-discharge(2,:)';%电流
Vot=discharge(3,:)';%测量得到的端电压
RSOC=discharge(4,:)';%SOC真实值-安时法计算得到
T=length(tm)-1;%时间

EKF算法

Xekf=[0;0.8];%[U1,U2,SOC]初始值
Uoc=zeros(1,T+1);%OCV
Vekf=zeros(1,T+1);%估计得到的端电压值
Uoc(1)=p(1)*Xekf(2)^8+p(2)*Xekf(2)^7+p(3)*Xekf(2)^6+p(4)*Xekf(2)^5+p(5)*Xekf(2)^4+p(6)*Xekf(2)^3+p(7)*Xekf(2)^2+p(8)*Xekf(2)+p(9);%OCV
Vekf(1)=Uoc(1)+C*Xekf-Cur(1)*R0;%估计得到的端电压值
K=zeros(2,T);%卡尔曼增益
H=zeros(T,2);%观测矩阵
for i=1:T
    Xekf(:,i+1)=A*Xekf(:,i)+B*Cur(i+1);%先验状态值
    Uoc(i+1)=p(1)*Xekf(2,i+1)^8+p(2)*Xekf(2,i+1)^7+p(3)*Xekf(2,i+1)^6+p(4)*Xekf(2,i+1)^5+p(5)*Xekf(2,i+1)^4+p(6)*Xekf(2,i+1)^3+p(7)*Xekf(2,i+1)^2+p(8)*Xekf(2,i+1)+p(9);
    H(i,:)=[-1 p(1)*8*Xekf(2,i+1)^7+p(2)*7*Xekf(2,i+1)^6+p(3)*6*Xekf(2,i+1)^5+p(4)*5*Xekf(2,i+1)^4+p(5)*4*Xekf(2,i+1)^3+p(6)*3*Xekf(2,i+1)^2+p(7)*2*Xekf(2,i+1)+p(8)];
    Vekf(i+1)=Uoc(i+1)+C*Xekf(:,i+1)-Cur(i+1)*R0;%估计得到的端电压值
    P=A*P0*A'+Q;%先验状态误差协方差
    K(:,i)=P*H(i,:)'/(H(i,:)*P*H(i,:)'+R);%卡尔曼增益
    Xekf(:,i+1)=Xekf(:,i+1)+K(:,i)*(Vot(i+1)-Vekf(i+1));%后验状态值
    P0=(eye(2)-K(:,i)*H(i,:))*P;%后验状态误差协方差
end

画图

t=0:0.1:length(tm)/10-0.1;
figure(1);
% plot(t,Vot,'-k',t,Vekf,'-r','lineWidth',2); grid on

plot(t,Vot,'-k',t,Vekf,'-r','lineWidth',2); grid on

legend('真实值','估计值-EKF');
ylabel('端电压','Fontsize', 16)
xlabel('时间(s)', 'Fontsize', 16)
figure(2);
plot(t,RSOC,'-k',t,Xekf(2,:),'-r','lineWidth',2); grid on
legend('真实值','估计值-EKF');
ylabel('SOC','Fontsize', 16)
xlabel('时间(s)', 'Fontsize', 16)
    V_error=Vot-Vekf';
    SOC_error=RSOC-Xekf(2,:)';
SOC_error_mean=mean(abs(SOC_error(5000:end)));
SOC_error_max=max(abs(SOC_error(5000:end)));
figure(3);
% plot(t,V_error ,'-k','lineWidth',2); grid on
plot(t,V_error,'-k','lineWidth',2); grid on
legend('端电压误差');
ylabel('端电压误差','Fontsize', 16)
xlabel('时间(s)', 'Fontsize', 16)
figure(4);
plot(t,SOC_error,'-k','lineWidth',2); grid on
legend('SOC误差');
ylabel('SOC误差','Fontsize', 16)
xlabel('时间(s)', 'Fontsize', 16)

figure(5);
plot(t,Cur,'-k','lineWidth',2); grid on
legend('电流');


SOC_EKF=Xekf(2,:);
SOC_error_EKF=SOC_error;
save SOC_EKF.mat SOC_EKF
save SOC_error_EKF.mat SOC_error_EKF
save RSOC.mat RSOC

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值