Mesures à haute fréquence avec le Yocto-3D-V2

Mesures à haute fréquence avec le Yocto-3D-V2

Nous recevons régulièrement des questions sur l'obtention de mesures à haute fréquence avec le Yocto-3D et Yocto-3D-V2. Le principe a déjà été donné dans un article précédent, mais pour vous simplifier la tâche nous vous avons préparé un exemple concret.




Principe

La seule manière vraiment efficace pour récupérer des mesures à une fréquence élevée consiste à configurer le module pour qu'il envoie spontanément les mesures dès qu'elles sont disponibles via le mécanisme de fonction callback. Aucune autre méthode ne permet l'acquisition de mesures à des fréquences pouvant aller jusqu'à 100Hz avec les modules Yoctopuce.

Lecture de l'orientation à 100Hz

La manière la mieux comprise d'exprimer l'orientation est sous forme des angles de Tait-Bryan issus de l'aéronautique, décrivant l'orientation par rapport au nord (lacet), l'élévation (tangage) et la balance (roulis) par trois angles. Ce sont les angles que l'on peut obtenir à plus basse fréquence respectivement via les fonction compass, tilt2 et tilt1 des modules Yocto-3D et Yocto-3D-V2.

Pour les obtenir à haut vitesse, il faut procéder comme suit:

  1. définir 3 variables pour stocker la valeur courante des angles:

    static double _roll;
    static double _pitch;
    static double _head;

  2. définir la fonction de callback qui sera appelée aussi souvent que nécessaire par la librairie, et qui stocke les valeurs reçues dans les variables, pour qu'elles soient à disposition à tout moment:

    static void anglesCback(YGyro yGyro, double roll, double pitch, double head)
    {
        _roll = roll;
        _pitch = pitch;
        _head = head;
    }

  3. dans le code d'initialisation lors de la détection du module, activer le callback:

    YGyro gyro = YGyro.FindGyro(deviceSerialNumber + ".gyro");
    gyro.registerAnglesCallback(anglesCback);

  4. dans le code de l'application, ajouter un timer à la fréquence désirée (par exemple 100Hz) qui appelle la méthode YAPI.HandleEvents(), ou un thread qui appelle en boucle YAPI.Sleep(). C'est l'un de ces appels qui permettra le déclanchement des callbacks. Par exemple, une application graphique pourrait inclure le code suivant:

    private void RefreshTimer_Tick(object sender, EventArgs e)
    {
        string errmsg = "";
        YAPI.HandleEvents(ref errmsg);
        refreshUI();
    }


Lecture de l'orientation sous forme de quaternion à 100Hz

Bien que l'expression de l'orientation sous forme d'angles soit plus intuitive, elle a le défaut de présenter des singularités vers les deux pôles (lorsque le module est vertical). Pour éviter ces singularités, il faut utiliser à la place la représentation de l'orientation sous forme de quaternion. Vous pouvez aussi configurer un callback qui travaille sur le quaternion plutôt que sur les angles:

static void quaternionCback(YGyro yGyro, double w, double x, double y, double z)
{
    _w = w;
    _x = x;
    _y = y;
    _z = z;
}


Et dans le code d'initialisation:

YGyro gyro = YGyro.FindGyro(deviceSerialNumber + ".gyro");
gyro.registerQuaternionCallback(quaternionCback);


Ne nous demandez pas de vous expliquer comment s'utilisent les quaternions, il y a plein de sites sur internet qui vous expliqueront cela bien mieux que nous!

Lecture de l'accélération 3D à 100Hz

Pour certaines applications, il peut être souhaitable de recevoir les coordonnées du vecteur d'accélération à 100Hz. Avec le Yocto-3D ce n'est pas possible, mais avec le Yocto-3D-V2 ça l'est si on est prêt à renoncer à l'estimation de l'orientation.

Pour ce faire, il faut effectuer quelques opérations de plus à la configuration du module. Il faut en premier lieu affecter les fonctions qt2, qt3 et qt4 à l'accélération plutôt qu'à la représentation du quaternion. Pour d'obscures raisons techniques, cela se fait via un changement de nom logique:

YQt qt2 = YQt.FindQt(deviceSerialNumber + ".qt2");
YQt qt3 = YQt.FindQt(deviceSerialNumber + ".qt3");
YQt qt4 = YQt.FindQt(deviceSerialNumber + ".qt4");
qt2.set_logicalName("ax");
qt3.set_logicalName("ay");
qt4.set_logicalName("az");


Ensuite, il faut configurer le module pour supprimer le filtrage sur l'accéléromètre de sorte à ce qu'il retourne le maximum de mesures, même si elles sont un peu bruitées:

accelerometer = YAccelerometer.FindAccelerometer(deviceSerialNumber + ".accelerometer");
accelerometer.set_bandwidth(100);


On définit un callback qui recevra les coordonnées du vecteur d'accélération:

static void accelCback(YGyro yGyro, double w, double x, double y, double z)
{
    _ax = x;
    _ay = y;
    _az = z;
}


Finalement, on active ce callback de vecteur d'accélération comme s'il s'agissait d'un quaternion, puisque c'est par les fonctions Qt que les valeurs vont arriver:

YGyro gyro = YGyro.FindGyro(deviceSerialNumber + ".gyro");
gyro.registerQuaternionCallback(accelCback);


Un programme d'exemple complet

Si vous voulez voir ce que cela donne dans la réalité, vous pouvez ouvrir le nouvel exemple intitulé Prog-3D-Callback dans la librairie C#. Il s'agit d'une petite application graphique qui permet de voir la fluidité obtenue par les callbacks à haute fréquence, et de mesurer le nombre de valeurs différentes reçues par seconde.

Interface du programme d'exemple
Interface du programme d'exemple



Rappelons pour conclure que même s'il est possible d'obtenir ces coordonnées du vecteur d'accélération à 100Hz, il s'agit de valeurs assez bruitées et il est illusoire de penser pouvoir intégrer ce vecteur pour en estimer la vitesse: le cumul du bruit ne convergera pas. Par conséquent, il serait carrément naïf d'imaginer intégrer cette mauvaise estimation de la vitesse pour en calculer une estimation de la position: cela ne marchera pas !.

Commenter aucun commentaire Retour au blog












Yoctopuce, get your stuff connected.