Robots humanoïdes 2013 groupe II
Sommaire
Projet de Coopération Nao N2N: Partie Communication/Réseau
Présentation du projet
Le projet global a pour but de réaliser une coopération entre deux robots NAO; cette coopération nécessite la synchronisation des deux humanoïdes à l’aide d’un serveur de données. Les NAO doivent donc utiliser des données communes pour se synchroniser, par exemple: déplacement d’un carton “volumineux” à deux. Ceci induit que les NAO vont devoir synchroniser leurs positions, ainsi que leurs déplacements, afin de pouvoir réaliser correctement l’action.
Cahier des charges
- Communication entre deux robots NAO à l’aide d’un serveur de données, afin de pouvoir réaliser une coopération synchronisée entre ceux-ci.
> Pour cela, nous allons donc utiliser une mémoire partagée afin de communiquer les différents états possibles dans lesquels seront les NAO (attente, prêt, etc.), ainsi que les positions des NAO afin d’effectuer une bonne synchronisation lors des mouvements.
- Communication entre les NAO et le routeur réalisée par WiFi: réception et envoi de données entre les NAO et le routeur.
> Programmation en C++ (a priori) dans les NAO.
Matériel nécessaire
- Deux NAO;
- Un routeur;
- Un PC fonctionnant sous Linux.
Étapes importantes (prévisionnel)
- Étude approfondie de la communication NAO vers PC et PC vers NAO;
- Création d'une zone de mémoire partagée;
- Détermination des échanges à effectuer pour accomplir la tâche définie auparavant.
Avancement du projet
Semaine 1
Lors de cette première semaine, nous avons effectué des recherches sur le NAO afin de mieux comprendre son fonctionnement:
> prise de connaissance des bibliothèques spécifiques au NAO, ainsi que des variables qui sont indispensables à son bon fonctionnement;
> prise en main des logiciels utiles et nécessaires à la programmation sur PC du NAO;
> réalisation de tests avec le NAO: programmes en C++ de base pour contrôler le NAO (nous avons réussi à faire parler le NAO à l'aide d'un PC lié par câble ethernet au routeur et une connexion Wifi établie entre le routeur et le NAO).
Objectifs pour la semaine 2: écrire des programmes de test qui agissent sur les actionneurs et qui récupèrent des données du NAO.
Semaine 2
Nous avons essayé de compiler plusieurs autres programmes proposés par Aldebaran:
> problèmes liés à la compilation en début de semaine, désormais réglés;
> tests en compilation simple qui agissent sur les actionneurs du NAO (sa tête, par exemple);
> problèmes de cross-compilation: impossibilité de tester des programmes qui nécessitent d'être dans le NAO.
Objectifs pour la semaine 3: réaliser une cross-compilation afin d'agir sur les actionneurs, suivant les actions réalisées sur les capteurs du NAO et récupérer des données du NAO.
Semaine 3
Après des réapparitions de problèmes liés à la compilation, nous avons décidé d'enquêter sur notre compilateur (qibuild) distribué par Aldebaran. Il est apparu que ce compilateur n'était pas à jour et ne convenait pas à notre version du NAO. Il nous empêchait notamment d'utiliser les commandes de déploiement du programme directement dans le NAO (deploy...). Désormais: Utilisation de qibuild2.
Nous avons alors repris le travail précédent (compilation et test des exemples) avec ce nouveau compilateur légèrement différent mais plus fonctionnel. Ensuite nous avons constitué notre architecture de travail afin de commencer à créer nos propres programmes en s'inspirant des exemples testés auparavant.
Premier test avec qibuild2: récupération des données de la centrale inertielle du NAO.
> dans un premier temps, en lançant le programme à partir du PC: Succès de la récupération des valeurs sur le terminal en temps réel;
> dans un deuxième temps, le but était d'écrire ces valeurs dans un fichier .txt afin d'en garder une trace. Nous avons pu implémenter l’exécutable de ce code directement dans le NAO grâce aux nouvelles commandes de qibuild2.
Nous avons alors utilisé la cross-compilation, c'est-à-dire compiler un code afin de créer un exécutable compréhensible par différentes plate-formes (ici le NAO et le PC). Ensuite, l'exécution du binaire peut se faire simplement en passant par ssh dans le NAO. Après lancement, on récupère ainsi dans un fichier .txt des valeurs de la centrale inertielle le temps de l'exécution du programme.
Objectifs pour la semaine 4: déployer un code dans le NAO permettant de tester certains capteurs afin de le faire réagir selon leurs états.
Semaine 4
Nous avons essayé de modifier un code d'exemple fourni par Adebaran afin d'agir sur le NAO. Cependant, nous nous sommes aperçu que beaucoup de paramètres concernant les degrés de liberté du NAO devaient être modifiés afin de réaliser un simple mouvement de bras. Nous avons décidé de ne pas nous y pencher, car ce genre de mouvements est facilement réalisable via Chorégraphe...
Nous avons ensuite réfléchi à une manière simple de synchroniser le NAO (sans passer par la mémoire partagée pour le moment):
> nous avons vu que le NAO pouvait attendre la fin d'un événement réalisé par lui-même avant de réaliser une nouvelle action (par exemple, après avoir parlé);
> nous avons alors réalisé la suite d'événements suivants:> abaissement de la tête du NAO (récupération des valeurs liées à l'axe de la tête du NAO)> réaction du NAO par la parole (après avoir dépassé un certain seuil lors de son mouvement de tête)> mouvement quelconque du NAO (après l'événement de parole)
Objectifs pour la semaine 5: réaliser une synchronisation simple entre deux NAO, à l'aide des modules de détection de sons ou de parole.
Semaine 5
Nous avons commencé par tester des exemples de détection de sons et de détection de langage:
> la détection de sons tourne autour d'une détection de seuils: le problème rencontré est que le NAO s'entend marcher et bouger, ce qui rend impossible la synchronisation grâce à ce moyen;
> la détection de parole consiste à pré-saisir une liste de mots que le NAO pourra reconnaître: après avoir effectué des tests, nous avons remarqué que le NAO détectait très bien les mots prononcés par le second NAO, mais moins bien ceux prononcés par nous.
Cette seconde solution nous permettrait alors de réaliser une synchronisation de manière facile; toutefois, nous pensons que réaliser un système client-serveur nous permettra d'avoir une marche de manœuvre plus grande pour la communication entre NAO (par exemple, si l'on fait interagir plus de deux NAO).
C'est pour cela que nous avons commencé à réaliser un système client-serveur, avec pour clients les NAO et pour serveur un PC. Le système actuellement réalisé permet les échanges client-serveur entre deux PC. Nous allons devoir intégrer à ce programme le code nécessaire au NAO pour exécuter un programme local (donc dans le NAO).
Par ailleurs, nous avons réfléchi à l'algorithme simple de synchronisation que nous allons utiliser pour synchroniser les deux NAO avant qu'ils ne réalisent l'action de soulever ensemble un objet.
Objectifs pour la semaine 6: intégrer l'algorithme de synchronisation et le code requis pour l'exécution du programme sur le système du NAO.
Bilan de mi-projet
Au cours de ce projet, nous avons pu dans un premier temps nous familiariser avec l'interface du NAO. Nous nous sommes rapidement orientés vers la programmation C++ des robots afin de comprendre leur architecture et leurs différentes fonctions. Au cours des premières semaines, la mission principale était donc d'apprendre à utiliser un environnement de cross-compilation: Qibuild. Nous avons donc appris à utiliser des chaînes de compilation (toolchains) permettant de créer des exécutables en local afin d'utiliser le NAO à partir de notre PC. Le but du projet résidant dans un programme C++ intégré au NAO, nous nous sommes rapidement intéressés à la cross-compilation. La cross-compilation permet de créer des exécutables compréhensibles par le NAO. Cette compilation permet de compiler le projet ciblé dans un langage que le NAO pourra ensuite exécuter.
Après avoir étudié les exemples fournis par Aldebaran, nous avons pu contrôler le NAO et récupérer certaines informations grâce à des NAO Keys (arguments de fonctions permettant de récupérer la valeur d'un certain capteur). Nous avons alors modifié ces exemples pour récupérer des données intéressantes liées au NAO (inclinaison de la tête, position de sa centrale inertielle...) et qui permettront plus tard la synchronisation des deux NAO.
Nous avons ensuite tenté d'utiliser les fonctions de reconnaissance audio du bruit et de la parole. Cependant, la reconnaissance du bruit n'est pas utilisable lorsque le NAO ou qu'un autre NAO est en mouvement à proximité car le seuil maximum de détection est atteint trop rapidement. Nous nous sommes donc plus intéressés à la reconnaissance de parole afin de se rendre compte qu'elle est assez fiable pour synchroniser les NAO. En effet, lorsque le NAO 1 parle, le NAO 2 reconnaît avec un indice de confiance de 90% ce qu'il a dit. Nous allons alors baser notre synchronisation sur cette fonction.
Aujourd'hui, nous avons décidé de créer un réseau simple afin de faire communiquer les NAO entre eux. De cette façon, nous allons pouvoir informer l'état de NAO 2 à NAO 1 et vice versa. Lorsque le NAO 1 sera prêt, on attendra que le NAO 2 soit prêt pour commencer à soulever l'objet. En accord avec l'autre groupe de projet, un NAO sera prêt lorsque sa tête sera baissée. Nous savons actuellement récupérer la position de la tête du NAO, ce qui nous facilite alors la tâche.
La partie la plus importante restante est donc la communication réseau des NAO avec notre PC qui fera office de serveur.
Semaine 6
Lors de cette semaine, nous avons tout d'abord cherché à réaliser un programme permettant le système client/serveur entre NAO et PC. Le système client/serveur utilise le protocole TCP, car il est important que les NAO reçoivent les bonnes données au risque de ne plus être synchronisés. Après avoir réalisé ceci, nous avons écrit les algorithmes de synchronisation pour les NAO (clients) et pour le PC (serveur). Nous avons ensuite procédé à l'intégration du système client/serveur dans les algorithmes de synchronisation précédemment écrits. Les tests ont montré qu'il y avait un problème d'algorithme, car le réseau client/serveur fonctionnait correctement:> comme le serveur lit continuellement les données et que les NAO envoient continuellement leur état, lorsqu’un NAO est prêt, lui seul reçoit la "bonne" variable de retour, alors que l’autre reçoit la variable de retour qui correspond à son état.
Nous avons donc essayé de résoudre ce problème avec un système de sémaphores (quand le premier NAO envoie une donnée d'état, il attend que le second NAO reçoive la donnée retour du serveur avant d'autoriser la réception de son côté):
> le serveur renvoie une erreur, car il ne renvoie pas la réponse au bon client...
Objectifs pour la semaine 7: résoudre le problème d'algorithme afin de permettre aux deux NAO d'être synchronisés.
Semaine 7
Nous avons modifié le programme afin de synchroniser correctement les deux NAO. Pour pallier le problème précédent, il a fallu réaliser un simple test afin d'éviter que la valeur envoyée par le serveur ne revienne à l'étape précédente... Nous avons aussi rajouté la récupération des adresses IP des NAO afin de pouvoir les différencier et de réaliser les bons tests pour la synchronisation. Cette fois-ci les tests ont montré que les deux NAO étaient synchronisés. On peut tout de même noter qu'actuellement, les NAO ne sont pas parfaitement synchronisés: il y a un décalage d'une durée égale à la durée d'émission et de réception entre le serveur et le client (en effet, les données sont envoyées à un NAO, puis à l'autre, ce qui explique ce décalage).Nous avons ensuite de nouveau modifié le programme afin d'arrêter le client et le serveur lorsque la synchronisation est finie. Lors d'un débuggage, nous avons par ailleurs remarqué que le système client/serveur fonctionnait, mais de manière peu correcte niveau programmation... le client ouvre actuellement des sockets en continu, ce qui n'est évidemment pas ce qu'il faut faire... Nous avons donc décidé de modifier ce système afin d'avoir un programme plus propre...
Objectifs pour la semaine 8: modifier le système client/serveur pour corriger le problème des sockets.
Semaine 8
Nous avons dans un premier temps résolu le problème de la création des sockets de communication. Actuellement, nous ne créons qu'un seul socket par client NAO et chaque NAO n'utilise que son socket respectif pour communiquer avec le serveur. Cela nous permet alors d'avoir un programme plus fiable et d'éviter de potentielles erreurs de réseau durant la création et les tentatives de communication de nouveaux sockets avec le serveur.Ensuite, nous avons réfléchi à un algorithme permettant de quitter proprement les programmes des clients et du serveur lorsque la synchronisation des NAO était terminée. L'implémentation a été effectuée et cela fonctionne.
Au niveau de la synchronisation, elle s'effectue avec quelques millisecondes de décalage (temps de communication entre un NAO et le PC), un temps totalement négligeable pour le bon déroulement du programme Choregraphe des NAO.
Objectifs pour la semaine 9 : Vérifier avec le second binôme du projet NAO que l'intégralité du projet fonctionne correctement.
Semaine 9
Lors des tests avec le second binôme du projet NAO, nous nous sommes rendu compte qu'il y avait encore quelques erreurs d'algorithmes, au niveau de certains cas initiaux ou peu probables auxquels nous n'avions pas pensé auparavant. Nous avons alors amélioré l'algorithme du programme client afin de pallier tous les potentiels cas défaillants: état "prêt" des NAO au démarrage, ou encore les deux NAO sont prêts exactement en même temps. Enfin, après avoir réglé ces problèmes, nous avons filmé la synchronisation des NAO avec le deuxième groupe.
Bilan du projet
Les premières semaines de projet, nous avons commencé par appréhender les logiciels, les notions et les spécificités liés au NAO. Nous avons alors principalement lu de la documentation et exécuté les exemples afin de comprendre au mieux son fonctionnement avant de le programmer.
Après cette première approche du NAO, nous avons réfléchi à ce qu’il était alors concrètement possible de faire pour synchroniser les deux NAO. Nous en avons discuté avec le second binôme du projet NAO, et nous avons décidé de les synchroniser par un événement de parole. Visuellement parlant, nous avons décidé que lorsqu’un NAO était “prêt” (et attendait alors le second NAO), il devait baisser la tête.
Dans cette seconde partie du projet, après avoir apporté des précisions sur le cahier des charges, nous avons donc commencé à programmer le système clients/serveur. Pour que ce système fonctionne, il fallait exécuter le serveur sur un ordinateur et les clients sur les NAO. Ceci nécessitait ainsi de réaliser une cross-compilation, et de se connecter via ssh aux NAO. Après la réalisation de ce système de clients/serveur, nous avons écrit l’algorithme de synchronisation. De par la communication par TCP, les NAO ne pouvaient parfaitement être synchronisés, car l’un des deux NAO recevait nécessairement l’information après l’autre. Cependant, la synchronisation réalisée était amplement suffisante pour le reste du programme de comportement sous Choregraphe.
Au cours de ces 10 semaines de projet, nous sommes alors parvenus à réaliser un système de clients/serveur en C++ (utilisant les librairies de C pour la partie réseau), qui permet de réaliser une synchronisation de deux NAO. Ceci correspond au cahier des charges que l’on s’était fixé au début du projet.
Améliorations possibles
Notre système clients/serveur ne peut actuellement gérer que deux NAO. Pour améliorer cela, il aurait été bien de:
> restructurer notre programme et utiliser un tableau (ou une liste) de structure de données: on pourrait par exemple créer une structure de données pour les NAO avec leur adresse IP et leur état;
> utiliser des fonctions de sondage de la socket (poll() ou select()) pour récupérer toutes les connexions potentielles de clients;
ou
> utiliser des processus légers (threads) pour le système clients/serveur, ce qui aurait amélioré l’efficacité du système et nous aurait permis de gérer facilement tous les clients potentiels.