jeudi 24 décembre 2015

Notes sur la Sensor Fusion Demo d'Alexander Pacha

Cette très intéressante démo présente les différences de stabilité obtenues selon la source utilisé pour déterminer la position d'un téléphone.

Tous les capteurs du SDK d'android renvoient leurs données dans le système de coordonnées mondial dit main droite:

Axis globe
Dans ce système de coordonnées une rotation positive:

- selon l'axe X fait pointer le haut du téléphone vers le bas.
- selon l'axe Y fait pencher le téléphone à droite(sens inverse des aiguilles d'une montre)
- selon l'axe Z fait tourner le téléphone vers la droite.

Le code montre l'utilisation de getRotationMatrixFromVector et getQuaternionFromVector
SensorManager.getRotationMatrixFromVector(currentOrientationRotationMatrix.matrix, event.values);
// Calculate angle. Starting with API_18, Android will provide this value as event.values[3], but if not, we have to calculate it manually.
SensorManager.getQuaternionFromVector(q, event.values);
currentOrientationQuaternion.setXYZW(q[1], q[2], q[3], -q[0]);
Déjà comme le commentaire l'indique si l'on code pour une API supérieure à 18 on peut oublier l'appel à getQuaternionFromVector puisque event.values contiendra déjà les quatre réels (x,y,z,w) nécessaires à l'initialisation d'un quaternion.

De plus la matrice de rotation n'est pas utilisée plus tard donc on peut supprimer cet appel également et n'avoir que:
currentOrientationQuaternion.setXYZW(event.values[0], event.values[1], event.values[2], -event.values[3]); PS: je ne comprends pas la nécessité d'utiliser le négatif de event.values[3]
Dans la fonction getEulerAngles qui renvoient la position du téléphone sous la forme de trois angles d'Euler, on peut également supprimer la matrice de rotation et passer directement via le quaternion:
SensorManager.getOrientation(currentOrientationQuaternion.getMatrix4x4().matrix, angles); Lorsque l'on veut réaliser l'affichage du cube en OpenGL on va presque directement passer ces valeurs à la fonction glRotatef que l'on applique sur la matrice MODELVIEW. Quaternion q = orientationProvider.getQuaternion();
gl.glRotatef((float) (2.0f * Math.acos(q.getW()) * 180.0f / Math.PI), q.getX(), q.getY(), q.getZ());
Ceci est possible car glRotatef appliquée à MODELVIEW interprète les rotations à l'inverse du système de coordonnées de l'orientation du téléphone. Ainsi dans ce système:

gl.glRotatef(15, 1, 0, 0) fait pointer le téléphone vers le haut
gl.glRotatef(15, 0, 1, 0) fait pencher le télépone vers la droite (rotation dans le sens des aiguilles)
gl.glRotatef(15, 0, 0, 1) fait tourner le téléphone vers la gauche

La seule adaptation nécessaire au système de coordonnées opengl est la transformation du demi angle de rotation (en radian) stocké par le quaternion en un angle complet en degré: theta_deg = ((2 *half_theta_rad) * 180 / M_PI)
https://play.google.com/store/apps/details?id=org.hitlabnz.sensor_fusion_demo

Aucun commentaire:

Enregistrer un commentaire