2012-06-17 7 views
16

Я собираюсь разработать приложение для Android, которое должно быть читать x, y, z координаты телефона на 3D-пространстве.Прочитайте x y z координаты телефона android с помощью акселерометра

Я хотел бы написать простой код и тест на устройстве ..

Я использую имбирь хлеб на устройстве и эмулятора.

+0

Возможный дубликат [Использование акселерометра, гироскопа и компаса для расчета движения устройства в 3D-мире] (http://stackoverflow.com/questions/8264518/using-accelerometer-gyroscope-and-compass-to-calculate-devices- перемещение-в-3d), которое также запрашивает состояние вращения. –

ответ

16

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

Интеграция ускорения дает вам скорость и интеграция скорости дает вам положение.

Имейте в виду, что интегрирующий шум создает дрейф, а интегрирующий дрейф создает ДЛИННУЮ дрейф, датчики андроида имеют тенденцию генерировать довольно много шума.

На моей галактике S3 я смог получить дрейф в положении до 0,02 м за 5 секунд с использованием композитного датчика линейного акселерометра Google.

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

Если вы еще не сделали, читайте здесь все http://developer.android.com/guide/topics/sensors/sensors_motion.html

Большой разговор о датчиках в андроида

http://www.youtube.com/watch?v=C7JQ7Rpwn2k

Код:

static final float NS2S = 1.0f/1000000000.0f; 
float[] last_values = null; 
float[] velocity = null; 
float[] position = null; 
long last_timestamp = 0; 

@Override 
public void onSensorChanged(SensorEvent event) { 
    if(last_values != null){ 
     float dt = (event.timestamp - last_timestamp) * NS2S; 

     for(int index = 0; index < 3;++index){ 
      velocity[index] += (event.values[index] + last_values[index])/2 * dt; 
      position[index] += velocity[index] * dt; 
     } 
    } 
    else{ 
     last_values = new float[3]; 
     velocity = new float[3]; 
     position = new float[3]; 
     velocity[0] = velocity[1] = velocity[2] = 0f; 
     position[0] = position[1] = position[2] = 0f; 
    } 
    System.arraycopy(event.values, 0, last_values, 0, 3); 
    last_timestamp = event.timestamp; 
} 

Теперь у вас есть положение в 3d-пространстве, помните, что предполагается, что телефон неподвижен, когда он rts выборки.

Если вы не удалите гравитацию, это скоро будет очень далеко.

Это не фильтрует данные и генерирует много дрейфа.

+1

Это не просто шум датчика, создающий дрейф. Основное ограничение этого подхода состоит в том, что принципиально невозможно обнаружить постоянную скорость с помощью акселерометра.Таким образом, интеграция может показаться разумным, когда вы просто слегка встряхиваете свой телефон, но для других типов движения, например, во время вождения или езды на велосипеде, дрейф будет огромным. – Junuxx

+0

Ты абсолютно прав. Я использую акселерометр для отслеживания автомобиля, и для этого я применил калмановский фильтр для дальнейшего уменьшения дрейфа. Я также вычисляю точность акселерометра, измеряя шум, когда он неподвижен, а затем используется для взвешивания данных в фильтре. До сих пор я получаю довольно хорошие результаты. – spontus

+0

Здесь вы также получите много «дрифта», как вы его называете, потому что вы вычисляете все это с помощью физики Ньютона, что является неточным. Сделайте Runge-kutta или какой-нибудь другой более точный способ расчета позиции, чтобы получить лучшие результаты. – Automatico

7

Прочитано this tutorial.

краткое описание приведенного выше учебника ::

сначала получить экземпляр SensorManager и Sensor.
Внутри onCreate() ::

mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); 

после этого переопределения onSensorChanged(SensorEvent event) и использовать event.values[], чтобы получить координаты.

Смежные вопросы