2012-06-17 25 views
16

Voy a desarrollar la aplicación Android que necesita leer las coordenadas x, y, z del teléfono en el espacio 3D.Leer las coordenadas x y z del teléfono Android usando el acelerómetro

me gustaría escribir un código simple y prueba en el dispositivo ..

estoy usando pan de jengibre en el dispositivo y emulador.

+0

Posible duplicado de [Usando el acelerómetro, el giroscopio y la brújula para calcular el movimiento del dispositivo en el mundo 3D] (http://stackoverflow.com/questions/8264518/using-accelerometer-gyroscope-and-compass-to-calculate-disvices- superconjunto movimiento-en-3d) que también solicita el estado de rotación. –

Respuesta

16

Para obtener la posición de la aceleración, necesita integrarla dos veces.

La aceleración de integración le da velocidad e integrando la velocidad le da la posición.

Tenga en cuenta que la integración del ruido crea deriva y la deriva de integración crea MUCHA deriva, los sensores de Android tienden a generar bastante ruido.

En mi Galaxy S3 he podido conseguir la deriva en posición hasta 0,02 m en 5 segundos utilizando el sensor de compilación lineal Acelerómetro de Google.

No estoy seguro si puede usar el sensor de acelerómetro lineal en gingerbread. Si no puedes, tendrás que eliminar la gravedad antes de integrarlo.

Si no lo ha hecho, lea todo lo que aquí http://developer.android.com/guide/topics/sensors/sensors_motion.html

una gran charla sobre los sensores de movimiento en el androide Código

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

Ahora usted tiene la posición en el espacio 3D, tenga en cuenta que supone que el teléfono está estacionario cuando está muestreo de rts

Si no quita la gravedad, pronto estará muy lejos.

Esto no filtra los datos en absoluto y generará mucha deriva.

+1

No es solo el ruido del sensor el que genera deriva. La principal limitación de este enfoque es que es fundamentalmente imposible detectar una velocidad constante con un acelerómetro.Por lo tanto, la integración podría dar resultados razonables cuando simplemente agita un poco el teléfono, pero para otros tipos de movimiento, por ejemplo, al conducir o andar en bicicleta, la deriva será enorme. – Junuxx

+0

Tienes toda la razón. Estoy usando el acelerómetro para rastrear un automóvil y para eso he implementado un filtro kalman para reducir aún más la deriva. También calculo la precisión del acelerómetro midiendo el ruido cuando está parado, esto se usa para ponderar los datos en el filtro. Estoy obteniendo resultados bastante buenos hasta ahora. – spontus

+0

Aquí también obtendrá una gran cantidad de "deriva" como la está llamando porque calcula todo esto con la física newtoniana, que es inexacta. Haz Runge-kutta u otra forma más precisa de calcular la posición para obtener mejores resultados. – Automatico

7

Lee this tutorial.

breve resumen del tutorial dada arriba ::

En primer lugar obtener una instancia de SensorManager y Sensor.
Dentro onCreate() ::

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

después de esto, anular onSensorChanged(SensorEvent event)event.values[] y utilizar para obtener las coordenadas.

@Override 
public void onSensorChanged(SensorEvent event) { 
    float x = event.values[0]; 
    float y = event.values[1]; 
    float z = event.values[2]; 
} 
Cuestiones relacionadas