2010-09-20 11 views
22

Tengo valores del acelerómetro para el 3 eje (por lo general cuando sólo hay gravedad contiene datos entre -1,0 y 1,0):3d Acelerómetro calcular la orientación

float Rx; 
    float Ry; 
    float Rz; 

hago cálculos Soma, entonces consigo los ángulos para cada eje

float R = sqrt(pow(Rx,2)+pow(Ry,2)+pow(Rz,2)); 
    float Arx = acos(Rx/R)*180/M_PI; 
    float Ary = acos(Ry/R)*180/M_PI; 
    float Arz = acos(Rz/R)*180/M_PI; 

Entonces definir los valores de los ángulos de la caja en OpenGL

rquad = Arx; 
yquad = Ary; 

que gira mi caja:

glRotatef(yquad,1.0f,0.0f,0.0f); 
glRotatef(rquad,0.0f,1.0f,0.0f); 

que funcione en el hemisferio. Me gustaría usar la esfera completa y sé que tengo que usar el valor de Arz para hacerlo funcionar, pero no sé cómo puedo usar eso para esta rotación. ¿Usted me podría ayudar?

Actualización: La respuesta final es en mi caso:

rquad = -atan2(Rx/R, Rz/R)*180/M_PI; 
    yquad = -atan2(Ry/R, Rz/R)*180/M_PI; 

Respuesta

34

La respuesta correcta es:

Roll = atan2(Y, Z) * 180/M_PI; 
Pitch = atan2(-X, sqrt(Y*Y + Z*Z)) * 180/M_PI; 

Fuente: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf (. Página 10, la Ecuación 25 & 26)

La respuesta de uesp es incorrecta. Parece una aproximación aceptable hasta que cabeceo y balanceo van por encima de 45 grados.

Puedo estar asumiendo una convención de orientación diferente, pero incluso si intercambia ejes e invierte valores de manera consistente, los cálculos de uesp nunca serán equivalentes.

+3

Sé que esta pregunta es muy antigua, pero odio ver respuestas equivocadas. Yo mismo estaba buscando esto, y encontré cientos de visitas en Google, la mayoría de ellas con la misma respuesta incorrecta – matteo

+2

Por cierto, me olvidé de mencionar la fuente, que contiene una explicación muy exhaustiva: http: //www.freescale. com/files/sensors/doc/app_note/AN3461.pdf – matteo

+1

Suponiendo que está utilizando las ecuaciones 25 y 26 de la fuente vinculada (un gran recurso por cierto), ¿no debería el tono ser 'atan2 (-X, sqrt (Y * Y + Z + Z)) '? – uesp

-1

utilizo los siguientes cálculos para convertir las lecturas del acelerómetro en balanceo y cabeceo valores:

Roll = atan2(sqrt(Y*Y + X*X), Z) * 180/M_PI; 
Pitch = atan2(sqrt(X*X + Z*Z), Y) * 180/M_PI; 

Es posible que tenga que cambiar los valores X/Y/Z o traduce el Roll/Pitch dependiendo de cómo estén definidos tus acelerómetros. Para usarlos en la pantalla de ellas es una simple cuestión de:

glRotatef (Pitch, 0.0f, 0.0f, 1.0f); 
glRotatef (Roll, 1.0f, 0.0f, 0.0f); 
+0

Gracias por responder, pero lo probé y obtuve 0 ° -180 ° para cabeceo y balanceo. Me gustaría obtener 0 ° -360 ° –

+0

Lo intenté de nuevo con la cabeza clara :) Funciona bien –

+0

la ecuación de la rotación es incorrecta. Ver mi answare (no tomo ningún crédito, lo encontré por ahí) – matteo

10

Mientras que la respuesta de Matteo es correcto, que no proporciona la solución completa, completa: Las fórmulas son correctas:

Roll = atan2(Y, Z) * 180/M_PI; 
Pitch = atan2(-X, sqrt(Y*Y + Z*Z)) * 180/M_PI; 

Sin embargo, cuando tono es + 90/-90 grados y el eje X es vertical apuntando hacia arriba/abajo, la salida normalizada acelerómetro ideal debe ser:

accX = -1/accX = 1 
accY = 0 
accZ = 0 

lo que significa un roll angle of 0 degrees; correcto. Pero en la práctica, la salida del acelerómetro es ruidoso y se conseguiría algo más cercano a:

accX = -1/accX = 1 
accY = 0.003 
accZ = 0.004 

Esto puede parecer pequeña, pero que hará que el ángulo de balanceo sea ~ 30 dregrees lo cual no es correcto.

El instinto obvio sería filtrar los últimos dígitos, pero esto afectaría la precisión, que no siempre es aceptable.

El compromiso, que está muy bien explicado en la aplicación de la nota de referencia, es incluir un porcentaje muy pequeño del acelerómetro X lectura eje en la fórmula para roll:

Roll = atan2(Y, sign* sqrt(Z*Z+ miu*X*X)); 
sign = 1 if accZ>0, -1 otherwise 
miu = 0.001 

el error introducido de esta manera es dramáticamente más pequeño que el caso anterior: 2-3 grados cuando se mide el balanceo en las mismas condiciones explicadas anteriormente.

2

He intentado con la solución recomendada (matteo), y aunque al principio parecía funcionar bien, noté que cuando el tono se acerca a 90 grados (comenzando a 70 grados pero no necesariamente a través de diferentes teléfonos), el rollo de repente surge. Cuando el tono está en 90, la tirada que debería estar alrededor de 0 ahora es de más de 100 y sigue aumentando a 180. Estoy intentando pensar en una forma de prevenir matemáticamente esto, si restrinjo el rollo a + 90/-90 se comporta normalmente pero no obtengo el rango que quiero (+ 180/-180): Math.atan2 (y, Math.sqrt ((x x) + (z z))) * (180/Math. PI))

+0

Me sale el mismo problema, tan pronto como el dispositivo está cerca de la mitad de la marca "al revés", el rodillo simplemente voltea muy rápido, intenté ejecutar la función agregando sgn (Z) al otro cálculo o simplemente volteando cuando estaba cerca, pero su no tan simple Si cambio los ejes del sistema de coordenadas y luego cambio mis salidas de cabeceo/balanceo, puedo obtener lo mismo, pero con el balanceo causando el problema, no el tono. – rajkosto

Cuestiones relacionadas