Robots suiveurs 3 - Code Tutoriel Communication

De Learning Lab Environnements Connectés
Sauter à la navigation Sauter à la recherche

Introduction

Pour ce tutoriel, on partirá d’un monde de base du logiciel Webots, qui s'appelle “emitter_receiver”. Il possède deux robots qui se déplacent de façon à éviter les obstacles et qui si communiquent (en affichant une message sur le console) quand le robot récepteur se trouve dans la portée du signal de communication, représentée par une sphère blanche autour du robot émetteur. Les deux robots utilisent le contrôleur “emiiter_receiver”, mais ont des comportements différents en fonction de ses noms.

fonctionnement des robots (cliquez pour jouer le GIF)
Messages sur le console

Le contrôleur et la communication

Dans cette section, on expliquerá la partie du code relative à la communication entre les robots. Le code étant en C, on presenterá aussi les fonctions équivalents en C++, qui sont utiles pour comprendre le projet.

Au tout début, il faut ajouter les bibliothèques pour l’émetteur et le récepteur.

#include <webots/emitter.h>
#include <webots/receiver.h> 

On doit créer un “deviceTag” pour la communication, ce qui n’est pas nécessaire en C++, et prendre la main de l’émetteur ou du récepteur, selon le cas. Ensuite, on choisit la chaîne de communication (si c’est pas la bonne) pour l'émetteur et on habilite le récepteur.

WbDeviceTag communication;

Émetteur :

communication = wb_robot_get_device("emitter"); 
wb_emitter_set_channel(communication, COMMUNICATION_CHANNEL);

Récepteur :

communication = wb_robot_get_device("receiver");
wb_receiver_enable(communication, TIME_STEP); 

En C++, cela devient :

Émetteur :

Emitter *emitter = robot->getEmitter("emitter");
emitter->setChannel(COMMUNICATION_CHANNEL);

Récepteur :

Receiver *receiver = robot->getReceiver("receiver");
receiver->setChannel(COMMUNICATION_CHANNEL); 

On remarque que, dans ce cas, l’habilitation du récepteur est faite en choisissant la chaîne de communication.

Enfin, l'émetteur doit envoyer le message et le récepteur doit le recevoir et l’afficher sur le console. Pour pouvoir le faire, on doit vérifier si la queue du récepteur est vide et, si cela n’est pas le cas, mettre la méssage sur un buffer, qui sera affiché une seule fois (utilisation du if avec la variable “message_printed”). Il est important de remarquer qu’il faut chercher le nouveau paquet de l'émetteur après avoir affiché le message, sinon on vide la queue de façon permanent.

Émetteur :

const char *message = "Hello!";
wb_emitter_send(communication, message, strlen(message) + 1);

Récepteur :

/* is there at least one packet in the receiver's queue ? */
if (wb_receiver_get_queue_length(communication) > 0) {

     /* read current packet's data */
     const char *buffer = wb_receiver_get_data(communication);

     if (message_printed != 1) {
          /* print null-terminated message */
          printf("Communicating: received \"%s\"\n", buffer);
          message_printed = 1;
     }

     /* fetch next packet */
     wb_receiver_next_packet(communication);

} else {

     if (message_printed != 2) {
          printf("Communication broken!\n");
          message_printed = 2;
     }
} 

En C++ :

Émetteur :

const char *message = "Hello!";
emitter->send(message, strlen(message) + 1);

Récepteur :

if (receiver->getQueueLength() > 0) 
{

     /* read current packet's data */
     const char *buffer = (const char*)receiver->getData();
     const double *position= receiver->getEmitterDirection();

     /* print null-terminated message */
     if (message_printed != 1) {
          printf("Communicating: received \"%s\"\n", buffer);
          message_printed = 1;
     }

     /* fetch next packet */
     receiver->nextPacket();

} else {

     if (message_printed != 2) 
     {
          printf("Communication broken!\n");
          message_printed = 2;
     }
}