Hasnain Rahman Fahim
Hasnain Rahman Fahim

Reputation: 25

Accelerometer values are not perfect in android

I get the sensor values from android accelerometer but the values are not consistent. I think if we can add some filter then we can easily check for data reliability. Suppose if i built a low pass filter like fix two values low high

if value less than low ---- device is still(not moving)

if values more than low less than high -- device is staring to move

if values more than high --- we attenuate the value( device moving)

Now i cant determine what should be the values and how to implement such a thing. Or if my thinking are correct i mean if this types of filter is going to work or not.

Upvotes: 1

Views: 75

Answers (1)

Zahan Safallwa
Zahan Safallwa

Reputation: 3914

Your idea is more or less ok. But need some addition. We can use a low pass filter. The logic you gave should be used to determine the rate of change of data alpha (not the data). I can give you a simple class that does the work for you

public class minPassFilter {

private static final float A_DEFAULT = 0.333f;
private static final float A_STEADY       = 0.001f;
private static final float A_START_MOVING = 0.6f;
private static final float A_MOVING       = 0.9f;

private minPassFilter() { }

public static float[] filter(float min, float max, float[] present, float[] former) {
    if (present==null || former==null) 
        throw new NullPointerException("Input and former arrays can't be NULL");
    if (present.length!=former.length) 
        throw new IllegalArgumentException("Input and former arrays must have the same length");

    float A = computeA(min,max,present,former);

    for ( int i=0; i<present.length; i++ ) {
        former[i] = former[i] + A * (present[i] - former[i]);
    }
    return former;
}

private static final float computeA(float min, float max, float[] present, float[] former) {
    if(former.length != 3 || present.length != 3) return A_DEFAULT;

    float x1 = present[0],
          y1 = present[1],
          z1 = present[2];

    float x2 = former[0],
          y2 = former[1],
          z2 = former[2];

    float distance = (float)(Math.sqrt( Math.pow((double)(x2 - x1), 2d) +
                                        Math.pow((double)(y2 - y1), 2d) +
                                        Math.pow((double)(z2 - z1), 2d))
    );

    if(distance < min) {
        return A_STEADY;
    } else if(distance >= min || distance < max) {
        return A_START_MOVING;
    } 
    return A_MOVING;
}
}

You can pass your sensor data to this class and get the filtered value.

For reference the github link is this

Upvotes: 1

Related Questions