Robots suiveurs 3 - Code Tutoriel Communication

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

Introduction

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

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













Le contrôleur et la communication

Dans cette section, on expliquera la partie du code relative à la communication entre les robots. Le code étant en C, on presentera 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 le canal de communication (si ce n’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 le canal de communication.

Enfin, l'émetteur doit envoyer le message et le récepteur doit le recevoir et l’afficher sur la console. Pour pouvoir le faire, on doit vérifier si le buffer du récepteur est vide et, si cela n’est pas le cas, mettre le message dans un autre 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 permanente.

  • É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;
     }
}