扩展卡尔曼滤波

1、重点看【SLAM中的EKF,UKF,PF原理简介 - 半闲居士 - 博客园

2、机器人重点看【定位(一):扩展卡尔曼滤波_windSeS的博客

3、重点实例【扩展卡尔曼滤波(EKF)理论讲解与实例(matlab、python和C++代码)

转自【扩展卡尔曼滤波_菜鸟知识搬运工的博客-CSDN博客_扩展卡尔曼滤波

扩展卡尔曼滤波(Extended Kalman Filter,EKF)是标准卡尔曼滤波在非线性情形下的一种扩展形式,EKF算法是将非线性函数进行泰勒展开,省略高阶项,保留展开项的一阶项,以此来实现非线性函数线性化,最后通过卡尔曼滤波算法近似计算系统的状态估计值和方差估计值,对信号进行滤波。

一、泰勒级数展开

       泰勒级数展开是将一个在x=x_{0}处具有n阶导数的函数f(x),利用关于(x-x_{0})n多项式逼近函数值的方法。

       若函数f(x)在包含x_{0}的某个闭区间[a,b]上具有n阶导数,且在开区间(a,b)上具有(n+1)阶导数,则对闭区间[a,b]上的任意一点x,都有:

其中{​{f}^{(n)}}({​{x}_{0}})表示函数f(x)x=x_{0}处的n阶导数,等式右边成为泰勒展开式,剩余的{​{R}_{n}}(x)是泰勒展开式的余项,是(x-x_{0})^{n}的高阶无穷小。

         当变量是多维向量时,一维的泰勒展开就需要做拓展,具体形式如下:

其中,{​{[\nabla f({​{\mathbf{x}}_{k}})]}^{T}}={​{\mathbf{J}}_{F}}表示雅克比矩阵,\mathbf{H}({​{\mathbf{x}}_{k}})表示海塞矩阵,{​{\mathbf{o}}^{n}}表示高阶无穷小。

{[\nabla f({​{\bf{x}}})]^T} = {​{\bf{J}}({\bf x})} = \begin{bmatrix} \frac{\partial f({\bf x})_1}{\partial {\bf x}_1} & \hdots & \frac{\partial f({\bf x})_1}{\partial {\bf x}_n}\\ \vdots & \ddots & \vdots \\ \frac{\partial f({\bf x})_m}{\partial {\bf x}_1} & \hdots & \frac{\partial f({\bf x})_m}{\partial {\bf x}_n} \end{bmatrix}

这里,f({​{\bf{x}}_k})m维,{​{\bf{x}}_k}状态向量为n维,\frac{​{​{\partial ^2}f({​{\bf{x}}_k})}}{​{\partial {x_m}\partial {x_n}}} = \frac{​{\partial f({​{\bf{x}}_k})^T}}{​{\partial {x_m}}}\frac{​{\partial f({​{\bf{x}}_k})}}{​{\partial {x_n}}}。 

        一般来说,EKF在对非线性函数做泰勒展开时,实际应用只取到一阶导,同样也能有较好的结果。取一阶导时,状态转移方程和观测方程就近似为线性方程,高斯分布的变量经过线性变换之后仍然是高斯分布,这样就能够延用标准卡尔曼滤波的框架。

二、扩展卡尔曼滤波EKF                                                                           

标准卡尔曼滤波KF的状态转移方程和观测方程为

{​{\mathbf{\theta }}_{k}}=\mathbf{A}{​{\mathbf{\theta }}_{k-1}}+\mathbf{B}{​{\mathbf{u}}_{k-1}}+{​{\mathbf{s}}_{k}}

{​{\mathbf{z}}_{k}}=\mathbf{C}{​{\mathbf{\theta }}_{k}}+{​{\mathbf{v}}_{k}}

扩展卡尔曼滤波EKF的状态转移方程观测方程为:

                   ,

利用泰勒展开式对上式在上一次的估计值处\left\langle {​{\mathbf{\theta }}_{k-1}} \right\rangle(估计值)展开得

 ,

再利用泰勒展开式,在本轮的状态预测值处\theta^{'} _k展开得

,  

其中,{\mathbf{F}}_{k-1}{\mathbf{H}}_{k}分别表示函数f(\mathbf{\theta })h(\mathbf{\theta })\left\langle {​{\mathbf{\theta }}_{k-1}} \right\rangle\mathbf{\theta }_{k}^{'}处的雅克比矩阵。

(注:这里对泰勒展开式只保留到一阶导,二阶导数以上的都舍去,噪声假设均为加性高斯噪声)

基于以上的公式,给出EKF的预测(Predict)和更新(Update)两个步骤:

Propagation:

\mathbf{\theta }_{k}^{'}=f(\left\langle {​{\mathbf{\theta }}_{k-1}} \right\rangle)

\mathbf{\Sigma }_{k}^{'}=\mathbf{F}_{k-1}{​{\mathbf{\Sigma }}_{k-1}}{​{\mathbf{F}}_{k-1}^{T}}+\mathbf{Q}

                     

Update:

\mathbf{S}_{k}^{'}={​{\left( \mathbf{H_{k}\Sigma }_{k}^{'}{​{\mathbf{H}}_{k}^{T}}+\mathbf{R} \right)}^{-1}}

\mathbf{K}_{k}^{'}=\mathbf{\Sigma }_{k}^{'}{​{\mathbf{H}}_{k}^{T}}\mathbf{S}_{k}^{'}

\left\langle {​{\mathbf{\theta }}_{k}} \right\rangle =\mathbf{\theta }_{k}^{'}+\mathbf{K}_{k}^{'}\left( {​{\mathbf{z}}_{k}}-{h(\theta }_{k}^{'}) \right)

{​{\mathbf{\Sigma }}_{k}}=\left( \mathbf{I}-\mathbf{K}_{k}^{'}\mathbf{H}_{k} \right)\mathbf{\Sigma }_{k}^{'}

   

其中的雅克比矩阵和分别为

(H的导数只能在预测值处取,因为这个时候你还不知道估计值,是先有k时刻的H,然后有K,最后才有k时刻的估计值)

雅可比矩阵的计算,在MATLAB中可以利用对自变量加上一个eps(极小数),然后用因变量的变化量去除以eps即可得到雅可比矩阵的每一个元素值。

from :卡尔曼滤波系列——(二)扩展卡尔曼滤波_GHelpU的博客-CSDN博客_扩展卡尔曼滤波算法

from :扩展卡尔曼滤波(EKF)算法详细推导及仿真(Matlab)_钢蛋_小朋友的博客-CSDN博客_ekf算法


这是书上给出的一个例子,我希望从中能归纳一种套路可以用在 大部分EKF问题中

一:建立数学模型

(一):建立状态方程

状态方程是由具体问题的物理意义抽象出来的,不同问题具有不同的状态方程,是已知量。

(二):建立观测方程

观测方程也是由实际物理意义抽象出来的,已知量。

(三):一阶线性化状态方程,求状态转移矩阵F(k)。(其实就是把状态方程求偏导的过程)

(四):一阶线性化观测方程,求解观测矩阵H(k)

接下来进入卡尔曼滤波,首先时间更新

(五):状态预测

EKF的状态预测和KF的状态预测其实没有差别,都是假设没有过程噪声w,然后使用状态方程将上一时刻的后验估计值代入,X(k|k-1)是指用k-1时刻估计出来的k时刻的值,也即k时刻的先验估计值,同理X(k-1|k-1)就是指k-1时刻的后验估计值

(六):观测预测(下面状态更新时要用)

说实话当时看参考书这里一直没看懂,y不应该是传感器测出来的值吗,为什么要预测?这里我的理解是,“预测”指的是第5步的预测,这里只是把预测结果转化到测量度量下。

(七):求协方差预测,EKF的协方差预测和KF也是基本没差别,只不过是F(k)需要用偏导先求出来

接下来进入状态更新

(八):求卡尔曼滤波增益

(九):求状态后验估计值

(十):协方差更新

至此,卡尔曼滤波需要的所有方程推导完毕,从(三)到(十)为一次EKF迭代

from:卡尔曼滤波(5):一种用EKF解决问题的思路_buaazyp的博客-CSDN博客


雅克比矩阵计算参考扩展卡尔曼滤波(EKF)理论讲解与实例(matlab、python和C++代码)(有空记得看这篇博文)

matlab示例:

    
    
  1. % author : Perry.Li @USTC
  2. % function: simulating the process of EKF
  3. % date: 04 / 28 / 2015
  4. %
  5. N = 50; %计算连续N个时刻
  6. n = 3; %状态维度
  7. q = 0.1; %过程标准差
  8. r = 0.2; %测量标准差
  9. Q =q^ 2 *eye(n); %过程方差
  10. R =r^ 2; %测量值的方差
  11. f =@(x)[ x(2); x(3); 0.05 * x(1) *( x(2) + x(3))]; %状态方程
  12. h =@(x)[ x(1); x(2); x(3)]; %测量方程
  13. s =[ 0; 0; 1]; %初始状态
  14. %初始化状态
  15. x =s +q *randn( 3,1);
  16. P = eye(n);
  17. xV = zeros(n,N);
  18. sV = zeros(n,N);
  19. zV = zeros(n,N);
  20. for k = 1:N
  21. z = h(s) + r *randn;
  22. sV(:,k) = s; %实际状态
  23. zV(:,k) = z; %状态测量值
  24. [x 1,A] =jaccsd(f,x); %计算f的雅可比矩阵,其中x 1对应黄金公式 line 2
  25. P =A *P *A '+Q; %过程方差预测,对应line3
  26. [z1,H]=jaccsd(h,x1); %计算h的雅可比矩阵
  27. K=P*H' *inv(H *P *H '+R); %卡尔曼增益,对应line4
  28. x=x1+K*(z-z1); %状态EKF估计值,对应line5
  29. P=P-K*H*P; %EKF方差,对应line6
  30. xV(:,k) = x; %save
  31. s = f(s) + q*randn(3,1); %update process
  32. end
  33. for k=1:3
  34. FontSize=14;
  35. LineWidth=1;
  36. figure();
  37. plot(sV(k,:),'g- '); %画出真实值
  38. hold on;
  39. plot(xV(k,:),'b- ','LineWidth ',LineWidth) %画出最优估计值
  40. hold on;
  41. plot(zV(k,:),'k + '); %画出状态测量值
  42. hold on;
  43. legend('真实状态 ', 'EKF最优估计估计值 ','状态测量值 ');
  44. xl=xlabel('时间(分钟) ');
  45. t=['状态 ',num2str(k)] ;
  46. yl=ylabel(t);
  47. set(xl,'fontsize ',FontSize);
  48. set(yl,'fontsize ',FontSize);
  49. hold off;
  50. set(gca,'FontSize ',FontSize);
  51. end
  52. function [z,A]=jaccsd(fun,x)
  53. % JACCSD Jacobian through complex step differentiation
  54. % [z J] = jaccsd(f,x)
  55. % z = f(x)
  56. % J = f'(x)
  57. %
  58. z =fun(x);
  59. n =numel(x);
  60. m =numel(z);
  61. A = zeros(m,n);
  62. h =n *eps;
  63. for k = 1:n
  64. x 1 =x;
  65. x 1(k) =x 1(k) +h *i;
  66. A(:,k) =imag(fun(x 1)) /h;
  67. end

from :扩展卡尔曼滤波器的原理及应用_hankecs的博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值