Acelerómetro 3d calcular la orientación

8 minutos de lectura

Puntero de funcion como parametro
roland soos

Tengo valores de acelerómetro para los 3 ejes (generalmente cuando solo hay gravedad contiene datos entre -1.0 y 1.0):

  float Rx;
  float Ry;
  float Rz;

Hago algunos cálculos, luego obtengo 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;

Luego establecí los valores para 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);

Funciona en un hemisferio. Me gustaría usar la esfera completa y sé que tengo que usar el valor Arz para que funcione, 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;

Acelerometro 3d calcular la orientacion
mateo

La respuesta correcta es:

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

Fuente: https://www.nxp.com/docs/en/application-note/AN3461.pdf (página 10, ecuaciones 25 y 26)

La respuesta de usp es incorrecta. Parece una aproximación aceptable hasta que tanto el cabeceo como el balanceo superen los 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 usp nunca serán equivalentes.

  • Sé que esta pregunta es muy antigua, pero odio ver respuestas incorrectas. Yo mismo estaba buscando esto y encontré cientos de resultados en Google, la mayoría de ellos con la misma respuesta incorrecta.

    – mateo

    25 de abril de 2012 a las 17:14


  • Por cierto, olvidé mencionar la fuente, que contiene una explicación muy exhaustiva: freescale.com/files/sensors/doc/app_note/AN3461.pdf

    – mateo

    25 de abril de 2012 a las 17:14

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

    – uesp

    25 de abril de 2012 a las 18:22

  • Sí, lo siento, fue un error tipográfico, en realidad es atan2(X, sqrt(YY+ZZ)) sin el signo menos en X si suponemos que el acelerómetro da valores positivos cuando el eje está alineado con la gravedad y apunta HACIA ARRIBA, que es al menos lo que hace mi teléfono. En el artículo asumen la convención opuesta. No he investigado por qué no necesito otro signo menos para Roll pero lo probé y funciona

    – mateo

    25 de abril de 2012 a las 22:28

  • ¿Qué son X, Y y Z? ¿Te refieres a Rx, Ry y Rz? ¿O te refieres a algo completamente diferente?

    – Noob anubiano

    03/08/2014 a las 15:45

Si bien la respuesta de Matteo es correcta, no proporciona la solución 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 la inclinación es de +90/-90 grados y el eje X es vertical apuntando hacia arriba/abajo, la salida normalizada del acelerómetro ideal debería 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 ruidosa y obtendrías algo más cercano a:

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

Esto puede parecer pequeño, pero hará que el ángulo de balanceo sea de ~30 grados, 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 nota de la aplicación de referencia, es incluir un porcentaje muy pequeño de la lectura del eje X del acelerómetro en la fórmula para rodar:

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 menor que el caso anterior: 2-3 grados cuando se mide el balanceo en las mismas condiciones explicadas anteriormente.

  • Lo es accY lo mismo que Y? Porque mencionas en esta respuesta ambos Y y accY y no sé si te refieres a valores diferentes o no.

    – Dekike

    11 de febrero de 2020 a las 15:25

  • También hice esta pregunta en stackoverflow. No se si me podrian ayudar a resolver mis dudas… stackoverflow.com/questions/60174039/…

    – Dekike

    12 de febrero de 2020 a las 12:50

1647568629 96 Acelerometro 3d calcular la orientacion
FaithNoMan

Probé la solución recomendada (la de Matteo) y, aunque al principio parecía funcionar muy bien, noté que cuando el tono se acerca a los 90 grados (comenzando en alrededor de 70 grados pero no necesariamente consistente en diferentes teléfonos), el balanceo aumenta repentinamente. Cuando el tono está en 90, el giro que debería estar alrededor de 0 ahora está por encima de 100 y sigue aumentando hasta 180. Estoy tratando de pensar en una forma de evitar esto matemáticamente, si restrinjo el giro a +90/-90. se comporta normalmente pero no obtengo el rango que quiero (+180/-180): Math.atan2(y, Math.sqrt((xx) + (zz))) * (180/Math.PI))

  • Tengo el mismo problema, tan pronto como el dispositivo está cerca de la marca de la mitad de “boca abajo”, el rollo simplemente voltea muy rápido, intenté contrarrestar agregando sgn (Z) al otro cálculo o simplemente volteando cuando estaba cerca, pero no es así tan simple. Si cambio los ejes del sistema de coordenadas y luego cambio mis salidas de cabeceo/balanceo, puedo obtener lo mismo, pero el problema es el balanceo, no el cabeceo.

    – rajkosto

    11 mayo 2017 a las 13:59


  • Estoy teniendo el mismo problema. Las cosas se ven relativamente bien cuando miran hacia adelante, pero cuando miran hacia abajo o hacia arriba, toda la cámara gira rápidamente. ¿Encontraste alguna solución?

    – Andrés Hernández

    19 de enero de 2020 a las 4:26

¿Como actualizar WordPress wp usermeta
Ian Bloomfield

Para rollhe encontrado que puedes usar arctan(y/sqrt(X*X)+(z*z)) esto va a dar rollo -90/90 que es el estándar de aviación sin dar el problema de tono

Utilizo los siguientes cálculos para convertir las lecturas de nuestro acelerómetro en valores de balanceo y cabeceo:

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 deba intercambiar los valores X/Y/Z o traducir el Roll/Pitch dependiendo de cómo se definan sus acelerómetros. Para usarlos en la pantalla es una simple cuestión de:

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

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

    – Roland Soos

    20 de septiembre de 2010 a las 21:01

  • la ecuación para rodar es incorrecta. Ver mi respuesta (no tomo ningún crédito, lo descubrí por ahí)

    – mateo

    25 de abril de 2012 a las 17:16

  • Debo confesar que, de hecho, basé mi código y esta respuesta en la variedad de otras fuentes que existen, pero (desafortunadamente) nunca encontré la fuente que publicaste. De hecho, mis ecuaciones no coinciden con nada en su fuente, aunque están cerca de las ecuaciones 38 y 39, excepto por los parámetros invertidos atan2(). También habría adivinado que el cabeceo sería incorrecto y no el balanceo, ya que en pruebas anteriores, el balanceo parece funcionar bien de -90 a +90 grados y el cabeceo nunca se ha probado. Tendré que mirar con más detalle y averiguarlo…

    – uesp

    25 de abril de 2012 a las 18:25

  • El incorrecto es el balanceo, pero el balanceo en su ecuación funciona correctamente de -90 a 90 SI el tono permanece en 0. Se vuelve incorrecto cuando el tono no es cero, y se nota cuando el tono supera los 45 grados. Si “el cabeceo nunca ha sido probado” significa que en tus pruebas solo variaste el balanceo manteniendo el cabeceo cercano a cero, eso explicaría que no detectaste el error en la fórmula del balanceo.

    – mateo

    25 de abril de 2012 a las 22:37

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

    – Roland Soos

    20 de septiembre de 2010 a las 21:01

  • la ecuación para rodar es incorrecta. Ver mi respuesta (no tomo ningún crédito, lo descubrí por ahí)

    – mateo

    25 de abril de 2012 a las 17:16

  • Debo confesar que, de hecho, basé mi código y esta respuesta en la variedad de otras fuentes que existen, pero (desafortunadamente) nunca encontré la fuente que publicaste. De hecho, mis ecuaciones no coinciden con nada en su fuente, aunque están cerca de las ecuaciones 38 y 39, excepto por los parámetros invertidos atan2(). También habría adivinado que el cabeceo sería incorrecto y no el balanceo, ya que en pruebas anteriores, el balanceo parece funcionar bien de -90 a +90 grados y el cabeceo nunca se ha probado. Tendré que mirar con más detalle y averiguarlo…

    – uesp

    25 de abril de 2012 a las 18:25

  • El incorrecto es el balanceo, pero el balanceo en su ecuación funciona correctamente de -90 a 90 SI el tono permanece en 0. Se vuelve incorrecto cuando el tono no es cero, y se nota cuando el tono supera los 45 grados. Si “el cabeceo nunca ha sido probado” significa que en tus pruebas solo variaste el balanceo manteniendo el cabeceo cercano a cero, eso explicaría que no detectaste el error en la fórmula del balanceo.

    – mateo

    25 de abril de 2012 a las 22:37

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad