8

There are lots of questions about removing the noise from accelerometer data, other sensor's data, calculating spatio-temporal state, and using a Kalman filter in Android and in other devices.

Apparently, the easiest way of doing this is implementing the JKalman filter on Android for stable moving devices for example for cars.

But looking at the sample implementation in JKalman code package, it doesn't say much and it is actually very different from other Kalman implementations.

They instantiate a Kalman class like this:

JKalman kalman = new JKalman(4, 2);

Where according to the definition

public JKalman(int dynam_params, int measure_params) throws Exception {
    this(dynam_params, measure_params, 0);
}

dynam_params is "the number of measurement vector dimensions" and measure_params is "the number of state vector dimensions".

How should the sensor data read in Android be mapped to these?

Below is the data from accelerometer to be seen, that is sampled every 500ms. In other listeners there are data from gyroscope and compass. How should I transform this data to input to Kalman?

    @Override
    public void onSensorChanged(SensorEvent event) {
        actualTime = System.currentTimeMillis();
        if(actualTime - lastUpdateAcc < 500)
            return;
        else{
            lastUpdateAcc = actualTime;
            //update myPosition
            TextView tv = (TextView)findViewById(R.id.textView3);
            tv.setText(String.format("X: %8.4f -- Y: %8.4f -- Z: %8.4f",
                    event.values[0], event.values[1], event.values[2]));
            //draw on the screen

            //draw new path, if one exists
        }
    }
duru
  • 270
  • 4
  • 14
  • [Kalman filter and quality of internal state variables](http://stackoverflow.com/questions/9229878/kalman-filter-and-quality-of-internal-state-variables) says that they have implemented JKalman which makes them smarter then me. – duru Aug 06 '12 at 04:13
  • And [Ali](http://stackoverflow.com/users/341970/ali) has an [answer](http://stackoverflow.com/users/341970/ali?tab=answers) or a [comment](http://stackoverflow.com/users/341970/ali?tab=activity&sort=comments) under each sensor or Kalman related question. So I am using his profile as a reference for the topic. – duru Aug 06 '12 at 04:18
  • I am flattered :) What would you like to achieve? Do you wish to track orientation or position? As far as I know Android already has something like the Kalman filter, why are you trying to implement your own? – Ali Aug 06 '12 at 07:55
  • Hi Ali :) I wanna track position. Do you mean the "fused" sensors as in [here](http://stackoverflow.com/a/8006832/222888)? They do not by their own, because you need a cumulative approximation of the next step anyway. – duru Aug 06 '12 at 10:52
  • Another thing is, [these guys](http://www.youtube.com/watch?v=HTZFRDBdQck) has done this using a pedofilter (as far as their survey suggests) and with constant step lengths. So this is somehow possible then and it gives me courage watching this video. – duru Aug 06 '12 at 10:56
  • did u implement kalman for android? I did it ... but I can't initial Process noise variance for the accelerometer and gyro correctly... can u help me please? – jion Feb 17 '15 at 10:59
  • sadly, i abandoned that project. if you can work it out, please contribute to the answer. good luck. – duru Feb 18 '15 at 00:39

3 Answers3

1

It seems you need 3D JKalman filter. You may try this:

JKalman kalman = new JKalman(6, 3);

Matrix s = new Matrix(6, 1); // state [x, y, z, dx, dy, dz]        
Matrix c = new Matrix(6, 1); // corrected state
Matrix m = new Matrix(3, 1); // measurement [x, y, z]

// the initial values follow (sorry for programming in stackoverflow):
m.set(0, 0, x);
m.set(1, 0, y);
m.set(2, 0, z);

// transitions for x, y, z, dx, dy, dz (velocity transitions)
double[][] tr = { {1, 0, 0, 1, 0, 0}, 
                  {0, 1, 0, 0, 1, 0}, 
                  {0, 0, 1, 0, 0, 1}, 
                  {0, 0, 0, 1, 0, 0}, 
                  {0, 0, 0, 0, 1, 0}, 
                  {0, 0, 0, 0, 0, 1} };
kalman.setTransition_matrix(new Matrix(tr));

Follow then the example in KalmanTest.java and check this for errors, please.

P3k
  • 11
  • 2
1

this is how I do it with 2 variables (GPS:LAT, LON):

import jkalman.JKalman;
import jama.Matrix;

public class KalmanFilter {
    private int variables;
    private JKalman kalman;
    private Matrix s; // state [x, y, dx, dy, dxy]
    private Matrix c; // corrected state [x, y, dx, dy, dxy]
    private Matrix m; // measurement [x]

    /*
     * Inicializa el filtro kalman con 2 variables
     */
    public void initialize2() throws Exception{
        double dx, dy;

        if(variables != 0){
             throw new RuntimeException();
        }
        variables = 2;
        kalman = new JKalman(4, 2);

        // constant velocity
        dx = 0.2;
        dy = 0.2;

        s = new Matrix(4, 1); // state [x, y, dx, dy, dxy]        
        c = new Matrix(4, 1); // corrected state [x, y, dx, dy, dxy]                

        m = new Matrix(2, 1); // measurement [x]
        m.set(0, 0, 0);
        m.set(1, 0, 0);

        // transitions for x, y, dx, dy
        double[][] tr = { {1, 0, dx, 0}, 
                          {0, 1, 0, dy}, 
                          {0, 0, 1, 0}, 
                          {0, 0, 0, 1} };
        kalman.setTransition_matrix(new Matrix(tr));

        // 1s somewhere?
        kalman.setError_cov_post(kalman.getError_cov_post().identity());

    }

    /*
     * Aplica Filtro a variables
     */
    public void push(double x,double y) throws Exception{
         m.set(0, 0, x);
         m.set(1, 0, y);

         c = kalman.Correct(m);
         s = kalman.Predict();
    }

    /*
     * obtiene arreglo con datos filtrados.
     */
    public double[] getKalmanPoint2() throws Exception{
        double[] point = new double[2];
        point[0] = c.get(0,0);
        point[1] = c.get(1,0);
        return point;
    }

    /*
     * obtiene arreglo con prediccion de punto.
     */
    public double[] getPredict2() throws Exception{
        double[] point = new double[2];
        point[0] = s.get(0,0);
        point[1] = s.get(1,0);
        return point;
    }

    /*
     * obtiene cantidad de variables del objeto
     */
    public int getNVariables() throws Exception{
        return this.variables;
    }

}

But I don't know how to set the first point, I always start from (0,0) and take 50 samples to reach the point, with a loop is not very elegant.

Alex
  • 781
  • 10
  • 23
Leo
  • 41
  • 5
0

You cannot make a general-purpose position tracking app simply because the gyros are too noisy. (Yes, the gyros and not the accelerometer.)

As for indoor positioning, see also the above link.

Community
  • 1
  • 1
Ali
  • 56,466
  • 29
  • 168
  • 265
  • 1
    Thanks Ali :) I have read that question as well as others before. But I don't wanna decide before experiencing it. At this step, I need to implement the Kalman filter. – duru Aug 06 '12 at 14:47
  • And about the gyros. Why should you need the gyros when they are so noisy and when you have a 3-axis accelerometer? The accelerometer gives you the vector of acceleretion on three axis, so you can make an estimate of where you are headed and you can even calculate your position. – duru Aug 06 '12 at 14:49
  • And you said that Android already had something like the Kalman filter, any clue on this direction? – duru Aug 06 '12 at 14:50
  • I am really trying to help but at this point I have to ask you to watch / read carefully the linked materials, especially the video and the linked UCAM-CL-TR-696.pdf file, subsection 6.2.3. If you do that you will understand why you need the gyros. You will also understand why you cannot do general-purpose position tracking. If you watch the video, you will know what to look for on the Android platform that implements the Kalman filter (or something like that). – Ali Aug 06 '12 at 14:58
  • I see how much you are trying to help in SO and I really appreciate it. Thank you again :) I watched and look over the documents (though I didn't really) a few times now. David Sachs suggests at 27:13 that model dynamics with Kalman filter is better than a high pass filter, both of which correct the drift on their own way (and then there is pedofilter if you are walking). And on the paper you mentioned, they say that the source of the drift is the double integration. Since I couldn't find a way of implementing JKalman, I am trying to calculate the distance via x = 1/2 at^2 (...>) – duru Aug 06 '12 at 15:34
  • (...) where a is the average acceleretion of 15 samples taken each 300ms after subtraction of standard average noise, which happens while the device stands on the desk. So this is pretty straight logic and yet in theory only. But in a few hours, I think I will have it finished. – duru Aug 06 '12 at 15:37
  • *What I was trying to say about the documents was, I didn't really understand all the concepts in them. But I got an idea. – duru Aug 06 '12 at 15:39