2012-07-16 13 views
16

Tengo un administrador de sensores que devuelve un rotationMatrix basado en los dispositivos Magnetómetro y Acelerómetro. He estado tratando de calcular también el cabeceo y balanceo del dispositivo del usuario, pero estoy descubriendo que el cabeceo y el balanceo interfieren entre sí y dan resultados inexactos. ¿Hay alguna forma de extraer YAW PITCH y ROLL de un dispositivo del rotationMatrix?extraer guiñada, cabeceo y balanceo de un rotationMatrix

EDITAR tratar de interpretar la respuesta de la licuadora a continuación, que estoy agradecido por, pero no ha llegado todavía, yo estoy tratando de conseguir el ángulo de una matriz rotaion así:

 float R[] = phoneOri.getMatrix(); 
     double rmYaw = Math.atan2(R[4], R[0]); 
     double rmPitch = Math.acos(-R[8]); 
     double rmRoll = Math.atan2(R[9], R[10]); 

i don' Sé si estoy haciendo referencia a las partes incorrectas de la matriz o no, pero no obtengo los resultados que pensaría.

estaba esperando obtener valores en grados, pero estoy obteniendo números enteros raros.

mi matriz proviene de mi sensorManager que se parece a esto:

public void onSensorChanged(SensorEvent evt) { 
      int type=evt.sensor.getType(); 
      if(type == Sensor.TYPE_ORIENTATION){ 
       yaw = evt.values[0]; 
       pitch = evt.values[1]; 
       roll = evt.values[2]; 
      } 
      if (type == Sensor.TYPE_MAGNETIC_FIELD) { 
       orientation[0]=(orientation[0]*1+evt.values[0])*0.5f; 
       orientation[1]=(orientation[1]*1+evt.values[1])*0.5f; 
       orientation[2]=(orientation[2]*1+evt.values[2])*0.5f; 
      } else if (type == Sensor.TYPE_ACCELEROMETER) { 
       acceleration[0]=(acceleration[0]*2+evt.values[0])*0.33334f; 
       acceleration[1]=(acceleration[1]*2+evt.values[1])*0.33334f; 
       acceleration[2]=(acceleration[2]*2+evt.values[2])*0.33334f; 
      } 
      if ((type==Sensor.TYPE_MAGNETIC_FIELD) || (type==Sensor.TYPE_ACCELEROMETER)) { 
       float newMat[]=new float[16]; 

       SensorManager.getRotationMatrix(newMat, null, acceleration, orientation); 
       if(displayOri==0||displayOri==2){ 
        SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_X*-1, SensorManager.AXIS_MINUS_Y*-1,newMat); 
       }else{ 
        SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X,newMat); 
       } 

       matrix=newMat; 

matriz de la muestra cuando el dispositivo está poniendo boca arriba sobre la mesa

0.9916188, -0.12448014, -0.03459576, 0.0 
0.12525482, 0.9918981, 0.021199778, 0.0 
0.031676512,-0.025355382, 0.9991765, 0.0 
0.0,   0.0,   0.0,   1 

RESPUESTA

double rmPitch = Math.toDegrees(Math.acos(R[10])); 

Respuesta

19

Guiñada, cabeceo y balanceo corresponden a ángulos de Euler. Puede convert a transformation matrix to Euler angles con bastante facilidad:

enter image description here

+5

Gracias, pero para ser honesto eso es, griego para mí. ¿Serías tan kias para traducir eso para mí ... como a java? – erik

+14

Bueno, esos * son * letras griegas;) 'A_31' significa la entrada en la 3ra fila y la 1ra columna. Java tiene estas funciones incorporadas para que pueda traducirlo. – Blender

+0

por favor vea mi edición de arriba ... mi matriz de rotación tiene 16 valores de tamaño. no sé si estoy haciendo esto bien ... – erik

12

creo que la respuesta de Blender no es correcta, ya que dio una transformación de la matriz de rotación a ángulos de Euler (zxz extrínseca), and Roll Pitch guiñada son un tipo diferente de ángulos de Euler (zyx extrínseco).

La fórmula de transformación real sería más bien:

yaw=atan2(R(2,1),R(1,1)); 
pitch=atan2(-R(3,1),sqrt(R(3,2)^2+R(3,3)^2))); 
roll=atan2(R(3,2),R(3,3)); 

Source

+1

Esta respuesta debería tener un millón +1. Es la fórmula perfecta para transformar correctamente la matriz de rotación obtenida de SensorManager.TYPE_ROTATION_VECTOR. –

+1

¿Qué es "R" aquí? Si se trata de una matriz de rotación tomada de SensorManager.getRotationMatrix(), entonces, en este caso, R es una matriz de dimen simple, pero en la respuesta anterior parece una matriz 2D. –

+1

Lo siento, no sé nada sobre la programación de Android, mi código era solo una implementación de las ecuaciones de la fuente. – Aquadarius

2

Administrador de sensor proporciona un SensorManager.getOrientation para obtener todos los tres ángulos.

+0

Me parece que el "guiñada" proporcionado por 'getOrientation()' no es del todo correcto; el javadoc lo describe como el "acimut". Sin embargo, todo está más allá de mi cerebro mortal. –

Cuestiones relacionadas