2011-08-12 19 views
12

私はgetOrientationを使用してデバイスの実際の向きを取得することに苦労しています。 TYPE_ACCELEROMETERとTYPE_MAGNETIC_FIELDを使って加速度計と磁界の読み取り値を取得するのは、TYPE_ORIENTATIONで方向を取得するのと同じように簡単です。しかし、getOrientationを使って世界の座標系に従って向きを取得する。 herehereには数多くの良いチュートリアルがありますが、私はまだそれをまとめていません。その目的のために、私は、getOrientationからAccelerometer、Magnetic Field、生のOrientationデータ、およびOrientationデータを吐き出すアプリを開発していました。私はコードを添付したが、それは私の電話で絶えず失敗する。助言がありますか?getRotationMatrixとgetOrientationチュートリアル

package com.sensorall; 


import com.sensorall.R; 
import android.hardware.*; 
import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 



public class OrientationAccelerometer extends Activity { 

    SensorManager sensorManager; 
    float[] mGravs = new float[3]; 
    float[] mGeoMags = new float[3]; 
    float[] mRotationM = new float[16]; 
    float[] mInclinationM = new float[16]; 
    float[] mOrientation = new float[3]; 
    float[] mOldOreintation = new float[3]; 
    String[] mAccelerometer = new String[3]; 
    String[] mMagnetic = new String[3];  
    String[] mRotation = new String[16]; 
    String[] mInclination = new String[16]; 
    String[] mOrientationString = new String[3]; 
    String[] mOldOreintationString = new String[3]; 


    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.orientationaccelerometer); 
     sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 

    } /* End onCreate activity */ 

    private SensorEventListener sensorEventListener = new SensorEventListener() { 

     public void onAccuracyChanged(Sensor sensor, int accuracy) { 

     } 


     /* Get the Sensors */ 
     public void onSensorChanged(SensorEvent event) { 

       switch (event.sensor.getType()) { 
        case Sensor.TYPE_ACCELEROMETER: 
           System.arraycopy(event.values, 0, mGravs, 0, 3); 
           break; 
        case Sensor.TYPE_MAGNETIC_FIELD: 
           System.arraycopy(event.values, 0, mGeoMags, 0, 3); 
           break; 
        case Sensor.TYPE_ORIENTATION: 
          System.arraycopy(event.values, 0, mOldOreintation, 0, 3); 
         break; 

        default: 
           return; 
      } 

       // If mGravs and mGeoMags have values then find rotation matrix 
       if (mGravs != null && mGeoMags != null) { 

        // checks that the rotation matrix is found 
        boolean success = SensorManager.getRotationMatrix(mRotationM, mInclinationM, mGravs, mGeoMags); 
        if (success) { 
         /* getOrientation Values */ 
         SensorManager.getOrientation(mRotationM, mOrientation); 

          for(int i=0; i<2; i++){ 
           mAccelerometer[i] = Float.toString(mGravs[i]); 
           mMagnetic[i] = Float.toString(mGeoMags[i]); 
           mOrientationString[i] = Float.toString(mOrientation[i]); 
           mOldOreintationString[i] = Float.toString(mOldOreintation[i]); 
          } 

          /* Make everything text to show on device */ 
          TextView xaxisAccelerometerText = (TextView)findViewById(R.id.xaxisAccelerometer); 
          xaxisAccelerometerText.setText(mAccelerometer[0]);  
          TextView yaxisAccelerometerText = (TextView)findViewById(R.id.yaxisAccelerometer); 
          yaxisAccelerometerText.setText(mAccelerometer[1]); 
          TextView zaxisAccelerometerText = (TextView)findViewById(R.id.zaxisAccelerometer); 
          zaxisAccelerometerText.setText(mAccelerometer[2]);  
          TextView xaxisMagneticText = (TextView)findViewById(R.id.xaxisMagnetic); 
          xaxisMagneticText.setText(mMagnetic[0]);  
          TextView yaxisMagneticText = (TextView)findViewById(R.id.yaxisMagnetic); 
          yaxisMagneticText.setText(mMagnetic[1]); 
          TextView zaxisMagneticText = (TextView)findViewById(R.id.zaxisMagnetic); 
          zaxisMagneticText.setText(mMagnetic[2]); 
          TextView xaxisOrientationText = (TextView)findViewById(R.id.xaxisOrientation); 
          xaxisOrientationText.setText(mOrientationString[0]);  
          TextView yaxisOrientationText = (TextView)findViewById(R.id.yaxisOrientation); 
          yaxisOrientationText.setText(mOrientationString[1]); 
          TextView zaxisOrientationText = (TextView)findViewById(R.id.zaxisOrientation); 
          zaxisOrientationText.setText(mOrientationString[2]); 
          TextView xaxisOldOrientationText = (TextView)findViewById(R.id.xaxisOldOrientation); 
          xaxisOldOrientationText.setText(mOldOreintationString[0]);  
          TextView yaxisOldOrientationText = (TextView)findViewById(R.id.yaxisOldOrientation); 
          yaxisOldOrientationText.setText(mOldOreintationString[1]); 
          TextView zaxisOldOrientationText = (TextView)findViewById(R.id.zaxisOldOrientation); 
          zaxisOldOrientationText.setText(mOldOreintationString[2]); 

        }else{ 

         /* Make everything text to show on device even if getRotationMatrix fails*/ 
          String matrixFailed = "Rotation Matrix Failed"; 
          TextView xaxisAccelerometerText = (TextView)findViewById(R.id.xaxisAccelerometer); 
          xaxisAccelerometerText.setText(mAccelerometer[0]);  
          TextView yaxisAccelerometerText = (TextView)findViewById(R.id.yaxisAccelerometer); 
          yaxisAccelerometerText.setText(mAccelerometer[1]); 
          TextView zaxisAccelerometerText = (TextView)findViewById(R.id.zaxisAccelerometer); 
          zaxisAccelerometerText.setText(mAccelerometer[2]);  
          TextView xaxisMagneticText = (TextView)findViewById(R.id.xaxisMagnetic); 
          xaxisMagneticText.setText(mMagnetic[0]);  
          TextView yaxisMagneticText = (TextView)findViewById(R.id.yaxisMagnetic); 
          yaxisMagneticText.setText(mMagnetic[1]); 
          TextView zaxisMagneticText = (TextView)findViewById(R.id.zaxisMagnetic); 
          zaxisMagneticText.setText(mMagnetic[2]); 
          TextView xaxisOrientationText = (TextView)findViewById(R.id.xaxisOrientation); 
          xaxisOrientationText.setText(matrixFailed);  
          TextView yaxisOrientationText = (TextView)findViewById(R.id.yaxisOrientation); 
          yaxisOrientationText.setText(matrixFailed); 
          TextView zaxisOrientationText = (TextView)findViewById(R.id.zaxisOrientation); 
          zaxisOrientationText.setText(matrixFailed); 
          TextView xaxisOldOrientationText = (TextView)findViewById(R.id.xaxisOldOrientation); 
          xaxisOldOrientationText.setText(mOldOreintationString[0]);  
          TextView yaxisOldOrientationText = (TextView)findViewById(R.id.yaxisOldOrientation); 
          yaxisOldOrientationText.setText(mOldOreintationString[1]); 
          TextView zaxisOldOrientationText = (TextView)findViewById(R.id.zaxisOldOrientation); 
          zaxisOldOrientationText.setText(mOldOreintationString[2]); 





        } 
       } 


     } 
    }; 


    @Override 
    protected void onResume() { 
     super.onResume(); 
     sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 
     sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL); 
     sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL); 
    } 


    protected void onPause() { 
     super.onPause(); 
     sensorManager.unregisterListener(sensorEventListener); 
    }  

} 
+1

「失敗する」とはどういう意味ですか?それはあなたにエラーを与えている、あなたはデータ/間違ったデータが表示されますか? – arunkumar

+0

メッセージが表示されます。アプリケーションSensorAllが予期せず停止しました。もう一度お試しください。その後、強制的に閉じる必要があります –

+2

私たちがあなたを助けるためにlogcatからスタックトレースを提供してください。 –

答えて

-2

イベントの受信は、リニアプログラムの実行フローに従いません。 問題を回避するために、センサーイベントの受信に関連するコードを相互排除ブロックに配置することをお勧めします。

私は意味:

public void onSensorChanged(SensorEvent event) { 
    synchronized (this) { 
     ... 
    } 
} 

は、この情報がお役に立てば幸いです。

+1

本当ではありません。特に指定しない限り、すべてのセンサーコールバックはメインスレッド上で発生します。 – Dorje

+0

これを裏付けるための文書へのリンクまたは参照はありますか? – jap1968

+0

これは、[ここ](http://stackoverflow.com/questions/17681870/android-which-thread-calls-onsensorchanged)on stackoverflowで議論されています。 [SensorManagerのソースコード](https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/hardware/SensorManager.java)を参照してください。 – Aditya

1

これはおそらくあなたのコードには当てはまりませんが、一般にgetRotationMatrix()を使用する点では、他人の問題を解決する可能性があります。

私はこれが私の側のバージョン管理の問題だったかどうかわからないんだけど、私はgetRotationMatrix()メソッドのソースコードをチェックアウトして、ドキュメントがR[]I[]パラメータについて言っていることとは違って、彼らははNULLにすることはできません。このように私のRIを宣言した後:

float[] r = new float[9];

float[] i = new float[9];

方法が正しく作動しました。

SensorManager.getRotationMatrix(r,i,gravity,geomagnetic) - >true

...奇妙なドキュメントのエラー。

3

次私と一緒に働いていた:I

float[] mOrientation = new float[4]; 

はいないため

float[] r = new float[**16**]; 

使用ヌル。しかし、あなたは3つだけを使用します。

SensorManager.getRotationMatrix(rotationMatrix, null, accelVals, magVals); 

私のために働いた。

0

強制終了が必要なアプリに答えて、あまりにも多くのUIスレッドであまりにも多くのことをやっているように聞こえます。あなたは遅れてSENSOR_DELAY_NORMALの3つの異なるセンサーからデータを受信して​​います。これは約5回の読み取り/秒でなければならないが、センサの遅延はほんのわずかな遅延であるため、毎秒20回以上の読み取りが可能であることがわかった。だから、あなたは3つのすべてのセンサーについて毎秒60回以上の読み取りを受けているはずです。読書ごとに、あなたはを更新しているので、毎秒720以上のUIアップデートをしている可能性があります。これにより私の電話機もクラッシュしました。 UIの更新の間の最小時間を設定してみてください:

long currentTime = System.currentTimeMillis(); 
if ((currentTime - lastUpdateTime) >= MIN_TIME_BETWEEN_UPDATES) { 
    // Update UI 
    lastUpdateTime = currentTime; 
} 

あなたは、あなたがそれを必要とする場合に使用するために高速な間隔でデータを保存しますが、UIの更新を遅くすることができます。

関連する問題