Как узнать направление движения с помощью акселерометра?

Я разрабатываю приложение для Android, и я хотел бы знать, возможно ли определить направление движения с одной фиксированной осью. Например, я хочу положить свой телефон на стол и определить направление, когда я его двигаю (влево, вправо, вверх и вниз). Расстояние не обязательно, я просто хочу знать точное направление.


person Marcos Passos    schedule 07.05.2012    source источник
comment
Несколько сообщений об акселерометре: anddev.org/advanced -tutorials-f21/ developer.android.com/reference /андроид/оборудование/   -  person Niko    schedule 07.05.2012


Ответы (2)


да.

Используя SensorEventListener.onSensorChanged(SensorEvent event), вы можете определить значения по осям X и Y. Вам нужно будет записать эти значения, а затем сравнить их с любыми новыми значениями, которые вы получите при последующих вызовах метода onSensorChanged, чтобы получить дельта-значение. Если значение дельты по одной оси положительное, то устройство движется в одну сторону, если отрицательное — в противоположную.

Вам, вероятно, потребуется точно настроить как скорость, с которой вы получаете события акселерометра, так и порог, при котором вы считаете, что значение дельты указывает на изменение направления.

Вот краткий пример кода того, о чем я говорю:

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
    }
}

Этот код предоставит вам только общее направление по осям X и Y, в котором перемещался телефон. Чтобы обеспечить более точное определение направления (например, для попытки имитировать движение компьютерной мыши), вы можете акселерометр телефона не подходит для этой цели.

Чтобы попытаться это сделать, я бы сначала установил задержку датчика на SensorManager.SENSOR_DELAY_FAST и создал список нескольких событий истории, чтобы я мог обнаруживать движение с течением времени и не подвергаться влиянию небольших движений в противоположном направлении, которые часто случаются при измерениях акселерометра при такой скорости. прекрасный уровень. Вам также нужно будет измерить количество прошедшего времени, чтобы помочь рассчитать точную меру движения, как это предлагается в ваших комментариях.

person Louth    schedule 07.05.2012
comment
Привет Лаут! Спасибо за ответ. Я уже тестировал подобный код, проблема в изменениях при движении телефона. Поскольку мне нужна точность, я работаю с xChange около 0,3. Даже при постоянном движении слева направо значение меняется многократно. Анализируя показания акселерометра, я понял, что иногда после движения акселерометр выдает эквивалентные значения в противоположном направлении, что и вызывает изменение. Мне нужно получить направление с точностью, как у старых мышей (со сферами), по крайней мере. У вас есть совет? - person Marcos Passos; 07.05.2012
comment
Добро пожаловать, Маркос. Вы должны обновить свой вопрос, потому что попытка заставить ваш телефон вести себя как мышь - это не то же самое, что определение направления. Я не уверен, что акселерометр был разработан для того, что вы хотите делать. Поскольку он измеряет ускорение, вы, возможно, не сможете добиться требуемого точного обнаружения движения. - person Louth; 08.05.2012
comment
Я обновил свой ответ, чтобы учесть ваши комментарии. Пожалуйста, обновите свой вопрос и рассмотрите возможность принятия этого ответа. - person Louth; 08.05.2012
comment
@Louth Не могли бы вы взглянуть на этот вопрос, пожалуйста? - person Skizo-ozᴉʞS; 28.01.2016
comment
Какие датчики следует использовать для имитации движений мыши (dx, dy) по необходимой координате плоскости. Я пробовал акселерометр, но движение скорее связано с вращением телефона, чем с движением телефона в самолете. - person Michał Ziobro; 29.08.2017
comment
@MichałZiobro Я думаю, что лучше использовать TYPE_LINEAR_ACCELERATION датчик, потому что сила тяжести исключена. - person Ehsan Shadi; 01.05.2021

Из того, что я читал, с помощью датчиков можно определить только ускорение и ориентацию телефона. Таким образом, вы можете легко определить начало движения (и в каком направлении) и остановку движения, поскольку скорость меняется, поэтому есть ускорение (когда останавливающееся ускорение направлено против направления скорости).

Если телефон движется с постоянной скоростью, акселерометры будут давать нулевые значения (линейное ускорение, за вычетом силы тяжести). Таким образом, чтобы узнать, движется ли телефон, вы должны вычислить скорость в каждый момент времени с помощью

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

в котором:

  • V(t-1) — известная скорость в предыдущий момент,
  • V(t) - скорость в текущий момент,
  • a - это ускорение (учитывайте ускорение в предыдущий момент или среднее ускорение между предыдущим и текущим моментом).

Проблема в том, что из-за неопределенности значений датчиков вы можете суммировать небольшие ошибки в каждый момент времени, что приведет к ошибочным значениям скорости. Вероятно, вам придется настроить фильтр нижних частот на значения.

person renatogsousa    schedule 19.11.2015