Android Low pass filter and High pass filter

前端 未结 4 1108
一整个雨季
一整个雨季 2020-12-07 16:46

I have a very basic question. What is Low Pass filter and High Pass filter in case of Android Accelerometer?

When I see the output from the Accelerometer Sensor, I

相关标签:
4条回答
  • 2020-12-07 17:29

    Low Pass Filter: passes low-frequency signals and reduces the amplitude of signals with frequencies higher than the threshold frequency

    High Pass Filter: passes high-frequency signals and reduces the amplitude of signals with frequencies lower than the threshold frequency

    If you look at the documentation, it says: "in order to measure the real acceleration of the device, the contribution of the force of gravity must be eliminated. This can be achieved by applying a high-pass filter. Conversely, a low-pass filter can be used to isolate the force of gravity."

    You could check out this tutorial on low pass filtering: http://www.raweng.com/blog/2013/05/28/applying-low-pass-filter-to-android-sensors-readings/

    Reading the docs at http://developer.android.com/reference/android/hardware/SensorEvent.html#values, you can see that you can access the a values on all x,y,z axis by doing:

    values[0] - a on x axis
    values[1] - a on y axis
    values[2] - a on z axis
    
    0 讨论(0)
  • 2020-12-07 17:44

    Output of accelerometer includes noise if you subtract directly from these values that include noise. To eliminate noise it is required to implement highpass and lowpass filters.

    0 讨论(0)
  • 2020-12-07 17:51

    If you look at the documentation you will see that SensorEvent returns an array which represents the vector of all the forces. http://developer.android.com/reference/android/hardware/SensorEvent.html#values This is how the components of the acceleration break down into each axis:

     values[0] //acceleration on x axis
     values[1] //acceleration on y axis
     values[2] //acceleration on z axis
    

    You need to find which direction gravity is operating in then decompose that into its component parts. The magnitude of the gravity force will always be 9.8 but the direction, and hence how it breaks down into the component parts, will change. Assuming that we could get the value of gravity and store that vector in an array like gravity[3]:

     gravity[0] //gravity x axis
     gravity[1] //gravity y axis
     gravity[2] //gravity z axis
    

    The total acceleration, T, on the phone is T = g + a. To get just a we would need a = T - g:

     linear_acceleration[0] = event.values[0] - gravity[0];
     linear_acceleration[1] = event.values[1] - gravity[1];
     linear_acceleration[2] = event.values[2] - gravity[2];
    

    Notice how this calculates everything element by element because it's a vector operation.

    The tricky part is finding gravity because there is only one accelerometer in the phone which measures both the gravity AND the other forces at the same time. We have 2 different forces that we want to find from the one sensor. If we could only look at the forces at an isolated point in time we wouldn't be able to extract the information. However we do get samples over a range of times and by looking at how the forces change over time we can extract the information.

    This means we need to filter out the results from that one source based on how quickly those forces change. The magnitude of acceleration due to gravity does not change quickly because it doesn't change at all. Gravity is a constant force. However other forces will change over time. If we filter out the slow changing forces like gravity by using a high-pass filter then the remaining forces are the fast changing ones like the forces being applied to the phone. This is why the high-pass filter is used.

    0 讨论(0)
  • 2020-12-07 17:51

    I usually use this formula To filter the data from the accelometer sensor data coming out to linear sensor(like gyroscope) data. Use it if you are not sure there is a built-in Gyroscopic sensor.

    private float[] values;
    private float[] valuesN;
    private float[] prev;
    private float[] prevHF;
    private boolean doHPF = false;
    
    // ind - index of three dimensions (x, y, z)
    private void makeHPFf() {
        for (int ind = 0; ind < 3; ind++) {
            valuesN[ind] = values[ind] * 0.002f * 9.8f;
            if (doHPF)
                values[ind] = valuesN[ind] - prev[ind] + (prevHF[ind] * 0.8f);
            prev[ind] = valuesN[ind];
            prevHF[ind] = values[ind];
        }
    
        if (!doHPF)
            doHPF = true;
    }
    
    0 讨论(0)
提交回复
热议问题