SensorManager.getRotationMatrix()
tut, was unten beschrieben ist, geschrieben, bevor ich das herausgefunden habe. Ich werde die zusätzliche Erklärung hinterlassen, denn wenn du den Unterschied zwischen magnetischem und echtem Norden korrigieren willst, wirst du es immer noch brauchen.
Der grobe Algorithmus ist, die Rotationsmatrix zu erhalten, multiplizieren Sie Vektor [0,0,-1]
damit, und passen Sie dies dann an Ihr Koordinatensystem an. Warum? Android docs gibt die Koordinatensysteme für die Einrichtung und die Welt
Hinweis [0,0,-1]
in Android Gerät Koord Punkte senkrecht nach rückwärts von dem Bildschirm entfernt. Wenn Sie die Rotationsmatrix R mit diesem Vektor multiplizieren, erhalten Sie [0,0,-1]
in Weltkoordinaten, wenn das Gerät auf dem Tisch liegt, wie Sie es wünschen. Wenn es nach Norden ausgerichtet ist, erhalten Sie [0,-1,0]
, was bedeutet, dass Sie ein Koordinatensystem gewählt haben, in dem x
und y
in Bezug auf das Android-System ausgetauscht werden, aber das ist nur eine Änderung der Konventionen.
Hinweis R * [0,0,-1]^T
ist nur die dritte Spalte von R
negiert. Von diesem bekomme ich den Pseudocode:
getRotationMatrix(R);
Let v = first three elements of third column of R.
swap v[0] and v[1]
Dies sollte bekommen, was Sie wollen.
Weitere Informationen darüber, was getRotationMatrix()
tut, folgt.
Sie benötigen beiden accerometer Daten die Richtung „down“ und Magnetometer-Daten, die Richtung zu bestimmen, zu etablieren „nördlich.“ Sie müssen annehmen, dass die Beschleunigungsmesser nur die Schwerkraft messen (das Gerät ist stationär oder bewegt sich mit einer gleichmäßigen Geschwindigkeit). Dann müssen Sie den Magnetometervektor auf die Ebene senkrecht zum Gravitationsvektor projizieren (weil das Magnetfeld im Allgemeinen nicht tangential zur Erdoberfläche ist). Dies gibt Ihnen zwei Achsen. Die dritte ist orthogonal, so kann durch Kreuzprodukt berechnet werden. Dies gibt Ihnen die Erdkoordinatenvektoren im Gerätesystem. Es sieht so aus, als ob Sie das Gegenteil wollen: Gerätekoordinaten in Erdkoordinaten. Dazu konstruiere einfach die Matrix von Richtungskosinus und invertiere.
Ich füge hinzu, dass die obige Diskussion annimmt, dass der Magnetometervektor nach Norden zeigt. Ich denke (aus der Highschool-Wissenschaft!)) Es ist eigentlich in Richtung magnetischer Süden, aber habe kein Gerät zur Hand, also kann ich es nicht versuchen. Natürlich ist der magnetische Norden/Süden von Null bis 180 Grad verschieden, je nachdem, wo du dich auf der Erde befindest. Sie können GPS-Koordinaten abrufen und einen tatsächlichen Offset berechnen.
Wenn Sie nicht vertraut mit der Mathematik sind notwendig, um diese zu tun, kann ich erklären weiter, aber es wird später sein.
Danke, das wirklich hilfreich ist. Ihr beide habt so gute Antworten gegeben, ich wünschte, es gäbe einen Weg, sie beide auszuwählen. Es sieht so aus, als ob ich den Gravitationsvektor mit nur Sensor.TYPE_GRAVITY bekommen kann - sie haben das für mich funktioniert. Ich wünschte, es wäre genauso einfach, einen "nördlichen" Vektor zu bekommen. – Joey
Ich habe es mit Ihrer Erklärung bekommen. Es stellt sich heraus, dass ich die von einem Gravitationssensor und einem Magnetfeldsensor zurückgegebenen Werte direkt in getRotationMatrix() übergebe und alles funktioniert. Dann multiplizierte man diese Matrix einfach mit [0,0, -1] und erhielt das dv. – Joey