Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to track path using accelerometer in android?

I want to create an application which tracks path in android. I have used following code for calculating accelerations in different directions.

package com.example.usrivast.accelerometer;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;


public class MainActivity extends Activity implements SensorEventListener{

Sensor accelerometer = null;
SensorManager sm = null;
TextView acceleration = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    sm = (SensorManager)getSystemService(SENSOR_SERVICE);
    accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    acceleration = (TextView)findViewById(R.id.acceleration);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@Override
public void onSensorChanged(SensorEvent event) {

    acceleration.setText("x: " + event.values[0] + "\ny: " + event.values[1] + "\nz: " + event.values[2]);
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
   }
}

But I am not able to understand the output of the values. They change very rapidly. Also if my phone is at rest then also these values change. An example of these values when my phone is at rest on my desk are x: -0.1278 y: 0.2968 z: 9.6323 They change very rapidly. I am using Nexus 5.

like image 658
Utkarsh Srivastav Avatar asked Sep 01 '26 22:09

Utkarsh Srivastav


1 Answers

The accelerometers in smart-phones are extremely cheap and tiny. This means that their output is of very poor quality.

The first thing that you will notice is what you already have noticed, which is that the values will be very noisy. This means that the values will bounced up and down randomly and very rapidly, all the time. This is just typical signal noise or white noise, and cheap sensors have a lot of it, especially when they are packed inside a small package that has lots of digital electronics and antennas (wifi, cell freq., etc..). Figuring out ways to get rid of that noise is an entire field of science of its own (called signal processing), and it's far more intricate than you might suspect. A basic idea is to use some sort of low-pass filter.

The second thing you will not notice right now, but you will if you try to do anything more with the signal (especially if integrating it). This problem is about biases in the sensors. Basically, this problem is about a zero acceleration not registering as zero on the sensors. To complicate the matter, this "bias" will typically float and change over time (and change with temperature too, like when a battery gets hot or the phone is in the palm of a hand). Again, properly getting rid of this bias is not easy (could be as easy as applying a high-pass filter, but the preferred method is to use an augmented Kalman filter).

The third problem is non-linearity. Most cheap accelerometers are far from having a linear relationship between acceleration and the measured value. They are usually designed to be relatively linear around 0, and get worse towards the upper and lower bound of the range of accelerations they can measure. So, this won't be a problem if you don't move too violently.

And the result of all these problems put together is that the accelerometers inside smartphones are simply not good enough to produce anything precise like a trace of the path of motion of the phone. To actually produce this path, you would need numerically integrate the signal twice (once to get velocities, once more to get positions). Numerical integration will typically make each of the above problems much worse, and doing it twice is going to be disastrous. And most filters that you can apply to remove noise and/or bias will add other problems when it comes to integrating the signals. One way or the other, you are battling with some unbreakable forces of nature, signal processing is a very unforgiving field, and the bottom line is that you need better signals to begin with if you hope to get anything other than garbage at the end, or as we say, garbage in, garbage out.

This is why accelerometers in smartphones are rarely used for anything other than detecting the direction the phone is being held (which is a simple calculation based on accelerometer values averaged over some time) and to detect fairly violent gestures (detecting large/long spikes on the values). Even something like a Wii-mote, which has much better sensors, can't even be used to recreate the path, the signals are still too noisy and biased for that.

like image 75
Mikael Persson Avatar answered Sep 03 '26 14:09

Mikael Persson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!