Aperçu de l’orientation du téléphone Android, y compris la boussole

J’ai essayé de me familiariser avec les capteurs d’orientation Android pendant un moment. Je pensais l’avoir compris. Puis j’ai réalisé que non. Maintenant, je pense (j’espère) que je ressens un peu mieux pour cela, mais je ne suis toujours pas à 100%. J’essaierai d’expliquer ma compréhension incomplète et j’espère que les gens pourront me corriger si je me trompe dans certaines parties ou remplir des blancs.

J’imagine que je suis debout à 0 degré de longitude (méridien principal) et 0 degré de latitude (équateur). Cet endroit est en fait au large de la côte africaine, mais avec moi. Je tiens mon téléphone devant mon visage pour que le bas du téléphone pointe vers mes pieds; Je fais face au nord (en regardant vers Greenwich) donc le côté droit du téléphone pointe vers l’est en direction de l’Afrique. Dans cette orientation (en référence au diagramme ci-dessous), l’axe des abscisses pointe vers l’est, l’axe des z est orienté vers le sud et l’axe des ordonnées vers le ciel.

Maintenant, les capteurs du téléphone vous permettent de déterminer l’orientation (et non l’emplacement) de l’appareil dans cette situation. Cette partie m’a toujours dérouté, probablement parce que je voulais comprendre comment quelque chose fonctionnait avant d’accepter que cela fonctionnait. Il semble que le téléphone utilise son orientation en combinant deux techniques différentes.

Avant d’y arriver, imaginez que vous êtes sur la terre imaginaire à 0 degrés de latitude et de longitude dans la direction indiquée ci-dessus. Imaginez aussi que vous avez les yeux bandés et que vos chaussures soient fixées sur un rond-sharepoint la cour de récréation. Si quelqu’un vous pousse dans le dos, vous tomberez en avant (vers le nord) et vous mettrez les deux mains pour rompre votre chute. De même, si quelqu’un vous pousse l’épaule gauche, vous tomberez sur votre main droite. Votre oreille interne est dotée de “capteurs gravitationnels” (un clip sur youtube) qui vous permettent de détecter si vous tombez en avant / en arrière, si vous tombez à gauche / à droite ou si vous tombez (ou montez !!). Par conséquent, les humains peuvent détecter l’alignement et la rotation autour des mêmes axes X et Z que le téléphone.

Maintenant, imaginez que quelqu’un vous tourne à 90 degrés sur le rond-point pour que vous soyez maintenant face à l’Est. Vous êtes en train de tourner autour de l’axe Y. Cet axe est différent car nous ne pouvons pas le détecter biologiquement. Nous soaps que nous avons un certain angle mais nous ne connaissons pas la direction par rapport au pôle nord magnétique de la planète. Au lieu de cela, nous devons utiliser un outil externe … un compas magnétique. Cela nous permet de déterminer la direction à laquelle nous sums confrontés. La même chose est vraie avec notre téléphone.

Maintenant, le téléphone dispose également d’un accéléromètre à 3 axes. Je n’ai aucune idée de la façon dont ils fonctionnent, mais je conçois la gravité comme une «pluie» constante et uniforme qui tombe du ciel et imagine les axes de la figure ci-dessus comme des tubes capables de détecter la quantité de pluie. Lorsque le téléphone est tenu droit, toute la pluie passe à travers le tube Y. Si le téléphone pivote progressivement de manière à ce que son écran soit face au ciel, la quantité de pluie qui coule à travers Y diminue à zéro tandis que le volume à travers Z augmente progressivement jusqu’à ce que la quantité maximale de pluie coule. De même, si nous inclinons maintenant le téléphone sur le côté, le tube X finira par capter la quantité maximale de pluie. Par conséquent, en fonction de l’orientation du téléphone en mesurant la quantité de pluie qui traverse les 3 tubes, vous pouvez calculer l’orientation.

Le téléphone dispose également d’un compas électronique qui se comporte comme une boussole normale – son “aiguille virtuelle” pointe vers le nord magnétique. Android fusionne les informations de ces deux capteurs pour que chaque fois qu’un SensorEvent de TYPE_ORIENTATION est généré, le tableau de values[3] a
valeurs [0]: Azimut – (la boussole à l’est du nord magnétique)
valeurs [1]: Pas, rotation autour de l’axe des x (le téléphone est-il penché en avant ou en arrière)
valeurs [2]: Roll, rotation autour de l’axe des y (le téléphone est-il penché sur son côté gauche ou droit)

Donc, je pense (c.-à-d. Je ne sais pas) que la raison pour laquelle Android donne l’azimut (relèvement de la boussole) plutôt que la lecture du troisième accéléromètre est que le relèvement de la boussole est juste plus utile. Je ne sais pas pourquoi ils ont déprécié ce type de capteur car il semble maintenant que vous deviez enregistrer un écouteur avec le système pour SensorEvent de type TYPE_MAGNETIC_FIELD . Le tableau value[] l’événement doit être transmis à la méthode SensorManger.getRotationMasortingx(..) pour obtenir une masortingce de rotation (voir ci-dessous) qui est ensuite transmise à la SensorManager.getOrientation(..) . Est-ce que quelqu’un sait pourquoi l’équipe Android a déprécié Sensor.TYPE_ORIENTATION ? Est-ce une chose efficace? C’est ce qui est impliqué dans l’un des commentaires d’une question similaire, mais vous devez quand même enregistrer un autre type d’écouteur dans l’exemple development / samples / Compass / src / com / example / android / compass / CompassActivity.java .

J’aimerais maintenant parler de la masortingce de rotation. (C’est là que je suis le plus incertain) Donc, ci-dessus, nous avons les trois chiffres de la documentation Android, nous les appellerons A, B et C.

A = Figure de la méthode SensorManger.getRotationMasortingx (..) et représente le système de coordonnées du monde

B = Système de coordonnées utilisé par l’API SensorEvent.

C = méthode de SensorManager.getOrientation (..)

Donc, je crois comprendre que A représente le “système de coordonnées du monde” qui, je suppose, se réfère à la façon dont les emplacements sur la planète sont donnés en tant que couple (latitude, longitude) avec une option (altitude). X est la coordonnée “est” , Y est la coordonnée “nord” . Z pointe vers le ciel et représente l’altitude.

Le système de coordonnées du téléphone est illustré à la figure B est fixe. Son axe Y pointe toujours vers le haut. La masortingce de rotation est constamment calculée par le téléphone et permet une correspondance entre les deux. Ai-je raison de penser que la masortingce de rotation transforme le système de coordonnées de B en C? Donc, lorsque vous appelez la SensorManager.getOrientation(..) , vous utilisez le tableau de values[] avec des valeurs correspondant à la figure C. Lorsque le téléphone est dirigé vers le ciel, la masortingce de rotation est la masortingce d’identité (l’équivalent mathématique de 1) signifie qu’aucun mappage n’est nécessaire car le périphérique est aligné sur le système de coordonnées du monde.

D’accord. Je pense que je ferais mieux d’arrêter maintenant. Comme je l’ai déjà dit, j’espère que les gens me diront où j’ai foiré ou aidé les gens (ou confondu les gens encore plus loin!)

Vous pourriez vouloir vérifier le One Screen Turn Un autre article mérite . Cela explique pourquoi vous avez besoin de la masortingce de rotation.

En résumé, les capteurs du téléphone utilisent toujours le même système de coordonnées, même lorsque l’appareil est pivoté.

Dans les applications qui ne sont pas verrouillées dans une seule orientation, le système de coordonnées de l’écran change lorsque vous faites pivoter le périphérique. Ainsi, lorsque le périphérique est pivoté par rapport à son mode d’affichage par défaut, le système de coordonnées du capteur n’est plus le même que le système de coordonnées de l’écran. La masortingce de rotation dans ce cas est utilisée pour transformer A en C (B rest toujours fixe).

Voici un extrait de code pour vous montrer comment l’utiliser.

 SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE); // Register this class as a listener for the accelerometer sensor sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); // ...and the orientation sensor sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL); //... // The following code inside a class implementing a SensorEventListener // ... float[] inR = new float[16]; float[] I = new float[16]; float[] gravity = new float[3]; float[] geomag = new float[3]; float[] orientVals = new float[3]; double azimuth = 0; double pitch = 0; double roll = 0; public void onSensorChanged(SensorEvent sensorEvent) { // If the sensor data is unreliable return if (sensorEvent.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) return; // Gets the value of the sensor that has been changed switch (sensorEvent.sensor.getType()) { case Sensor.TYPE_ACCELEROMETER: gravity = sensorEvent.values.clone(); break; case Sensor.TYPE_MAGNETIC_FIELD: geomag = sensorEvent.values.clone(); break; } // If gravity and geomag have values then find rotation masortingx if (gravity != null && geomag != null) { // checks that the rotation masortingx is found boolean success = SensorManager.getRotationMasortingx(inR, I, gravity, geomag); if (success) { SensorManager.getOrientation(inR, orientVals); azimuth = Math.toDegrees(orientVals[0]); pitch = Math.toDegrees(orientVals[1]); roll = Math.toDegrees(orientVals[2]); } } } 

Le roulis est fonction de la gravité, un roulis à 90 degrés place toute la gravité dans le registre x.

La hauteur est la même, une hauteur de 90 degrés place toute la composante de la gravité dans le registre y.

Le lacet / cap / azimut n’a aucun effet sur la gravité, il est TOUJOURS perpendiculaire à la gravité, donc peu importe la direction à laquelle vous faites face, la gravité sera impossible.

C’est pourquoi vous avez besoin d’une boussole pour évaluer, c’est peut-être logique?

Regardez ceci: Stackoverflow.com: Q.5202147

Vous semblez être principalement droit jusqu’aux 3 diagrammes A, B, C. Après cela, vous vous êtes confus.

J’avais ce problème alors j’ai tracé ce qui se passe dans différentes directions. Si l’appareil est monté en mode paysage, par exemple dans une voiture, les «degrés» de la boussole semblent aller de 0 à 275 (aller dans le sens des aiguilles d’une montre) au-dessus de 269 (entre l’ouest et le nord). avance de 0 à 269. 270 devient -90

Still In landscape mais avec le dispositif sur son dos, mon capteur donne 0-360. et en mode portrait, il court 0-360 à la fois allongé sur le dos et debout en portrait.

J’espère que ça aide quelqu’un