mercredi 26 novembre 2014

Apéros-projets

Demain de 18h30-20h30, c'est les apéro-projets au fablab nantais PlateformeC.
J'y présenterai notamment le projet robokite.
N'hésitez pas à venir, c'est ouvert à tous!

Reconnexion automatique du port série entre arduino et python avec pyserial

Si jamais une connexion est ouverte entre l'arduino et un programme python utilisant pyserial et que je débranche le câble, je n'arrive jamais à me reconnecter ensuite à moins de rouvrir la console arduino.

J'ai cherché une alternative en ligne de commande à l'ouverture d'arduino.
J'ai d'abord trouvé la commande screen, qui permet d'écouter ce qui arrive sur le port série (entre autres) :

screen /dev/ttyACM0 57600.cs8

La commande suivante permet ensuite de fermer cette session
Ctrl + A + k

Une autre solution plus simple et de tapper la commande

stty -F /dev/ttyACM0 57600 cs8 cread clocal

J'ai finalement inclus cette commande dans mon script python, pas très beau et cross-platform, mais ça marche :
os.system("stty -F /dev/ttyACM0 57600 cs8 cread clocal")

J'ai le même problème de déconnection reconnection avec le joystick. Pygame qui utilise SDL 1.2 ne fait pas ça de base. Mais quelqu'un dit avoir trouvé une solution, mais sans l'expliquer... Rageant.


J'ai finalement trouvé la bonne alchimie, en faisant une reconnexion automatique si aucun mouvement du joystick n'a été envoyé dans les deux dernières secondes.
Le code python correspondant est .
Le code arduino est .

Difficultés avec arduino

Cet été, au moment de faire les tests sur la plage, plus rien ne marchait à un moment du test : impossible de faire fonctionner le programme arduino envoyant les ordres aux moteurs, alors que le code était inchangé et avait marché même au début du test.

Ayant eu un problème, je l'avais simplement rechargé sur la carte arduino et plus rien ne marchait.
Au dernier moment, juste avant d'abandonner, j'avais eu la bonne idée de tester avec la version 1.03 d'arduino que j'utilisais avant au lieu de la 1.05 que j'utilisais depuis quelques jours sur d'autres développements.

Et là, comme par miracle tout s'était mis à remarcher.

Suite à la confrontation à différents bugs sur les versions précédentes, je suis maintenant sur la version 1.6.0.

Et j'essaie simplement de reprendre un code qui a déjà marché... mais là de même plus rien ne marche.

Il est vrai que maintenant un message d'erreur s'affiche pour me signaler que la mémoire dynamique restante est faible et que je pourrais avoir des problèmes de stabilité...

J'ai d'abord ajouté des traces pour identifier l'origine du bug. Assez vite j'ai trouvé qu'il y a avait un problème dans la lecture des String reçus via la communication série. Un peu comme si la mémoire n'était pas allouée/modifiée.
Au fur et à mesure, j'ai essayé d'enlever du code pour arriver à la portion de code minimale levant l'erreur.
J'ai bien trouvé une erreur potentielle avec les dimensions d'un tableau qui était en dur. Mais même après la correction de ce bug potentiel, une erreur restait et qui ne semblait pas déterministe. En enlevant des lignes sans aucun rapport à différents endroits, cela corrige parfois le problème.

J'ai finalement testé sur une carte arduino mega, et là, plus de problème, ce qui montre bien que le problème ne vient pas vraiment du code, ou alors d'une fuite mémoire.

J'ai donc essayé de refaire le code à zéro, pour enlever éventuellement des fonctionnalités, et avoir un code plus léger, mais fonctionnel.

J'ai finalement réussi à trouver que le problème survenait lors de l'ouverture d'une communication avec Software serial.
 SWSerial.begin(9600);

Le problème arrive en rajoutant cette simple ligne dans l'exemple serialEvent. Si les bauds rate sont identiques, rien ne passe, s'ils sont différents, seulement quelques caractères.

Le software serial que j'utilise n'est cependant pas générique "mysoftwareserial" et le problème pourrait venir de là.

Pour rappel, j'ai du utiliser cette version de la bibliothèque modifiée à cause de problème de compatibilité avec les interrupts venant du codeur linéaire, comme expliqué ici.

Je vais essayer de voir s'il est possible de régler le problème. Dans l'immédiat, je devrais de toute manière être capable de faire une démo demain, juste en joystick, ou tout au moins sans boucle fermée sur le border-choquer.

Au passage, cela me permet de noter un problème de gestion de configuration, le code modifié n'étant pas commité. Mais aussi de m'autoféliciter d'avoir aussi bien documenté par ailleurs ;-).

Edit:
Le problème a fini par apparaître avec la librairie Software serial basique également.
En fait le problème vient du fait que la variable NOT_A_PIN était utilisée pour désigner la pin en réception, en mettant par exemple le port 10, plus de problème. Mais ça reste toujours mystérieux pour moi...

mardi 25 novembre 2014

Python et mavlink

J'ai pour l'instant fait quelques tests d'émission de message d'attitude avec Mavlink à partir d'un arduino connecté à une petite IMU.

Ces données sont envoyées par le port série, via un kit radio, puis récupérées sur un pc (mon pc en phase de développement,  puis un raspberry ensuite).

J'ai pour l'instant pu vérifier la bonne réception des trames avec QGroundControl.

Je souhaite maintenant recevoir les messages avec un programme python qui contiendra l'algorithme de pilotage et renverra des ordres en vitesse de moteur ou en position de barre.

Je me suis d'abord basé sur la documentation officiel

  git clone git://github.com/mavlink/mavlink.git
  cd mavlink/pymavlink
  python setup.py install

J'ai ensuite essayé de lancer un exemple (mavtester.py). Je suis malheusement tombé sur une erreur concernant le sous-module mavtest qui n'existait pas.

J'ai donc cherché à recompiler à partir de
  mavgen.py -o mavlinkv10.py mavlink/message_definitions/v1.0/common.xml

Cette fois j'obtiens l'erreur "No module named mavgen_python"

En fait l'erreur ne vient pas vraiment de là, mais de l'utilisation de mavgen.py au lieu de mavgenerate.py

Voici donc les bonnes commandes à exécuter :

  cd mavlink
  sudo python  mavgenerate.py -o mavlinkv10.py message_definitions/v1.0/common.xml

Cela lance une GUI permettant de choisir les messages à générer à partir d'un fichier xml de définition des messages.


A la fin de l'opération, j'ai eu un message me signalant que tout s'était bien passé.
Cependant, dans la console j'avais un message d'erreur, mais qui semble sans importance :

^CException in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__
    return self.func(*args)
  File "mavgenerate.py", line 172, in generateHeaders
    tkinter.messagebox.showinfo('Successfully Generated Headers', 'Headers generated successfully.')
  File "/usr/lib/python2.7/lib-tk/tkMessageBox.py", line 83, in showinfo
    return _show(title, message, INFO, OK, **options)
  File "/usr/lib/python2.7/lib-tk/tkMessageBox.py", line 72, in _show
    res = Message(**options).show()
  File "/usr/lib/python2.7/lib-tk/tkCommonDialog.py", line 48, in show
    s = w.tk.call(self.command, *w._options(self.options))
KeyboardInterrupt

Mais cela ne réglait pas plus le problème du manque de mavtest.

J'ai finalement modifié le script mavtester.py pour supprimer la dernière ligne qui était la seule à utiliser le module mavtest.

Le test se lance de la manière suivante
  python mavtester.py --device /dev/ttyUSB0

Mais le programme stoppait sur :

  Waiting for APM heartbeat

Cela ne fonctionnait pas, alors que des bits de vie étaient bien envoyés par l'arduino, ce que j'ai pu vérifier avec QgroundControl.

Etait-ce dû à un problème de version de la librairie (lors de l'installation avec setup.py, la version 0.9 et la version 1.0 sont copiées)?

J'ai cherché dans le code. mavutil.mavlink10() permet de vérifier si la version 1.0 est bien utilisée, et c'était le cas.

J'ai finalement trouvé l'erreur. Je n'avais pas précisé le baudrate dans la commande (il est par défaut à 115200).
Avec la commande suivante, j'arrive bien à revevoir le bit de vie.

  python mavtester.py --device /dev/ttyUSB0 --baudrate 57600

Un petit bit, mais qui fait toujours plaisir.

Le programme de test modifié est ici

Ptites news

KiteboatProject

De belles images de navigations à proximité ou sous le Golden Gate Bridge.

EPFL
Une nouvelle équipe s'intéresse au sujet de systèmes automatisés pour la production d'énergie à partir des kites.
Sean Costello, Grégory François et Dominique Bonvin ont déjà écrit un papier.
Voici également un article et la vidéo en lien.





Fotokite

Pour comprendre Fotokite, le mieux est de regarder la conférence TED donnée par Sergei Lupashin.


L'idée était dans l'air, mais c'est la première fois que je vois une réalisation ausssi aboutie. Il n'y a plus qu'à rajouter un peu de surface portante, et cela permettra d'avoir un hybride drone-cerf-volant.

Divertissement
Voici une vidéo d'un cerf-volant très rapide (lien partagé sur le forum AirborneWindEnergy, comme beaucoup de ces news).


R2/230 -2 from Andre Eibel on Vimeo.

Kitebot
Voici un lien vers quelques photos des avancées du projet DIY low tech kitebot. Des pièces de vélo sont utilisées pour réaliser un volant d'inertie avec un peu de béton.


FlygenKite
Voici un article plus tout récent sur le système flygenkite

Makani
Makani cherche à montrer que l'installation d'un prototype pendant  1 an ne sera pas un danger pour la navigation aérienne.


KUL
Un peu de transparence dans les financements européens, mais toujours peu de liens vers les résultats pour cette coquette somme.


ENSTA Bretagne
De nouveaux thésards sont arrivés, notamment Alain de Solminihac qui a réalisé son stage de fin d'études chez Kitegen à Turin. Plus de nouvelles bientôt j'espère.

lundi 24 novembre 2014

Raspberry Pi B+

Un raspberry pi est pour l'instant utilisé sur le projet robokite.

Quelques inconvénients devraient disparaître avec la nouvelle version B+.

D'abord le nombre de ports USB plus élevé (4 au lieu de 2) devrait permettre d'avoir à la fois le joystick, le module wifi et la connexion vers l'arduino, sans utiliser de hub usb supplémentaire. Le port USB restant pourrait même être utilisé pour faire tourner l'os, à la place de la carte sd qui était souvent corrompu (on trouve aujourd'hui des clés USB de plusieurs gigaoctets et à peine plus grande que le connecteur USB pour le même prix qu'une carte SD.

J'ai acheté le raspberry directement chez E44 electronique.

J'ai eu une petite surprise car je n'avais pas fait attention, que la carte SD a été remplacée par une carte microSD.

J'ai eu peur que cela pose un problème pour la mettre sur mon ordinateur, mais les cartes microSD sont en général vendues avec des adapteurs SD.

La procédure pour programmer la carte est donc théoriquement inchangée.

Malheureusement, la carte que j'ai flashée n'a pas fonctionnée (et n'est même plus reconnue sur mon PC). Il s'agit d'une carte SanDisk "HD video" de 8Go.

A suivre...

dimanche 23 novembre 2014

Tests mavlink

Afin de vérifier la qualité de la communication radio, j'ai essayé d'utiliser mavlink.

Voici l'idée : un programme tourne sur la carte arduino et envoie un bit de vie sur le port série.
Ce message est transmis en radio vers mon pc équipé de la carte RF sol. Je vérifie la validité des messages reçus.

J'ai essayé de suivre http://qgroundcontrol.org/dev/mavlink_arduino_integration_tutorial

Malheureusement, cette documentation n'est pas à jour, et des liens sont morts.

D'autres que moi ont déjà eu les mêmes problèmes, et j'ai essayé de suivre leurs conseils

http://diydrones.com/forum/topics/beginning-tests-using-mavlink

Après avoir appliqué ces conseils, j'avais ensuite de nouvelles erreurs à la compilation :
avr-gcc: error: unrecognized command line option ‘-assembler-with-cpp’

Cela vient de la nouvelle version du compilateur (dans ubuntu 14.04) qui n'est plus compatible avec les anciennes versions d'arduino.
Le problème a été résolu dans la version de développement d'arduino.

Malheureusement, d'autres erreurs arrivaient de nouveau.

J'ai finalement simplement enlevé la dépendence à FastSerial qui n'est pas indispensable.
J'ai également mis le chemin en dur vers mavlink.h

J'ai alors pu compiler, et voir passer les messages (codés) du bit de vie dans le "serialmonitor".

Afin de vérifier l'intégrité de ces messages, j'ai installé GGroundControlStation (installation très simple à partir des binaires).

QGroundControl a automatiquement détecté les messages arrivant sur le port série. Malheureusement la version du protocole Mavlink, ne correspondait pas, un message d'erreur fut affiché.

Finalement, j'ai repris le script de test et téléchargé le code source plus récent généré en C

L'include suivant était suffisant pour utiliser la bibliothèque.
#include "/home/bat/sketchbook/libraries/mavlink/ardupilotmega/mavlink.h"

J'arrivais ensuite bien à voir les messages dans QGroundControl (il faut pour cela aller dans Communication, ajouter la liaison série si elle n'est pas connectée automatiquement, et ouvrir la connexion).

Malheureusement, les messages s'arrêtaient systématiquement au bout d'un certain temps. Mais cette fois c'était ma faute, car je stockais le temps en ms dans un int (allant jusqu'à 32 767 ). Au bout de 32s, le programme se retrouvait donc bloqué...

J'ai également ajouté des messages fictifs d'attitude et de position. J'ai ainsi pu tester les outils de logs et de graphique en temps réels, ainsi que les possibilités de rejeu.

Le code pour l'arduino est là.

Attitude et trajectoire simulées et envoyées à partir d'une carte arduino connectée en série

Graphiques temps réels et inspecteur mavlink.



Open atelier

Jeudi c'est open-atelier à PlateformeC.

Et aujourd'hui, c'est déjà noël !

Je teste un nouveau kit de télécommunication radio, suite à l'essai d'un kit plus basique, mais dont les performances s'étaient révélées limites (mais pas testé en pleine puissance d'émission).
Cette paire doit permettre d'atteindre une portée de 1km, pour un prix de 47€ (contre 5 euros pour le kit précédent), et une utilisation très simple. Il s'agit d'un clone d'une autre carte dont la documentation est ici.

Le kit permet de remplacer le câble série utilisé avec un arduino.
D'un côté,  il y a un connecteur USB.
De l'autre côté, il y a 4 fils seulement, masse, 5v, RX et TX.
En sortant le kit de la boite il n'est cependant pas possible de le brancher puis de charger un programme sur la carte arduino, car par défaut la connexion est à 57600 bauds, alors que le chargement des programmes sur l'arduino se fait à 9600 bauds (je n'ai pas trouvé comment le modifier).

J'ai donc chargé l'exemple Analog/AnalogInOutSerial d'arduino et modifié le baud rate à 57600.

Voici les messages reçus (à une distance de 5cm...). On voit déjà que des parties sont perdues (1 ligne sur 5, environ). Plusieurs caractères sont perdus.

sensor = 268 oor = 267 output = 66
sensor = 269 output = 67
sensor = 269 output = 67
senso 67
sensor = 266 output = 66
sensor = 266 output = 66
sensor = 268 output = 66
sensor = 269 output = 67
sput = 67
sensor = 268 output = 66
sensor = 266 output = 66
sensor = 266 output = 66
sensor = 269 output = 67
tput = 66
sensor = 269 output = 67
sensor = 267 output = 66
sensor = 266 osensor = 269 output = 67
sensor = 267 output = 66
sensor = 266 output output = 66
sensor = 266 output = 66
sensor = 266 output = 66
sensor = 269 output = 67
sensor = 268 output = output = 67
sensor = 267 output = 66
sensor = 266 output = 66
sensor = 267 r = 266 output = 66
sensor = 269 output = 67
sensor = 269 output = 67

Il semble donc nécessaire d'avoir un mécanisme de vérification des messages.
Je vais donc essayer de faire des tests plus poussés avec des messages NMEA, ou des messages Mavlink.
Il semble aussi nécessaire d'intégrer un bit de vie (heartbeat) pour être capable de vérifier la connexion.

vendredi 21 novembre 2014

IMU

J'avais recommandé 2 IMU 10DOF chez Drotek, suite à la destruction d'une carte par une pile qui a explosé, puis coulé.

J'ai recommandé une carte identique pour pouvoir repartir de là où j'étais rendu, et une carte utilisant les derniers composants.

Les cartes étant livrées sans "pin header", j'ai d'abord soudé des connecteur coudées, aux contacts SDA, SCL, GND, 5V (en laissant de côté le 3.3V, les arduino nano et uno que j'utilise fonctionnant en 5V).

Malheureusement, les programmes restaient désespérément bloqués à l'initialisation avec les deux cartes. Dès le premier "write" le programme bloquait.

Dans le doute, j'ai utilisé une autre librairie  I2C ainsi qu'un programme de scan des adresses I2C.

Avec l'ancienne carte, même endommagée, j'arrivais bien à détecter le MPU6050, mais rien avec la nouvelle, comme si le fil de données SDA n'était pas connecté. J'ai pourtant pu vérifier avec un multimètre que les contacts étaient bons jusqu'aux pattes du circuit intégré.

Rien non plus avec la carte plus récente. Alors que je commençais à desespérer de n'avoir pu faire fonctionner aucune des deux cartes j'ai trouvé, en cherchant sur le forum de drotek, un poste expliquant probablement l'origine de mon problème sur la carte récente. La carte doit être modifiée si on veut utiliser le protocole I2C. Des "Pull up solder bridged' sont prévus sur la carte, comme on peut le voir sur le schéma de drotek (Points jaunes, oranges et rouges dans la vue "TOP").


Je n'ai pas trouvé d'explication sur la manière de faire ces soudures. J'ai donc essayé en chauffant au fer à souder, mais je n'arrivais pas à faire le contact. J'ai donc essayé d'amener un peu d'étain, mais là, catastrophe! Le plastique se mettait à fondre recouvrant les pastilles d'une couche isolante empêchant tout contact.

Etant incapable de réaliser le contact électrique, j'ai essayé d'enlever le plastique en chauffant de nouveau avec la pointe du fer à souder. Et là, les choses ont empiré, le plastique a complètement fondu, et les pastilles se décalaient lorsque je raclais avec la pointe du fer à souder.

A l'heure actuelle, je ne sais dire si cela est dû à un fer à souder trop chaud (je n'ai pas de contrôle de la température), une panne trop grosse, ma maladresse (bientôt légendaire), ou mon manque d'expérience.

Le problème est que je n'ai pas acquis plus d'expérience de mes erreurs... Que faire? Racheter une carte, renvoyer une des deux en SAV? Trouver une autre carte sans soudure à réaliser?

J'ai finalement commandé la version précédente de la carte.
Il n'y a effectivement pas de jumper à souder (mais toujours des pins). Un autre avantage est que le code proposé pour le MPU9250 n'était pas vraiment officiel, alors que la documentation sur le MPU9150 est plus importante.

J'ai aussi remarqué que l'accéléromètre et le gyro de la carte endommagée, fonctionnent encore (mais pas le magéntomètre et le capteur de pression).