6

我的增強現實應用程序需要相機視圖的指南針方向,並且有很多從sensormanager獲取方向的示例。指南針方向根據手機方向而有所不同

但是,我發現取決於手機方向的結果值有所不同 - 風景向右旋轉約10度不同於風景向左旋轉(ROTATION_0和ROTATION_180之間的差異較小,但仍然不同)。這種差異足以毀掉任何AR效應。

這是否與校準有關? (我不相信我正在做8件事的數字 - 我嘗試了各種在YouTube上找到的方式)。

任何想法爲什麼有區別?我弄亂了旋轉矩陣的東西嗎?我有限制的應用程序的單一取向的選擇,但它仍然令我擔憂的是,羅盤讀數還不是很準確的(即使過濾後的相當穩定)

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();  
     } 
    } 

回答

10

試試這個

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

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

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

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

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

您不需要switch語句,似乎有很多關於getRotationMatrix,remapCoordinateSystem和getOrientation的疑惑。
我可能會在不久的將來寫出這些細節的解釋。

+0

男人!我一直在搜索超過2個小時,並且有很多錯誤的答案。你是第一個真正爲我正確工作的人。謝謝你。 – BoD 2013-08-26 22:57:55

+0

我複製並編輯了帖子。我沒有意識到Mush有mGravity = event.values,它應該是event.values.clone()。 mGeomagnetic爲 – 2013-08-27 14:21:43

+0

'SensorManager.remapCoordinateSystem'爲解決方案。謝謝。 – 2015-06-18 14:40:40

1

Hoan的答案實際上是不正確的,因爲它沒有考慮到顯示旋轉。 This是正確的答案。