Calculando la distancia usando aceleración lineal android

Posible duplicado:
Precisión del acelerómetro Android (navegación por inercia)

Estoy usando el siguiente código para calcular la distancia. tnew y tnew son arraylists contienen timestamps y aceleraciones, respectivamente.

  double distance=0; double init_vel=0; long time_prev=tnew.next(); while(anew.hasNext()) { float temp_acc=anew.next(); long temp_time=tnew.next(); interval=(temp_time-time_prev)/1000f; //milliseconds to seconds double fin_vel=init_vel+(temp_acc*interval); distance+=(init_vel*interval)+0.5f*temp_acc*interval*interval; init_vel=fin_vel; time_prev=temp_time; } 

¿Hay algún error lógico en el código? Porque estoy obteniendo valores mucho más pequeños que la longitud real.

Salida de LogCat :

 --------- beginning of /dev/log/system --------- beginning of /dev/log/main V/PhonetapeActivity( 8842): Sensor Listener Registered V/PhonetapeActivity( 8842): Sensor Unregistered V/PhonetapeActivity( 8842): No. of Iterations : 49 V/PhonetapeActivity( 8842): Value of acceleration : 3.5762787E-7 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665585965 V/PhonetapeActivity( 8842): Value of acceleration : -0.15275347 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586017 V/PhonetapeActivity( 8842): Value of acceleration : 0.15585232 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586077 V/PhonetapeActivity( 8842): Value of acceleration : 1.075269 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586138 V/PhonetapeActivity( 8842): Value of acceleration : 3.6529458 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586199 V/PhonetapeActivity( 8842): Value of acceleration : 9.645137 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586257 V/PhonetapeActivity( 8842): Value of acceleration : 17.022213 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586316 V/PhonetapeActivity( 8842): Value of acceleration : 9.721476 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586376 V/PhonetapeActivity( 8842): Value of acceleration : -18.729362 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586437 V/PhonetapeActivity( 8842): Value of acceleration : -22.868385 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586497 V/PhonetapeActivity( 8842): Value of acceleration : -16.777517 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586557 V/PhonetapeActivity( 8842): Value of acceleration : -7.0492268 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586617 V/PhonetapeActivity( 8842): Value of acceleration : -3.860828 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586677 V/PhonetapeActivity( 8842): Value of acceleration : 1.7244682 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586737 V/PhonetapeActivity( 8842): Value of acceleration : 5.0734243 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586797 V/PhonetapeActivity( 8842): Value of acceleration : 6.4193974 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586857 V/PhonetapeActivity( 8842): Value of acceleration : 2.739545 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586917 V/PhonetapeActivity( 8842): Value of acceleration : 5.559997 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586977 V/PhonetapeActivity( 8842): Value of acceleration : 4.2290807 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587037 V/PhonetapeActivity( 8842): Value of acceleration : 5.0012918 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587097 V/PhonetapeActivity( 8842): Value of acceleration : 5.9317436 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587157 V/PhonetapeActivity( 8842): Value of acceleration : 5.20226 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587217 V/PhonetapeActivity( 8842): Value of acceleration : 7.1381693 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587276 V/PhonetapeActivity( 8842): Value of acceleration : 7.6460614 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587337 V/PhonetapeActivity( 8842): Value of acceleration : 5.566694 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587396 V/PhonetapeActivity( 8842): Value of acceleration : 3.355657 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587457 V/PhonetapeActivity( 8842): Value of acceleration : 1.8876343 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587517 V/PhonetapeActivity( 8842): Value of acceleration : -0.8815446 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587577 V/PhonetapeActivity( 8842): Value of acceleration : -0.9595623 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587646 V/PhonetapeActivity( 8842): Value of acceleration : -4.233544 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587697 V/PhonetapeActivity( 8842): Value of acceleration : -1.9580669 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587765 V/PhonetapeActivity( 8842): Value of acceleration : -1.4569702 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587822 V/PhonetapeActivity( 8842): Value of acceleration : -0.6058636 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587876 V/PhonetapeActivity( 8842): Value of acceleration : -0.21207428 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587937 V/PhonetapeActivity( 8842): Value of acceleration : 0.5068469 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587997 V/PhonetapeActivity( 8842): Value of acceleration : 5.614555 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588057 V/PhonetapeActivity( 8842): Value of acceleration : -4.5297813 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588122 V/PhonetapeActivity( 8842): Value of acceleration : -0.29250193 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588178 V/PhonetapeActivity( 8842): Value of acceleration : -2.4922757 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588237 V/PhonetapeActivity( 8842): Value of acceleration : -1.7652755 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588297 V/PhonetapeActivity( 8842): Value of acceleration : -2.3279366 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588357 V/PhonetapeActivity( 8842): Value of acceleration : -1.8127642 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588419 V/PhonetapeActivity( 8842): Value of acceleration : -1.956768 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588477 V/PhonetapeActivity( 8842): Value of acceleration : -0.8337221 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588537 V/PhonetapeActivity( 8842): Value of acceleration : -0.24841261 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588601 V/PhonetapeActivity( 8842): Value of acceleration : 0.23997736 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588657 V/PhonetapeActivity( 8842): Value of acceleration : 0.14441395 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588723 V/PhonetapeActivity( 8842): Value of acceleration : 0.23150349 V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588777 V/PhonetapeActivity( 8842): 1st while loop ended V/PhonetapeActivity( 8842): 2nd while loop ended V/PhonetapeActivity( 8842): Avg value : 0.4006781578063965 V/PhonetapeActivity( 8842): Max Value : 17.022213 V/PhonetapeActivity( 8842): Min Value : -22.868385 V/PhonetapeActivity( 8842): Standard Deviation : -0.0031174493 V/PhonetapeActivity( 8842): 3rd while loop started V/PhonetapeActivity( 8842): startpos=3 endpos=8 V/PhonetapeActivity( 8842): acceleration=0.1558523178100586 interval=0.061000000685453415 V/PhonetapeActivity( 8842): distance=5.799264876044276E-4 V/PhonetapeActivity( 8842): next init velocity=0.009506991493243078 V/PhonetapeActivity( 8842): acceleration=1.0752689838409424 interval=0.061000000685453415 V/PhonetapeActivity( 8842): distance=0.005160928954000712 V/PhonetapeActivity( 8842): next init velocity=0.07509840024458736 V/PhonetapeActivity( 8842): acceleration=3.6529457569122314 interval=0.057999998331069946 V/PhonetapeActivity( 8842): distance=0.021805144861910285 V/PhonetapeActivity( 8842): next init velocity=0.2869692480489858 V/PhonetapeActivity( 8842): acceleration=9.645136833190918 interval=0.05900000035762787 V/PhonetapeActivity( 8842): distance=0.07231105232279186 V/PhonetapeActivity( 8842): next init velocity=0.8560323246566197 V/PhonetapeActivity( 8842): acceleration=17.022212982177734 interval=0.05999999865889549 V/PhonetapeActivity( 8842): distance=0.18495295465057213 V/PhonetapeActivity( 8842): next init velocity=1.8773650807587172 V/PhonetapeActivity( 8842): 3rd while loop ended V/PhonetapeActivity( 8842): final distance=0.18495295465057213 V/PhonetapeActivity( 8842): values of acceleration, timestamp, distance, start_time and calibrating reset 

Si observa el logcat, primero itera a través de 49 valores de aceleración y sus respectivos sellos de tiempo en milisegundos. Entonces hay un promedio, la suma, el máximo, el min etc.
Entonces si ves que hay un startpos=3 y endpos=8 . Este es el rango de números de iteración, estoy usando para calcular la distancia. Yo estoy usando los valores de aceleración y timestamp sólo de la iteración 3 a 8.
Esto se debe a que, detecto el inicio del cálculo de la distancia de un aumento en la aceleración a un cambio repentino en la dirección opuesta. Puede ver que los valores de 3-8 encajan en la lógica. A partir de 3 hay un aumento considerable en la aceleración y después de 8 hay una disminución repentina.

Los acelerómetros son muy precisos pero malos en el cálculo de los tiempos muertos. Los giroscopios son buenos en eso, pero "derivan" con el tiempo. " Sensor-fusión " es el proceso de usar los datos de accel / gyro en tándem para corregir la deficiencia de uno usando el otro. AFAIR, "sensor-fusion" NO está habilitado en Galaxy Ace. LINEAR_ACCELERATION no es más que ACCELEROMETER – componente de gravedad. En dispositivos sin giroscopio, la fusión no es posible por definición, requiere accel + giro.

Los datos del acelerómetro contienen el componente de gravedad de 9.8. Esto es filtrado simplemente determinando la diferencia entre 2 muestras consecutivas de datos del acelerómetro. Esto nos da los datos LINEAR_ACCELERATION .

Compruebe esto para el código interno real:
Frameworks / base / servicios / sensorservice / LinearAccelerationSensor.cpp
La función LinearAccelerationSensor::process() es de interés en el archivo anterior.

También las operaciones rudimentarias como el filtrado / promediar que el vínculo anterior y el video hablan, deben realizarse en los datos de accel obtenidos en su aplicación. Los valores procesados ​​obtenidos de esta manera serán mejores (aunque no tan buenos como los que se habrían obtenido si la fusión del sensor estuviera presente en su dispositivo) que los valores sin procesar. A continuación, se pueden utilizar para calcular la velocidad y la posición con mayor precisión.

Dicho esto, 16 muestras por segundo (@ poll-rate = 60ms) es relativamente inexacta en sí misma. Es posible que desee intentar registrar el sensorEventListner utilizando SENSOR_DELAY_FASTEST para ver el número máximo de muestras que puede obtener en su dispositivo.

También tenga en cuenta que los acelerómetros de los teléfonos se sujetan a una determinada sensibilidad MAX (generalmente – / + 2/4/8 G). Si bien la marcha normal puede funcionar bajo estos rangos, un impulso repentino en la aceleración (por ejemplo, en una bicicleta) definitivamente se sujetará a la MAX y perderá la sincronización en la cuenta muerta. Esto se puede comprobar anotando el número de muestras que están muy cerca del – / + MAX. Muchas muestras en – / + MAX implican que habría perdido la sincronización con la posición real.

La primera cosa que comprobaría es su intervalo de tiempo. No estoy seguro de que se está convirtiendo correctamente. La marca de tiempo se muestra como:

Public timestamp largo El tiempo en nanosecond en el que ocurrió el evento

Y así en la documentación vemos que la conversión se hace dividiendo por mil millones en vez de mil.

 float dT = (event.timestamp - timestamp) / 1000000000.0f; timestamp = event.timestamp; 

Dicho esto, creo que el cambio sólo reducirá los valores, pero para calcular la distancia real del mundo que necesita para ver sus unidades.

A continuación, al leer acerca de estas cosas la gente siempre va sobre cómo usted necesita saber su posición inicial para cada lectura para tener algún sentido con respecto a las mediciones lineales del mundo real. No veo el seguimiento de su aceleración anterior que hará cada integración de la siguiente medida basada en la aceleración instantánea, o el cambio en la aceleración, en lugar de aceleración completa.

Intente algo como esto:

 final int X = 0; double distance[]; double init_vel[]; double total_Accel[]; void dblIntegrate(SensorEvent event){ double data[] = new double[3]; for(int i = 0; i < event.lenght; i++){ data[i] = (double)event[i]; total_Accel[i] += data[i]; vel[i] = init_vel[i] + (total_Accel[i] * dt); init_vel[i] = vel[i]; ....rinse and repeate to get distance (not using the accel data of course) } } 

Me doy cuenta de que usted entiende esto, pero para cualquier otra persona está leyendo esto => recuerde que no puede tener el contando vars total_Accel o init_vel re-instanciado cada vez que llame a dblIntegrate ().

Si lo está haciendo bien, debe ver total_Accel ir de cero a algún valor máximo y volver a cero cada vez que mueva el dispositivo. Esto significa que está agregando partes iguales de aceleración positiva y negativa cada vez que el dispositivo se mueve en cualquier dirección.

Creo que esta es la propiedad de la aceleración que es la más difícil de entender correctamente, porque para que el dispositivo pase del estado de reposo al estado de reposo su total_acceleration pasará de cero a un valor máximo pos / neg de nuevo a cero al valor máximo oppposite y luego De nuevo a cero.

Por ejemplo, si muevo un teléfono apoyado en la espalda sobre una mesa con la parte inferior mirando mi pecho a la derecha por un metro, obtendrá algo como esto:

Total_Accel = 0.0 (0 Meters)

Total_Accel = 0,5

Total_Accel = 1.0

Total_Accel = 1,5 (aproximadamente 0,25 metros)

Total_Accel = 1.0

Total_Accel = 0,5

Total_Accel = 0.0 (si accel está perfectamente distribuido, .5 Metros)

Total_Accel = -0,5

Total_Accel = -1.0

Total_Accel = -1,5 (aproximadamente 0,75 metros)

Total_Accel = -1.0

Total_Accel = -0,5

Total_Accel = 0.0 (1 metro)

En el ejemplo se puede empezar a ver por qué simplemente la doble integración del cambio en la aceleración no va a dar el cambio real en la velocidad / desplazamiento.

Espero que de todos modos porque escribir esto tomó mucho más tiempo de lo que había pensado que sería! 🙂

Esta es una respuesta a su pregunta:

Por qué necesito seguir mi aceleración anterior. OnSensorChanged (evento MotionEvent) {} se llama cuando hay un cambio en la aceleración. Proporciona la nueva aceleración y no el cambio en la aceleración.

La respuesta corta es, integrando la lectura w / o incluyendo la condición inicial (su aceleración total anterior) usted terminará para arriba con un valor que no incluye toda la información. Además, cuanto más tiempo vas, más tu valor se obtiene del valor real porque estás perdiendo más y más información.

No creo que quiera una explicación de la aceleración, la velocidad y el desplazamiento (y este no es el lugar para eso), así que tal vez pueda mostrarlo ampliando el ejemplo que he incluido anteriormente.

Un teléfono que descansa en su parte posterior en una tabla con la parte inferior que hace frente a mi pecho se mueve a la derecha para una distancia arbitraria y para. Si miras tus datos obtendrás algo como esto. Por supuesto, los números reales varían ampliamente, pero sus signos serán los mismos y las proporciones serán la misma de la misma, pero comenzará más pequeño que el pico como se esperaría (a menos que disparó de una pistola en una pared o lo que sea) .:

Tiempo ……….. Accel Leer ……….. Total Accel …….. Velocidad Total

00ms ………….. 0.0 …………………. 0.0 ……….. 0,000 ..

10 ms ………….. 0,5 …………………. 0,5 ……….. ………… 0,005 m / s ..

20 ms ………….. 0,5 …………………. 1,0 ……….. 0,015 m / s ..

30 ms …………. 0,5 …………………. 1,5 ………… ……….. 0.030 m / s ..

40ms …………. -0.5 …………………. 1.0 ……….. ………… 0.040 m / s ..

50ms …………. -0.5 …………………. 0.5 ……….. ………… 0.045 m / s ..

60ms …………. -0.5 …………………. 0.0 ……….. ………… 0.045 m / s ..

70ms …………. -0.5 …………………- 0.5 ……….. ………… 0.040 m / s ..

80ms …………. -0.5 …………………- 1.0 ……….. ………… 0.030 m / s ..

90ms …………. -0.5 …………………- 1.5 ……….. 0,015 m / s ..

100 ms …………. 0,5 …………………- 1,0 ………… ……….. 0.005 m / s ..

110ms …………. 0,5 …………………- 0,5 ………… ………… 0,000 m / s ..

120 ms 0,5 …………………. 0,0 ………… ………… 0,000 m / s ..

Puede ver que si no realiza un seguimiento de la aceleración total, su velocidad total sería la columna marcada como Total Accel anterior. Eso significaría que su teléfono estaría moviéndose en la dirección positiva del eje x todo el tiempo pero su velocidad sería negativa (moviéndose hacia atrás) la última mitad del movimiento.

Espero que esto demuestre mi caso incluso si no explica la mecánica detrás de aceleración o acelerómetros.

Si quería consultar cómo funciona el acelerómetro, son sensores de tipo MEMS y creo que utilizan una viga en voladizo suspendida con un extremo ponderado para medir la fuerza de aceleración.

  • Android sensorPortrait no funciona para el modo de retrato inverso
  • ¿Cuál es la alternativa al sensor de orientación de Android?
  • Rajawali cámara giratoria con Sensor.TYPE_ROTATION_VECTOR comportamiento extraño
  • Constante de fecha y hora de Android SensorEvent
  • Cómo detectar Orientación al revés en android?
  • Mi algoritmo para calcular la posición del teléfono inteligente - GPS y sensores
  • Cómo obtener RotationMatrix de guiñada, tono y rollo
  • Obtenga el ángulo de rotación de Android en el eje x
  • Alternativa para TYPE_GAME_ROTATION_VECTOR
  • La brújula android parece poco fiable
  • Adquisición de datos de Sensor en plataformas Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.