Git Product home page Git Product logo

low-pass-filter-to-android-sensors's Introduction

Applying Low Pass Filter to Android Sensor's Readings


Overview of Android Sensors

The Android sensor framework lets you access many types of sensors. Two very basic types are:

  1. Hardware Sensors.
  2. Software Sensors.

Hardware sensors are physical components built into a handset or tablet device. They derive their data by directly measuring specific environmental properties, such as acceleration, geomagnetic field strength, or angular change.
ex. Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_MAGNETIC_FIELD

Software sensors are not physical devices, although they mimic hardware-based sensors. Software-based sensors derive their data from one or more of the hardware-based sensors and are sometimes called virtual sensors or synthetic sensors. ex.Sensor.TYPE_ORIENTATION, Sensor.TYPE_ROTATION_VECTOR

Best Practices for Accessing and Using Sensors

  1. Unregister sensor listeners.
  2. Don't test your code on the emulator.
  3. Don't block the onSensorChanged() method.
  4. Avoid using deprecated methods or sensor types.
  5. Verify sensors before you use them.
  6. Choose sensor delays carefully.
  7. Filter the values received in onSensorChanged(). Allow only those that are needed.

After we register the Sensors, the sensor reading get notified in SensorEventListener's onSensorChanged() method. However, the rate of change in sensor values is such high that if we map these small changes a.k.a 'Noise' the values jump within a large range of values.


We can also specify the SensorManager's delay properties from one of these:

  1. SENSOR_DELAY_FASTEST
  2. SENSOR_DELAY_GAME
  3. SENSOR_DELAY_UI
  4. SENSOR_DELAY_NORMAL


This is however only a hint to the system. Events may be received faster or slower than the specified rate. Usually events are received faster.

Moral of the story is...

Allow only those values which are useful and discard the unnecessary noise.

The solution for this is to apply a Low-Pass Filter on these values.

A Small Glimpse of Low Pass Filter

A low-pass filter is a filter that passes low-frequency signals/values and attenuates (reduces the amplitude of) signals/values with frequencies higher than the cutoff frequency.
Let us take an example of simple signal with values ranging from 0 to 1. The values can be anything between 0 to 1. Due to some external source, environmental factors such as jerks, vibrations., a considerable amount of noise is added to these signals. These high frequency signals (noise) cause the readings to hop between considerable high and low values.

Enough of Physics...
Lets understand this in programming concept rather. :)

Programmatically Apply Low Pass Filter

Device's sensor readings add noise data due to high sensitivity of its hardware to various factors as mentioned above. For gaming purpose these highly sensitive values are much a boon. But for application where there has to be smoothness in the readings, these hopping values are a mess.
Lets take an example of Augmented Reality View, where we have to point markers on Camera SurfaceView.
The high sensitivity causes the markers the change positions very randomly due to the noise.
A Low-Pass Filter concept comes to rescue. We can omit those high frequencies in the input signal applying some suitable threshold and apply the filter output reading to plot the markers.
With this implementation the markers won't hop randomly because we have removed the unwanted high reading values.

Here is the algorithm implementation:
for i from 1 to n
y[i] := y[i-1] + α * (x[i] - y[i-1])

Here, α is the cut-off/threshold.

Lets see how to implement it in Android.
lowPass(float[] input, float[] output)
The above method filters the input values and applies LPF and outputs the filtered signals

static final float ALPHA = 0.25f; // if ALPHA = 1 OR 0, no filter applies.

protected float[] lowPass( float[] input, float[] output ) {
    if ( output == null ) return input;
     
    for ( int i=0; i<input.length; i++ ) {
        output[i] = output[i] + ALPHA * (input[i] - output[i]);
    }
    return output;
}


Low-Pass Filter is finally applied to sensor values in onSensorChanged(SensorEvent event) as follows:

@Override
public void onSensorChanged(SensorEvent evt) {


	if (evt.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
		gravSensorVals = lowPass(evt.values.clone(), gravSensorVals);

	} else if (evt.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
		magSensorVals = lowPass(evt.values.clone(), magSensorVals);
	}
	
	if (gravSensorVals != null && magSensorVals != null) {
		SensorManager.getRotationMatrix(RTmp, I, gravSensorVals, magSensorVals);

		int rotation = Compatibility.getRotation(this);

		if (rotation == 1) {
			SensorManager.remapCoordinateSystem(RTmp, SensorManager.AXIS_X, SensorManager.AXIS_MINUS_Z, Rot);
		} else {
			SensorManager.remapCoordinateSystem(RTmp, SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_Z, Rot);
		}

		SensorManager.getOrientation(Rot, results);

		UIARView.azimuth = (float)(((results[0]*180)/Math.PI)+180);
		UIARView.pitch = (float)(((results[1]*180/Math.PI))+90);
		UIARView.roll = (float)(((results[2]*180/Math.PI)));

		radarMarkerView.postInvalidate();
	}
}


An example of this can be found here.
Here i have applied low pass filter for Sensor.TYPE_ACCELEROMETER and Sensor.TYPE_MAGNETIC_FIELD.

low-pass-filter-to-android-sensors's People

Contributors

bhide avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.