How can I get the direction of movement using an accelerometer?
Asked Answered
A

2

20

I'm developing a Android application and I would like to know if is possible detect the direction of movement with one axis fixed. For example, I want put my phone on the table and detect the direction when I move it (left, right, up and down). The distance is not necessary, I just want know the accurate direction.

Ambulacrum answered 7/5, 2012 at 4:26 Comment(1)
Some posts about accelerometer: anddev.org/advanced-tutorials-f21/… developer.android.com/reference/android/hardware/…Dives
D
27

Yes.

Using the SensorEventListener.onSensorChanged(SensorEvent event) you can determine the values provided along the X & Y axis. You would need to record these values and then compare them to any new values that you receive on subsequent calls to the onSensorChanged method to get a delta value. If the delta value on one axis is positive then the device is moving one way, if its negative its moving the opposite way.

You will probably need to fine tune both the rate at which you receive accelerometer events and the threshold at which you consider a delta value to indicate a change in direction.

Here's a quick code example of what I'm talking about:

public class AccelerometerExample extends Activity implements SensorEventListener {
    TextView textView;
    StringBuilder builder = new StringBuilder();

    float [] history = new float[2];
    String [] direction = {"NONE","NONE"};

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        textView = new TextView(this);
        setContentView(textView);

        SensorManager manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        Sensor accelerometer = manager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
        manager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        float xChange = history[0] - event.values[0];
        float yChange = history[1] - event.values[1];

        history[0] = event.values[0];
        history[1] = event.values[1];

        if (xChange > 2){
          direction[0] = "LEFT";
        }
        else if (xChange < -2){
          direction[0] = "RIGHT";
        }

        if (yChange > 2){
          direction[1] = "DOWN";
        }
        else if (yChange < -2){
          direction[1] = "UP";
        }

        builder.setLength(0);
        builder.append("x: ");
        builder.append(direction[0]);
        builder.append(" y: ");
        builder.append(direction[1]);

        textView.setText(builder.toString());
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // nothing to do here
    }
}

This code will only provide you with the general direction on the X and Y axis that the phone has moved in. To provide a more fine grained determination of direction (e.g. to attempt to mimic the movement of a computer mouse) you might find that a phone's accelerometer is not fit for purpose.

To attempt this, I would first set the sensor delay to SensorManager.SENSOR_DELAY_FAST and create a list of multiple history events so that I could detect movement over time and not be influenced by slight movements in the opposite direction that often happen when taking accelerometer measurements at such a fine level. You would also need to measure the amount of time that has passed to help calculate the accurate measure of movement as suggested in your comments.

Defrock answered 7/5, 2012 at 5:30 Comment(6)
Hello Louth! Thanks for your reply. I've already tested a similar code, the problem are the changes when the phone is moving. As I need accurancy, I work with a "xChange" about 0.3. Even the movement being "constant" from left to right, the value changes many times. Analysing the accelerometer values, I've realized that sometimes after a movement, the accelerometer generates equivalents values in opposite direction and it causes the change. I need get the direction with an accurancy similar to old-style mouses (with spheres) at least. Do you have some tip?Ambulacrum
Welcome Marcos. You should update your question because trying to make your phone behave as a mouse is not the same as detecting direction. I'm not sure the accelerometer was designed for the kind of thing that you want to do. As it measures acceleration, you might not be able to achieve the fine grained movement detection you are looking for.Defrock
I've updated my answer to consider your comments. Please update your question and consider accepting this answer.Defrock
@Defrock Can you take a look on this question please?Subliminal
Which sensors should I use to simulate mouse movements (dx, dy) on plane coordinate needed. I have tried accelerometer but the movement is rather related to phone rotation, rather than phone movement on the planeEndocardial
@MichałZiobro I think it is better to use TYPE_LINEAR_ACCELERATION sensor because the gravity is excluded.Quantify
S
1

From what I've read, with the sensors one can detect only accelerations and phone orientation. So you can easily detect the start of the movement (and in which direction) and the stop of the movement, since the velocity is changing so there is acceleration (when stoping acceleration is against the velocity direction).

If the phone is moving with constant velocity, the accelerometers will give zero values (linear acceleration which subtracts gravity). So in order to know if the phone is moving you should compute the velocity at each instant, by

V(t)=V(t-1)+a*dt

in which:

  • V(t-1) is the known velocity at previous instant,
  • V(t) is the velocity at current instant,
  • a is the acceleration (consider the acceleration in previous instant or mean acceleration between previous and current instant).

The problem is that due to the uncertainty of the sensor values, you might end up summing small errors at each instant, which will lead to erroneous velocity values. Probably you'll have to adjust a low pass filter to the values.

Stipitate answered 19/11, 2015 at 15:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.