卡尔曼滤波以及Matlab实现_参考书籍_核心剖析_经验分享_EKF(1)

版权声明:本文为博主原创文章,未经博主允许不得转载。https://mp.csdn.net/mdeditor#

1.前言
  首先,关于卡尔曼滤波理论的定义、种类、算法实现过程步骤以及相关例子方面,博主有两个推荐。(1)网络资源博客方面我推荐下面这位博主,里面温度的例子可以作为切入点去理解卡尔曼这种“最优化自回归数据处理算法”:
http://www.china-vision.net/blog/user1/6/archives/2006/2006111115624.shtml;
并且我自己也转载过这篇:https://blog.csdn.net/weixin_38451800/article/details/85462129 。
  (2)书方面我推荐黄小平老师的“卡尔曼滤波原理及应用-Matlab仿真”:本书的源程序代码下载网址为:http://yydz.phei.com.cn/book/eebook/卡尔曼滤波原理及应用:matlab仿真/
  博主的百度网盘下载链接为:https://pan.baidu.com/s/1ZNvZ6OCgg4-bg4LI84Se1w 提取码:7t5w
  黄老师这本书讲得的很好,应用也普遍广泛,主要章节还有代码,博主鼎力推荐给初次接触卡尔曼的人。

2.卡尔曼滤波算法
  卡尔曼滤波是一种线性滤波算法,是卡尔曼先生1960年首次在其论文中提出,最早是其在参观美国阿波罗计划时,最早也是频域范围,后来衍生到时域,再然后针对诸多非线性系统,利用非线性化的数学手段比如泰勒级数展开取前两项的方式产生扩展卡尔曼(Extended kalman filter,EKF),然后2002年先后诞生了无迹卡尔曼或者也称为无嗅卡尔曼(unscented kalman filter, UKF)和中心差分卡尔曼(center differential kalman filter,CDKF),之后2009年针对UKF在处理高维非线性系统方面的缺陷,提出了容积卡尔曼(cubature kalman filter,CKF),至于这个高维是多少呢?提出来的时候是15维以上。所以,博主不谈CKF,就其他三种非线性KF,比如EKF、UKF和CDKF,博主会给一些心得经验。但是,鉴于内容很多,笼统的谈又没有太大意义,所以,本节以下将结合黄小平老师书中的代码针对EKF算法,给出一些编程和调参建议。
  
3.EKF编程和调参

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %函数功能:标量非线性系统扩展Kalman滤波问题
    %状态函数:X(k+1)=0.5X(k+1)+2.5X(k)/(1+X(k)^2)+8cos(1.2k)+w(k)
    %观测方程:Z(k)=X(k)^2/20+v(k)
    %编写者:a往南向北,日期:2017/8/10
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function EKF_for_One_Div_UnLine_System
    %% 1.初始化
    T=50;                                  %总时间
    Q=10;                                  %Q值改变,观察不同Q值滤波结果
    R=1;                                   %测量噪声
    w=sqrt(Q)*randn(1,T);                  %产生过程噪声
    v=sqrt(R)*rand(1,T);                   %产生观测噪声
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% 2.状态方程
    x=zeros(1,T);
    x(1)=0.1;
    y=zeros(1,T);
    y(1)=x(1)^2/20+v(1);
    for k=2:T
        x(k)=0.5*x(k-1)+2.5*x(k-1)/(1+x(k-1)^2)+8*cos(1.2*k)+w(k-1);
        y(k)=x(k)^2/20+v(k);
    end
    %% 3.EKF滤波算法
    Xekf=zeros(1,T);
    Xekf(1)=x(1);
    Yekf=zeros(1,T);
    Yekf(1)=y(1);
    P0=eye(1);
    for k=2:T
        %状态预测
        Xn=0.5*Xekf(k-1)+2.5*Xekf(k-1)/(1+Xekf(k-1)^2)+8*cos(1.2*k);
        %观测预测
        Zn=Xn^2/20;
        %求状态矩阵F
        F=0.5+2.5*(1-Xn^2)/(1+Xn^2)^2;
        %求观测矩阵
        H=Xn/10;
        %协方差预测
        P=F*P0*F'+Q;
        %求Kalman增益
        K=P*H'*inv(H*P*H'+R);
        %状态更新
        Xekf(k)=Xn+K*(y(k)-Zn);
        %协方差阵更新
        P0=(eye(1)-K*H)*P;
    end
    %误差分析
    Xstd=zeros(1,T);
    for k=1:T
        Xstd(k)=abs(Xekf(k)-x(k));
    end
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% 4.画图略

以上是一个非线性系统EKF的MATLAB例子程序,博主建议初学者以这个为模板,编写EKF代码时,带进自己的系统方程便可。
  以上是编程建议,调参主要我们分两个方面分析,一方面是非线性系统方程参数的初始化,有点像工程应用中的系统参数标定性质;另一方面是EKF的核心就是状态方程或者观测方程非线性关系的线性化过程。
  (1)参数初始化过程:这其中几个参数需要重点注意的是,状态和观测值的初始值以及初始的协方差矩阵P0;过程噪声Q和测量噪声R;锂离子电池中还需注意等效模型代入方式和OCV-SOC曲线关系拟合精度;
  (2)线性化过程:对于维数低的一般都是取偏导数,还有一些是取比值斜率的,博主这两种方式都尝试过,归结为取偏导数的精度高些但是计算量也大,取比值斜率则正好相反,锂离子电池系统中还是取偏导数为好,阶数也不宜太高4-8阶即可。

你可能感兴趣的:(电池管理系统BMS,扩展卡尔曼EKF,MATLAB代码)