如何在 Apache Commons 卡尔曼滤波器实现中填充矩阵

Posted

技术标签:

【中文标题】如何在 Apache Commons 卡尔曼滤波器实现中填充矩阵【英文标题】:How to populating matrices in the Apache Commons Kalman filter Implementation 【发布时间】:2016-03-14 19:26:25 【问题描述】:

背景:为了给大家一些背景知识,我正在尝试使用卡尔曼滤波器(Apache 共同实现)。我应该包括什么样的动态噪音 在我关于矩阵 P0、Q 和 R 的实现中,我知道 除了位置(X和Y)之外,我唯一的输入是水平的 X 和 Y 分量的精度和速度。这不是一个常数 速度示例,因为速度可能会从一个 ping 变为 另一个 ping。

实现库:Apache Common - http://commons.apache.org/proper/commons-math/userguide/filter.html

用法:我现在只考虑二维空间

我的输入: 1. 纬度 2. 经度 3. 水平精度或水平精度稀释 (HDOP),以米/秒为单位 4. 两次 ping 之间的时间 (dt) = 30 秒

我关心的输出 1. 新纬度 2.新经度

计算值:Vx(X 方向速度) Vy(Y 方向速度) 不同的速度,所以我可以使用公式计算 Vx 和 Vy V * sin(theta) 和 V * Cosine(theta)

我应该如何将我的值映射到 Apache Common 实现。?

当前设置:

X = Initial State = [  

     X Y X-Vel Y-Vel

    ]  

 // I only care about X and Y coordinates so this is a 2 * 4 matrix  
 H = Observation variables = [   

     1, 0, 0, 0,  
     0, 1, 0, 0 



 ]  

 // This is a 4 * 4 matrix  
 P0 = Cov(X) = [     

     (horizontal accuracy from i/p), 0, 0, 0,  
     0, (horizontal accuracy from i/p), 0, 0,  
     0, 0, (some initial value for VY), 0,  
     0, 0, 0, (some initial value for VX) 

    ]  

 // Copied this from somewhere. What values should I have in this?   //
 This is a 4 * 4 matrix  
 Q = Cov(Dynamic noise) = [          

      Math.pow(dt, 4d)/4d, 0d, Math.pow(dt, 3d)/2d, 0d ,  
      0d, Math.pow(dt, 4d)/4d, 0d, Math.pow(dt, 3d)/2d ,  
      Math.pow(dt, 3d)/2d, 0d, Math.pow(dt, 2d), 0d ,  
      0d, Math.pow(dt, 3d)/2d, 0d, Math.pow(dt, 2d) 

    ]  

 // This is a 2 * 2 matrix  
 R = Cov(measurement noise) = [  

      Math.pow((horizontal accuracy from i/p), 2d) , 0,  
      0, Math.pow((horizontal accuracy from i/p), 2d) 

 ]  

 // This is a 4 * 4 matrix  
 A = State transition matrix =   [

      1d, 0d, dt, 0d ,  
      0d, 1d, 0d, dt ,  
      0d, 0d, 1d, 0  ,  
      0d, 0d, 0d, 1d   

 ] 

我的矩阵是否适合我正在尝试做的事情?当我运行它们时,我 不断收到 MatrixDimensionMismatchException ,因此我决定 问一个问题。任何帮助将不胜感激。

【问题讨论】:

请重新格式化您的问题。不需要花哨的格式。对代码使用代码格式,对引号使用引号格式。 我觉得很不寻常,但是格式很好,不用改格式 GPS 坐标已经经过重度卡尔曼滤波。平滑会使它们不太准确。想想您是否可能需要过滤不需要的位置而不是平滑。 我删除了 MATLAB 标签,因为 Apache Commons Math 库是一个 Java 库。它与 MATLAB 无关。此外,代码似乎是 Java(即Math.pow),因此重新标记是合理的。 @AlexWien - 该设备可能是一块手表,其芯片上可能没有卡尔曼滤波器。另外,如果从 WIFI 接收到 ping,因此我认为我需要过滤。 【参考方案1】:

我能够通过使用最新版本的 Apache Commons Math 库来解决这个问题。

事实证明 Apache Commons Math 3.2 及更早版本存在重大错误 在这里报道:https://issues.apache.org/jira/browse/MATH-1033

问题是 measNoise 列维度必须始终为 1,这意味着矩阵 R 应该始终只有 1 列

// row dimension of R must be equal to row dimension of H
if (measNoise.getRowDimension() != measurementMatrix.getRowDimension() ||
    measNoise.getColumnDimension() != 1)   
    throw new MatrixDimensionMismatchException(measNoise.getRowDimension(), measNoise.getColumnDimension(), measurementMatrix.getRowDimension(), 1); 

【讨论】:

以上是关于如何在 Apache Commons 卡尔曼滤波器实现中填充矩阵的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中使用卡尔曼滤波器获取位置数据?

Matlab:如何在卡尔曼滤波器状态估计后模拟模型

如何将滚动卡尔曼滤波器应用于 DataFrame 中的列?

如何从卡尔曼滤波器估计部分状态的概率?

在位置估计中使用卡尔曼滤波器

如何将卡尔曼滤波器与旋转对象一起使用