Wie man Android-Handy Orientierung matching menschliche Orientierung?
Mache ich eine Karte-app, einschließlich der Position Pfeil, der Ihnen zeigt, welchen Weg Sie konfrontiert sind, etwa so:
Bekomme ich die Ausrichtung direkt aus SensorManager.getOrientation()
mit den ersten Rückgabewert: Azimut. Wenn das Telefon gehalten wird, so dass der Bildschirm zeigt über dem Horizont, und in der Porträt -, der Pfeil funktioniert einwandfrei. Allerdings:
- Wenn das Telefon gehalten wird, so dass der Bildschirm zeigt unter dem Horizont, der Pfeil um 180 Grad, Weg von der Richtung, die der Benutzer konfrontiert ist.
- Wenn das Telefon gehalten wird, so dass der Bildschirm gegenüberstellt, ist die Ebene mit dem Horizont, der Pfeil hat keine Ahnung, welchen Weg es zeigt. Azimut nicht wieder sinnvolle Ergebnisse.
- Wenn das Telefon gekippt wird, Links oder rechts (oder statt im landscape-Modus), der Pfeil kippt nach Links oder rechts.
Den sorgfältig konstruierten und wissenschaftliche Bild unten zeigt, was ich meine (wo blau ist dem Benutzer zugewandt, rot ist der Pfeil-Richtung, der Bildschirm ist ungefähr dem Benutzer zugewandte Gesicht, und Google Maps macht genau das, was ich will):
(Beachten Sie, dass mit Google Maps, ist es nicht erfolgreich zu tun, die letzten zwei Aktionen auf der Liste, wenn automatisch drehen ausgeschaltet ist. Aber ich bin nicht selbst in dieser Phase noch nicht. Eine Sache zu einer Zeit.)
Scheint es, als ob es einfach mit der Y-Achse nach Richtung wie hier gezeigt: http://developer.android.com/reference/android/hardware/SensorEvent.html, wenn ich will, es zu benutzen, die Umkehrung der Z-Achse nach der Richtung, die meiste Zeit, und das Y, wenn das Telefon flach. Jedoch, angesichts der Werte, die getOrientation()
gibt, würde ich schreiben, komplexe Fälle zu lösen einige der Probleme, und die Telefon-facing-Horizont use-case ist nicht lösbar. Ich bin sicher, es ist ein einfacher Weg.
Hier mein code (Wo lastAcceleration und lastMagneticField beide kamen von den internen sensor):
float[] rotationMatrix = new float[9];
if(SensorManager.getRotationMatrix(rotationMatrix, null, lastAcceleration, lastMagneticField)){
float[] orientMatrix = new float[3];
SensorManager.getOrientation(rotationMatrix, orientMatrix);
orientation = orientMat[0]*180/(float)Math.PI;
}
Was mache ich falsch? Gibt es ein einfacher Weg, dies zu tun?
Edit: Nur um klarzustellen, ich mache die Annahme, dass der Benutzer das Gerät hält vor Ihnen, und der Bildschirm zeigt Ihnen gegenüber. Darüber hinaus, ich kann natürlich nicht sagen, wenn nur einer von Ihnen dreht. Auch bin ich mit der Bewegung des Benutzers, wenn Sie in Bewegung sind, aber dies ist für, wenn Sie stationär.
- +1 für das wissenschaftliche Bild
- ist Ihr problem gelöst? Wie hast du lastAcceleration, lastMagneticField?
- NÖ. Nie gelöst. Vielleicht war es nie lösbar, und es scheint, dass google maps war nicht so smart wie ich dachte, damals. Habe ich schon lange verworfen, es von meiner Liste der Aufgaben, die erledigt werden muss, als ich nicht mehr arbeiten für die gleiche Firma, geschweige denn das gleiche Projekt. Android funktioniert wahrscheinlich ganz anders in diesen Tagen, wie auch immer.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hast, Ruf Sie an remapCoordinateSystem? Andernfalls erhalten Sie nur den rechten Verkleidung Wert, wenn Sie das Telefon senkrecht halten. Für den Fall, Wenn das Telefon gehalten wird, so dass der Bildschirm gegenüberstellt, ist die Ebene mit dem Horizont, es gibt keine Weise können Sie sich die Benutzer gegenübersehen. Denn um die vor-Sie haben zum Projekt der z-Wert den der sensor das Lesen in der xy-Ebene in der Welt zu koordinieren, und Sie ist null, wenn das Gerät waagerecht gehalten.
Um genauer zu sein, wenn Sie wollen, um das Telefon zu bekommen die Verkleidung dann hat das Telefon zu geneigt sein, mindestens etwa 25 Grad von der horizontalen, und Sie haben zu nennen remapCoordinateSystem. Der folgende code wird Ihnen, was Sie wollen für die letzten 2 Bildern oben.
Code
Den getOrientation gibt Ihnen die richtigen Werte, vorausgesetzt das Telefon ist flach. Also, wenn das Telefon aufrecht gehalten wird, dann haben Sie neu koordinieren, um die flache position. Geometrisch, Sie Projekt die Telefon -z-Achse nach unten auf der Welt xy-Ebene und berechnen Sie dann den Winkel zwischen dieser Projektion der Vektor-und der Welt-y-Achse.
remapCoordinateSystem
. Die docs sind nicht völlig klar, wie es zu benutzen.Das sieht ziemlich tricky. Ich bin die Entwicklung einer PNS für Android und bin vor ein irgendwie ähnliches problem, für das ich bin immer noch in der Notwendigkeit des Lichts : Wie man die rotation zwischen accelerometer-Achse und den Bewegungsvektor?
Sache ist, dass es sieht für mich absolut unmöglich zu finden, in welche Richtung der Benutzer konfrontiert ist (nicht das Gerät), wenn er sich nicht bewegt. Das ist der menschliche hat kein sensor an seinem Körper, was also, wenn das Gerät blieb in der absolut gleichen position, aber der Benutzer wird um 90° gedreht ? Ich sehe keinen Weg, um diese zu finden.
Was ich vorschlagen kann, (und das passt eigentlich zu meinem problem) ist, dass man (ich weiß nicht, was Sie eigentlich in Ihrem code) Verwendung der Bewegung des Benutzers, um zu bestimmen, seine Position. Lassen Sie mich erklären. Lassen Sie uns sagen, Sie haben eine erste position A. Benutzer gehen zu B. Dann können Sie bauen den Vektor AB und bekommen die Position des Benutzers, wenn er hält an B. würde Man dann beschränken Sie Ihre code, um die Richtung, die er konfrontiert ist, wenn man zum Ziel.
Ich weiß, das ist nicht so gut wie das, was Google Maps bekommt, aber wissen Sie, was Google verwendet für diese ? Ich meine, tun Sie nur verwenden, accelero und mag.Feld-sensoren ?
Scheint es, dass der geeignete Weg, um das Lager, wenn der Benutzer das Handy senkrecht halten, ist die Verwendung so etwas wie dieses:
Wenn Sie möchten, Griff in beide Richtungen (vertikal und flach) werden Sie wahrscheinlich benötigen, um zu erkennen, dass und dann nur diese neu zuordnen, wenn es vertikal ist.
Finden Sie in der API-Dokumentation hier.
Sollten Sie die pitch-und bestimmen, ob der Benutzer in der Nähe halten Sie das Telefon vertikal.
wählte ich, dass nach 45 Grad Steigung nach oben oder unten von der flach auf dem Tisch, das Koordinaten-system sollten neu zugeordnet werden.
Es hat ganz gut geklappt.
Lassen Sie mich wissen, wenn jemand vorschlagen kann, eine Verbesserung auf diesem. Danke.