6

La mia app per realtà aumentata ha bisogno della direzione della bussola della vista della telecamera, e ci sono molti esempi di come ottenere la direzione dal sensormanager.La direzione della bussola è diversa a seconda dell'orientamento del telefono

Tuttavia, sto trovando il valore risultante diverso a seconda dell'orientamento del telefono: il paesaggio ruotato a destra è di circa 10 gradi diversi rispetto al paesaggio ruotato a sinistra (la differenza tra ROTATION_0 e ROTATION_180 è inferiore, ma comunque diversa). Questa differenza è sufficiente a rovinare qualsiasi effetto AR.

E 'qualcosa che ha a che fare con la calibrazione? (Non sono convinto di fare la figura dell'8 in modo corretto - ho provato vari modi che ho trovato su youtube).

Qualche idea del perché c'è differenza? Ho incasinato la roba sulla matrice di rotazione? Ho la possibilità di limitare l'applicazione per un unico orientamento, ma mi preoccupa ancora che la lettura della bussola ancora non è molto preciso (anche se dopo il filtraggio è abbastanza stabile)

public void onSensorChanged(SensorEvent event) { 
     if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) { 
      return; 
     } 

     if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) mGravity = event.values; 
     if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) mGeomagnetic = event.values; 

     if (mGravity != null && mGeomagnetic != null) { 

      float[] rotationMatrixA = mRotationMatrixA; 
      if (SensorManager.getRotationMatrix(rotationMatrixA, null, mGravity, mGeomagnetic)) { 

       float[] rotationMatrixB = mRotationMatrixB; 

       Display display = getWindowManager().getDefaultDisplay(); 
       int deviceRot = display.getRotation(); 

       switch (deviceRot) 
       { 
       // portrait - normal 
       case Surface.ROTATION_0: SensorManager.remapCoordinateSystem(rotationMatrixA, 
         SensorManager.AXIS_X, SensorManager.AXIS_Z, 
         rotationMatrixB); 
       break; 
       // rotated left (landscape - keys to bottom) 
       case Surface.ROTATION_90: SensorManager.remapCoordinateSystem(rotationMatrixA, 
         SensorManager.AXIS_Z, SensorManager.AXIS_MINUS_X, 
         rotationMatrixB); 
       break; 
       // upside down 
       case Surface.ROTATION_180: SensorManager.remapCoordinateSystem(rotationMatrixA, 
         SensorManager.AXIS_X, SensorManager.AXIS_Z, 
         rotationMatrixB); 
       break; 
       // rotated right 
       case Surface.ROTATION_270: SensorManager.remapCoordinateSystem(rotationMatrixA, 
         SensorManager.AXIS_MINUS_Z, SensorManager.AXIS_X, 
         rotationMatrixB); 
       break; 

       default: break; 
       } 

       float[] dv = new float[3]; 
       SensorManager.getOrientation(rotationMatrixB, dv); 
       // add to smoothing filter 
       fd.AddLatest((double)dv[0]); 
      } 
      mDraw.invalidate();  
     } 
    } 

risposta

10

Prova questa

Non è necessaria l'istruzione switch, sembra esserci molta confusione riguardo a getRotationMatrix, remapCoordinateSystem e getOrientation dalle domande stackoverflow.
Probabilmente scriverò una spiegazione dettagliata di questi nel prossimo futuro.

+0

Man! Ho cercato SO per più di 2 ore e ci sono molte risposte SBAGLIATE. Il tuo è il primo che funziona correttamente per me. Grazie per questo. – BoD

+0

Ho copiato e modificato il post. Non avevo capito che Mush aveva mGravity = event.values, dovrebbe essere event.values.clone(). Lo stesso per mGeomagnetic –

+0

'SensorManager.remapCoordinateSystem' è la soluzione. Grazie. –

1

La risposta di Hoan è effettivamente errata perché non tiene conto della rotazione del display. This è la risposta corretta.