Implement a Kalman filter to smooth data from deviceOrientation API

tiny_m picture tiny_m · Sep 9, 2014 · Viewed 9.8k times · Source

I'm trying to smooth the data I'm getting from the deviceOrientation API to make a Google Cardboard application in the browser.

I'm piping the accelerometer data straight into the ThreeJs camera rotation but we're getting a lot of noise on the signal which is causing the view to judder.

Someone suggested a Kalman filter as the best way to approach smoothing signal processing noise and I found this simple Javascript library on gitHub

https://github.com/itamarwe/kalman

However its really light on the documentation.

I understand that I need to create a Kalman model by providing a Vector and 3 Matrices as arguments and then update the model, again with a vector and matrices as arguments over a time frame.

I also understand that a Kalman filter equation has several distinct parts: the current estimated position, the Kalman gain value, the current reading from the orientation API and the previous estimated position.

I can see that a point in 3D space can be described as a Vector so any of the position values, such as an estimated position, or the current reading can be a Vector.

What I don't understand is how these parts could be translated into Matrices to form the arguments for the Javascript library.

Answer

Ita picture Ita · Sep 9, 2014

Well, I wrote the abhorrently documented library a couple of years ago. If there's interest I'm definitely willing to upgrade it, improve the documentation and write tests.

Let me shortly explain what are all the different matrices and vectors and how they should be derived:

x - this is the vector that you try to estimate. In your case, it's probably the 3 angular accelerations.

P - is the covariance matrix of the estimation, meaning the uncertainty of the estimation. It is also estimated in each step of the Kalman filter along with x.

F - describes how X develops according to the model. Generally, the model is x[k] = Fx[k-1]+w[k]. In your case, F might be the identity matrix, if you expect the angular acceleration to be relatively smooth, or the zero matrix, if you expect the angular acceleration to be completely unpredictable. In any case, w would represent how much you expect the acceleration to change from step to step.

w - describes the process noise, meaning, how much does the model diverge from the "perfect" model. It is defined as a zero mean multivariate normal distribution with covariance matrix Q.

All the variables above define your model, meaning what you are trying to estimate. In the next part, we talk about the model of the observation - what you measure in order to estimate your model.

z - this is what you measure. In your case, since you are using the accelerometers, you are measuring what you are also estimating. It will be the angular accelerations.

H - describes the relation between your model and the observation. z[k]=H[k]x[k]+v[k]. In your case, it is the identity matrix.

v - is the measurement noise and is assumed to be zero mean Gaussian white noise with covariance R[k]. Here you need to measure how noisy are the accelerometers, and calculate the noise covariance matrix.

To summarize, the steps to use the Kalman filter:

  1. Determine x[0] and P[0] - the initial state of your model, and the initial estimation of how accurately you know x[0].
  2. Determine F based on your model and how it develops from step to step.
  3. Determine Q based on the stochastic nature of your model.
  4. Determine H based on the relation between what you measure and what you want to estimate (between the model and the measurement).
  5. Determine R based on the measurement noise. How noisy is your measurement.

Then, with every new observation, you can update the model state estimation using the Kalman filter, and have an optimal estimation of the state of the model(x[k]), and of the accuracy of that estimation(P[k]).