使用卡尔曼滤波器对设备方向API的数据进行平滑处理

17

我尝试着平滑从deviceOrientation API获取的数据,以便在浏览器中制作Google Cardboard应用程序。

我将加速度计数据直接传输到ThreeJs相机旋转中,但我们收到了很多信号噪声,导致视图抖动。

有人建议使用卡尔曼滤波器来处理平滑信号处理噪声,我在gitHub上找到了这个简单的Javascript库

https://github.com/itamarwe/kalman

然而,它的文档非常简略。

我知道需要通过提供向量和3个矩阵作为参数来创建一个Kalman模型,然后再在一段时间内使用向量和矩阵作为参数更新模型。

我还知道Kalman滤波器方程有几个不同的部分:当前估计位置、Kalman增益值、从方向API读取的当前读数和先前估计的位置。

我可以看出,3D空间中的一个点可以描述为向量,因此任何位置值(例如估计位置或当前读数)都可以是向量。

我不理解的是如何将这些部分转换成矩阵,以形成Javascript库的参数。


说实话,这个库的文档写得非常糟糕。如果他/她/它在我的团队里工作,我是绝对不会允许这样的问题存在的!坦率地说,我会尝试联系作者,如果失败了,就换其他的东西。 - Lightness Races in Orbit
我已经在 Github 仓库中添加了一个问题,希望他们能够对我产生同情。我假设如果信号处理是你的专业领域,那么这可能是显而易见的,但我对矩阵的目的有些困惑。我在思考矩阵是否代表时间状态之间的转换。因此,您可以将当前位置表示为实际读数与上一个时间状态中读取的读数之间的位移,而不是将其表示为向量形式的当前位置? - tiny_m
2个回答

16

几年前,我编写了一个文档不好的库。如果有兴趣,我一定愿意更新它,改进文档并编写测试。

让我简要解释一下所有不同的矩阵和向量以及它们应该如何推导:

x - 这是您尝试估计的向量。在您的情况下,它可能是三个角加速度。

P - 是估计的协方差矩阵,表示估计的不确定性。它也在Kalman滤波器的每个步骤中与x一起估计。

F - 描述X如何根据模型发展。通常,模型为x[k] = Fx[k-1]+w[k]。在您的情况下,如果您预计角加速度相对平稳,则F可能是单位矩阵;如果您预计角加速度完全不可预测,则F可能是零矩阵。无论如何,w会表示您期望加速度从一步到另一步变化的程度。

w - 描述过程噪声,即模型与“完美”模型偏离的程度。它被定义为具有协方差矩阵Q的零均值多元正态分布。

上述所有变量都定义了您的模型,即您要尝试估计的内容。在下一部分中,我们将讨论观察模型 - 即您测量以估计模型的内容。

z - 这是您测量的内容,由于您使用加速度计,因此您测量的也是您正在估计的内容,即角加速度。

H - 描述您的模型与观察之间的关系。z[k]=H[k]x[k]+v[k]。在您的情况下,它是单位矩阵。

v - 是测量噪声,假定为具有协方差R[k]的零均值高斯白噪声。在这里,您需要测量加速度计的噪声水平,并计算噪声协方差矩阵。

使用Kalman滤波器的步骤如下:

  1. 确定x[0]P[0]-模型的初始状态以及您对x[0]了解程度的初始估计。
  2. 基于您的模型和其从一步到另一步的发展方式,确定F
  3. 基于您的模型的随机性质,确定Q
  4. 根据您所测量的内容与您想要估计的内容之间的关系(模型与测量之间),确定H
  5. 基于测量噪声,确定R。您的测量有多嘈杂。

然后,每次有新观测时,您可以使用Kalman滤波器更新模型状态估计,并对模型状态(x[k])和该估计的准确性(P[k])进行最优估计。


感谢您抽出时间。我非常感激,也感谢您首先创建了这个库。 - tiny_m

4
var acc = {
 x:0,
 y:0,
 z:0
};

var count = 0;

if (window.DeviceOrientationEvent) {
  window.addEventListener('deviceorientation', getDeviceRotation, false);
}else{
  $(".accelerometer").html("NOT SUPPORTED")
}

var x_0 = $V([acc.x, acc.y, acc.z]); //vector. Initial accelerometer values

//P prior knowledge of state
var P_0 = $M([
              [1,0,0],
              [0,1,0],
              [0,0,1]
            ]); //identity matrix. Initial covariance. Set to 1
var F_k = $M([
              [1,0,0],
              [0,1,0],
              [0,0,1]
            ]); //identity matrix. How change to model is applied. Set to 1
var Q_k = $M([
              [0,0,0],
              [0,0,0],
              [0,0,0]
            ]); //empty matrix. Noise in system is zero

var KM = new KalmanModel(x_0,P_0,F_k,Q_k);

var z_k = $V([acc.x, acc.y, acc.z]); //Updated accelerometer values
var H_k = $M([
              [1,0,0],
              [0,1,0],
              [0,0,1]
            ]); //identity matrix. Describes relationship between model and observation
var R_k = $M([
              [2,0,0],
              [0,2,0],
              [0,0,2]
            ]); //2x Scalar matrix. Describes noise from sensor. Set to 2 to begin
var KO = new KalmanObservation(z_k,H_k,R_k);

//each 1/10th second take new reading from accelerometer to update
var getNewPos = window.setInterval(function(){

    KO.z_k = $V([acc.x, acc.y, acc.z]); //vector to be new reading from x, y, z
    KM.update(KO);

    $(".kalman-result").html(" x:" +KM.x_k.elements[0]+", y:" +KM.x_k.elements[1]+", z:" +KM.x_k.elements[2]);
    $(".difference").html(" x:" +(acc.x-KM.x_k.elements[0])+", y:" +(acc.y-KM.x_k.elements[1])+", z:" +(acc.z-KM.x_k.elements[2]))


}, 100);

 //read event data from device
function getDeviceRotation(evt){

    // gamma is the left-to-right tilt in degrees, where right is positive
    // beta is the front-to-back tilt in degrees, where front is positive
    // alpha is the compass direction the device is facing in degrees
    acc.x = evt.alpha;
    acc.y = evt.beta;
    acc.z = evt.gamma; 
    $(".accelerometer").html(" x:" +acc.x+", y:" +acc.y+", z:" +acc.z);
}

这是一个演示页面,展示了我的结果。您可以通过以下链接访问:http://cardboard-hand.herokuapp.com/kalman.html
目前,我将传感器噪声设置为2个标量矩阵,以查看卡尔曼滤波器是否正常工作。但我们注意到当手机平放在桌子上时,x轴上的传感器方差更大。我们认为这可能与万向锁定有关。我们尚未进行测试,但设备的方向可能会影响每个轴上的方差变化。

你的系统是静态的吗?如果是,那么 Q 为0就可以了。但是如果你的系统在运动,那么你必须有一个非零的 Q 来表示从一步到另一步加速度变化的协方差。此外,我会用第一个加速度计测量值来初始化 x,因为这是你最好的猜测,并且会加速滤波器的收敛。 - Ita

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接