Unterschiedliche Werte zwischen den Sensoren TYPE_ACCELEROMETER / TYPE_MAGNETIC_FIELD und TYPE_ORIENTATION

Es gibt 2 Möglichkeiten, die 3 Rotationswerte (Azimut, Tonhöhe, Rolle) zu erhalten.

Man registriert einen Zuhörer eines Typs TYPE_ORIENTATION. Es ist der einfachste Weg, und ich bekomme einen korrekten Bereich von Werten aus jeder Umdrehung, wie die Dokumentation sagt: Azimut: [0, 359] Tonhöhe: [-180, 180] Rolle: [-90, 90]

Die andere, die genaueste und komplexe zu verstehen, das erste Mal sehen Sie es. Android empfiehlt es, also möchte ich es benutzen, aber ich bekomme verschiedene Werte.

Azimut: [-180, 180]. -180/180 ist S, 0 i N, 90 E und -90 W.
Tonhöhe: [-90, 90]. 90 ist 90, -90 ist -90, 0 ist 0 aber -180/180 (liegend mit dem Bildschirm nach unten) ist 0.
Rollen: [-180, 180].

Ich sollte die gleichen Werte bekommen, aber mit Dezimalstellen, richtig?

Ich habe den folgenden Code:

aValues = new float[3]; mValues = new float[3]; sensorListener = new SensorEventListener (){ public void onSensorChanged (SensorEvent event){ switch (event.sensor.getType ()){ case Sensor.TYPE_ACCELEROMETER: aValues = event.values.clone (); break; case Sensor.TYPE_MAGNETIC_FIELD: mValues = event.values.clone (); break; } float[] R = new float[16]; float[] orientationValues = new float[3]; SensorManager.getRotationMatrix (R, null, aValues, mValues); SensorManager.getOrientation (R, orientationValues); orientationValues[0] = (float)Math.toDegrees (orientationValues[0]); orientationValues[1] = (float)Math.toDegrees (orientationValues[1]); orientationValues[2] = (float)Math.toDegrees (orientationValues[2]); azimuthText.setText ("azimuth: " + orientationValues[0]); pitchText.setText ("pitch: " + orientationValues[1]); rollText.setText ("roll: " + orientationValues[2]); } public void onAccuracyChanged (Sensor sensor, int accuracy){} }; 

Bitte helfen Sie. Es ist sehr frustrierend.

Muss ich mit diesen Werten zu tun haben oder ich mache etwas falsches

Vielen Dank.

  • Erhalten Sie Gerätewinkel mit der Funktion getOrientation ()
  • Wie soll ich Azimut, Tonhöhe, Orientierung berechnen, wenn mein Android-Gerät nicht flach ist?
  • Mobiltelefonsensoren
  • 3 Solutions collect form web for “Unterschiedliche Werte zwischen den Sensoren TYPE_ACCELEROMETER / TYPE_MAGNETIC_FIELD und TYPE_ORIENTATION”

    Ich weiß, dass ich hier Thread Nekromanten spielte, aber ich habe in letzter Zeit viel an diesem Zeug gearbeitet, also dachte ich, ich würde meine 2 ¢ werfen.

    Das Gerät enthält keine Kompass- oder Inklinometer, so dass es nicht Azimut, Tonhöhe oder Rolle direkt misst. (Wir nennen diese Euler-Winkel, BTW). Stattdessen werden Beschleunigungsmesser und Magnetometer verwendet, die beide 3-Raum-XYZ-Vektoren erzeugen. Diese werden verwendet, um die Azimut usw. zu berechnen.

    Vektoren befinden sich im Gerätekoordinatenraum:

    Gerätekoordinaten

    Weltkoordinaten haben Y nach Norden, X nach Osten und Z nach oben:

    Weltkoordinaten

    So liegt die "neutrale" Orientierung eines Geräts auf dem Rücken auf einem Tisch, wobei die Oberseite des Gerätes nach Norden gerichtet ist.

    Der Beschleunigungsmesser erzeugt einen Vektor in der "UP" -Richtung. Das Magnetometer erzeugt einen Vektor in der "Nord" -Richtung. (Beachten Sie, dass es in der nördlichen Hemisphäre dazu neigt, durch magnetisches Dip nach unten zu zeigen.)

    Der Beschleunigungsmesservektor und der Magnetometervektor können mathematisch über SensorManager.getRotationMatrix () kombiniert werden, der eine 3×3 Matrix zurückgibt, die Vektoren in Gerätekoordinaten auf Weltkoordinaten abbildet oder umgekehrt. Für ein Gerät in der Neutralstellung würde diese Funktion die Identitätsmatrix zurückgeben.

    Diese Matrix variiert nicht mit der Bildschirmorientierung. Das bedeutet, dass Ihre Bewerbung sich der Orientierung bewusst sein muss und entsprechend kompensieren muss.

    SensorManager.getOrientation () nimmt die Transformationsmatrix und berechnet Azimut-, Tonhöhen- und Rollwerte. Diese werden in Bezug auf ein Gerät in der Neutralstellung gebracht.

    Ich habe keine Ahnung, was der Unterschied zwischen dem Aufrufen dieser Funktion und nur mit TYPE_ORIENTATION Sensor, außer dass die Funktion können Sie manipulieren die Matrix zuerst.

    Wenn das Gerät bei 90 ° oder in der Nähe davon geneigt ist, dann fällt die Verwendung von Euler-Winkeln auseinander. Dies ist ein degenerierter Fall mathematisch. In diesem Bereich, wie soll das Gerät wissen, ob Sie Azimut ändern oder rollen?

    Die Funktion SensorManager.remapCoordinateSystem () kann verwendet werden, um die Transformationsmatrix zu manipulieren, um das zu kompensieren, was Sie über die Ausrichtung des Gerätes wissen können. Allerdings haben meine Experimente gezeigt, dass dies nicht alle Fälle, nicht einmal einige der gemeinsamen. Wenn Sie zum Beispiel ein Gerät aufheben möchten, das aufrecht steht (zB um ein Foto zu machen), möchten Sie die Transformationsmatrix mit dieser Matrix multiplizieren:

     1 0 0 0 0 1 0 1 0 

    Vor dem Aufruf von getOrientation (), und das ist nicht eine der Orientierungs-Remappings, die remapCoordinateSystem () unterstützt [jemand bitte korrigieren Sie mich, wenn ich etwas hier verpasst habe].

    OK, also war das alles eine langwierige Art zu sagen, dass, wenn du Orientierung nimmst, entweder vom TYPE_ORIENTATION Sensor oder von getOrientation (), vermutlich machst du es falsch. Die einzige Zeit, die Sie wirklich wollen, dass die Euler-Winkel ist, Orientierungsinformationen in einer benutzerfreundlichen Form anzuzeigen, um ein Foto zu kommentieren, um Fluginstrument-Display oder etwas ähnliches zu fahren.

    Wenn Sie Berechnungen im Zusammenhang mit der Geräteorientierung machen wollen, sind Sie mit der Transformationsmatrix und mit XYZ-Vektoren fast sicher besser.

    Als Berater zu arbeiten, wann immer jemand zu mir kommt mit einem Problem mit Euler-Winkeln, ich wieder auf und frage sie, was sie wirklich versuchen zu tun, und dann einen Weg finden, um es mit Vektoren stattdessen zu tun.

    Wenn man auf Ihre ursprüngliche Frage zurückblickt, sollte getOrientation () drei Werte in [-180 180] [-90 90] und [-180 180] (nach Umwandlung von Bogenmaß) zurückgeben. In der Praxis denken wir an Azimut als Zahlen in [0 360], also solltest du einfach 360 irgendwelche negativen Zahlen hinzufügen, die du empfängst. Dein Code sieht richtig aus. Es würde helfen, wenn ich genau wüsste, welche Ergebnisse du erwartet hast und was du stattdessen hast.

    Bearbeitet, um hinzuzufügen: Ein paar weitere Gedanken. Moderne Versionen von Android verwenden so genannte "Sensor Fusion", was im Grunde bedeutet, dass alle verfügbaren Eingänge – Beschleuniger, Magnetometer, Kreisel – zusammen in einer mathematischen Black Box (in der Regel ein Kalman-Filter, aber hängt vom Anbieter) zusammen. Alle Sensoren – Beschleunigung, Magnetfeld, Kreisel, Schwerkraft, Linearbeschleunigung und Orientierung – werden als Ausgänge aus dieser Black Box aufgenommen.

    Wann immer möglich, sollten Sie TYPE_GRAVITY anstatt TYPE_ACCELEROMETER als Eingabe in getRotationMatrix () verwenden.

    Ich könnte hier im Dunkeln schießen, aber wenn ich deine Frage richtig verstehe, [-179..179] du dich, warum du [-179..179] statt [0..360] ?

    Beachten Sie, dass -180 das gleiche wie +180 und das gleiche wie 180 + N*360 wobei N eine ganze Zahl (Integer) ist.

    Mit anderen Worten, wenn Sie die gleichen Zahlen wie mit Orientierungssensor erhalten möchten, können Sie dies tun:

     // x = orientationValues[0]; // y = orientationValues[1]; // z = orientationValues[2]; x = (x + 360.0) % 360.0; y = (y + 360.0) % 360.0; z = (z + 360.0) % 360.0; 

    Dies gibt Ihnen die Werte im Bereich [0..360] wie gewünscht.

    Ihnen fehlt eine kritische Berechnung in Ihren Berechnungen.
    Das remapCoordinateSystem ruft an, dass du eine getRotationMatrix hast .

    Füge das deinem Code hinzu und alles wird gut.
    Hier können Sie mehr darüber erfahren .

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.