NAO, robot d’accueil du CFAU

robot-humanoide-programmable-nao-evolution-rouge

Sommaire

Introduction

 

A PROJET : Présentation des Formations

 

I   Le Robot NAO

 

Ses caractéristiques

Chorégraphe

Création du dialogue

 

II L’outil développé

 

Les méthodes développées

Un premier programme en version console

La version avec interface graphique

 

B PROJET : Déplacer Robotino avec NAO

 

I Le Robotino

 

Ses caractéristiques

Le programme Robotino-view

Le simulateur

 

II Comment communique NAO avec Robotino ?

 

Récupération d’une trame

Décomposition de la trame

Lire automatiquement une trame reçue

Écrire « automatiquement » une trame

Code de déplacement

Step1

Step2

Le programme Python

 

III Début de programmation du robot NAO

 

Les diagrammes blocs

Conclusion

Introduction

Le projet avec le robot NAO se décompose en deux parties.

La première consiste à aider lors de portes ouvertes ou lors de salons d’orientations (comme La journée des carrières à Mulhouse ou Le salon de l’emploi et de la formation à Colmar) les jeunes visiteurs à trouver une formation pour leurs poursuites d’études. Le robot appartenant au CFAU, il ne présentera en toute logique que les formations administrées par le CFAU.  Comme son nom l’indique le CFAU, Centre de Formation d’Apprentis Universitaires, ne gère que des formations en université, allant du DUT au Master en passant par le DEUST(niveau bac+2) ou le Diplôme Supérieur de Comptabilité et de Gestion (niveau bac+5), soit plus de 111 formations en Alsace.

La seconde partie du projet consiste à déplacer NAO dans le bâtiment B du département GEII de l’IUT de Mulhouse afin qu’il puisse en faire une visite guidée. NAO, se déplaçant sur pieds, est trop lent. C’est pourquoi nous l’installons sur un autre robot à roues. Dans cette partie nous programmons donc deux robots différents, le NAO et un Robotino commandé par NAO. Cette partie n’a pas été menée à terme contrairement à la première.

A PROJET : Présentation des Formations

I Le Robot NAO

Ses caractéristiques

 

En allant sur cette page, https://www.ald.softbankrobotics.com/fr/cool-robots/nao , vous en saurez beaucoup.

Mais allons à l’essentiel:

-NAO est un robot constitué d’une multitude de capteurs, de moteurs et de logiciels pilotés par un système d’exploitation sur mesure : NAOqi OS.

-Il possède 25 degrés de liberté , et une centrale inertielle qui lui permet de garder son équilibre, de savoir s’il est debout ou couché.

-NAO est équipé de deux caméras qui filment son environnement et lui permettent reconnaître les formes et les objets.

-Il peut accéder à Internet de manière autonome, avec le Wifi ou en Ethernet.

-Il peut entendre et parler à l’aide  de ses 4 micros directionnels et hauts-parleurs.

Et c’est avant tout cette dernière spécificité qui nous intéresse. En effet Nao doit pouvoir nous répondre lorsque l’on s’adresse à lui.

Chorégraphe

 

C’est à l’aide du logiciel Chorégraphe, développé par Aldebaran (société Française, à l’origine du robot NAO rachetée par SoftBank Robotics Europe en 2015), que l’on programme un robot NAO.

Environnement chorégraphe
Environnement chorégraphe

Sur cette capture se trouvent tous les onglets nécessaires.

ProjectContent: On comprend naturellement que cet onglet concerne tous les fichiers qui sont utilisés pour le projet.

Box librairies : Cet onglet contient une multitude de fonctions réalisables par le NAO. Comme lui faire dire quelque chose, le faire marcher, se lever, allumer des voyants ou réaliser des calculs.

Root : Cet onglet présente une version graphique du programme de notre robot NAO. Un programme NAO est composé de box comme celles qui sont visibles sur la capture.Les box peuvent être:

  • Des « Diagram Box », c’est à dire une box contenant d’autres box.
  • Des « Python Box », contenant du code en python, puisque NAO interprète ce langage(ainsi que le C#).
  • Des « Timeline Box », permettant de programmer une série de mouvement du robot.
  • Des blocs de fonctions , ceux que l’on trouve dans l’onglet Box librairies.
  • Des « Dialog Box », permettant comme son nom l’indique de programmer des dialogues.

Log viewer : Cet onglet est comme un banquier, si il vient vers vous c’est rarement bon signe. C’est un onglet de débogage. Si une compilation échoue, c’est ici que vous verrez pourquoi. Il est explicite.

Daliog : Cet onglet permet de communiquer avec NAO. À son démarrage Chorégraphe lance un NAO virtuel. Évidemment celui-ci n’a pas de micro, alors pour dialoguer avec lui on utilise cet onglet. Cet onglet sera l’un des deux onglets les plus utilisé.

Robot view: Cet onglet permet de connaitre la position du robot (robot virtuel et véritable NAO). Il affiche aussi ce que dit le NAO.

Script Editor: Cet onglet permet d’éditer tous les fichiers sous forme de texte propres à Chorégraphe, tel que les codes de bloc fonctions, bloc python, et surtout les dialogues. Cet onglet sera le second onglet le plus utilisé.

Le programme actuel du Robot NAO est extrêmement simple puisqu’il  n’est composé d’uniquement deux box et de deux liaisons. De plus il ne contient pour le moment qu’un seul fichier de dialogue. Il est possible que par la suite il y ai deux à trois « Dialog Box » supplémentaires. La box « Formation »(voir capture la capture d’écran qui suit) ne traite que les DUTs pour le moment. Peut être d’autres box serons utilisés pour les licences et les Masters.

Programme NAOjpg
Programme actuel du NAO

Création du dialogue

 

Pour la réalisation du dialogue, il est difficile d’imaginer la quantité d’information à traiter. A titre d’exemple, il n’y a que 16 DUTs en alternances contre 49 licences et 41 Masters. Et à l’heure actuelle le dialogue n’a été réalisé que pour les DUTs, ce qui représente tout de même une centaine d’échanges. En effet bien qu’il n’y ai que 16 DUTs, il faut trouver un moyen de les distinguer pour ne pas avoir à tous les énoncer d’un coup. Par exemple, j’ai pris comme critères « Industrie » (6 formations) , « Gestion »(5 formations), et « autre » ( 5 formations). Ainsi il n’y a que trois paragraphes principaux à générer. Ensuite on présente les formations par ville. Ce qui donne une sorte d’arborescence dans la conversation, comme vous pouvez le voir dans capture suivante:

Arborescencejpg
Extrait du dialogue programmé

L’extrait peut être téléchargé  ici en .docx .

Dans cet extrait apparaissent des tags sous la forme %NOM. Ces tags permettent le passage d’un niveau à l’autre de la conversation lorsqu’on ne suit pas un ordre « naturel ». J’entends par là, lorsque que notre interlocuteur souhaite finalement non plus parler d’industrie mais de gestion. Ou par la suite lorsqu’il voudra parler de licence plutôt que de DUT. Ces tags peuvent être rejoins à l’aide des commandes ^goto et ^gotoReactive . La première sert à rejoindre une partie du dialogue qui ne fait pas partie de son arborescence (Lorsqu’on parle de l’industrie puis on veut parler de gestion). La seconde sert a retourner à une partie du dialogue de son arborescence  (un dialogue en u5 peut rejoindre un dialogue en u4  si ils descendent du même dialogue u3). Ces nuances sont probablement difficiles à saisir, mais elles se comprennent très naturellement dès lors qu’on les utilises.

Un dialogue comme celui-ci est très long à réaliser. Malgré tout, c’est une tâche réalisable car il n’ y a que 16 DUTs. (voici le dialogue DUT complet, Le texte étant brut, il n’a pas pour but d’être lu intégralement, mais de démontrer la difficulté à réaliser un dialogue).

En revanche, il y a 49 licences et 41 Masters. Pour les différencier, il faudrait étudier chaque intitulés de formations et compter le nombre d’occurrence des domaines. Un travail conséquent si il devait être réalisé à la main. C’est pourquoi des fonctions, puis finalement une application ont été développés pour accélérer l’étude des formations.

La version actuelle du programme, testable sur chorégraphe (version d’essai à télécharger*) est disponible ici.

*Inscription nécessaire

II L’outil développé

 

Les formations et leurs intitulés sont visibles ici. Elles ont toutes été recopiés dans un fichier CSV que voici.

Ce format a été choisi car les formations sont  sous forme de tableau sur le site du CFAU, de plus python comprend de base une librairie lui permettant de traiter ce type de fichier. Python est utilisé car NAO lui même utilise ce langage et les fonctions ont étés initialement écrites pour lui (mais cette stratégie a été abandonnée).

Le terme fonction est utilisé en langage C et est très parlant. C’est pourquoi je l’ai utilisé jusqu’à maintenant. Mais le vrai terme en python est méthode. La suite de ce document traitant de code python, nous n’utiliserons donc plus le terme fonction, mais bien méthode.

Les méthodes développées:

 

conversion (filenameSource,filenameDestination) : Elle permet de convertir un fichier CSV en fichier TXT

filtre (filenameDestination): Lors de la conversion, des caractères inutiles apparaissent , tel que « ; ». Cette fonction permet de les supprimer.

trie (string,filenameSource,filenameDestination): Lorsqu’on envoie une chaine de caractères à cette fonction, celle ci va chercher dans le fichier  Source  si pour chaque lignes (1 ligne = 1 formation) la chaine s’y trouve. Auquel cas, elle écrit dans le fichier Destination la ligne contenant la formation. En résumé cette fonction permet de trouver chaque formation contenant cette chaîne.

triebarre (string,filenameSource,filenameDestination): Cette méthode n’inscrit dans le fichier Destination que les lignes ne contenant pas la chaine de caractères, à l’inverse de trie.

copie (filenameSource,filenameDestination) : Cette méthode est appelée a la fin de trie et triebarre. Le fichier Source est écrasé pour être la copie du fichier Destination.

txtcount (filename): Cette méthode donne le nombre de ligne dans le fichier Destination après un trie ou triebarre.

csvcount (filename): Cette méthode donne le nombre de ligne dans le fichier « listedeformations.csv ». Ce nombre est nécessaire à la génération du premier fichier Source.

NbOccurence (string,filenameSource): Cette méthode permet de savoir combien de fois on retrouve la chaine envoyée dans un fichier source (à ce niveau fichier Source et Destination sont identiques). Sa fonction première est implémentée dans l’outil final. Mais cette méthode pourrait aussi être utilisée pour ne pas faire rater une recherche avec un mot qui ne serait pas présent dans le fichier CSV (imaginons qu’on envoie « sethdfv » à trie, alors les fichiers Source et Destination seraient vide). Ce n’est pas encore implémentée dans l’outil final.

Ainsi, si on appelle les méthodes trie ou triebarre plusieurs fois de suite (sans rappeler la fonction conversion entre temps) on peut trier le fichier d’origine avec plusieurs mots. A titre d’exemple, si on veux avoir tout les DUTs de l’industrie mais où il n’y pas d’informatique, on appellera deux fois la méthode trie et une fois triebarre ( l’ordre n’a aucune importance) et copie sera appelée 3 fois (la dernière ne servira que si l’on souhaite encore affiner la recherche avec un quatrième appel de trie ou triebarre). Il serait trop compliqué de réaliser une méthode réalisant le tout en une fois. Pour une nouvelle recherche, il suffit d’appeler conversion.

D’autres méthodes pour le traitement du document CSV ont étés développées. Mais n’étant pas gardées pour l’outil final, elles ne seront pas détaillées ici.

Un premier programme en version console

 

Ces codes ont été réalisés avec l’IDE Spyder. Spyder, avec un interpréteur, nous permet d’exécuter nos codes sans les compiler (comme on le ferait dans un autre langage), puis d’interagir avec, comme lui envoyer des mots. C’est très pratique.

Environnement Spyder : Sur la droite , le code en python, sur la gauche l'interpréteur avec qui on peut interagir
Environnement Spyder : Sur la gauche , le code en python. Sur la droite, l’interpréteur avec qui on peut interagir

Mais dès lors qu’on désire effectuer de nombreuses recherches, interagir avec l’interpréteur n’est plus aussi pratique. Pour mieux comprendre, nous allons étudier la capture précédente.

Spyder - Copie

Le code sur la gauche a été interprété (sorte de compilation ne générant pas de fichier .exe) après avoir pressé la touche F5 . Sur la partie de gauche est alors apparu dans le champ encadré en rouge avec le terme « Critères : »

J’y ai écris « DUT » , ce qui a affiché le champ encadré en bleu. txtcount nous apprend qu’on a 16 formations répondants à ce critère.

Par la suite j’ai écrit « industrie ». Malheureusement ce mot s’écrit Industrie dans le fichier Source. Il n’a donc pas été trouvé dans le fichier, on obtient alors le champ encadré en vert. Comme nous l’indique txtcount avec le 0, notre fichier destination est vide.  Cette situation aurait pu être évitée en utilisant NbOccurence comme garde fou.

Le programme demande alors si on veut effectuer un nouvelle recherche comme on peut le voir dans le champ encadré en orange. Tant qu’on ne renvoie pas « NON » , une nouvelle recherche est lancée , mais en repartant depuis le début. C’est là qu’apparait la limite de la version « console » de ce programme. Dans ce cas ce n’est pas très grave puisque qu’un seul critères a été entré. En revanche si il avait fallu travailler sur les licences, plus de critères sont nécessaires, mais aussi plus de recherches différentes (plusieurs combinaisons différentes de mots).

Le champ encadré en mauve, montre simplement la même recherche sans erreur.

De manière générale ces méthodes sont très utiles , mais ne sont pas pratiques sous cette forme.

Vous pouvez les retrouver ici.

La version avec interface graphique

 

La solution  pour rendre ce programme plus pratique a été de développer une interface graphique pour utiliser toutes ces méthodes.

J’ai choisi de travailler avec Tkinter, une librairie python permettant de programmer un environnement graphique. L’avantage est qu’il est aisé de trouver de nombreuses ressources sur cette  librairie, et même en français.

Dans un premier temps, j’ai dessiné sur papier la disposition générale que je désirais pour mon application. Assez vite j’ai codé cette disposition avec Tkinter. L’application est découpée en 5 panneaux qui sont:

  • Parcourir ( ne fonctionne pas pour le moment) , permettra de choisir le fichier à analyser. Actuellement , l’adresse du fichier est inscrite dans le code du programme.
  • L’insertion des mots clés, où l’on précise si on doit garder ou supprimer les lignes contenants ces mots. Limité à 6 mots pour le moment.
  • L’affichage du fichier destination. Le panneau est actualisé à chaque nouvelle recherche
  • Nombre d’occurrences. On y inscrit les mots dont on veut connaitre le nombre d’occurrence.
  • Lancer la recherche qui permet de … lancer la recherche (si si).

Les fonctions des panneaux ont donc été codées après leur mise en place. Un panneau est traité après l’autre.

Voici le rendu actuel du programme :

Programme

Le programme m’a permit de trouver tout les DUTs touchants l’industrie, d’ignorer les licences (ce qui avait déjà été fait en ne gardant que les DUTs) et d’ignorer toutes les formations touchants la gestion.

L’écran principale nous apprend alors qu’on a 6 formations répondants à ces critères. Puis les affiches. Le panneau du milieu nous confirme bien que nous avons 6 DUTs , 6 qui touchent l’industrie , et aucun  ne touchant la gestion ou le tourisme (ce qui me fait penser que certains étudiants en GEII n’ont pas été informés par un NAO bien programmé). Un  bug apparait pour le Bac+2 , alors que « ac+2 »  affiche bien 6 .

Le programme est actuellement très mal écrit. Prochainement il sera récrit. La fonction parcourir devrait fonctionner afin de pouvoir, pourquoi pas, traiter d’autres CSV, ou même des fichiers TXT ou XLS. J’essaierais aussi d’améliorer la disposition des panneaux. Mais avant tout ça, je me servirais de cet outil pour trier les formations en licence et en master afin d’adapter au mieux le dialogue du robot NAO.

Vous pouvez tester cet outil en téléchargeant cette archive. Vous y trouverez le code python ainsi que la liste des formations déjà donnée plus haut. Veillez à mettre Versionrapport.py et Listedesformations.csv dans le même répertoire.

À titre indicatif, cette application a permit le traitement des masters en  moins de  5 minutes , hors rédaction du dialogue. La capture nous apprends que nous 3 master en industrie, 14 en « gestion » (dont 6 en gestion de projet), 22 en management, 5 en informatique, 7 en marketing, 6 en achats, 6 en chimie et 1 en journalisme.

Trie master
il y a plus que 41 masters ici. Certaines formations traitent plusieurs domaines. Ainsi une formation peut être en gestion et en management (3 formations)

En appelant triebarre avec cette application , il n’en ressort aucun master : En traitant les masters avec les critères indiqués plus haut, on s’assure de n’en manquer aucun lors de la rédaction du dialogue (capture téléchargeable ici).

Trie master2
Cette capture nous confirme l’intérêt de traiter les masters avec ces critères

B PROJET : Déplacer Robotino avec NAO

I Le Robotino

Ses caractéristiques

image Robotino

Comme le robot NAO, Robotino est un robot pédagogique. Il est possible de le programmer de très nombreuses de manières comme en C, C++, Java, .Net, Matlab, LabVIEW et Microsoft Robotics Developer Studio. Pour ma part, j’ai utilisé un logiciel fourni par FESTO, l’entreprise ayant développée ce robot. Robotino est en open source. À la différence de NAO, Robotino se déplace sur roue et non sur pied.

Voici quelques-unes de ses caractéristiques qui me seront utiles :

  • Déplacement omnidirectionnel.
  • Capteurs de distance infrarouge.
  • Capteurs incrémentaux qui permettent de mesurer la vitesse de rotation réelle de chaque moteur.
  • Communication Wifi.
  • Peut porter jusqu’à 20 kg.

Présentation de Robotino-view

Il faut comprendre qu’avec Robotino-view, le programme n’est pas sur le Robotino mais bien sur un PC. Et c’est ce PC qui à l’aide d’une connexion WIFI (possible aussi en en filaire) envoi les commandes à Robotino. En revanche c’est bien le Robotino qui est le serveur dans cas. C’est-à-dire que c’est lui qui fournit une adresse IP au PC.

Voici une description de différentes options disponibles.

capture_robotino_view

Lecture  Lecture                 : Permet de démarrer le programme du Robotino sur le PC.

Connexion Connexion           : Permet de se connecter à un Robotino pour lui transmettre les instructions.

Grafcet

GRAFCET            : Permet d’organiser notre programme sous la forme d’un grafcet. Son usage est contre-intuitif. Je ne l’ai compris qu’au moment de rédiger ces lignes.

prg

Progr / Step       : Permet de savoir si le programme est en cours d’exécution, et dans quelle tâche avec un voyant vert. Selon le grafcet, plusieurs étapes peuvent êtres actives simultanément.

variables

Les variables      : Ce tableau affiche les variables disponibles dans le programme.

Robotino-SIM

De la même manière que l’on pouvait utiliser un NAO virtuel, il est possible d’utiliser un Robotino virtuel. À ceci prêt que cette fonction n’est pas intégrée au logiciel permettant de le programmer Robotino-view. Dans la capture d’écran de Robotino-View, dans le rectangle bleu on peut voir l’adresse suivante : « 127.0.0.1:8080 ».

« 127.0.0.1 » est en fait une carte réseau virtuelle et 8080 le port de communication utilisé sur cette carte. Ce sont ces coordonnées que l’on va utiliser pour se connecter au robot virtuel généré par Robotino-Sim.

Dans la vidéo qui suit vous pouvez voir le Robot en mouvement.

Ce robot virtuel a été très pratique pour travailler à la maison.

II Comment communique NAO avec Robotino ?

Le programme Robotino-view permet d’utiliser un ou plusieurs serveurs UDP .

Ces serveurs gèrent 2 « messages » :

– message 0

– message 1

Il faut comprendre « message » comme un canal.

Le message 0 permet la lecture de 8 sorties et l’écriture sur 8 entrées. Idem pour le message 1.

Tous les X temps (à définir dans la configuration du serveur) le serveur envoi aux adresses configurées les valeurs de ces sorties.

Dès que le serveur reçoit une trame sous la bonne forme, il écrit sur les entrées du message de destination.

L’idée est alors de demander au robot NAO d’envoyer une trame pour commander le Robotino. Mais Nao doit aussi considérer les informations envoyées par Robotino. Par exemple, dans mon programme Robotino-view je demande à ce que, dès que les capteurs du Robotino détectent un objet, Nao soit au courant afin qu’il adapte sa conduite.

Robotino vers Nao

NAO vers Robotino

Récupération d’une trame

 

À l’aide d’un petit code en python, téléchargeable ici, il est possible de récupérer une trame .

Pour expliquer le plus simplement ce code, le client UDP attend en permanence un message sur le socket* « monSocket ». Dès qu’un message est reçu il est encodé en HEXADÉCIMAL et affiché.

En HEXA signifie qu’il n’affichera que des caractères compris entre 0 et 9 et A et F. La trame, qui peut être vue comme une série de 0 et de 1, est découpée en octets.

*« Les sockets servent à communiquer entre deux hôtes appelés Client / Serveur à l’aide d’une adresse IP et d’un port […]; ces sockets permettront de gérer des flux entrant et sortant afin d’assurer une communication entre les deux (le client et le serveur) » explication obtenues à la page https://openclassrooms.com/courses/introduction-aux-sockets-1.

 

Explications : Admettons que mon client UDP reçoive «0010101100000111», en HEXA cela donne 2B 07. Seulement en ASCII  2B correspond à un + et 07 correspond à un « bip sonore ». Si + est bien un caractère affichable, ce n’est pas le cas du bip. En l’occurrence les trames émises par Robotino-view sont destinées à envoyer des nombres et non des chaînes de caractères. Alors si on n’encode pas la trame, l’interpréteur python tentera d’afficher des caractères.

Dans la vidéo qui suit vous verrez la récupération une trame. Par la suite l’interpréterai.

Tout d’abord quelques explications.

Sur la partie gauche de la vidéo vous voyez la « console » de l’interpréteur python. C’est là que ce sont affichées les trames encodées en HEXA.

Sur la partie droite vous voyez une partie du logiciel Robotino-view ainsi que la fenêtre de commande du serveur UDP. On y voit bien que le serveur s’adresse au port 9180 de l’adresse 127.0.0.1. Sans ça, le client UDP n’aurait rien reçu.

Prenons ici la dernière trame reçue :

002400abf401000000000000fc000000000000000000000044fdffff0000000000000000.

Mais que dit Robotino-view sur ces trames ?

 

Décomposition de la trame

 

Voici ce qu’indique l’aide de Robotino-view sur le contenu d’une trame interprétable :

Exporter trame

Ici, le détail de ce qu’est la somme de contrôle :

Somme de controle

La forme que doit voir avoir une trame sur le « message 0 »:

La forme a avoir

Pour finir quelques explications sur un INT 32 (il y a le même tableau pour INT16, mais celui-ci suffit): INT32

La totalité de ces tableaux sera nécessaire pour interpréter la trame.

Reprenons la trame :

002400abf401000000000000fc000000000000000000000044fdffff0000000000000000

Commençons par définir quel octet correspond à tel ou tel information :

00 2400 ab f4010000 00000000 fc000000 00000000 00000000 44fdffff 00000000 00000000

00 : C’est l’ID du message (le « canal »). Ici il vaut 0.

2400 : C’est le nombre d’octet qui compose la trame. En HEXA ce devrait valoir : 9216. Pourtant il est évidant que si l’on regarde la trame indiquée plus haut on est loin de cette valeur. En vérité on est à 36 octets. Pour mieux comprendre il faut revenir sur le tableau sur les INT32. En fait le byte 0 (octet 0) est le byte de poids faible. Autrement dit, il faut lire non pas 24 00 mais 00 24, ce qui en base dix donne 2*16 + 4 = 36.

ab : C’est la somme de contrôle. Elle est égale à la somme de tous les octets composant la trame.

Tableau 1 Trames

La somme de contrôle s’obtient en faisant : 255 – la somme de tous les octets de la trame.

Mais 1364 ne tiens pas sur un octet (qui peut valoir 255 max). Il faut alors faire 1364 % 256 = 84.

(256 car un octet peut valoir de 0 à 255, soit 256 valeurs possibles).

Et 255-84 = 171.

Cet octet, ainsi que le nombre d’octet dans la trame sont des outils pour tester l’intégrité de la trame.

 

Les octets suivant contiennent les valeurs lues sur les sorties INT0 à INT7 du message 0. Ici il s’agit de INT32 signés. C’est à dire que la valeur max est de 2^31 soit 2 147 483 648. Le bit de poids fort indiquant le signe de la valeur.

Voici une formule pour calculer facilement la valeur un INTX :

Byte3 * 128*256^2 + Byte2 * 256^2 + Byte1 * 256 + Byte0

Prenons aussi un byte exprimé en HEXA :  F4

On fait F*16 + 5 = 15 *16 +4 = 244

Tableau 1 Trames2

Si l’on regarde le bit de poids fort du INT5, on  constate qu’il vaut 1 ( 255 en base 10 = 1111 1111 en base 2). Les nombres étant codés en complément à 2*, cela qui veut que dire c’est un entier négatif.

*C’est écrit nulle-part dans Robotino-view, c’est une conclusion que j’ai dû tirer moi même.

On peut obtenir sa valeur de deux façons différentes .

Tout d’abord écrivons tout en binaire :

Byte 3 : 1111 1111 Byte2 : 1111 1111 Byte1 : 1111 1101 Byte 0 : 0100 0100

On complémente sa valeur et on additionne 1:

Byte 3 : 0000 0000 Byte2 : 0000 0000 Byte1 : 0000 0010 Byte 0 : 1011 1100

Soit en base 10 :

0* 128*256^2 + 0 * 256^2 + 2 *256 + 11*16 +12 = 700

On sait alors que INT5 = -700

L’autre solution est de rester en base 10 et de faire :

A= (255 *256^3 + 255*256^2 +253*256 + 68) -256^4

A= -700

Maintenant nous savons lire une trame à la main, nous pouvons donc gérer théoriquement une communication de Robotino vers NAO et inversement. Mais il faut encore pouvoir automatiser l’écriture et la lecture de ces trames.

 

Lire automatiquement une trame reçue

 

J’ai écrit une méthode qui ne permet que de lire qu’un INTX à la fois, après réception d’une trame.

C’est la méthode Conversion_en_INT(String_a_Massacrer, int_a_retourner)

La méthode Conversion_en_INT demande comme argument la chaine que l’on veut étudier (que l’on a obtenue avec un client UDP) et surtout quel INTX on souhaite lire.

Afin de ne pas surcharger le Word press, vous trouverez un code python commenté ici de cette méthode.

Je propose de tester cette méthode.

J’utilise un nouveau code python, téléchargeable ici, qui me permet d’utiliser un client UDP qui appellera en boucle la méthode Conversion_en_INT(String_a_Massacrer,int_a_retourner) afin de lire les 8 INTX fournies par le message 0 et les 8 INTX fournies par le message 1.

Dans la vidéo suivante vous verrez le code en application:

 

Dans la partie de droite, on voit un programme Robotino-view qui écrit sur les entrées 0 à 7 du message 0, pareil pour le message 1. Les valeurs utilisées ont été notées au hasard.

Sur la partie gauche de la vidéo vous retrouverez ces mêmes valeurs suite à l’interprétation de la trame faite par ma méthode. Je prends le soin d’analyser l’ID du message.

Écrire « automatiquement » une trame

 

Cette méthode prend en argument 8 valeurs : l’ID des messages et les valeurs que l’on souhaite écrire pour INT0 à INT 7. Voici le prototype : ConversionUdp(ID_Message, int0,int1,int2,int3,int4,int5,int6,int7)

Là aussi, pour ne pas surcharger le WordPress, je vous propose de lire la méthode commentée, téléchargeable ici .

Dans la vidéo suivante vous verrez un code avec, téléchargeable ici, en application:

 

Je commence par envoyer la trame qui a été écrite dans la méthode commentée plus haut. On peut voir dans Robotino-view que les entrées prennent bien les valeurs désirées.

Ensuite le programme python s’arrête durant 4 secondes. Puis on envoie la trame qui a été écrite juste avant par la méthode ConversionUdp(1,0,0,0,0,0,0,0,0).

 

Nous maitrisons maintenant parfaitement l’envoi et la réception de ces trames. Nous pouvons commander le Robotino et Robotino peut envoyer les informations nécessaires, sous forme d’entier.

 

Code de déplacement

 

Je propose maintenant l’automatisation une tâche : La recherche d’un mur.

Ce ne sera pas UN programme, mais deux programmes qui communiquent l’un avec l’autre.

L’un est fait avec Robotino-view, l’autre avec Spyder en python.

Je vais commencer par présenter le programme sous Robotino-view.

Tout d’abord, voici son GRAFCET :

G7

Il existe deux façons de faire se déplacer Robotino :

-Soit on lui indique une vitesse. En mm par seconde pour un déplacement verticale ou horizontale. En degré par seconde pour un déplacement angulaire => Ce sera fait avec la tâche « Step1 »

-Soit on lui indique une coordonnée en mm ou en degré. => Ce sera fait avec la tâche « Step2 »

Step1

Pour passer d’une étape à l’autre j’écris dans une variable « Changement_d_etape ».

STEP1

rouge step1

C’est l’entrainement omnidirectionnel. C’est lui qui envoi les consignes aux 3 moteurs de Robotino.

La consigne de déplacement sur l’axe de X proviendra de INT0 du message 0.

La consigne de déplacement sur l’axe de Y proviendra de INT1 du message 0.

La consigne de déplacement angulaire proviendra de INT2 du message 0.

vert step1

C’est la variable qui me permet de passer de STEP1 vers STEP2 (et inversement).

Elle sera affectée par INT3 du message 0.

bleu step1

Cette entrée INT5 du message 0 me permet d’activer le frein des moteurs.

  rose step 1

 

Cette partie est un peu plus complexe.

IR4 step 1Ceci est le capteur infrarouge 4. Dès qu’il voit un obstacle, il renvoi une valeur entre 0 et 2.54. S’il revoie 2.54 c’est que le capteur IR4 est presque au contact de l’obstacle.

Plutôt que de travailler sur une plage de 0 à 2.54. Je décide de traiter cette information sur une page de 0 à 100 qui est plus intuitive. Dès que mon capteur renvoi une information > 30% de 2.54, alors j’entre un 1 dans un sommateur.

 

bleu marine step1

Voici le sommateur. Le résultat obtenu est écrit dans INT0 du message 1.

C’est ainsi que je peux savoir si mon Robotino voit un mur ou obstacle à une distance que je considère suffisante.

Cette partie etait destinée à être optimisée. L’idée est de multiplier la sortie du comparateur du capteur 2 par 10, du capteur 3 par 100(pour le capteur 3), etc, jusqu’au capteur 9 par 100000000. Ainsi, on pourra manipuler la , à l’aide de modulo et de soustraction, la valeur lue dans INT0 du message 1 afin de déterminer précisément quel capteur voit un obstacle.

 

jaune step1

Si mon capteur infrarouge 1 voit un obstacle, j’écris dans INT1 du message 1.

J’ai besoin de cette information indépendamment de celles autres capteurs dans mon programme en python.

 

 

En résumé, STEP1 me permet de donner une vitesse de déplacement à Robotino, et de savoir s’il détecte un obstacle.

 

Step2

  STEP2

orange STEP2

Cette fonction est un « parcoureur de position ». Il permet de parcourir une distance pour atteindre une coordonnée qu’on lui aurait donné en consigne. Il envoie les ordres de déplacement aux moteurs en fonction de la distance parcourue. Cette information il obtient à partir à partir de la fonction « odométrie ».

On envoie la consigne de distance sur l’axe des X avec l’entrée INT0 du message 0.

On envoie la consigne de distance sur l’axe des Y avec l’entrée INT1 du message 0.

On envoie la consigne d’angle avec l’entrée INT2 du message 0.

Curieusement dès qu’on envoie une distance à parcourir sur l’axe des X ou des Y, la fonction « parcoureur de position » s’exécute de suite. En revanche, si on veut parcourir un nouvel angle, il faut un front descendant sur cette entrée.On réalise ce front avec l’entrée INT4 du message 0.

bleu Step2

Voici la fonction « Odométrie ». Avant de savoir quelle distance on a parcourue il faut lui donner un point de référence.

Pour ma part j’ai configuré  les valeurs suivantes :

-0 en X.

-0 en Y.

-0 en degré.

Dès lors que l’on veut redéfinir un point de référence, il faut faire un front montant sur cette entrée. On réalise ce front avec l’entrée INT5 du message 0.

 

Ces deux fonctions méritent d’être illustrées par un exemple :

Disons que les positions de référence valent :

-> 25 en X.

->-72 en Y.

-> 0 en degré.

Maintenant disons que je donne en consigne au « parcoureur de position » :

-> -27 en X.

-> 257 en Y.

->15 en degré.

Robotino ne parcourra pas :

-> -27 en X.

-> 257 en Y.

->15 en degré.

Mais il parcoura :

-> (-27) – (25) = -52 en X.

->-257 – (-72) = 329 en Y.

-> 15 – 0= 15 en degré.

En réinitialisant systématiquement le point de référence à {0,0,0}. Ce « parcoureur de position » devient un  « parcoureur de distance », bien plus pratique pour mon application.

 

jaune step2

Le capteur IR1 envoie une valeur comprise entre 0 et 2.54. Mais les entrées/sorties du serveur UDP ne traitent que des entiers.

Ce qui réduit beaucoup la précision du capteur puisque qu’on ne pourrait lire 0,1 ,et 2 si l’on le connectait directement à la sortie INT1 du message 1. En multipliant la sortie du capteur par 100, on peut écrire 255 valeurs sur la sortie INT1 du message1.

En résumé, STEP2 permet de faire parcourir une distance à Robotino et de lire les informations fournies par le capteur IR1.

Le programme Python

Dans l’image qui suit, vous voyez la disposition des capteurs à infrarouge (IRx) autour de Robotino. Je précise que la notion d’avant et arrière est arbitraire. Pour moi l’avant de Robotino est au niveau de IR1.

Dispositions capteurs IR

Le code que je vous présente (il ne sera pas détaillé comme les codes) n’est pas exécuté à partir d’un NAO, mais toujours depuis l’IDE Spyder.

Il est téléchargeable ici.

Début du programme :

 

# Le programme de Robotino-view doit être à l’étape Step1.

Au moment de démarrer le Robotino, celui-ci est incapable de savoir où il est.

J’envoie donc une trame au serveur UDP de Robotino-view. Celle-ci permet de dire à Robotino de reculer jusqu’à ce que n’importe lequel de ses capteurs à infrarouge détecte un mur. Le code python est en attente d’une trame qui l’informera quand les capteurs voient un mur : INT0 du message 1 > 0.

Le serveur UDP envoie en permanence des trames. Le programme python étant incapable de savoir laquelle contient l’information qu’il lui faut, il les scrute toutes.

Lorsque le programme python lit que INT0 du message 1 > 0, il active le frein des moteurs en envoyant une trame contenant INT5 du message 0 = 1.

Je demande alors à Robotino de tourner, jusqu’à ce que ce soit son capteur IR1 qui voit le mur. Le programme python attend alors une trame contenant INT1 du message 1 > 0.

Évidemment si le capteur IR1 voit déjà un mur, cette étape est passée instantanément.

Ensuite le programme python envoie une trame pour que le programme de Robotino-view passe à l’étape Step2. Ceci se fait en envoyant 2 sur l’entrée INT5 du message 0.

# Le programme de Robotino-view doit être à l’étape Step2.

L’objectif ici est de trouver la position optimum, pour que le capteur IR1 soit « en face » du mur. Je demande à Robotino de tourner de 3 degrés et de relever la valeur lue par le capteur IR1. Plus IR1 se rapproche du mur, plus la valeur qu’il lit est élevée. Le programme python compare toute ces valeurs. Dès que IR1 renvoie une valeur plus faible que la précédente, c’est qu’il s’éloigne du mur : La position optimum est passée. On retourne alors dans la position précédente.

Dans la vidéo qui suit, vous verrez les programmes communiqués, et le Robotino virtuel se déplacer en conséquence.

https://www.youtube.com/watch?v=1u3FIJXI2ek&feature=youtu.be

 

III Début de programmation du robot NAO

 

Les diagrammes blocs

Il faut maintenant exécuter ce code non plus depuis l’IDE Spyder, mais depuis NAO.

On va commencer par enregistrer les méthodes développées (lecture et écriture de trame) dans fichier python. Pour ce faire on créer un fichier python « Robotino ». Le fichier python est téléchargeable ici.

On prend le soin de le mettre à la racine de projet NAO.

biblioteque_robotno

Ensuite on créer un block python qui sera lancé au démarrage.

Block python

 

Par la suite on importera ces méthodes dans les « python block », avec la commande :

from robotino import*

Malheureusement pour moi, je n’ai pas pu terminer mon projet. La suite ne présentera donc qu’une ébauche de programme.

Programme_Nao

Le fonctionnement est le suivant :

Au démarrage on lance le chargement du fichier python contenant les méthodes développées. Ensuite on active la caméra qui se situe dans la bouche du NAO et on active la reconnaissance des NAOMARKS(exemple visible sur l’image suivante).

NaoMarks

Les valeurs lues par la caméra rentrent dans un switch case. En fonction du résultat on active la box « Com_simple », ou la box « STOP ».

-> « Com_simple » demande à Robotino de reculer jusqu’à ce qu’il voie un mur. Tourne jusqu’à ce que IR1 voit le mur. Et on active « Com_simple_2», qui sert à obtenir l’angle optimum. Les résultats de Com_simple2 ne sont pas probant, je n’ai pas trouvé les raisons.

-> « STOP » envoie une trame pour retourner à l’étape Step1 et remettre toutes les valeurs à 0.

Le projet NAO est téléchargeable ici.

Voici une vidéo où le NAO virtuel commande le Robotino virtuel.

 

Conclusion :

Si je suis satisfait de certain résultats obtenus comme la maitrise des trames ou la communication entre les robots, je reste déçu de ne pas avoir réussis à atteindre les objectifs fixés. Peut-être étaient-ils trop ambitieux pour mes compétences.

J’ai dans l’espoir que les ressources que je laisse seront assez lisibles pour de futurs utilisateurs, ou qu’au moins ils puissent s’aider des informations misa à disposition sur cette page.

La présentation du projet est terminée. Merci de votre attention.


Pour finir cette page, je vous présente le groupe à l’origine de ce projet : Le mononôme Alexandre Ribault.

La distribution du travail s’est faite de la façon suivante, pour une répartition juste et équitable de la charge de travail:

Alexandre a tout fait.

– Les autres ont fait le reste.

index
Rapport réalisé avec 100 % de pixels recyclés