Comment devrais-je calculer l'azimut, la hauteur, l'orientation lorsque mon appareil Android n'est pas plat?
Je suis en utilisant l'Android gravité et le champ magnétique capteurs pour calculer l'orientation via SensorManager.getRotationMatrix et SensorManager.getOrientation. Cela me donne l'azimut, la hauteur et l'orientation des nombres. Les résultats semblent de bon sens lorsque l'appareil est posée à plat sur une table.
Cependant, j'ai désactivé commute entre les modes portrait et paysage dans le manifeste, de sorte que getWindowManager().getDefaultDisplay().getRotation() est toujours à zéro. Lorsque je tourne l'appareil de 90 degrés, de sorte qu'il est debout à la verticale, j'en difficulté. Parfois, les chiffres semblent assez mal, et j'ai réalisé que cela se rapporte à Gimbal lock. Cependant, d'autres applications ne semblent pas avoir ce problème. Par exemple, j'ai comparé mon application à l'encontre de deux gratuit de test de capteur apps (Capteur De Testeur (Dicotomica) et Surveillance du capteur (R)). Mon application est en accord avec ces applications lorsque l'appareil est à plat, mais comme je l'ai faites pivoter l'appareil dans la position verticale, il peut y avoir des différences significatives. Les deux applications semblent être d'accord les uns avec les autres, alors comment font-ils contourner ce problème?
source d'informationauteur gisking | 2013-03-27
Vous devez vous connecter pour publier un commentaire.
Je pense que la meilleure façon de la définition de vos angles d'orientation lorsque l'appareil n'est pas plat est d'utiliser un plus approprié angulaire du système de coordonnées que le standard angles d'Euler que vous obtenez à partir de
SensorManager.getOrientation(...)
. Je suggère celui que je décris ici math.stackexchange.com. J'ai aussi mis un peu de code qui ne l'implémente dans une réponse ici. En dehors d'une bonne définition de l'azimut, il a également une définition de l'angle de ce qui est exactement l'angle donné parMath.acos(rotationMatrix[8])
qui est mentionné dans une autre réponse ici.Vous pouvez obtenir les détails complets sur les deux liens que j'ai donné dans le premier paragraphe. Toutefois, en résumé, votre matrice de rotation R de SensorManager.getRotationMatrix(...) est
où Ex Ea Ez), (NxNaNz) et (GxGaGz) sont des vecteurs pointant à l'Est, au Nord, et dans la direction de la Gravité. Ensuite, l'angle d'azimut que vous voulez est donnée par
Lorsque l'appareil n'est pas plat, vous devez appeler
remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);
avant d'appelergetOrientation
.La
azimuth
renvoie pargetOrientation
est obtenu par orthogonalement projet de l'unité périphériqueY axis
dans le mondeEast-North plane
puis de calculer l'angle entre la projection résultante vecteur et l'axe Nord.Maintenant, nous avons l'habitude de penser direction que la direction de l'arrière de la caméra est pointée. C'est le sens de
-Z
oùZ
est le dispositif de l'axe de pointage de l'écran. Lorsque l'appareil est à plat nous ne pensons pas de la direction et d'accepter ce que jamais donnée. Mais quand il n'est pas plat, nous attendons, c'est la direction de-Z
. MaisgetOrientation
calculer la direction de laY axis
donc nous avons besoin d'échanger laY and Z axes
avant d'appelergetOrientation
. C'est exactement ce queremapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR)
ne, garder leX axis
intacte et la carteZ to Y
.Maintenant alors, comment savez-vous quand vous
remap
ou pas. Vous pouvez le faire en vérifiantL'inclinaison ci-dessus est l'angle entre l'écran de l'appareil et le monde à l'Est-Nord-plan. Il montre combien l'appareil est inclinable.