Eloark miniature

Eloark, mon nouveau robot hybride Raspberry Pi & Arduino écrit en Python

Il y a presque un an je finissais Discovery, mon premier robot autonome. Le passage au hackathon Nao 2013 de la Cité des Sciences a considérablement changé ma vision de la robotique domestique : connexion à Internet, interaction avec son environnement et l’Humain. Construire mon nouveau robot m’a appris plein de choses 🙂

J’avais gagné un Arduino-compatible grâce à un concours DFRobot, gracieusement expédié par un revendeur français. Peu après Guillaume m’avait offert un Raspberry Pi B ainsi qu’un boîtier qu’il avait imprimé en 3D avec le matériel de sa boite. Il ne m’a pas fallu très longtemps pour savoir quoi en faire : lisez la suite pour le découvrir !

Définir les grandes lignes d’un projet est le moment le plus excitant : tout est possible. Faire un brainstorming avec soit même prend des semaines, c’est un moment de la vie où les idées fusent et se croisent à tout moment de la journée, surtout quand on n’a rien pour noter. Certains environnements sont plus adaptés que d’autres au développement de l’imagination et l’important est de vous y sentir détendu.

Concept initial

En terme d’objectif, je me suis inspiré de mon expérience sur Nao. À ce jour, j’aimerais beaucoup découvrir le framework libre de Darwin-OP que l’on devrait retrouver sur un dérivé nommé Jimmy. En attendant voici ce que j’ai dégagé pour mon proof of concept :

  • pilotage par le réseau à l’aide du protocole HTTP
  • interface web de contrôle à l’aide de joysticks virtuels tactiles
  • bouton de connexion permettant à un seul utilisateur à la fois de piloter
  • retour vidéo d’une webcam embarquée sur une page publique pour tous le monde

Et plus tard :

  • une page de statistiques (graphs de températures, uptime, load average, load en fonction du temps, …)
  • reconnaissance vidéo à l’aide d’OpenCV (suivi d’objets, de visages, …)
  • IA de pilotage automatique par reconnaissance vidéo
  • reconnaissance d’empreintes sonores à la Shazaam pour avoir des commandes en jouant des sons depuis un téléphone
  • text to speech pour signaler son état (IP, position, objets reconnus)
  • speech to text pour avoir des commandes vocales
  • amélioration de l’IA pour être capable d’apprentissage

Le code a été pensé dès le départ avec ces impératifs et découpé en modules indépendants exécutés dans des threads. Ce planning est prévisionnel et a encore le temps d’évoluer d’ici que je trouve le temps d’y arriver.

Pour y parvenir, j’ai choisi de placer toute l’intelligence du robot dans un programme exécuté sur le micro ordinateur embarqué. L’Arduino a pour rôle de faire ce qu’on lui dit et reçoit ses ordres du programme via son port USB. Le Raspberry Pi peut ainsi servir pour exécuter bien d’autres fonctionnalités : serveur Web, streaming de webcam, base de données et pourquoi pas une centrale domotique !

Liste de courses

Il faut tout d’abord se construire un châssis avec une plateforme roulante de votre choix. Moi j’ai réutilisé des Meccano de mon enfance mais j’ai aidé des amis à se servir de vieilles voitures radiocommandées. Si vous n’avez rien de tout ça chez vous, pas de panique : soyez inventif, allez sur un site de petites annonces et cherchez des occasions type robot aspirateur. Voici les composants dont je me suis servi :

  • Une variante de l’Arduino Leonardo appelée DFRobot Romeo v2. Elle a l’avantage de proposer une multitude d’interfaces pour connecter des servomoteurs, deux borniers moteurs ainsi que deux borniers d’alimentation externe pour moteurs et servos
  • une batterie de modélisme à connecter dessus
  • un servo moteur pour orienter une webcam
  • Un micro-ordinateur type Raspberry Pi B, assez puissant pour faire de l’encodage vidéo (matériellement en H264)
  • une batterie de rechargement USB possédant au moins deux ports USB, dont un de 1A et l’autre de 2A, par exemple une RAVPower 14000mAh
  • un hub à alimentation externe, par exemple un D-Link DUB H4, pour alimenter les périphériques connectés au Pi
  • un cordon USB A mâle vers DC 5.5×2.1mm pour alimenter le hub D-Link avec la batterie sur le port USB 2A
  • deux cordons USB vers Micro USB pour relier l’Arduino au Hub et le Raspberry au port 1A de la batterie
  • une webcam

Il est important de séparer l’alimentation du circuit informatique de celle du circuit « de puissance » car les moteurs provoqueront des appels de courant, et par conséquent des chutes de tension pouvant amener le circuit de commande à redémarrer aléatoirement. Voici de bons vieux schémas :

Eloark schéma électronique Eloark schéma informatique

Commencer par le début

J’aime beaucoup avancer par petites itérations. Installer le Raspberry Pi et écrire un programme Arduino basique sont les deux premières choses que j’ai faites. Cela m’a permis de tester le bon fonctionnement de mon matériel, batteries et moteurs. Paramétrer le Raspberry Pi en Wifi m’a demandé quelques recherches supplémentaires pour profiter des avantages du roaming et ainsi ne plus avoir à jongler entre mes différents points d’accès.

Puis j’ai commencé à faire des choix techniques. Ayant choisi de faire mon programme en Python, j’ai d’abord planché sur un moyen de piloter la carte Arduino. Cela se fait très simplement via la bibliothèque Nanpy, livrée avec un firmware à téléverser sur l’Arduino. J’ai fait un article séparé pour la présenter et la comparer avec les solutions alternatives utilisant le firmware Firmata.

J’ai ensuite réfléchi à la manière dont piloter la carte Raspberry Pi (qui pilote à son tour l’Arduino, vous suivez ? :D). Ce problème revient à se demander comment transmettre de l’information entre deux ordinateurs modernes, ce qui est relativement trivial. J’avais déjà bien assez de pain sur la planche pour me lancer dans la rédaction de mon propre protocole (même basique) qui aurait impliqué un client spécifique pour communiquer.

Au lieu de ça, j’ai choisi le bon vieux protocole HTTP pour mille raisons : implémentations à foison sur tout type de terminaux, support dans tous les langages, livré avec un langage de balisage et un langage de script qui permettent de créer très rapidement des interfaces, etc.

J’avais besoin d’une bibliothèque légère, très basique, simple à utiliser. J’ai choisi Bottle pour cette tâche. Là encore, j’ai rédigé un article séparé pour comparer les autres solutions trouvées.

Il m’a fallu trouver une base de données, car Bottle ne gère pas le stockage de session. La contrainte de travailler sur un système installé sur une carte SD sont les accès en écriture : ils usent le support et ralentissent le système. J’ai pris Redis principalement pour son stockage volatil en Ram : les écritures se font sur demande ou à la fermeture de la base. Le risque de perdre des données existe mais un robot ne manipule aucune donnée critique. C’est une base NoSQL de type clé/valeur, on y stocke donc des variables (hash compris) et c’est tout !

Pour finir, il me fallait pouvoir contrôler l’API que j’avais l’intention de créer (une simple URL retournant une page vide dont les paramètres transmettent la direction des moteurs à faire appliquer par le serveur) sur tout terminal supportant HTML5, tactile compris. Je me suis orienté vers virtualjoystick.js, une superbe petite bibliothèque de joysticks virtuels qui fonctionne parfaitement sur mon téléphone Firefox OS ainsi que sur PC à l’aide d’une souris. Comme à mon habitude, j’aime prendre le temps de comparer les alternatives, c’est chose faite.

La gestion du streaming vidéo de la webcam a été tranchée trop tardivement pour pouvoir être mise en place dans les temps. Il me fallait quelque chose d’intégrable dans une page web, transportable par HTTP. Peu de formats vidéo répondent à cet impératif. Voici le dilemme : vous avez une application qui s’ouvre dans n’importe quel navigateur, mais aucun standard n’impose le format vidéo:

  • OGV, libre mais inefficace en qualité et en poids ?
  • WEBM, touché par des brevets, Open Source mais plus gourmand ?
  • MP4, criblé de brevets mais souvent supporté matériellement ?

Pour avoir expérimenté avec un flux vidéo en 280p, l’encodage est quelque chose de très consommateur pour un processeur ARM11. Le Raspberry Pi n’en est tout simplement pas capable. En revanche il dispose d’une puce dédiée à ce travail, capable d’encoder/décoder du 1080p en MP4. Reste à trouver une application permettant de le réaliser, pour l’heure à ma connaissance seul le logiciel gstreamer sait le faire (API OpenMax). Hors c’est une telle usine à gaz qu’il m’a été impossible d’en comprendre le principe.

J’ai contourné le problème et me suis rabattu sur le format le plus universel à ce jour : le Motion JPEG (ou mjpeg), un flux d’images jpg indépendantes qui se remplacent les unes les autres dans la balise HTML img. Oui, c’est moche. VLC sait faire cela via son utilitaire en lignes de commande cvlc. L’inconvénient : il me semble que les images sont écrites sur le support de stockage au lieu d’être acheminées directement de la caméra sur le réseau. J’ai rédigé un billet entrant un peu plus loin dans le débat des formats vidéo pour HTML5.

Lancer des programmes externes et communiquer avec eux via un pipe se fait très bien avec le module subprocess de Python. À terme, OpenCV devrait venir s’intercaler entre la source vidéo et le flux streamé pour déterminer comment diriger le robot, comme l’illustre le schéma ci-dessous :

Schéma projet Eloark v1.0

Des tests au déploiement

On se retrouve vite à vouloir faire exécuter son programme par le Raspberry Pi plutôt que par l’ordinateur qui sert au développement. Plusieurs méthodes pour cela :

  1. coder directement sur les fichiers présents sur le Raspberry Pi au travers d’SSHFS (leeeent)
  2. coder depuis un ordinateur, pusher sur GIT, ouvrir un terminal et puller les révisions sur le Raspberry Pi
  3. coder depuis un ordinateur et utiliser un script « hook » post-push pour déclencher un pull sur le Raspberry Pi

J’ai jusque là exclusivement utilisé la seconde option, la troisième serait bien plus commode mais je ne vois pas comment la mettre en place sachant que l’IP du robot change selon les points d’accès Wifi.

Une fois en place, il ne reste qu’à gérer l’envoi d’un mail contenant l’URL de l’interface web pour faire d’une pierre deux coups : connaître l’IP de la machine et pouvoir tester l’interface web. Python le fait nativement en moins de dix lignes.

Dernière chose à ne pas oublier : automatiser le lancement du programme. Deux écoles : crontab et /etc/init.d/ j’ai choisi le crontab @reboot qui se lance à chaque démarrage du système d’exploitation.

Choix d’une licence

C’est la première fois que je distribue un Logiciel Libre. Libre de droit, libre de mon droit d’auteur. Proposer les sources ouvertes de ce projet est une démarche pédagogique, les proposer avec une licence permet à quiconque de les modifier, de les partager, de les vendre au travers d’une page dans un magazine, d’un blog contenant de la publicité. La licence que j’ai choisi pose quelques conditions à cela dont l’une est de conserver la paternité.

Poser un cadre légal pour quelques lignes de code n’est pas utile à proprement parler. Ce que j’ai créé existe en partie parce que toutes les briques que j’ai utilisé sont libres. Par contre j’aime beaucoup l’idée qu’une communauté puisse se former autour d’un projet, c’est pour cela que je tiens à diffuser la paternité du code : retrouver l’auteur originel pour discuter avec lui n’est possible que si tout le monde joue le jeu en passant le flambeau.

Choisir une licence est quelque chose de difficile, on peut remercier les auteurs de choosealicense et de Veni Vivi Libri. Je voulais quelque chose de permissif et simple à comprendre. La Simplified BSD License, datant d’avant la reconnaissance des brevets logiciels aux US, est une licence non copyleft en opposition à la GPL. J’aimais bien l’idéologie, mais je m’attendais à quelque chose moins brut de décoffrage, de plus sympa.

Je me suis attelé à mettre en place la CeCILL-B en anglais, la FAQ explique cela très bien. C’est une transposition de la philosophie de la Simplified BSD License en droit français, avec une préoccupation plus prononcée pour le respect de la paternité ainsi qu’un engagement du créateur qu’en cas de litige, 30j de délais seront accordés avant résiliation du contrat. Les licences CeCILL proposent aussi une version de la GPL et LGPL en droit français.

La première étape est de vérifier qu’aucune bibliothèque utilisée n’est publiée sous une licence incompatible (ex: une copyleft, qui interdit de sous licencier du code). Bottle, Redis-py et virtualjoystick.js sont sous MIT, une licence quasi identique à la Simplified BSD License. Il faudrait ensuite s’assurer la paternité et l’antériorité de l’œuvre en la protégeant de diverse façon décrites sur cette page. Merci aux auteurs de cette mine d’infos.

Bien que tout soit public sur Internet, ce que nous produisons peut être défendu par la juridiction française dans la mesure où le site causant l’infraction est accessible depuis la France et hébergé dans l’un des États membres de l’UE. En dehors, il appartiendra au pays du site fautif de reconnaître la juridiction française (indiquée par la licence CeCILL). Utiliser une licence garanti donc avant tout que vous concédez la libre exploitation de vos œuvres. Expliciter ses intentions est même une condition sine qua non à toute nouvelle production de Logiciel Libre : les entreprises ont besoin de sécurité.

Présentation des résultats

Voici finalement la raison d’être de cet article : le code source ! (on me souffle dans l’oreillette que le site est lent, n’en voulez pas à ma Freebox)

Guide d’installation : sur le lien ci-dessus vous trouverez un bouton « Download zip », dézippez, ouvrez une console, tapez « ./main.py », et voilà 😀 Visitez http://127.0.0.1:8080 et admirez. N’ayez pas peur de regarder le code, le Python se lit facilement.

J’ai réalisé trois vidéos durant le développement, à la suite sur cette playlist :

Ce n’était pas facile de filmer et de faire la démo en même temps, d’autre part je n’ai retrouvé chez moi que d’antiques batteries de modélisme qui n’avaient pas été entretenues pendant plus de sept ans. Le résultat n’est pas super réactif j’en conviens !

Pour aller plus loin

Je ne me suis pas tout de suite attelé à la gestion audio du port Jack en Python, mais il serait cool de pouvoir parler dans un micro qui soit émis dans des enceintes branchées sur le robot. J’ai listé en début d’article ce que je pourrais faire par la suite, il faudra patienter un peu.

Il me reste un tas d’applications à essayer, j’attends surtout vos réactions et vos sentiments sur ce projet pour glaner de nouvelles idées. À bientôt !

27 commentaires sur “Eloark, mon nouveau robot hybride Raspberry Pi & Arduino écrit en Python

  1. Félicitation pour cette réalisation. Combien de temps avez vous consacré à ce projet comprenant définition du besoin, recherche documentaire pour certaines briques de bases et le plus ingrat : l’étude et le choix de licences pour votre code ?
    Cordialement.

  2. C’est un projet que j’avais en tête depuis un bon moment, en fait j’ai commencé à y réfléchir lorsque j’achevais le robot précédent. L’idée a poussé jusqu’à la concrétisation matérielle.

    Les recherches aussi se sont étalées : à chaque nouvelle idée un nouveau dossier de marques pages dans mon navigateur.

    Le choix de la licence est une réflexion que j’estime « rigoureuse ». Faire du Logiciel Libre sans s’en préoccuper n’aurait aucun sens car cela limiterait son utilité aux codeurs du dimanche, là où associations et entreprises ne se le permettraient pas : quand on endosse la responsabilité des autres, on ne peut plus se fier à un inconnu imprévisible. C’est une considération juridique au contraire amusante à apporter dans un projet technique amateur.

    Cela aurait plus d’utilité si j’avais créé une bibliothèque ou un framework, ça va de soit, mais je souhaite prendre l’habitude de la démarche.

  3. Bonjour,
    Le temps que vous avez passé à la réalisation de votre projet serait une information utile qui je pense inciterait de nombreux développeurs. Personnellement, j’ai passé environ 50 heures à réaliser un petit projet java qui consite a piloter un robot (avec une raspberry pi, 4 moteurs et une webcam) depuis un smartphone android.
    Si vous avez passé par exemple 1000 heures cela représente 1000 heures de gagner pour votre prochain contributeur.
    Merci d’avance pour votre réponse,
    Roboart

  4. Bonjour, c’est bien difficile d’estimer le temps passé. En ce qui concerne l’architecture c’est tout bonnement impossible, il s’agit du résultat d’une réflexion occasionnelle, de prises de notes, d’idées spontanées. La réalisation concrète m’a pris trois semaines à raison de 2h par soir environ, mais j’avais opéré mes choix techniques antérieurement.

    J’ai été très ralenti par la réalisation du robot en lui même, qui suite à un défaut a dû être refait. Encore une fois, lorsqu’on sait où on va, ça va vite. L’estimation que je donnerais dépendrait de mon niveau d’aptitude, de ma capacité d’analyse etc. À vu de nez j’aurais dit 50h aussi.

    J’espère que ma réponse donne au moins le minimum d’info voulu 🙂

  5. Bonjour,
    Merci pour ce post, et ce partage! Beaucoup d’infos 😉

    J’ai essayé de faire tourner le code mais je rencontre quelques difficultés:
    j’ai bien upload nampy sur l’arduino uno, le raspberry et l’arduino connectés en USB , webcam usb. J’ai mjpg streamer, opencv, et tous les apps nécessaires dans votre tuto (python, redis, bottle, etc…).
    Voici mes problèmes, si vous avez une idée d’ou cela provient 😉
    1) quand je lance le main.py: Arduino link unreachable
    2) a la suite de ce message le script continue, et la, erreur:
    Traceback (most recent call last):
    File « main.py », line 19, in
    import globalConfig, robotControl, sendMail, videoProcessing
    File « /home/pi/projets/nodejs/eloark/videoProcessing.py », line 17, in
    process = subprocess.Popen( [« cvlc », « v4l2:///dev/video0 », « –sout », « #transcode{vcodec=MJPG,vb=500,width=352,height=288}:duplicate{dst=std{access=http{mime=multipart/x-mixed-replace;boundary=–7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:9090/webcam.mjpg}} »]
    File « /usr/lib/python2.7/subprocess.py », line 679, in __init__
    errread, errwrite)
    File « /usr/lib/python2.7/subprocess.py », line 1259, in _execute_child
    raise child_exception
    OSError: [Errno 2] No such file or directory

    J’ai essayé de regarder dans le fichier VideoProcessing, pour modifier la maniere dont on gère la vidéo, j’ai commenté et decommenté pour tester avec openCV, mais la resultat est different.
    La camera s’allume, mais mon terminal se remplit de caracteres bizzare, bip… et le serveur ne fonctionne pas…

    bref je n’arrive pas a le faire fonctionner.
    Y a til quelque chose de particulier a faire, que j’aurais raté?

    merci de votre aide et de votre partage d’expérience & code

  6. Bonjour ! C’était juste inespéré de voir quelqu’un y regarder d’aussi près, alors tout d’abord félicitations 🙂

    Le plus simple est de créer un petit bout de code Python qui permet de tester les liaisons quand ce genre de soucis survient. La première erreur que tu décris signifie que le client Python n’est pas parvenu à se connecter au serveur tournant sur l’Arduino. Plusieurs causes à cela, j’ai déjà vu :
    – un cordon USB< ->µUSB qui était uniquement capable d’alimenter, non pas de transférer des données
    – une instabilité du port USB du Raspberry, débrancher/rebrancher résolvait le problème

    On peut observer que la source de ce message provient du fichier robotControl.py (c’est moi qui l’ai écrit), et qui dit en substance que l’initialisation de la connexion série a échoué. Les méthodes SerialManager et ArduinoApi proviennent de Nanpy et permettent d’après mes souvenirs de choisir automatiquement le port sur lequel l’Arduino est connecté. Donc rien de spécial à faire normalement, sinon s’assurer que l’Arduino est bien sous tension 😀

    Les erreurs suivantes ne sont possibles que parce que j’ai eu recours à des threads : ces portions de codes s’exécutent indépendamment jusqu’à la mort du programme, ou à leur fin d’exécution naturelle. L’un de ces fils d’exécution (videoProcessing) créé un sous-processus qui lance un exécutable externe, cvlc, qui est simplement une version console de VLC, facilement scriptable. Ce programme ne vient pas avec VLC, il faut l’installer !

    Si cette dernière opération ne fonctionne pas, il se peut que ta webcam ne soit pas supportée par l’ordinateur qui exécute le code. Sur un PC x86/x64 pas de problème, mais les pilotes USB sur processeur ARM ont tendance à être buggés. Voilou, commence avec cette première réponse et tiens moi au courant !

    Quelle plateforme robotique as tu choisi ?

  7. Bonjour,

    Tout d’abord, félicitation pour votre travail ! Vous avez réussi là où je commence actuellement à me plonger : le retour vidéo et la commande joystick virtuel via un serveur web.

    Pourrais-je vous poser quelques questions? (je rencontre actuellement quelques difficultés pour mettre en place mes joysticks)

    En parcourant certaines pages internet, je suis tombé à plusieurs reprise sur le fameux fichier « joystick.js ». Étant (relativement) novice en programmation, j’aurai aimé en apprendre davantage sur ce fameux fichier, et notamment comment l’implémenter sur ma raspberry via mon serveur…

    J’ai actuellement installé raspbian (programmation en C). Ma raspberry héberge mon site web. Je suis parvenu à créer des curseurs en html qui gèrent la puissance de deux moteurs (mais l’envoi de données n’est actualisé qu’en appuyant sur un bouton « valider »). La transmission des informations est bien interprétée.

    Donc voici mes questions :
    1. Comment créer un serveur dynamique? (pas besoin d’appuyer sur « valider » pour transmettre les informations)
    2. Comment implémenter « jostick.js » sur ma raspberry/mon serveur? (il faudrait utiliser le makefile, seulement lorsque je l’éxécute, ma raspberry tourne pendant 2h voire plus et ne donne aucun résultat…) (autres pistes : il faudrait que j’installe node.js et npm…?)

    En espérant que vous puissiez m’éclairer sur ces différents aspects. Encore bravo pour vos travaux, et en attendant la publication de vos prochains éventuels projet, je vous souhaite une bonne continuation ! (si le miens aboutit, j’essayerai également de publier en open-source mes résultats !)

  8. Hé bien en soit, l’utilisation de virtualjoystick n’est pas compliquée, il y a de nombreux exemples proposés dans le dépôt https://github.com/jeromeetienne/virtualjoystick.js À mon sens le plus simple est de faire une boucle infinie avec un SetInterval (pour éviter de faire ramer le navigateur) et d’envoyer des requêtes AJAX périodiquement.

    Concernant tes questions (on peut se tutoyer !) je ne programme pas en C, je n’ai aucune idée de comment faire. D’habitude je cherche la meilleure bibliothèque pour ça et je m’en sers.

    Pour la question n°1 je ne suis pas certain d’avoir compris. Je pense que tu dois traiter les requêtes que tu appelles depuis le client, comme je te l’ai décrit. Dès lors tu pourras utiliser ce que tu auras transmit depuis les paramètres. Tu peux le faire en POST ou en GET, sachant que GET n’est pas fait pour ça mais que c’est bien plus simple à tester que du POST.

    Pour la question n°2, virtualjoystick est en JavaScript, c’est côté client. Il faut servir ce fichier en HTTP en plus de la page HTML, de sorte que le client puisse télécharger les deux.

    Je suis très content d’avoir des retours sur ce projet, merci à toi ! Dis moi si tu as d’autres questions 🙂

  9. Bonjour,

    Question 2. Alors avec un peu plus de pratique je peux confirmer que l’utilisation de joystick.js est un jeu d’enfant.
    Cependant j’avais un problème, plutôt idiot :
    Le répertoire dans lequel j’ai implanté mon serveur ne possédait pas les droit en lecture/écriture pour une machine externe à la raspberry.
    Grâce à ton post (si on peut se tutoyer..) et à cette phrase :
    « virtualjoystick est en JavaScript, c’est côté client »
    Cela m’a mis la puce à l’oreille. Effectivement la raspberry ne diffusait pas joystick.js car elle ne donnait pas le droit aux machines qui se connectaient au serveur de lire ce fichier joystick…

    solution : une simple commande « chmod a+ rwx » et le tour est joué (si d’autres sont dans mon cas..)

    Question 1.Concernant l’envoi de données du client au serveur j’ai programmé et modifié le code source de base de la page html fournit par jeromeetienne sur github. Je me suis inspiré de ton post. Tu parlais d’un certain « AJAX ». Je me suis donc renseigné et après 3-4h de lecture, test et écriture de lignes de codes, je suis enfin parvenu à créer LE code qu’il me fallait !
    Le client transmet bel et bien des valeurs sous formes de nombres vers ma raspberry. Cela me permet de contrôler un module hacheur+moteurs.

    NOUVELLE QUESTION – J’aurai à présent une nouvelle question. L’étape du joystick étant terminé, j’ai commencé la partie retour vidéo. J’ai actuellement créer un transfert d’une image par demi-seconde. Ce qui est très lent et la raspberry sature très vite…
    Aurais-tu des conseils à me donner? Quel type de flux as-tu utilisés?

    Un grand merci pour m’avoir répondu une première fois, et en espérant que tu puisses m’aider cette fois encore !

  10. Tu as l’air de surmonter tes difficultés avec succès jusque là, félicitations ! 🙂 Ça fait plaisir à lire.

    Concernant la vidéo sache que c’est le point que j’ai le moins travaillé et hélas ce que j’ai bricolé rame beaucoup aussi, je n’ai pas trouvé de réponse définitive à ce problème. Pour l’heure je lance un serveur web sur le Raspberry qui retransmet les images de ma webcam en HTTP et j’affiche ça dans ma page Web (c’est un flux mjpeg, c’est comme un jpeg mais en animé).

    Mais si c’est toi qui trouve, surtout partage le ici si ça te dit 🙂

  11. D’après les nombreux tutos et documents que j’ai pu lire là-dessus la meilleure option reste le flux vidéo par mjpeg.
    J’ai réussi à créer un flux via serveur avec ma raspberry, mais effectivement cela mange toute la RAM de la raspberry…
    Je vais tenter d’autres solutions pour essayer d’améliorer le flux quitte à diminuer la qualité (car en soit la raspberry B n’a que 250Mo de RAM ce qui nous limite également : peut être devrions nous investir dans un modèle 2 à 1Go de RAM…).

    Je mettrai à jour mon post pour les intéressés,
    Bonnes fêtes en attendant !

  12. Le challenge de l’embarqué c’est de devoir faire des sacrifices par moments, ou de travailler sur de l’optimisation. Pour ce problème, le mjpeg offre une qualité vraiment … dégueulasse, j’ai pas d’autre mot. Avec un Raspberry plus puissant en effet on pourrait se poser moins de question, mais c’est reporter la problème à plus tard : quid du traitement d’image ?

    Pour moi la meilleure solution est de faire traiter le flux par la partie de la puce dédiée à la vidéo (API OpenMax). Cela libérerait du CPU tout en permettant d’avoir un flux de plus haute qualité. Certains logiciels permettent de le faire, notamment gstreamer.

  13. Bonjour,

    Je viens aux nouvelles après plus d’un mois de travaux avec la Raspberry !

    Travail effectué————————————————————————————–
    • Un robot mobile
    • Autonomie 10 à 15 minutes
    • Contrôle via wifi (portée 10 mètres avec obstacles)
    • Contrôle sur serveur (lisible sur n’importe quel support (smartphone, pc,…) – requiert JAVASCRIPT et HTML)
    • Contrôle intuitif par joystick virtuel
    • Retour de 2 images par seconde sur le support de contrôle (smartphone, pc,..)
    • Possibilité d’exporter le serveur par internet (tests à l’appui)

    Amélioration—————————————————————————————–
    • Retour vidéo

    Piste pour amélioration—————————————————————————–
    J’ai récemment trouver un tutoriel qui a l’air très intéressant (je vous indique le lien ci-dessous). Il permettrait de générer un flux Streaming à partir d’une webcam connectée à une Raspberry.
    Les deux petits bonus : le flux vidéo pourrait s’intégrer dans une page web et être exporter sur la toile !

    Lien ————————————————————————————————–
    http://jacobsalmela.com/raspberry-pi-webcam-using-mjpg-streamer-over-internet/

    Ayant actuellement du temps libre je vais essayer de mettre en pratique ce flux vidéo sur mon site et ma Raspberry modèle B et je republierai un message pour tenir à jour ce post !

    Bonne continuation en attendant,
    Nadreoh

  14. Salut ! Merci pour ce retour (j’ai un peu traîné à répondre désolé !).

    Voilà un projet qui avance bien ! Je suis allé à peine plus loin, et la seule chose supplémentaire que j’ai apporté, c’est justement la vidéo MJPEG. Je déconseille, la qualité et la vitesse de rafraîchissement sont exécrables. Je n’ai pas mis en place de meilleure solution, alors ça sera difficile pour moi de conseiller plus, mais c’est très intéressant à étudier.

    Si tu (allons pour du tutoiement !) obtiens de bons résultats avec je suis preneur ! Car de mon côté, c’est à peine utilisable.

  15. Pas de soucis, je tiendrai à jour mon post. Quelques soit les résultats obtenus. Au moins pour guider les prochains utilisateurs !

    (d’ailleurs merci pour les réponses ! Peu de forums personnels sont tenus à jour comme celui-ci..)

  16. Bonjour,
    Très intéressant comme projet. Je pense me lancer dans quelque chose du genre pour ensuite le rendre autonome et un peu smart ^^. Une question, pourquoi ne pas avoir utiliser nodejs pour la vidéo et l’interfaçage? Les socket IO sont puissant et facile à mettre en œuvre.
    Merci en tout cas pour toutes les bibliothèques que je ne connaissais pas 🙂

  17. Salut Tuxtech !

    La réponse à ta question n’est pas technique : je cherche simplement à m’améliorer en Python ! NodeJS est une bonne technologie, effectivement plus adaptée pour faire du temps réel et mettre en commun le code du serveur et du client. Mais Python est si élégant !

  18. Salut à toi super boulot très intéressant ! Pourrais tu remettre le lien de telechargement il ne marche plus badgateway merci 🙂

  19. Merci beaucoup de me l’avoir signalé, ma base SQL a chaviré cette semaine et j’avais manqué ce service qui n’avait pas été redémarré 🙂 C’est tout bon, si tu as des questions je suis à ta disposition !

  20. Bonjour, et bravo pour ton projet et merci pour toutes les infos que tu nous donnes.
    Cela fait plusieurs jours que j’avance sur un projet semblable au tiens, et là je suis bloqué.
    La page html avec les joysticks s’ouvre bien sur mon PC, mais aucune commande n’arrive sur le raspberry, dans la fenêtre python. J’ai essayé en modifiant les requêtes coté PC (sous firefox) en remplaçant le port 80 par défaut par 8080 (port d’écoute de bottle) et là, les infos arrive bien dans le programme python.
    Donc, mes liens fonctionnent bien mais je n’arrive pas à envoyer des commandes sur le port 8080 et voir ma page web sur le port 80.
    J’ai essayer avec iptables de rediriger le port 80 sur 8080 mais je perd l’accès à ma page web, de faire du mirrorin du port 80 sur 8080 mais en vain !
    Comment as-tu procéder pour y parvenir ?
    Désolé d’avoir été si long et merci par avance.

  21. L’espace est infini, alors pourquoi se priver de messages longs ? 🙂

    Mh, alors dans un premier temps je crois comprendre que tu utilises le code source que j’ai open-sourcé, peux tu confirmer qu’il y a toujours une boucle infinie setInterval() qui créé des appels AJAX dans ton JS ?

    Si c’est bien le cas, tu as peut être modifié le code côté serveur (en Python) notamment le nom de la méthode appelée, si c’est le cas il faut changer l’URL appelée par le JS.

    Si tu as repris mon code, il y a un second serveur HTTP qui tourne sur le port 8080 (cvlc si je me souviens, pour la webcam). C’est donc bien sur le port 80 que tu dois interroger le serveur : l’appli Bottlepy gère tout !

    Dis moi si je t’ai avancé ^^

  22. Bonsoir, merci pour tes infos, j’ai pu « cibler » mon problème je pense.
    J’utilise ton code source et est comme tu l’a posté, je ne l’ai pas modifié.
    setInterval() est toujours présent dans la page index.html (et non js, est-ce normal ?)

    Coté serveur, je n’ai pas modifié de nom, mais il me semble bien que ma pages index.html n’arrive pas à « aller chercher » les méthode présentent dans main.py : @route(‘status’), @route(‘/controls…’) et les autres.

    Ma page index.html et les programmes python sont dans le dossier /srv/www/public.
    Le dossier vitualjoystick.js et les fichiers style.css et sripts.js sont dans le dossier assets.

    Merci pour tes infos, je ne désespère pas d’arriver à faire fonctionner mon robot ;

  23. Bonsoir, depuis le navigateur de mon PC, j’accède à ma page index.html à l’adresse 192.168.1.100:80 uniquement.
    Depuis le navigateur du raspberry, je n’accède qu’a la page d’accueil de nginx par défaut, pas à ma page index.html.
    De plus, est-il « normal » que lorsque je lance main.py sur le raspberry dans le terminal, je n’ai que ces 4 lignes qui apparaissent :
    – Arduino link correctly established
    – Bottle v0.12.7 server starting up (using WSGIRefServer())…
    – Listening on http://0.0.0.0.8080/
    – Hit Ctrl-C to quit

    Merci pour ton aide.

  24. Hello,

    Il faudrait qu’on en discute ailleurs car d’une part je ne reçois pas d’alerte lors de tes réponses (soucis technique) et d’autre part cela prendrait une éternité ! Vu que tu as repris mon projet en exemple je suis prêt à t’aider par téléphone, passe par le formulaire de contact du blog pour me laisser tes coordonnées si tu es d’accord 🙂

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont marqué du signe *