Site ELEC344/ELEC381

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

Catégories

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 .

Matrix reloaded ...

Hier, fort de la lecture de différents articles et codes source, je me suis lancé dans le code du filtre de Kalman, sans pouvoir toutefois réellement le tester (mais il compile !). J’ai fait attention d’optimiser un peu les opérations sur les flottants même si on peut sûrement faire quelque chose de mieux ‘hardcore style’. J’espère aussi qu’une opération flottante avec 0 prend moins de temps qu’une autre !

Au total, une passe de mon filtre de Kalman prend environ 870 multiplciations, 950 additions et 9 divisions. Je n’ai pas encore relié ça rigoureusement aux temps d’execution qu’on a mesuré avec Etienne mais il semble me souvenir que ça devrait faire aux alentours de 5ms. Vu le temps de réaction et l’inertie de l’hélicoptère, je pense qu’on est bon de ce point de vue là.

L’objectif de la journée d’aujourd’hui était d’intégrer l’algo FQA (pour la résolution du problème de Wahba) et le filtre de Kalman pour pouvoir le tester. Seulement, pour faire ça, il fallait d’abord vérifier que l’algo FQA marchait bien, à l’aide du visualisateur 3D. Le protocole est simple: Le visualisateur récupère les valeurs du capteur sur la carte (envoyées par Bluetooth), execute l’algo en local  (pour eviter des problèmes supplémentaires …) et met à jour l’affichage.

Et là, ça a été trèèèèèèèèèèèèèèèès long (oui, une journée complète de 10h, je ne comprends toujours pas comment le temps a pu filer ainsi !) pour avoir le lien entre l’affichage et la matrice renvoyée par l’algo avec tous les problèmes de changements de base (carte->monde physique réél->monde openGL->représentation de la carte dans le monde OpenGL), de matrices transposées ou pas, bref !

Voyant que je pataugeais, Etienne D. m’a bien aidé pour essayer de voir les choses clairement et systématiquement et on est (visiblement !) arrivé à quelque chose de cohérent là-dessus.

Ce qui nous a permis de voir que l’algo FQA (ainsi qu’une version allégée que Miguel a codé en parallèle) ne marche pas très bien, vraisemblablement à cause d’un problème d’ordre de rotation. J’ai essayé aussi de reprendre l’algo TRIAD (qui n’utilise que des opérations vectorielles donc normalement exempt de ces problèmes d’angle) sans grand succès non plus…

Bref, c’est un peu une journée désespérante de ce côté là, heureusement qu’Etienne avait à côté des résultats positifs (et que Pulse aussi, derrière nous, on pouvait s’amuser à les pinger ou à les synflooder pour se détendre :P ).

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.

Résumé des jours précédents

Celà fait quelques temps que je n’ai pas posté, je vais donc résumer ce que j’ai fait ces derniers jours :

  • Vendredi : j’ai testé (toujours avec le simulateur en python à base de threads, queues, etc…) les derniers algorithmes pour l’initialisation de GLiP (choix de l’orientation, …) ; j’ai commencé à intégrer les différents algos, qui étaient testés indépendamment, dans un simulateur « global » pour voir les éventuels problèmes de transition entre les différentes étapes (temps d’attente, critère de passage à l’étape suivante)
  • Lundi : j’ai continué et fini la simulation globale, j’ai réfléchi à une façon de détecter les « faux voisins » (blocs séparés d’un vide, qui captent leurs signaux réciproques, cf post de Julie) mais ma solution n’a pas été retenue au final !…
  • Mardi : j’ai implémenté en C les mêmes algorithmes afin de les mettre sur les cartes mais de nombreuses questions sont encore en suspens (API pour l’envoi/réception de messages IrDA notamment)… Je me suis aussi renseigné sur la façon de générer un ID unique pour les blocs sans avoir à les programmer un par un : Alexis avait évoqué un identifiant unique pour chaque STM32 (décrit section 28.2 du manuel de référence) que j’ai essayé d’exploiter sur ma carte de TP. Ce fut un échec puisque je n’ai réussi à lire que des « 1″ dans le registre concerné. Après quelques recherches, je suis tombé sur ce post sur le forum de ST qui explique que seuls les micro-contrôleurs produits après 2008 exploitent ce registre. Sans être sur de moi, je pense avoir lu sur le chip que les notres ont été produits en 2009 donc on devrait pouvoir accéder à cet ID… À confirmer et, le cas échéant, ça serait une bonne façon de déterminer les ID de chaque bloc GLiP.

J-27 Host in translation

Alors comme je n’ai pas posté depuis 3 jours, voici un petit récapitulatif.

Jeudi : j’ai regardé un peu le code qu’avaient fait les autres et j’ai réfléchi à une architecture plus propre pour notre PID, plus facilement portable sur STM.

Vendredi : Comme j’avais tout bien dans la tête après avoir rêvé de PID, j’ai refait bien proprement et de façon bien modulaire le code de l’aservissement. Un point important et que j’ai bien fait attention à n’utiliser que les données des capteurs que l’on aura réellement, parce qu’avant, le temps d’établir le modèle d’asservissement, je considérai toutes les données que je voulais en « trichant » avec le simulateur ( position, vitesse, acclération, angle, vitesse, vitesse angulaire, accélération angulaire ). Cette première phase nous avait permis de bien mettre le doigt sur l’intérêt d’un double asservissement. Dans ce nouveau asservissement tout est doublement asservi en position et vitesse ce qui donne de jolis résultats.

Samedi : Auujourd’hui j’ai amélioré le code d’asservissement pour les angles, en particulier en faisant en sorte que la poussée des moteurs lors des inclinaisons continue à compenser la gravité. J’ai également réfléchi aux cas limites pour l’asservissement, quand il fallait le désactiver pour passer en mode « exceptionnel ».

Sur le simulateur j’ai ajouté quelques sorties et scripts gnuplot pour représenter de façon pratique la réponse de notre engin aux différentes commandes. Je pense que cela pourra être utlie lorsqu’on fera voler l’heliokter au début pour analyser les données de vol.

J’ai aussi commencé à regarder l’article sur Kalman pour bien rester en phase avec les autres. J’ai lu la documentation de Free RTOS. Normalement demain je vais essayer de compiler et benchmarker mon code sur le STM de carte de TP ( pour avoir une idée de ce qu’il donnera sur notre carte ) .

Simulateur !

Aujourd’hui j’ai continué à tester les différents algorithmes que nous avons mis en place pour l’initialisation de GLiP à l’aide d’un simulateur en python. Suite à la soutenance de mercredi, plusieurs parties de l’algorithme ont été reprises (cf wiki) et les étapes de ping, d’élection de leader et d’orientation des modules ont été simulées. Cela a permis de mettre en évidence quelques problèmes d’algorithmique qui ont pu être résolus.

J-30 Euler sous tous les angles

Aujourd’hui j’ai porté le double asservissement sur les angles pour améliorer un peu la stabilisation en assiette, sans grand succès.

Je suis encore en train de me dépatouiller avec les angles d’Euler, demain je vais reposer proprement sur un papier les formules pour m’éclaircir un peu les idées.

Travail du Weekend et Mardi

Le week-end dernier j’ai fini faire marcher le simulateur sur mon PC et j’ai commencé a lire plus sérieusement sur le filtre Kalman. Mardi j’ai travaillé sur Matlab, j’ai testé le filtre que F-X utilisé pour éliminer le gros bruit du accéléromètre. Maintenait je peut désigner n’importe quel filtre à partir des spécifications :  fréquence d’échantillonnage, atténuation dans la bande passante, atténuation dans la bande atténue et fréquences de coupure.

Finalement, j’ai récupérée le travail qui a été fait  l’année dernier dans le projet « Localisation GPS/IMU » sur le filtre Kalman, j’ai lu l’article que ils ont fait mais pour bien comprendre je suis entrain de lire leur source.

J – 31 : Welcome to the Matrix

Le code du simulateur a bien avancé, maintenant le double asservissement en altitude marche impeccablement.
De plus le simulateur peut maintenant sortir des « courbes » pour des paramètres choisis qui peuvent être affichées avec gnuplot (plot « nom du fichier »), c’est notamment comme ça que j’ai pu trouver plus rapidement les paramètres pour le PID et mettre le doigt sur certains bugs vicieux qui m’avaient bloqué pendant quelques centaines de minutes.
Petit avant goût ci-dessous :
Nous avons aussi discuté sur la façon dont nous nous répartissions les tâches d’ici samedi. Pour ma part je continue à améliorer l’asservissement (notamment en angle) et il faut que je demande à Alexis si il existe une façon de brancher un de nos télémètres sur une carte de TP pour adapter le code de l’ADC au périphérique en question.
Il faut également commencer à traduire le code d’asservissement en virgule fixe et inclure le modèle de réponse des moteurs dans le simulateur ( linéaire pour l’instant )

Un peu de python, ça ne mord pas

Derrière ce titre vaseux se cache le résumé de ces derniers jours…

Pendant ce week-end (essentiellement lundi), j’ai réfléchi aux différentes étapes à mettre en oeuvre pour initialiser GLiP : c’est à dire, à partir de blocs inutiles et plutôt moches, comment lancer une jolie animation (qui ne sera peut-être pas plus utile).

En intégrant le travail de recherche d’algorithmes de Julie, nous sommes arrivés à cette page du wiki, qui a été peaufinée au cours de la journée d’aujourd’hui au fur et à mesure où nous découvrions les imperfections.

Cet après midi, j’ai plongé au coeur de Python (grâce au ebook du même titre) pour coder un simulateur qui simulera (!) les différentes étapes de l’initialisation de GLiP. L’algorithme servant à orienter les blocs semble bien fonctionner, même en injectant quelques erreurs aléatoires dans les messages (même si le modèle d’erreur est plutôt douteux).