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:
- Aplicación de realidad aumentada de Android convertir Lista de ubicación desde el punto de pantalla
- QualComm Vuforia Realidad Aumentada
- Realidad aumentada en android
- Android getOrientation Azimut se contamina cuando el teléfono está inclinado
- Realidad aumentada (AR) en HTML5 y WebGL
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)); }
- ¿Es posible utilizar la realidad aumentada en interiores sin GPS?
- Utilizar la biblioteca de Zxing en PreviewFrame para aumentar la realidad
- ¿Cómo hacer clics en parte del modelo en Vuforia (sin Unity)?
- Android: Problemas al calcular la orientación del dispositivo
- Metaio sdk (openGL) frena la representación de fuente y de imagen
- Marco de realidad aumentada basado en localización (Android, iOS) con POIs 3D?
- Cómo iniciar la aplicación Vuforia AR sample android?
- Integre la vista Unity3d en la actividad de Android
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.
- Android RecyclerView – animar la elevación del elemento al tocar
- Diferencia de rendimiento entre un método query () y rawQuery () en Android