webentwicklung-frage-antwort-db.com.de

getRotationMatrix und getOrientation Tutorial

Ich habe Probleme damit, mithilfe von getOrientation die tatsächliche Ausrichtung meines Geräts zu ermitteln. Das Abrufen der Beschleunigungsmesser- und Magnetfeldwerte über TYPE_ACCELEROMETER und TYPE_MAGNETIC_FIELD ist ebenso einfach wie das Abrufen der Orientierung über TYPE_ORIENTATION. Aber mit getOrientation die Orientierung nach dem Weltkoordinatensystem erhalten. Es gibt eine Reihe guter Tutorials hier und hier , aber ich muss noch alles zusammenfügen. Zu diesem Zweck habe ich eine App entwickelt, die einfach den Beschleunigungsmesser, das Magnetfeld, die rohen Orientierungsdaten und die Orientierungsdaten von getOrientation ausgibt. Ich habe den Code angehängt, aber er schlägt auf meinem Telefon ständig fehl. Irgendwelche Vorschläge?

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

}
12
John Kossik

Folgendes hat bei mir funktioniert:

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

Benutze null für I

float[] mOrientation = new float[4];  

Ja 4 nicht 3 . Sie verwenden jedoch nur 3.

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

Dieser Code arbeitete für mich.

3
M.Hefny

Dies trifft wahrscheinlich nicht auf Ihren Code zu, kann jedoch bei der Verwendung von getRotationMatrix () im Allgemeinen die Probleme anderer lösen.

Ich bin nicht sicher, ob dies ein Versionsproblem auf meiner Seite war, aber ich habe den Quellcode für die Methode getRotationMatrix() überprüft und anders als in der Dokumentation zu den Parametern R[] und I[] wird angegeben, dassNICHTnull sein kann . Nachdem ich meine R und I folgendermaßen deklariert habe:

float[] r = new float[9];

float[] i = new float[9];

Die Methode funktionierte korrekt.

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

... seltsamer Dokumentationsfehler.

1
brainmurphy1

Als Antwort auf Ihre App, die das Schließen einer Force erfordert, scheint es mir, dass Sie zu oft zu viel auf dem UI-Thread tun. Sie empfangen Daten von 3 verschiedenen Sensoren mit einer Verzögerung von SENSOR_DELAY_NORMAL. Während das ungefähr 5 Messwerte pro Sekunde sein sollte, habe ich gesehen, dass es mehr als 20 Messwerte pro Sekunde sein können (da die Sensorverzögerung nur eine empfohlene Verzögerung ist). Sie KÖNNTEN also für alle 3 Sensoren mehr als 60 Messwerte pro Sekunde erhalten. Für jeden Messwert aktualisieren Sie 12 TextView, sodass Sie möglicherweise mehr als 720 UI-Aktualisierungen pro Sekunde durchführen. Dies führte auch zu einem Absturz meines Telefons. Versuchen Sie, eine Mindestzeit zwischen den Benutzeroberflächenaktualisierungen festzulegen:

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

Sie können die Daten in kurzen Intervallen speichern, um sie bei Bedarf zu verwenden, die Benutzeroberflächenaktualisierungen jedoch verlangsamen.

0
James B