Smoothing Out Values

0
137

Accelerometer sensors are prone to spurious results. Accelerometer values are not always coming across at a regular pace, and users can make erratic movements. If you want to avoid a jittery effect, smooth out the values. You can do this by combining previous readings with the current reading and leaving out a range of values according to a defined filter.

There are two approaches to accomplishing this. A high-pass filter is used for an application that is looking for rapid changes by weighting the current reading more than the previous reading. A good use case for a high-pass filter is detecting a shake motion, as in our previous example. A low-pass filter is used for an application that is looking for fine-tuned, stable values. This type of filter would be used in a game of precision, such as carefully pushing an object toward a target.

When testing these filters, the values start adjusting as expected after a few seconds.

Using a high-pass filter

The high-pass filter works with a fixed filter. Try different filter values until you achieve the effect you are looking for:

const FILTER:Number = 0.10;
var high:Number = 0.0;
var oldHigh:Number = 0.0;
function onUpdate(event:AccelerometerEvent):void {
var ax:Number = event.accelerationX;
high = ax – (ax*FILTER) + oldHigh * (1.0 – FILTER);
oldHigh = high;
}

Let’s go over the formula. ax is the new accelerometer value on the x-axis. high is the adjusted value after applying the filter formula, and oldHigh is the cumulated value over time.

ax is reduced by one-tenth of its value. For instance, if ax is equal to 3:

high = ax – (ax*FILTER)
3 – (3*0.10)
3 – 0.30
2.70

Let’s say that initially oldHigh is equal to zero, but over time, it is equal to 2. The following code reduces oldHigh by one-tenth:

oldHigh = oldHigh * (1.0 – FILTER));
2 * (1.0 – 0.10);
2 * 0.90
1.80

The new high value is 4.5:

2.70 + 1.80
4.5

Let’s examine these values over time. Returning to our shake example, to test the code with the high-pass filter, the threshold value is increased:

const THRESHOLD:Number = 5.0;
var isMeasuring:Boolean = false;
var isShaking:Boolean = false;
const FILTER:Number = 0.10;
var high:Number = 0.0;
var oldHigh:Number = 0.0;
function onUpdate(e:AccelerometerEvent):void {
if (isMeasuring) {
return;
}
isMeasuring = true;
var ax:Number = event.accelerationX;
high = ax – (ax*FILTER) + oldHigh * (1.0 – FILTER);
oldHigh = high;
if (Math.abs(high) > THRESHOLD) {
isShaking = true;
}
if (isShaking) {
// we have a shake
}
isMeasuring = false;
}

Using a low-pass filter

The low-pass filter has the effect of changing slowly and stabilizing the input. It is handy for rotating art for a flight simulation or a rowing boat.

The low-pass filter looks as follows:

const FILTER:Number = 0.10;
var low:Number = 0.0;
var oldLow:Number = 0.0;
function onUpdate(event:AccelerometerEvent):void {
var ax:Number = accelerationX;
low = ax * FILTER + oldLow * (1.0 – FILTER);
oldLow = low;
}

Keep in mind that the more you filter the value, the more lag you will get in response because the average converses more slowly to the current value of the sensor.