itamarwe / kalman

Kalman Filter in Javascript
113 stars 30 forks source link

Determine matrices to be used as arguments #2

Open mairead opened 9 years ago

mairead commented 9 years ago

I can see both the model and update functions require a Vector and a set of Matrices as parameters.

Would it be possible to get a brief explanation of how one would derive these values? I am using the .alpha, .beta and .gamma readings from the deviceOrientation API which come out as floating point numbers. Am I right in thinking these form the 3 parts of the first Vector argument? What is the purpose of the remaining Matrices.

I put a question up on StackOverflow hoping someone might be able to explain. Any help would be gratefully received

https://stackoverflow.com/questions/25744984/implement-a-kalman-filter-to-smooth-data-from-deviceorientation-api

itamarwe commented 9 years ago

Hi! I'm writing you an answer on Stackoverflow shortly. Itamar.

itamarwe commented 9 years ago

If you need help adapting the model to your needs, just let me know.

scottmahr commented 9 years ago

Hey Itamar, I also would like to use your library. I also posted to stackoverflow https://stackoverflow.com/questions/28105771/using-kalman-filter-with-acceleration-and-position-inputs

I am pretty new to Kalman filters, but I have tried to read as much as I could in the last 4-6 hours. Hopefully you can point me in the right direction.

If I get it working I would be happy to post another example in your library if that might help others trying to use it.

Thanks!

Scott

mairead commented 9 years ago

So, I have been working on this over the last couple of months but I'm still struggling with my implementation. The filter is definitely smoothing variance in the signal however I have a couple of issues. I have read the stack overflow answer you gave me and I've tried to apply what I understand to the matrices available. I've added some notes to show what I understand each item to be.

My application is a 3D stage which moves in a VR simulation when you move your mobile device's accelerometer. There is greater signal noise in the accelerometer in the alpha channel (I'm not sure why)

There is also what I'm assuming to be greater process noise in the alpha channel from a user moving their head left to right, as opposed to tilting clockwise or anti-clockwise (beta) or looking up and down (gamma). Am I right in thinking I should be using the process noise to model a user making a change to the system signal? Is this what you meant by "if your system moves, than you must have a non zero Q that represents the covariance of the acceleration changes from step to step."

The second issue I have is the attack on correction seems quite severe at first but over each iteration appears to be less corrective so effectively what I get is a form of inertia where the amount of movement corrected is less. This makes the app look as if the corrections slows down over each frame. I can't tell whether this is because my previous knowledge of state is wrong, or because my model of the stochastic state is wrong.

Changing the prior knowledge of state doesn't seem to make much difference. Should I be pulling an accurate reading out of the accelerometer every time I want to set z_k. At the moment its just using the initial values I suck out when the page loads.

 var z_k = $V([alpha, beta, gamma]); //Updated accelerometer values.

Also if I try to set F_k to a 0 matrix, instead of an identity matrix then the filter stops working and sets the updated values to 0. I wondered if this could help determine change caused by interaction from the user

Here is what I currently have

//Create start vals dynamically depending on the position of the device
var startFlag = true, 
alpha = 0, 
beta = 0, 
gamma = 0;

window.addEventListener('deviceorientation', getDeviceRotation, false);

function getDeviceRotation(e){
    if(startFlag === true){
        alpha = THREE.Math.degToRad(e.alpha);
       beta = THREE.Math.degToRad(e.beta);
       gamma = THREE.Math.degToRad(e.gamma);
       console.log("start vals", alpha, beta, gamma);
 }
 startFlag = false;
}

var x_0 = $V([alpha, beta, gamma]); //vector. Initial accelerometer values.
//These are the base values when the device is held up straight

//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], //has to be set to 1
          [0,1,0], //0 if interaction is unpredictable. Setting this to zero actually sets all to zero??
          [0,0,1]
   ]); //identity matrix. How change to model is applied. Set to 1 if smooth changes
  var Q_k = $M([
          [4,0,0],
          [0,0.05,0],
          [0,0,1.5]
        ]); //Variance in movement caused by user

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

var z_k = $V([alpha, beta, gamma]); //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([
          [0.1,0,0],
          [0,0.001,0],
          [0,0,0.005]
        ]); //Describes noise from sensor.
  var KO = new KalmanObservation(z_k,H_k,R_k);