Orientación de Android AR

Estoy haciendo el programa para mostrar objetos del mapa en la cámara y esto funciona casi bien excepto pocos grados a la izquierda ya la derecha de la orientación vertical (como en 80-110 y 260-280 grados). En otros + -320 grados funciona bien. He intentado usar TYPE_ROTATION_VECTOR y acelerómetro con magnetómetro y tienen el mismo resultado. ¿Alguien sabe alguna solución?

Con TYPE_ROTATION_VECTOR:

if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { float[] roationV = new float[16]; SensorManager.getRotationMatrixFromVector(roationV, event.values); float[] orientationValuesV = new float[3]; SensorManager.getOrientation(roationV, orientationValuesV); tvHeading.setText(String.format( "Coordinates: lat = %1$.2f, lon = %2$.2f, time = %3$.2f", orientationValuesV[0], orientationValuesV[1], orientationValuesV[2])); float[] rotationMatrix=new float[16]; mSensorManager.getRotationMatrixFromVector(rotationMatrix, event.values); float[] orientationValues = new float[3]; SensorManager.getOrientation(rotationMatrix, orientationValues); double azimuth = Math.toDegrees(orientationValues[0]); double pitch = Math.toDegrees(orientationValues[1]); double roll = Math.toDegrees(orientationValues[2]); tvOrientation.setText(String.format( "Coordinates: lat = %1$.2f, lon = %2$.2f, time = %3$.2f", azimuth,pitch,roll)); } 

Con acelerómetro + magnetómetro

 if (event.sensor == mAccelerometer) { System.arraycopy(event.values, 0, mLastAccelerometer, 0, event.values.length); mLastAccelerometer = meanFilterAccelSmoothing .addSamples(mLastAccelerometer); mLastAccelerometer = medianFilterAccelSmoothing .addSamples(mLastAccelerometer); for (int i = 0; i < mLastAccelerometer.length; i++) { mLastAccelerometer[i] = (float) Math.floor(mLastAccelerometer[i] * 1000) / 1000; } mLastAccelerometerSet = true; } if (event.sensor == mMagnetometer) { System.arraycopy(event.values, 0, mLastMagnetometer, 0, event.values.length); mLastMagnetometer = meanFilterMagneticSmoothing.addSamples(mLastMagnetometer); mLastMagnetometer = medianFilterMagneticSmoothing.addSamples(mLastMagnetometer); for (int i = 0; i < mLastMagnetometer.length; i++) { mLastMagnetometer[i] = (float) Math.floor(mLastMagnetometer[i] * 1000) / 1000; } mLastMagnetometerSet = true; } if (mLastAccelerometerSet && mLastMagnetometerSet) { SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer); SensorManager.getOrientation(mR, mOrientation); if (angeles.size() > 0) { for (int i = 0; i < mapObjects.size(); i++) { compassFunc(i, mOrientation[0], mOrientation[1], mOrientation[2]); } } private void compassFunc(int number, float... values) { double angularXSpeed = Math.floor(values[0] * 180 / Math.PI * 100) / 100; double angularYSpeed = Math.floor(values[1] * 180 / Math.PI * 100) / 100; double angularZSpeed = Math.floor(values[2] * 180 / Math.PI * 100) / 100; tvOrientation.setText(String.format( "Screen: lt= %1$.2f : %2$.2f,rt= %3$.2f : %4$.2f,lb= %5$.2f : %6$.2f,rb= %7$.2f : %8$.2f", xLeftTop, yLeftTop, xRightTop,yRightTop,xLeftBottom,yLeftBottom,xRightBottom,yRightBottom)); } 

Esto suena como un caso típico de Gimbal Lock . Su descripción de cómo la rotación alrededor de un eje actúa para arriba cuando otro alcanza + -90 grados sugiere que éste es realmente el caso.

Este es un problema fundamental con los ángulos de Euler (Yaw / Azimuth, Pitch, Roll), por lo que la mayoría de estos cálculos se hacen usando matrices de rotación o cuaterniones, y los ángulos de Euler más a menudo sólo se utilizan cuando una orientación particular se muestra a un Humanos (los humanos son generalmente malos en la interpretación de matrices de rotación y cuaterniones).

El sensor ROTATION_VECTOR genera sus datos en un formato quaternion ( fuente ), aunque con valores reordenados, y el método getRotationMatrixFromVector() convierte esto en una matriz de rotación. Yo sugeriría usar una de estas descripciones para sus cálculos internos.

Las respuestas a esta pregunta similar proporcionan algunas sugerencias concretas sobre cómo resolver el problema.

  • ¿Cómo usar un vector de rotación y traducción OpenCV con OpenGL ES en Android?
  • Renderer sobre la cámara Ver ambos en GLSurfaceView mismo?
  • Ayuda para rectificar escalas de línea en Android OpenGL 2.0 con RQAR
  • ¿Cómo obtener la dirección de la cámara del teléfono habilitado para GPS?
  • Obtener coordenadas de pantalla por ubicación específica y longitud (android)
  • Buscar un conjunto de latitudes y longitudes utilizando la latitud, longitud y dirección actuales del usuario para ver un objeto
  • ¿Cómo integrar el metaio + Open CV para la aplicación android?
  • La dirección de la brújula es diferente dependiendo de la orientación del teléfono
  • ¿Existe alguna fuente abierta de Realidad Aumentada sdk para android?
  • Buscando un AR con biblioteca de reconocimiento de imágenes
  • Rotación Opengl de Android con datos de sensores
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.