Extraer la guiñada, el tono y el rollo desde una matriz de rotación

Tengo un gestor de sensores que devuelve un rotationMatrix basado en los dispositivos Magnetómetro y Acelerómetro. He estado tratando de calcular también el tono de guiñada y rollo del dispositivo del usuario, pero estoy encontrando que el tono y el rollo interfieren entre sí y dan resultados inexactos. ¿Hay una manera de extraer YAW PITCH y ROLL de un dispositivo de la rotationMatrix ?

EDIT El intentar interpretar la respuesta de la licuadora abajo, que estoy agradecido para pero no absolutamente allí todavía, estoy intentando conseguir el ángulo de una matriz del rotaion como esto:

  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]); 

No sé si estoy haciendo referencia a las partes equivocadas de la matriz o no, pero no estoy recibiendo los resultados que me gustaría pensar.

Yo estaba esperando para obtener valores en grados, pero estoy recibiendo enteros extraños.

Mi matriz viene 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á colocando boca arriba en 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 

RESPONDER

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

Yaw, pitch y roll corresponden a los ángulos de Euler. Puede convertir fácilmente una matriz de transformación en ángulos de Euler :

Introduzca aquí la descripción de la imagen

Creo que la respuesta de Blender no es correcta, ya que él dio una transformación de la matriz de rotación a los ángulos de Euler (zxz extrínseco), y el Yel del tono del rollo 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)); 

Fuente

Sensor Manager proporciona un SensorManager.getOrientation para obtener todos los tres ángulos.

  • ¿Cuál es la diferencia entre sensores de "gravedad" y "aceleración" en Android?
  • ¿Cómo / Debo implementar un filtro de Kalman para obtener datos precisos de Acelerómetro?
  • Android: ¿Cómo usar SensorManager.getAltitude (float p0, float p)?
  • Dispositivos Android con sensor de presión
  • La orientación del dispositivo Android es Paisaje, pero los sensores se comportan como si la orientación fuera Retrato
  • ¿Es mi "hal_process_report_ind: mala calidad del artículo: 11" algo de qué preocuparse?
  • Android: Valor de amplitud para el valor Decibel?
  • Implementación de JKalman en Android
  • Dibujo en el aire con el teléfono Android
  • TYPE_ROTATION_VECTOR, TYPE_ORIENTATION dan resultados diferentes que también con desviación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.