Thom Nichols

Thom

Technology is evolution outside the gene pool

Smoothing Sensor Data with a Low-Pass Filter

If you search StackOverflow, there are a number of posts about Android sensor data being very jittery, and suggestions on implementing a smoothing algorithm.  Well not many people have actually posted a smoothing algorithm, and those that I have seen tend to be fairly complex.  

After some searching, I came to the Wikipedia entry for Low Pass Filter.  There's a pseudocode algorithm that I adapted for Java which works splendidly.  Not only that, but it's extremely simple.  The algorithm essentially requires tracking only two numbers - the prior number and the new number.  There's a constant, alpha, which affects the 'weight' or 'momentum' -- basically how drastically does the new value affect the current smoothed value.  Here's the full implementation:

	/*
	 * time smoothing constant for low-pass filter
	 * 0 ≤ alpha ≤ 1 ; a smaller value basically means more smoothing
	 * See: http://en.wikipedia.org/wiki/Low-pass_filter#Discrete-time_realization
	 */
	static final float ALPHA = 0.15f;

	/**
	 * @see http://en.wikipedia.org/wiki/Low-pass_filter#Algorithmic_implementation
	 * @see http://developer.android.com/reference/android/hardware/SensorEvent.html#values
	 */
	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;
	}

In my particular case, I used this to normalize raw accelerometer and magetometer sensor readings before calculating a compass bearing. Note that the input and output array elements are not sequential values, but completely separate dimensions (x,y,z) so e.g. each new x value is normalized against the smoothed x value, the new y with the smoothed y, etc. 

This smoothing also has the curious effect of actually accelerating and decelerating the resulting visualization, e.g. the compass needle appears to have inertia and momentum if you quickly rotate the device.  Just like a physical compass needle would.  Neat!

Update: I've posted a follow-up, which explains how to take the low-pass output and get a compass rotation.

Category: Android Java data

(Comments are closed)

13 Comments

  1. avatar Re: Smoothing Sensor Data with a Low-Pass Filter Oct. 1, 2011 Elektrophreak

    Cool! :-)
  2. avatar Re: Smoothing Sensor Data with a Low-Pass Filter Oct. 26, 2011 Wolfgang

    Shouldn't be ALPHA somehow depend on the sampling rate?
  3. avatar Re: Smoothing Sensor Data with a Low-Pass Filter Jan. 2, 2012 Dave Rose

    This works very well, thanks!  I'm implementing my own compass using the accelerometer and mag sensors.  However, all examples I've found are incomplete in some way.  Would you post your sensor handling code?  It would be appreciated.

  4. avatar Re: Re: Smoothing Sensor Data with a Low-Pass Filter June 26, 2012 Thom

    Dave - finally got around to posting an example which should clarify how the lowPass function is used.  See my follow-up post.

  5. Re: Smoothing Sensor Data with a Low-Pass Filter March 20, 2012 Paweł

    Can you post an example how to use this ? 
  6. avatar Re: Smoothing Sensor Data with a Low-Pass Filter June 26, 2012 Andrew

    Shouldn't the code inside the for loop read:


    output[i] = output[i-1] + ALPHA * (input[i] - output[i]);

    ?
  7. avatar Re: Re: Smoothing Sensor Data with a Low-Pass Filter June 26, 2012 Thom

    Andrew - So the short answer is, no.  See my follow-up post, which should clarify how the function is used.

  8. avatar Re: Re: Re: Smoothing Sensor Data with a Low-Pass Filter Aug. 10, 2012 kw

    I used your code but I still seem to be returning small numbers. To set the angle of a degree I need something between -180 and 180. Any idea on how to get that back ? 
  9. avatar Re: Re: Re: Re: Smoothing Sensor Data with a Low-Pass Filter Aug. 10, 2012 Thom

    You mean you're getting small numbers from the output of SensorManager.getRotationMatrix(), I presume?  I don't remember but I think that value might be in radians.

  10. avatar Re: Re: Smoothing Sensor Data with a Low-Pass Filter Oct. 17, 2013 essay service

    Banquet healthful deals of fruits, wheat or cereal as it restrains coarse carbs essay service. It assists refresh your substance plus belief so that you endow be extra focused further be apt to stipend better complaisance while lessons during the rating dot.

  11. avatar Re: Smoothing Sensor Data with a Low-Pass Filter Nov. 6, 2012 daab89

    Awesome ! I google your post by "Java low pass filter", and found exacly what I was looking for :)    
  12. avatar Re: Smoothing Sensor Data with a Low-Pass Filter July 8, 2013 Sama

    Hello All, thanx for such an explanining post ;) great for real .  
    Does anyone help me apply high-pass filter as well ?  
    As far as know, in order to remove noise I need to first apply "low pass filter " then "high pass filter" over it  ( according to this post 
    http://seattlesensor.wordpress.com/2013/01/01/accelerometer-sensor-data-processing/comment-page-1/#comment-98 , this way is the best way to remove the noise ) .  Actually it would be great to learn the steps to remove the noise and have a proper set of acceleration data. 

    Regards, 
  13. avatar Re: High-pass filter? July 8, 2013 Thom

    I don't think you need to do a second filter if you use the technique I've detailed here.  This smooths out all of the "noise" - if you were to graph the output it would be a pretty smooth curve.  Increasing the value of alpha can make it smoother but it slows the rate of change.