Site ELEC344/ELEC381

Partie interactive du site pédagogique ELEC344/ELEC381 de Télécom ParisTech (occurrence 2010).

Catégories

Contrôle 2010 ELEC344 : partie pratique

La partie pratique du contrôle 2010 d’ELEC344 est destinée à vérifier vos capacités à corriger des petits problèmes lors du développement d’une application embarquée et à suivre de saines pratiques d’ingénierie, le tout de manière autonome. Lisez bien l’ensemble des instructions avant de commencer.

Contexte

Un de vos collègues a tenté de faire le communication challenge, mais malheureusement il n’y est pas parvenu : il reste encore quelques bugs dans sa solution. Votre mission est de corriger ces problèmes afin que votre solution modifiée puisse aller jusqu’à l’étape 7 (comprise). Votre collègue vous assure qu’il n’est pas très loin du résultat correct et que les problèmes qui restent sont mineurs. Mais pouvez-vous le croire ?

La durée de l’épreuve n’est pas connue à l’avance : les enseignants vous diront lorsque celle-ci est terminée et vous indiqueront comment procéder au rendu. Votre dépôt doit donc être dans un état partageable à n’importe quel moment, avec un maximum de corrections appliquées à l’intérieur et au format attendu.

Déroulement du contrôle

  • Récupérez le code de votre collègue avec Mercurial depuis le dépôt « https://login@hg.comelec.enst.fr/elec344/CC_2010″ (où « login » doit être remplacé par votre nom d’utilisateur sous Unix).
  • Dans votre version du dépôt, créez une branche nommée à partir de votre nom de famille, avec, par exemple, la commande « hg branch dupont ». Tous vos commits devront se placer dans cette branche.
  • Corrigez les bugs dans le code afin d’aller jusqu’à l’étape 7 du communication challenge. Chaque bug devra donner lieu à un commit indépendant, qui contient uniquement le changement nécessaire à la correction du bug et un message approprié.
  • Rajoutez un watchdog de façon à ce que la carte reboote toute seule si le programme principal plante. Précisez, en commentaire dans votre code et en anglais, un moyen de tester le fonctionnement correct du watchdog.
  • À la fin du contrôle, nous vous indiquerons comment procéder au rendu du dépôt par la mise à disposition de votre branche.

Pénalités

Étant donné qu’un des buts de cet examen est de vérifier que vous pouvez suivre des instructions simples et claires, certaines erreurs donneront lieu à des pénalités, voire à une disqualification (0 sur la partie pratique) :

  • communication avec un autre étudiant (orale, écrite, électronique, ou toute autre forme) ou commentaire public sur l’épreuve avant qu’elle soit terminée : disqualification
  • commit dans une autre branche que celle nommée par votre nom de famille : disqualification
  • commit avec un nom ou adresse électronique incorrect (format obligatoire : « Prénom Nom <adresse.électronique> », avec une majuscule au prénom et au nom) : disqualification
  • commit contenant autre chose que la correction d’un unique problème : pénalité (vous n’aurez pas les points correspondant aux différents problèmes)
  • commit contenant des fichiers inutiles (fichier objet par exemple) : disqualification
  • commit ne corrigeant pas un problème : pénalité
  • push avant la fin officielle de l’épreuve : disqualification

Vous aurez donc peut-être besoin d’utiliser les commandes « hg status » (pour vérifier l’état de ce que vous êtes sur le point de committer), « hg rollback » (pour défaire le dernier commit si vous vous apercevez après l’avoir examiné avec « hg log -p -b nomdebranche -l 1″ qu’il est incorrect), « hg help » et « hg help command » pour l’aide.

Un protocole générique

Semaine du Vacances

Étant donné que on travaille avec le bluetooth ou avec le ZigBee pour établier la communication entre la PC et entre la carte du notre Heliokter ou avec l’IMU, donc j’ai commence à travailler sur un protocole de communication universel. Avec ce  protocole on aura la possibilité soit de recevoir ou envoyer des données au Heliokter en utilisant les mêmes fonctions quand on fait use de la communication par ZigBee ou par Bluetooh. Le protocole doit être générique du côte PC et du côte carte .

Au début de la semaine j’ai commencé à faire le protocole en utilisant la carte interface ZigBee. Cette carte à un module ZigBee et est relié à la PC directement. Après la remarque du Samuel sur la configuration de la carte j’ai réussi faire la communication avec la carte du TP.

Après j’ai commence à faire le codage des fonctions génériques dans les fichiers protocol.c et protocol.h et j’ai testé sur la carte su TP.

Vendredi et jeudi,  j’ai lu code de Fernando sur le i2c et on a travaille ensemble, surtout le vendredi,  pour trouver les erreurs de la communication i2c. Au début les fonctions de i2c bloquaient tout le système quand ils n’avaient pas de moteurs sur le bus. Après de regarder, en utilisant l’oscilloscope, les trames qui ont était envoyés  au ISL pour lire la température ou autres registres du ISL , on a trouvé que il avait des cas que n’ont était pas traités dans les interruptions.

Lundi 25  et Mardi 26

J’ai porté la communication par Bluetooth sur le protocole générique. Aussi avec Fernando on a réfléchi  sur les possibles erreurs du protocole du communication.

Nous avons pris comme référence le protocole de Mikrocopter pou faire la notre. Mais, on avait des problèmes quand le byte de fin de trame était présent en milieu de la trame.  La solution qu’on a pris est de utiliser le caratère de échappe ( ‘\’ ) pour identifier les données qui ont le même valeur qui le caractère du fin du trame et le même caractère du échappe.

J’ai fait les fonctions génériques pour le protocole, mais il fallait aussi modifier les fonctions du ZigBee et du Bluetooth, toujours des deux côtes : PC et carte.  Maintenait ça marche bien avec le bluetooth, pour le zigbee , avec Fernando, on a finit de faire le codage mais il  maque faire les test.

Heliokter bourdonne

J’ai passé la fin des vacances sur le filtre de Kalman, pour l’affiner/le corriger. Je me suis rendu compte avec la carte IMU que je ne prenais en fait pas en compte les gyroscopes et que je me basais seulement sur l’accéléromètre/magnétomètre (l’accéléromètre étant excentré par rapport au centre de rotation de la carte IMU, on s’en aperçoit mieux). Le modèle cinématique de mise à jour de létat en fonction des gyros était en fait légèrement erroné (une petite matrice par-ci …).

Bon bref j’ai réussi à regler tout ça et avoir des resultats corrects et sans lag.

Hier, on a commencé à intégrer tout le code et à contrôler les moteurs correctement avec l’I2C, mais je laisse les autres détailler, je n’etais pas là l’après-midi …

Et aujourd’hui, c’etait au tour de l’asservissement d’être integré dans le code et testé. Il a fallu évidemment faire face aux éternels problème d’orientation  (argh, la carte est à 45° par rapport à l’avant de l’Helico !) et d’angles, en passe d’être résolu ce soir.

Fernando et Miguel s’occupent d’un protocole de communcation par ZigBee ou Bluetooth (compatible avec celui de Mikrkopter) qui nous permettra de régler les coefficients du PID de manière dynamique (sans avoir à reflasher à chaque fois). Je leur laisse le soin de détailler.

Voilà une petite vidéo du rodéo actuel, avec un asservissement inexact et trop fort.

Serpentina : début de la semaine

Lundi : étant bloqué au nombre de tâches depuis la semaine dernière, j’ai cherché des solutions pour notre problème de blocage. Je savais que le code de l’année dernière avec notre bibliothèque ne marchait pas, alors j’ai essayé de trouver la bonne configuration de cette bibliothèque (en la comparant avec celle de 2009), mais sans succès. À la fin de la journée, Jon m’a aidé, mais aussi sans succès pour trouver la source du blocage. Ce qu’on a vu qui marchait c’était notre code avec la bibliothèque de 2009.

Mardi : après un OK de Sam, on a migré notre code vers la bibliothèque de 2009. Enfin, après à peu près une semaine bloqué dans le même problème (dans cette période on a pu faire d’autres choses en plus), on a pu continuer à dévélopper notre programme. J’ai travaillé aussi sur notre carte du TP pour coder un programme qui simule d’autres cartes du serpent (comme ça, on peu vérifier qu’un carte reçoit et envoie bien des données par le can). Par fin, les configs du zigbee et du convertisseur analogique-numérique ont été ajouté au code des cartes du serpent.

Mercredi : J’ai fixé des bugs du zigbee, et il semble marcher bien. Je l’ai synchronisé avec la carte du tp, et la petite carte arrive à recevoir des données. Bientôt les cartes seront soudées dans les vertèbres et on pourra faire des tests directement dans le serpent, en espérant qu’il va bien faire des mouvements.

Serpentina : jeudi et vendredi

Jeudi et vendredi derniers, moi et Flavia, on a travaillé sur la communication can de la carte du serpent (entre deux cartes du Tp, le can marchait bien). On ne savait pas la raison (on pensait aux interruptions), mais toujours il y avait quelque chose qui bloquait son exécution. Peu à peu, on a trouvé des morceux de code qui ne nous posaient pas de problème et enfin on a fini par bien transmettre des trames. Juste l’interruption pour la transmission ne marche pas mais on peu envoyer des données quand même.

Ensuite, on s’est lancé à la réception des trames can. Toujours, quand on activait toutes nos tâches, la carte se bloquait. Donc, on a essaie d’utiliser juste une tâche de réception. Après mettre beaucoup de temps pour bien configurer notre carte du Tp et faire des tests, la réception a bien marché avec des interruptions et des masques.

Pendant cette recherche des solutions pour la communication can, on a trouvé un autre problème (peut-être celui qui nous posait des problèmes pour le can) qui ne nous semble pas être simple : on est limité à lancer juste trois ou quatre tâches maximum (cela dépend de ce qu’on configure/initialise). On ne connait pas la raison (on a parlé à Sam, mais il ne le sait pas non plus), et on est maintenant bloqué dans cette partie.

J’ai essayé d’utiliser le code de l’année dernière (juste la configuration des clocks et des leds pour savoir si la carte se bloque ou pas) avec notre bibliothèque STM32 et notre linker, et le blocage continue.

Demain, je continue à chercher une solution pour ce blocage.

Bluetooth

Hier jeudi j’ai fait une API pour la communication Bluetooth entre l’IMU et un ordinateur en linux. Ça me permettra faire de traces des capteurs qui seront envoyés au simulateur en temps réel. J’ai testé l’API et ça marche bien.

D’autre côte, apparentement  la cause du problème de la rotation sur le tangage a été parce que le vecteur mesure du magnétomètre n’a pas été projeté sur les axes X-Y de la base de référence  avant d’être passé au FQA .

Wahba pour Kalman

Lundi

Après les larges lectures des articles sur Kalman, MAV, IMU que Alexis nos a donné maintenant je peut dire que je  comprendre mieux les choses. A début des lectures j’ai eu des problèmes pour comprendre mais après un coup d’œil aux cours de physique, probabilités, et autres aspectes commet les angles d’Euler et les quaternions les choses ont commencé à être plus claires.

Mardi

Les neuf variables d’état du filtre Kalman  sont les trois vitesses de rotation angulaire mesures pour les gyroscopes plus les deux colonnes de la matrice de rotation de la base du mobile à la base de référence. Ces colonnes de matrice de rotation son trouvés à partir du algorithme FQA. FQA prend les valeurs mesures par l’accéléromètre et magnétomètre et donné la matrice rotation. Après lecture de Wahba, FQA, et le code de Fernando on a vu il y a encore le problème de singularité quand le tangage c’est près de quatre-vingt dix degrés.

Mercredi

En cherchant résoudre le problème de singularité j’ai vu que on peut trouver les colonnes de la matrice de rotation sans passer pour les quaternions. Celui-ci utilise plusieurs opérations comme sinus et cosinus qui sont très couteuses. Ainsi, j’ai fait une fonction qui donne les colonnes de la matrice en utilisant le minimum des opérations. Avec F-X on testé sur l’IMU et on a un problème sur le tangage, quand on fait la rotation l’axe n’est pas constante. Il reste de résoudre ce problème et celui de singularité, on a besoin que le problème de Wahba soit bien résolu pour tester le filtre Kalman sur l’IMU.

J-23 La note du banc

Aujourd’hui j’ai compilé réussi à bien compiler mon code et à l’exécuter sur la carte de l’Heliokter en RAM et en Flash ( XIP ). J’ai pu débugger ma plateforme de bench ( quelques problèmes avec le timer m’ont ralenti, en effet il faut  déclencher un event quelconque pour que le Prescaler soit bien pris en compte ce qui m’avait échappé, et qui passe inaperçu avec de l’autoreload ).

Après quoi on a benchmarké rapidement avec FX quelques fonctions de math.h : float cos(float) versus double cos ( double ) , sqrt , addition , mulitplication de double. Ce qui lui permettra d’évaluer la vitesse de son filtre de Kalman et de décider entre float et double. Il a noté les résultats je lui laisse le soin de les donner, et on fera peut être un rapport plus poussé plus tard pour mémoire.

Pour l’exécution in place (XIP) j’ai pu faire des tests extensifs avec des traces issues des capteurs dans le simulateur ( 180 mesures environ ).  J’ai obtenu un temps d’exécution de 755 µs en moyenne environ. Ci-dessous un schéma résumant les résultats ( avec en axe des ordonnées les µs et en abscisse le numéro de la mesure ). Il y a quelques petites choses bizarres sur la fin, je pense que je dois changer ma méthode de mesure pour prendre en charge le changement de contexte avec une macro de FreeRTOS exprès , à vérfier, ce que je ne fais absolument pas pour l’instant et donc les mesures ne sont pas pures …

Nous avons aussi regardé avec FX quelques bugs qu’il y avait sur les changements de bases entre les données des capteurs, la sortie de wahba / Kalman et le monde réel.

Il faut toujours que je définisse des symboles dans mon code pour réussir à mettre en ram la partie du code à benchmarker et laisser en flash les jeux de test.

Filtres complémentaires : mission accomplie

Bon, suite aux travaux d’aujourd’hui, j’ai réussi à obtenir de très bonnes courbes. Notre problème d’offset sur les valeurs et de temps de réponse du filtre a été résolu en choisissant une valeur beaucoup plus grande pour la fréquence de coupure.

J’ai ensuite mis en place un benchmark assez complet : oscillation rapide, oscillation lente avec plateau ou non, oscillations rapides de demi amplitudes.

J’ai ensuite calibré le coefficient relatif entre l’accéléromètre et le gyroscope en utilisant des oscillations de différentes fréquence, l’un et l’autre se manifestant ainsi différemment. Le bon coefficient relatif est celui qui permet d’avoir une même mesure de l’angle pour des oscillations de fréquence différente.

Voici le graphique obtenu, avec en haut la commande d’angle donnée aux servomoteurs, et en dessous, l’inclinaison, calculée en degré, en fonction des données recueillie par les capteurs lors du mouvement. Le seul défaut que l’on peut constater est un angle calculé un chouilla en dessous de 0 lorsque l’on vient de remonter la carte (aucun soucis lorsqu’elle vient de descendre). Cela est probablement du à un petit défaut des servo vis à vis de la gravité, et n’est donc a priori pas lié à notre travail.

J’ai ensuite implémenté le nouveau filtre en C, modifié le code du gyroscope pour intégrer après filtrage (et non avant comme c’était fait), et créé deux fonctions get_angle_degree et get_angle_radian qui intègrent les bons coefficients.

Enfin, j’ai testé l’execution sur la carte de tout ça, envoyant via bluetooth le résultat de la commande get_angle_degree*100 (pour avoir de la précision malgré le cast en entier pour l’itoa).

J’obtiens des résultats à l’image de la simulation MATLAB, plutôt satisfaisants. Hormis pour le troisième type d’impulsion, ou ça ne colle pas. Ca n’atteint pas les 10°, et surtout, ça fait deux oscillations au lieu d’une.

Compte tenu que j’ai bien vérifié que le filtre et les données traitées (vitesse donnée par le gyroscope et accélération donnée par l’accéléromètre) sont exactement les mêmes je ne comprends pas trop. Si quelqu’un à une piste je suis preneur, en attendant, je continue à chercher…

Avancé gestion des paquets & crc

Aujourd’hui j’ai continué à configurer le module led pour les transferts de paquets complets. J’ai de plus nettoyé un peu le code qui à force de copier coller devenait très sale !

Les paquets sont donc complétement transmis et ce entre trois IrDA différentes en transmission-réception quasi simultanée donc la prise en charge du half duplex semble correcte. De plus, je me suis aperçu que pour l’instant et malgrè l’utilisation de réflexions, il n’y a aucune erreur de transmission donc c’est plutôt positif quant à la fiabilité des transmissions.

Enfin j’ai tenté de décrypter l’algorithme du crc et j’ai du mal à trouver un algorithme fonctionnel et bien détaillé (tous mes tests même à la main ne me donnent pas de résultat correct…) donc je suis toujours en train de coder quelque chose qui fonctionne !