﻿<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://bacasable.arpitania.eu//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=De-almeida-ribeiro.thiago</id>
	<title>Learning Lab Environnements Connectés - Contributions de l’utilisateur [fr]</title>
	<link rel="self" type="application/atom+xml" href="https://bacasable.arpitania.eu//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=De-almeida-ribeiro.thiago"/>
	<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Sp%C3%A9cial:Contributions/De-almeida-ribeiro.thiago"/>
	<updated>2026-04-06T18:34:16Z</updated>
	<subtitle>Contributions de l’utilisateur</subtitle>
	<generator>MediaWiki 1.32.0</generator>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Code_Tutoriel_Communication&amp;diff=10969</id>
		<title>Robots suiveurs 3 - Code Tutoriel Communication</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Code_Tutoriel_Communication&amp;diff=10969"/>
		<updated>2020-05-13T09:47:05Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
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 [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], mais ont des comportements différents en fonction de leur noms. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:emitter_receiver.gif|400px|thumb|left|fonctionnement des robots (cliquez pour jouer le GIF)]]&lt;br /&gt;
&lt;br /&gt;
[[Fichier:console_emitter_receiver.jpg|400px|thumb|right|Messages sur le console]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Le contrôleur et la communication ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il faut ajouter les bibliothèques pour l’émetteur et le récepteur. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/emitter.h&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/receiver.h&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
WbDeviceTag communication; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
communication = wb_robot_get_device(&amp;quot;emitter&amp;quot;); &lt;br /&gt;
wb_emitter_set_channel(communication, COMMUNICATION_CHANNEL); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
communication = wb_robot_get_device(&amp;quot;receiver&amp;quot;);&lt;br /&gt;
wb_receiver_enable(communication, TIME_STEP); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En C++, cela devient : &lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Emitter *emitter = robot-&amp;gt;getEmitter(&amp;quot;emitter&amp;quot;);&lt;br /&gt;
emitter-&amp;gt;setChannel(COMMUNICATION_CHANNEL); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Receiver *receiver = robot-&amp;gt;getReceiver(&amp;quot;receiver&amp;quot;);&lt;br /&gt;
receiver-&amp;gt;setChannel(COMMUNICATION_CHANNEL); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On remarque que, dans ce cas, l’habilitation du récepteur est faite en choisissant le canal de communication. &lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
const char *message = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
wb_emitter_send(communication, message, strlen(message) + 1);  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
/* is there at least one packet in the receiver's queue ? */&lt;br /&gt;
if (wb_receiver_get_queue_length(communication) &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
     /* read current packet's data */&lt;br /&gt;
     const char *buffer = wb_receiver_get_data(communication);&lt;br /&gt;
&lt;br /&gt;
     if (message_printed != 1) {&lt;br /&gt;
          /* print null-terminated message */&lt;br /&gt;
          printf(&amp;quot;Communicating: received \&amp;quot;%s\&amp;quot;\n&amp;quot;, buffer);&lt;br /&gt;
          message_printed = 1;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     /* fetch next packet */&lt;br /&gt;
     wb_receiver_next_packet(communication);&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
&lt;br /&gt;
     if (message_printed != 2) {&lt;br /&gt;
          printf(&amp;quot;Communication broken!\n&amp;quot;);&lt;br /&gt;
          message_printed = 2;&lt;br /&gt;
     }&lt;br /&gt;
} &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En C++  :&lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
const char *message = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
emitter-&amp;gt;send(message, strlen(message) + 1); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
if (receiver-&amp;gt;getQueueLength() &amp;gt; 0) &lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
     /* read current packet's data */&lt;br /&gt;
     const char *buffer = (const char*)receiver-&amp;gt;getData();&lt;br /&gt;
     const double *position= receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
&lt;br /&gt;
     /* print null-terminated message */&lt;br /&gt;
     if (message_printed != 1) {&lt;br /&gt;
          printf(&amp;quot;Communicating: received \&amp;quot;%s\&amp;quot;\n&amp;quot;, buffer);&lt;br /&gt;
          message_printed = 1;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     /* fetch next packet */&lt;br /&gt;
     receiver-&amp;gt;nextPacket();&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
&lt;br /&gt;
     if (message_printed != 2) &lt;br /&gt;
     {&lt;br /&gt;
          printf(&amp;quot;Communication broken!\n&amp;quot;);&lt;br /&gt;
          message_printed = 2;&lt;br /&gt;
     }&lt;br /&gt;
} &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Code_Tutoriel_Communication&amp;diff=10968</id>
		<title>Robots suiveurs 3 - Code Tutoriel Communication</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Code_Tutoriel_Communication&amp;diff=10968"/>
		<updated>2020-05-13T09:46:34Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
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 [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], mais ont des comportements différents en fonction de leur noms. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:emitter_receiver.gif|400px|thumb|left|fonctionnement des robots (cliquez pour jouer le GIF)]]&lt;br /&gt;
&lt;br /&gt;
[[Fichier:console_emitter_receiver.jpg|400px|thumb|right|Messages sur le console]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Le contrôleur et la communication ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il faut ajouter les bibliothèques pour l’émetteur et le récepteur. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/emitter.h&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/receiver.h&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
WbDeviceTag communication; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
communication = wb_robot_get_device(&amp;quot;emitter&amp;quot;); &lt;br /&gt;
wb_emitter_set_channel(communication, COMMUNICATION_CHANNEL); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
communication = wb_robot_get_device(&amp;quot;receiver&amp;quot;);&lt;br /&gt;
wb_receiver_enable(communication, TIME_STEP); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En C++, cela devient : &lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Emitter *emitter = robot-&amp;gt;getEmitter(&amp;quot;emitter&amp;quot;);&lt;br /&gt;
emitter-&amp;gt;setChannel(COMMUNICATION_CHANNEL); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Receiver *receiver = robot-&amp;gt;getReceiver(&amp;quot;receiver&amp;quot;);&lt;br /&gt;
receiver-&amp;gt;setChannel(COMMUNICATION_CHANNEL); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On remarque que, dans ce cas, l’habilitation du récepteur est faite en choisissant le canal de communication. &lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
const char *message = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
wb_emitter_send(communication, message, strlen(message) + 1);  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
/* is there at least one packet in the receiver's queue ? */&lt;br /&gt;
if (wb_receiver_get_queue_length(communication) &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
     /* read current packet's data */&lt;br /&gt;
     const char *buffer = wb_receiver_get_data(communication);&lt;br /&gt;
&lt;br /&gt;
     if (message_printed != 1) {&lt;br /&gt;
          /* print null-terminated message */&lt;br /&gt;
          printf(&amp;quot;Communicating: received \&amp;quot;%s\&amp;quot;\n&amp;quot;, buffer);&lt;br /&gt;
          message_printed = 1;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     /* fetch next packet */&lt;br /&gt;
     wb_receiver_next_packet(communication);&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
&lt;br /&gt;
     if (message_printed != 2) {&lt;br /&gt;
          printf(&amp;quot;Communication broken!\n&amp;quot;);&lt;br /&gt;
          message_printed = 2;&lt;br /&gt;
     }&lt;br /&gt;
} &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En C++  :&lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
const char *message = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
emitter-&amp;gt;send(message, strlen(message) + 1); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
if (receiver-&amp;gt;getQueueLength() &amp;gt; 0) &lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
     /* read current packet's data */&lt;br /&gt;
     const char *buffer = (const char*)receiver-&amp;gt;getData();&lt;br /&gt;
     const double *position= receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
&lt;br /&gt;
     /* print null-terminated message */&lt;br /&gt;
     if (message_printed != 1) {&lt;br /&gt;
          printf(&amp;quot;Communicating: received \&amp;quot;%s\&amp;quot;\n&amp;quot;, buffer);&lt;br /&gt;
          message_printed = 1;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     /* fetch next packet */&lt;br /&gt;
     receiver-&amp;gt;nextPacket();&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
&lt;br /&gt;
     if (message_printed != 2) &lt;br /&gt;
     {&lt;br /&gt;
          printf(&amp;quot;Communication broken!\n&amp;quot;);&lt;br /&gt;
          message_printed = 2;&lt;br /&gt;
     }&lt;br /&gt;
} &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10967</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10967"/>
		<updated>2020-05-13T09:44:23Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Résultats finaux (05/05/2020) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bloc de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il active et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” active et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bloc de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’alors, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à se suivre mais cela se fait d’une façon plus lente et irrégulière. Cela pourrait être un problème puisque le robot maître pourrait trop s’écarter des esclaves et la communication entre eux serait alors coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais pourrait permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serial&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serial&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* Le premier robot se dirige avec les flèches, donc le [[Robots suiveurs 3 - Code Contrôle au Clavier |Code de contrôle au clavier]] est implanté.&lt;br /&gt;
* Robots suiveurs : chaque robot est associé à un controller dont le code est semblable au [[Robots suiveurs 3 - Code suivi d'un objet (robot) rouge |Code de suivi d'un objet (robot) rouge]], avec des changements pour la couleur.&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
=== Fusion de Code ===&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons choisi d'exporter les robots édités des différentes simulations dans une nouvelle scène. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|500px|thumb|right|Importer un robot]]  [[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie de gestion de l'émission de message faite dans le controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] au controller utilisé par le robot maitre pour suivre le robot rouge (par détection de couleurs).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;br /&gt;
&lt;br /&gt;
=== Evitement ===&lt;br /&gt;
&lt;br /&gt;
Les robots, en fonction de leur position dans la file, ayant des fonctions différentes (suivi d’un robot par analyse colorimétrique ou suivi d’un robot par communication sans fil), il est nécessaire d’adapter le code d’évitement pour ne pas interférer avec les fonctions de suivi. Ainsi la fonction d'évitement se base toujours sur le même principe, mais l’implémentation se fait de façon différente pour chaque controller, avec des contraintes plus ou moins complexes. &lt;br /&gt;
&lt;br /&gt;
Tous les robots évitent les obstacles grâce aux capteurs de distance, mais ils doivent différencier les robots qu’ils suivent des obstacles quelconques. Pour cela, le robot maître utilise la quantité de pixels rouges dans l’image de la câmera au moment de la détection de l’obstacle, pendant que le maître-esclave et l'esclave utilisent la force du signal de communication. Dans ce dernier cas, la vérification est faite même avant la détection des obstacles, de façon à arrêter les robots. &lt;br /&gt;
&lt;br /&gt;
De plus, on a aussi implémenté une fonction pour réduire la vitesse des robots au fur et à mesure qu’ils s’approchent de leur but (robots à suivre), en utilisant un produit en croix. &lt;br /&gt;
&lt;br /&gt;
À la fin de nos heures de travail, nous avions alors créé et mis en place les controllers suivants: [[Robots suiveurs 3 - Code Contrôle au Clavier | RobotHumain]], [[Robots suiveurs 3 - Code RobotCamera | RobotCamera]], [[Robots suiveurs 3 - Code emitter-receiver | RobotEmitterReceiver]] et [[Robots suiveurs 3 - Code RobotReceiver| RobotReceiver]].&lt;br /&gt;
&lt;br /&gt;
[[Fichier:MondeDeTest.gif|500px|thumb|center| Évitement d'obstacle]]&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10966</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10966"/>
		<updated>2020-05-13T09:39:33Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Résultats finaux (05/05/2020) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bloc de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bloc de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serial&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serial&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* Le premier robot se dirige avec les flèches, donc le [[Robots suiveurs 3 - Code Contrôle au Clavier |Code de contrôle au clavier]] est implanté.&lt;br /&gt;
* Robots suiveurs : chaque robot est associé à un controller dont le code est semblable au [[Robots suiveurs 3 - Code suivi d'un objet (robot) rouge |Code de suivi d'un objet (robot) rouge]], avec des changements pour la couleur.&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
=== Fusion de Code ===&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons choisi d'exporter les robots édités des différentes simulations dans une nouvelle scène. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|500px|thumb|right|Importer un robot]]  [[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie de gestion de l'émission de message faite dans le controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] au controller utilisé par le robot maitre pour suivre le robot rouge (par détection de couleurs).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;br /&gt;
&lt;br /&gt;
=== Evitement ===&lt;br /&gt;
&lt;br /&gt;
Les robots, en fonction de leur position dans la file, ayant des fonctions différentes (suivi d’un robot par analyse colorimétrique ou suivi d’un robot par communication sans fil), il est nécessaire d’adapter le code d’évitement pour ne pas interférer avec les fonctions de suivi. Ainsi la fonction d'évitement se base toujours sur le même principe, mais l’implémentation se fait de façon différente pour chaque controller, avec des contraintes plus ou moins complexes. &lt;br /&gt;
&lt;br /&gt;
Tous les robots évitent les obstacles grâce aux capteurs de distance, mais ils doivent différencier les robots qu’ils suivent des obstacles quelconques. Pour cela, le robot maître utilise la quantité de pixels rouges dans l’image de la câmera au moment de la détection de l’obstacle, pendant que le maître-esclave et l'esclave utilisent la force du signal de communication. Dans ce dernier cas, la vérification est faite même avant la détection des obstacles, de façon à arrêter les robots. &lt;br /&gt;
&lt;br /&gt;
De plus, on a aussi implémenté une fonction pour réduire la vitesse des robots au fur et à mesure qu’ils s’approchent de leur but (robots à suivre), en utilisant un produit en croix. &lt;br /&gt;
&lt;br /&gt;
À la fin de nos heures de travail, nous avions alors créé et mis en place les controllers suivants: [[Robots suiveurs 3 - Code Contrôle au Clavier | RobotHumain]], [[Robots suiveurs 3 - Code RobotCamera | RobotCamera]], [[Robots suiveurs 3 - Code emitter-receiver | RobotEmitterReceiver]] et [[Robots suiveurs 3 - Code RobotReceiver| RobotReceiver]].&lt;br /&gt;
&lt;br /&gt;
[[Fichier:MondeDeTest.gif|500px|thumb|center| Évitement d'obstacle]]&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10965</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10965"/>
		<updated>2020-05-13T09:37:51Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Description des champs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
les champs du capteur de mouvement sont composés d'une table servant a définir sa fonction de transfert et de caractéristiques du laser (son nombre de rayons, son ouverture, etc).&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== LookUpTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous pouvons modifier la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Caméra =&lt;br /&gt;
&lt;br /&gt;
Pour modéliser une caméra, nous utilisons une caméra embarquée classique, modélisée grâce au node [https://cyberbotics.com/doc/reference/camera Caméra], et en donnant une couleur rouge à l'objet à suivre, comme ci celui-ci était une source de chaleur. L'image résultante peut être affichée sur la fenêtre 3D et nous permet de visualiser l'image en RGB dans notre cas.&lt;br /&gt;
&lt;br /&gt;
== Champ du node Camera==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| fieldOfView&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0.7854&lt;br /&gt;
| [0, pi]&lt;br /&gt;
|-&lt;br /&gt;
| width &lt;br /&gt;
| SFInt32  &lt;br /&gt;
| 64&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| height&lt;br /&gt;
| SFInt32  &lt;br /&gt;
| 64 &lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| spherical&lt;br /&gt;
| SFBool &lt;br /&gt;
| FALSE&lt;br /&gt;
| {TRUE, FALSE}&lt;br /&gt;
|-&lt;br /&gt;
| near&lt;br /&gt;
| SFFloat  &lt;br /&gt;
| 0.01&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| far&lt;br /&gt;
| SFFloat  &lt;br /&gt;
| 0.0 &lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| antiAliasing&lt;br /&gt;
| SFBool  &lt;br /&gt;
| FALSE  &lt;br /&gt;
| {TRUE, FALSE}&lt;br /&gt;
|-&lt;br /&gt;
| ambientOcclusionRadius&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0 &lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bloomThreshold &lt;br /&gt;
| SFFloat &lt;br /&gt;
| -1.0 &lt;br /&gt;
| [-1, inf)&lt;br /&gt;
|-&lt;br /&gt;
| motionBlur  &lt;br /&gt;
| SFFloat  &lt;br /&gt;
| 0.0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| noise&lt;br /&gt;
| SFFloat &lt;br /&gt;
| 0.0 &lt;br /&gt;
| [0, 1]&lt;br /&gt;
|-&lt;br /&gt;
| noiseMaskUrl&lt;br /&gt;
| SFString &lt;br /&gt;
| &amp;quot;&amp;quot;&lt;br /&gt;
| any string&lt;br /&gt;
|-&lt;br /&gt;
| lens&lt;br /&gt;
| SFNode &lt;br /&gt;
| NULL&lt;br /&gt;
| {Lens, PROTO}&lt;br /&gt;
|-&lt;br /&gt;
| focus&lt;br /&gt;
| SFNode&lt;br /&gt;
| NULL&lt;br /&gt;
| {Focus, PROTO}&lt;br /&gt;
|-&lt;br /&gt;
| zoom&lt;br /&gt;
| SFNode &lt;br /&gt;
| NULL&lt;br /&gt;
| {Zoom, PROTO}&lt;br /&gt;
|-&lt;br /&gt;
| recognition&lt;br /&gt;
| SFNode&lt;br /&gt;
| NULL&lt;br /&gt;
| {Recognition, PROTO}&lt;br /&gt;
|-&lt;br /&gt;
| lensFlare&lt;br /&gt;
| SFNode &lt;br /&gt;
| NULL &lt;br /&gt;
| {LensFlare, PROTO}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Fonctions utiles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|'''Fonction'''&lt;br /&gt;
|'''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Activation de la caméra&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Désactivation de la caméra&lt;br /&gt;
|-&lt;br /&gt;
| int getWidth() const;&lt;br /&gt;
| Récupération de la largeur de l'image en pixels&lt;br /&gt;
|-&lt;br /&gt;
| int getHeight() const;&lt;br /&gt;
| Récupération de la hauteur de l'image en pixels&lt;br /&gt;
|-&lt;br /&gt;
| const unsigned char *getImage() const;&lt;br /&gt;
| Lecture de la dernière image saisie par l'appareil photo. L'image est codée comme une séquence de trois octets représentant les niveaux rouge, vert et bleu d'un pixel. Les pixels sont stockés sur des lignes horizontales allant du côté supérieur gauche de l'image jusqu'au coin inférieur droit.&lt;br /&gt;
|-&lt;br /&gt;
| static unsigned char imageGetRed(const unsigned char *image, int width, int x, int y);&lt;br /&gt;
| Accès au niveau de rouge d'un pixel RGB à partir de ses coordonnées&lt;br /&gt;
|-&lt;br /&gt;
| static unsigned char imageGetGreen(const unsigned char *image, int width, int x, int y);&lt;br /&gt;
| Accès au niveau de vert d'un pixel RGB à partir de ses coordonnées&lt;br /&gt;
|-&lt;br /&gt;
| static unsigned char imageGetBlue(const unsigned char *image, int width, int x, int y);&lt;br /&gt;
| Accès au niveau de bleu d'un pixel RGB à partir de ses coordonnées&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Utilisation de l'image ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Caméra.png ‎|155px|thumb|right|Image obtenue]]&lt;br /&gt;
L'image de la caméra est affichée en temps réel, en haut de la fenêtre 3D par défaut.&lt;br /&gt;
La résolution de la caméra peut être modifiée dans les caractéristiques de celle-ci.&lt;br /&gt;
&lt;br /&gt;
Afin d'exploiter l'image issue de la caméra, il suffit d'analyser tout ou partie des pixels qui la composent. Une comparaison entre les nombres de pixels rouges, verts et bleus permet par exemple de détecter la présence d'un objet de couleur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émetteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serial&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serial&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;serial&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du buffer de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infra-red&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire buffer, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength (ou getSignalStrength() en C++). Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction (ou getEmitterDirection() en C++). Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie le nombre d'octets de données présents dans le paquet de tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10964</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10964"/>
		<updated>2020-05-13T09:37:14Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Communication entre robots */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serial&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serial&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* Le premier robot se dirige avec les flèches, donc le [[Robots suiveurs 3 - Code Contrôle au Clavier |Code de contrôle au clavier]] est implanté.&lt;br /&gt;
* Robots suiveurs : chaque robot est associé à un controller dont le code est semblable au [[Robots suiveurs 3 - Code suivi d'un objet (robot) rouge |Code de suivi d'un objet (robot) rouge]], avec des changements pour la couleur.&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
=== Fusion de Code ===&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons choisi d'exporter les robots édités des différentes simulations dans une nouvelle scène. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|500px|thumb|right|Importer un robot]]  [[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie de gestion de l'émission de message faite dans le controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] au controller utilisé par le robot maitre pour suivre le robot rouge (par détection de couleurs).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;br /&gt;
&lt;br /&gt;
=== Evitement ===&lt;br /&gt;
&lt;br /&gt;
Les robots, en fonction de leur position dans la file, ayant des fonctions différentes (suivi d’un robot par analyse colorimétrique ou suivi d’un robot par communication sans fil), il est nécessaire d’adapter le code d’évitement pour ne pas interférer avec les fonctions de suivi. Ainsi la fonction d'évitement se base toujours sur le même principe, mais l’implémentation se fait de façon différente pour chaque controller, avec des contraintes plus ou moins complexes. &lt;br /&gt;
&lt;br /&gt;
Tous les robots évitent les obstacles grâce aux capteurs de distance, mais ils doivent différencier les robots qu’ils suivent des obstacles quelconques. Pour cela, le robot maître utilise la quantité de pixels rouges dans l’image de la câmera au moment de la détection de l’obstacle, pendant que le maître-esclave et l'esclave utilisent la force du signal de communication. Dans ce dernier cas, la vérification est faite même avant la détection des obstacles, de façon à arrêter les robots. &lt;br /&gt;
&lt;br /&gt;
De plus, on a aussi implémenté une fonction pour réduire la vitesse des robots au fur et à mesure qu’ils s’approchent de leur but (robots à suivre), en utilisant un produit en croix. &lt;br /&gt;
&lt;br /&gt;
À la fin de nos heures de travail, nous avions alors créé et mis en place les controllers suivants: [[Robots suiveurs 3 - Code Contrôle au Clavier | RobotHumain]], [[Robots suiveurs 3 - Code RobotCamera | RobotCamera]], [[Robots suiveurs 3 - Code emitter-receiver | RobotEmitterReceiver]] et [[Robots suiveurs 3 - Code RobotReceiver| RobotReceiver]].&lt;br /&gt;
&lt;br /&gt;
[[Fichier:MondeDeTest.gif|500px|thumb|center| Évitement d'obstacle]]&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Code_RobotCamera&amp;diff=10945</id>
		<title>Robots suiveurs 3 - Code RobotCamera</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Code_RobotCamera&amp;diff=10945"/>
		<updated>2020-05-12T14:40:43Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/Robot.hpp&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/Emitter.hpp&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/DistanceSensor.hpp&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/motor.hpp&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/Camera.hpp&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define COMMUNICATION_CHANNEL 1&lt;br /&gt;
#define MAX_SPEED 6.28&lt;br /&gt;
&lt;br /&gt;
// toutes les classes webots sont définies dans le namespace &amp;quot;webots&amp;quot;&lt;br /&gt;
using namespace webots;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv) {&lt;br /&gt;
&lt;br /&gt;
  // créé l'instance Robot.&lt;br /&gt;
  Robot *robot = new Robot();&lt;br /&gt;
&lt;br /&gt;
  // récupère le pas de temps du monde actuel&lt;br /&gt;
  int timeStep = (int)robot-&amp;gt;getBasicTimeStep();&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  // crée les instances des périphériques et les associe&lt;br /&gt;
  Emitter *emitter = robot-&amp;gt;getEmitter(&amp;quot;emitter&amp;quot;);&lt;br /&gt;
  Motor *left_motor = robot-&amp;gt;getMotor(&amp;quot;left wheel motor&amp;quot;);&lt;br /&gt;
  Motor *right_motor = robot-&amp;gt;getMotor(&amp;quot;right wheel motor&amp;quot;);&lt;br /&gt;
  Camera *camera = robot-&amp;gt;getCamera(&amp;quot;camera&amp;quot;);&lt;br /&gt;
  DistanceSensor *ps[8];&lt;br /&gt;
  char psNames[8][4] = {&lt;br /&gt;
    &amp;quot;ps0&amp;quot;, &amp;quot;ps1&amp;quot;, &amp;quot;ps2&amp;quot;, &amp;quot;ps3&amp;quot;,&lt;br /&gt;
    &amp;quot;ps4&amp;quot;, &amp;quot;ps5&amp;quot;, &amp;quot;ps6&amp;quot;, &amp;quot;ps7&amp;quot;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
    ps[i] = robot-&amp;gt;getDistanceSensor(psNames[i]);&lt;br /&gt;
    ps[i]-&amp;gt;enable(timeStep);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  // active la caméra&lt;br /&gt;
  camera-&amp;gt;enable(timeStep);&lt;br /&gt;
&lt;br /&gt;
  // initialisation du moteur&lt;br /&gt;
  left_motor-&amp;gt;setPosition(INFINITY);&lt;br /&gt;
  right_motor-&amp;gt;setPosition(INFINITY);&lt;br /&gt;
  left_motor-&amp;gt;setVelocity(0.0);&lt;br /&gt;
  right_motor-&amp;gt;setVelocity(0.0);&lt;br /&gt;
  &lt;br /&gt;
  // si mauvais canal&lt;br /&gt;
  const int channel = emitter-&amp;gt;getChannel();&lt;br /&gt;
    if (channel != COMMUNICATION_CHANNEL) &lt;br /&gt;
    {&lt;br /&gt;
      emitter-&amp;gt;setChannel(COMMUNICATION_CHANNEL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
  emitter-&amp;gt;setRange(0.4); // définit la plage de l'émetteur&lt;br /&gt;
  &lt;br /&gt;
  int exPos = 0; // utilisé pour définir dans quel sens tourner quand on voit plus le robot rouge&lt;br /&gt;
  &lt;br /&gt;
  double vitesse = 0; // utilisé pour faire la réduction de vitesse&lt;br /&gt;
  &lt;br /&gt;
  // utilisés pour faire l'évitement d'obstacles&lt;br /&gt;
  int evitementG = 0;&lt;br /&gt;
  int incrementEvitemment = 0;&lt;br /&gt;
&lt;br /&gt;
 // boucle principale&lt;br /&gt;
 &lt;br /&gt;
 // Le but est de séparer l'image en 3 partie : une partie centrale, gauche et droite&lt;br /&gt;
 // et d'analyser le nombre de pixel rouge dans chacune de ces parties&lt;br /&gt;
 // Si le nombre de pixel rouge est plus important au centre, on avance, si il l'est plus à &lt;br /&gt;
 // gauche, on tourne à gauche, etc...&lt;br /&gt;
 &lt;br /&gt;
  while (robot-&amp;gt;step(timeStep) != -1) {&lt;br /&gt;
  &lt;br /&gt;
      // envoie un message terminé par null&lt;br /&gt;
      const char *message = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
      emitter-&amp;gt;send(message, strlen(message) + 1);&lt;br /&gt;
  &lt;br /&gt;
    // crée des variables pour compter la somme des composantes rouge, verte et bleue des pixels pour chacune des 3 parties de l'image étudiée&lt;br /&gt;
    int red = 0;&lt;br /&gt;
    int blue = 0;&lt;br /&gt;
    int green = 0;&lt;br /&gt;
        &lt;br /&gt;
    int redg = 0;&lt;br /&gt;
    int blueg = 0;&lt;br /&gt;
    int greeng = 0;&lt;br /&gt;
    &lt;br /&gt;
    int redd = 0;&lt;br /&gt;
    int blued = 0;&lt;br /&gt;
    int greend = 0;&lt;br /&gt;
    &lt;br /&gt;
    int redPleinCadran = 0;&lt;br /&gt;
    int reddPleinCadran = 0;&lt;br /&gt;
    int redgPleinCadran = 0;&lt;br /&gt;
    &lt;br /&gt;
    int bluePleinCadran = 0;&lt;br /&gt;
    int bluedPleinCadran = 0;&lt;br /&gt;
    int bluegPleinCadran = 0;&lt;br /&gt;
    &lt;br /&gt;
    int greenPleinCadran = 0;&lt;br /&gt;
    int greendPleinCadran = 0;&lt;br /&gt;
    int greengPleinCadran = 0;&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    // lit les sorties des capteurs de distance&lt;br /&gt;
    double psValues[8];&lt;br /&gt;
    for (int i =0;i&amp;lt;8;i++){&lt;br /&gt;
      psValues[i] = ps[i]-&amp;gt;getValue();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // détecte les obstacles&lt;br /&gt;
    bool right_obstacle =&lt;br /&gt;
      psValues[0] &amp;gt; 100.0 ||&lt;br /&gt;
      psValues[1] &amp;gt; 100.0 ;&lt;br /&gt;
  &lt;br /&gt;
    bool left_obstacle =&lt;br /&gt;
      psValues[5] &amp;gt; 100.0 ||&lt;br /&gt;
      psValues[6] &amp;gt; 100.0 ;&lt;br /&gt;
   &lt;br /&gt;
    bool front_obstacle3 = right_obstacle || left_obstacle;&lt;br /&gt;
    &lt;br /&gt;
    double valMax = std::max(psValues[7], psValues[0]);&lt;br /&gt;
    &lt;br /&gt;
    // Booléen servant à éviter une collision avec un objet en face: Seuil 1&lt;br /&gt;
    bool front_obstacle1 = psValues[7] &amp;gt; 200 || psValues[0] &amp;gt; 200;&lt;br /&gt;
    // Booléen servant à éviter une collision avec un objet en face : Seuil 2&lt;br /&gt;
    bool front_obstacle2 = psValues[7] &amp;gt; 100 || psValues[0] &amp;gt; 100;  &lt;br /&gt;
    &lt;br /&gt;
    // Vitesse roue gauche et droite&lt;br /&gt;
    double leftSpeed = 0.5*MAX_SPEED;&lt;br /&gt;
    double rightSpeed = 0.5*MAX_SPEED;&lt;br /&gt;
    &lt;br /&gt;
    int width = camera -&amp;gt; getWidth();&lt;br /&gt;
    int height = camera -&amp;gt; getHeight();&lt;br /&gt;
    // Récupération de l'image de la caméra&lt;br /&gt;
    const unsigned char *image = camera -&amp;gt; getImage();&lt;br /&gt;
    &lt;br /&gt;
    // Première boucle servant à diviser l'image en 3 parties (partie centrale)&lt;br /&gt;
    for (int i = 2* width / 5; i &amp;lt; 3 * width / 5; i++) {&lt;br /&gt;
        for (int j = 2*height / 5; j &amp;lt; 3* height / 5; j++) {&lt;br /&gt;
          red += camera -&amp;gt; imageGetRed(image, width, i, j);&lt;br /&gt;
          blue += camera -&amp;gt; imageGetBlue(image, width, i, j);&lt;br /&gt;
          green += camera -&amp;gt; imageGetGreen(image, width, i, j);&lt;br /&gt;
        }&lt;br /&gt;
        for (int j = 0; j &amp;lt;  height; j++) {&lt;br /&gt;
          redPleinCadran += camera -&amp;gt; imageGetRed(image, width, i, j);&lt;br /&gt;
          greenPleinCadran += camera -&amp;gt; imageGetGreen(image, width, i, j);&lt;br /&gt;
           bluePleinCadran += camera -&amp;gt; imageGetBlue(image, width, i, j);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    // Deuxième boucle (partie droite)&lt;br /&gt;
    for (int i = 3* width / 5; i &amp;lt; width; i++) {&lt;br /&gt;
        for (int j = 2*height / 5; j &amp;lt;  3*height/5 ; j++) {&lt;br /&gt;
          redd += camera -&amp;gt; imageGetRed(image, width, i, j);&lt;br /&gt;
          blued += camera -&amp;gt; imageGetBlue(image, width, i, j);&lt;br /&gt;
          greend += camera -&amp;gt; imageGetGreen(image, width, i, j);&lt;br /&gt;
        }&lt;br /&gt;
        for (int j = 0; j &amp;lt;  height; j++) {&lt;br /&gt;
          reddPleinCadran += camera -&amp;gt; imageGetRed(image, width, i, j);&lt;br /&gt;
          greendPleinCadran += camera -&amp;gt; imageGetGreen(image, width, i, j);&lt;br /&gt;
          bluedPleinCadran += camera -&amp;gt; imageGetBlue(image, width, i, j);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    // Troisième boucle (partie gauche)&lt;br /&gt;
    for (int i = 0 ; i &amp;lt; 2*width/5; i++) {&lt;br /&gt;
        for (int j = 0; j &amp;lt;  2*height/5 ; j++) {&lt;br /&gt;
          redg += camera -&amp;gt; imageGetRed(image, width, i, j);&lt;br /&gt;
          blueg += camera -&amp;gt; imageGetBlue(image, width, i, j);&lt;br /&gt;
          greeng += camera -&amp;gt; imageGetGreen(image, width, i, j);&lt;br /&gt;
        }&lt;br /&gt;
        for (int j = 0; j &amp;lt;  height; j++) {&lt;br /&gt;
          redgPleinCadran += camera -&amp;gt; imageGetRed(image, width, i, j);&lt;br /&gt;
          greengPleinCadran += camera -&amp;gt; imageGetGreen(image, width, i, j);&lt;br /&gt;
          bluegPleinCadran += camera -&amp;gt; imageGetBlue(image, width, i, j);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (evitementG == 0){&lt;br /&gt;
    &lt;br /&gt;
    // Si on a plus de pixel rouges au milieu, alors...&lt;br /&gt;
    if ((red &amp;gt; 1.5*green) &amp;amp;&amp;amp; (red &amp;gt; 1.5*blue) ){&lt;br /&gt;
      // Si on a un obstacle devant alors on se stoppe&lt;br /&gt;
      if (front_obstacle3){&lt;br /&gt;
        if (front_obstacle1){&lt;br /&gt;
           if (right_obstacle &amp;amp;&amp;amp; reddPleinCadran&amp;gt; 2*bluedPleinCadran &amp;amp;&amp;amp; reddPleinCadran&amp;gt; 2*greendPleinCadran){&lt;br /&gt;
                left_motor-&amp;gt;setVelocity(0.0);&lt;br /&gt;
                right_motor-&amp;gt;setVelocity(0.0);       &lt;br /&gt;
           }&lt;br /&gt;
           else if (left_obstacle &amp;amp;&amp;amp; redgPleinCadran&amp;gt; 2*bluegPleinCadran &amp;amp;&amp;amp; redgPleinCadran&amp;gt; 2*greengPleinCadran){&lt;br /&gt;
                  left_motor-&amp;gt;setVelocity(0.0);&lt;br /&gt;
                  right_motor-&amp;gt;setVelocity(0.0);&lt;br /&gt;
           }&lt;br /&gt;
           else {&lt;br /&gt;
                left_motor-&amp;gt;setVelocity(0.0);&lt;br /&gt;
                right_motor-&amp;gt;setVelocity(0.0);&lt;br /&gt;
                evitementG=1;&lt;br /&gt;
           }&lt;br /&gt;
         }&lt;br /&gt;
        // Si on se rapproche d'un obstacle, on ralentit&lt;br /&gt;
        else if (front_obstacle2){&lt;br /&gt;
          double produitEnCroix = ((200-valMax)/(double)100);&lt;br /&gt;
          vitesse = produitEnCroix * 0.5 * MAX_SPEED;&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(vitesse);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(vitesse);&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
      // Sinon on avance&lt;br /&gt;
      else{&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(leftSpeed);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(rightSpeed);&lt;br /&gt;
      }&lt;br /&gt;
   &lt;br /&gt;
    }&lt;br /&gt;
    // Si il n'y a rien au milieu&lt;br /&gt;
    else{&lt;br /&gt;
    &lt;br /&gt;
      // Si on a plus de pixel rouge à droite alors on tourne à droite&lt;br /&gt;
      if((redd &amp;gt; 1.5*greend) &amp;amp;&amp;amp; (redd &amp;gt; 1.5*blued)){&lt;br /&gt;
       &lt;br /&gt;
        left_motor-&amp;gt;setVelocity(leftSpeed);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(-rightSpeed);&lt;br /&gt;
        exPos = 0;&lt;br /&gt;
        &lt;br /&gt;
      }&lt;br /&gt;
      // Sinon si on a plus de pixel rouge à gauche alors on tourne à gauche&lt;br /&gt;
      else{&lt;br /&gt;
        if((redg &amp;gt; 1.5*greeng) &amp;amp;&amp;amp; (redg &amp;gt; 1.5*blueg)){&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(-leftSpeed);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(rightSpeed);&lt;br /&gt;
          exPos = 1;&lt;br /&gt;
          &lt;br /&gt;
        }&lt;br /&gt;
        // Sinon on tourne sur nous même pour essayer de trouver un objet rouge&lt;br /&gt;
        else{&lt;br /&gt;
          if (exPos==1) {&lt;br /&gt;
            left_motor-&amp;gt;setVelocity(-leftSpeed);&lt;br /&gt;
            right_motor-&amp;gt;setVelocity(rightSpeed);&lt;br /&gt;
            &lt;br /&gt;
          }&lt;br /&gt;
          else {&lt;br /&gt;
            left_motor-&amp;gt;setVelocity(leftSpeed);&lt;br /&gt;
            right_motor-&amp;gt;setVelocity(-rightSpeed);&lt;br /&gt;
            &lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
    &lt;br /&gt;
    //évitement&lt;br /&gt;
      if (left_obstacle) {&lt;br /&gt;
        // tourner à gauche si obstacle à droite&lt;br /&gt;
        left_motor -&amp;gt; setVelocity(leftSpeed);&lt;br /&gt;
        right_motor -&amp;gt; setVelocity(-leftSpeed);&lt;br /&gt;
        exPos = 1;&lt;br /&gt;
        }    &lt;br /&gt;
       else if (right_obstacle) {&lt;br /&gt;
        // tourner à droite si obstacle à gauche &lt;br /&gt;
        left_motor -&amp;gt; setVelocity(-rightSpeed);&lt;br /&gt;
        right_motor -&amp;gt; setVelocity(rightSpeed);&lt;br /&gt;
        exPos = 0;&lt;br /&gt;
      } &lt;br /&gt;
      // Lorsque l'obstacle n'entrave plus la progression, on avance&lt;br /&gt;
      else if (incrementEvitemment &amp;lt;30){&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0.5 * MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0.5 * MAX_SPEED);&lt;br /&gt;
          incrementEvitemment++;&lt;br /&gt;
          } &lt;br /&gt;
      else{&lt;br /&gt;
      //Réinitialisation des flags et incréments&lt;br /&gt;
      incrementEvitemment=0;&lt;br /&gt;
      evitementG=0;&lt;br /&gt;
      }&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
   }; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Destruction des objets et fin de programme.&lt;br /&gt;
  delete robot;&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Codes&amp;diff=10944</id>
		<title>Robots suiveurs 3 - Codes</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Codes&amp;diff=10944"/>
		<updated>2020-05-12T14:40:18Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Codes finaux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=== Code Contrôle avec le Clavier ===&lt;br /&gt;
&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Code Contrôle au Clavier]]&lt;br /&gt;
&lt;br /&gt;
=== Code de robot suiveur via l'utilisation de capteurs de distance ===&lt;br /&gt;
&lt;br /&gt;
*[[Robots suiveurs 3 - Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs de distance]]&lt;br /&gt;
&lt;br /&gt;
=== Code de robot suiveur via communication ===&lt;br /&gt;
&lt;br /&gt;
* [[Robots suiveurs 3 - Code Communication Initial (C) |Code Communication Initial (C)]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Communication Initial (C++) |Code Communication Initial (C++) ]]&lt;br /&gt;
&lt;br /&gt;
* [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |Code Communication Intermédiaire (maître) ]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |Code Communication Intermédiaire (esclave) ]]&lt;br /&gt;
&lt;br /&gt;
*[[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) ]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) ]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) ]]&lt;br /&gt;
&lt;br /&gt;
=== Codes finaux ===&lt;br /&gt;
&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier | RobotHumain]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code RobotCamera | RobotCamera]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code emitter-receiver | RobotEmitterReceiver]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code RobotReceiver| RobotReceiver]]&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10943</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10943"/>
		<updated>2020-05-12T14:39:59Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Evitement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
=== Fusion de Code ===&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons choisi d'exporter les robots édités des différentes simulations dans une nouvelle scène. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|500px|thumb|right|Importer un robot]]  [[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie gestion de l'émetteur et émission de message du controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] (partie communication) au controller utilisé pour suivre le robot rouge (partie détection de couleur).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;br /&gt;
&lt;br /&gt;
=== Evitement ===&lt;br /&gt;
&lt;br /&gt;
Les robots, en fonction de leur position dans la file, ayant des fonctions différentes (suivi d’un robot par analyse colorimétrique ou suivi d’un robot par communication sans fil), il est nécessaire d’adapter le code d’évitement pour ne pas interférer avec les fonctions de suivi. Ainsi la fonction d'évitement se base toujours sur le même principe, mais l’implémentation se fait de façon différente pour chaque controller, avec des contraintes plus ou moins complexes. &lt;br /&gt;
&lt;br /&gt;
Tous les robots évitent les obstacles grâce aux capteurs de distance, mais ils doivent différencier les robots qu’ils suivent des obstacles quelconques. Pour cela, le robot maître utilise la quantité de pixels rouges dans l’image de la câmera au moment de la détection de l’obstacle, pendant que le maître-esclave et l'esclave utilisent la force du signal de communication. Dans ce dernier cas, la vérification est faite même avant la détection des obstacles, de façon à arrêter les robots. &lt;br /&gt;
&lt;br /&gt;
De plus, on a aussi implémenté une fonction pour réduire la vitesse des robots au fur et à mesure qu’ils s’approchent de son but (robot à suivre), en utilisant un produit en croix. &lt;br /&gt;
&lt;br /&gt;
À la fin, on avait les controllers : [[Robots suiveurs 3 - Code Contrôle au Clavier | RobotHumain]], [[Robots suiveurs 3 - Code RobotCamera | RobotCamera]], [[Robots suiveurs 3 - Code emitter-receiver | RobotEmitterReceiver]] et [[Robots suiveurs 3 - Code RobotReceiver| RobotReceiver]].&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3&amp;diff=10942</id>
		<title>Robots suiveurs 3</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3&amp;diff=10942"/>
		<updated>2020-05-12T14:39:16Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Résultat final */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Robot suiveur 2019/2020&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Le but du projet est de faire suivre une personne par une file indienne de robots.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Présentation du projet ==&lt;br /&gt;
&lt;br /&gt;
Dans la continuité du travail ayant été réalisé les années précédentes sur les sujets Robots Suiveurs 1 et 2, notre objectif initial était, dans cette 3ème itération du projet, de poursuivre leur développement tout en améliorant les fonctionnalités disponibles. Cependant, suite à l'apparition du covid-19 et au confinement s'en suivant, le matériel devint indisponible. Pour répondre à cette contrainte, il a fallu se tourner vers les simulateurs pour robotique.&amp;lt;br&amp;gt;&lt;br /&gt;
Le projet initial avait pour but de programmer des robots capables de suivre une personne en détectant la source de chaleur qu'elle émet. Le cahier des charges de base était l'utilisation d'une caméra thermique et de faire communiquer le robot principale avec les autres robots pour les faire suivre le robot principal.&amp;lt;br&amp;gt;&lt;br /&gt;
Il a donc fallu dans un premier temps déterminer quel simulateur était le plus adapté à notre utilisation, puis adapter notre cahier des charges en fonction des  technologies disponibles sur le simulateur.&lt;br /&gt;
L'objectif est donc de respecter le cahier des charges suivant :&lt;br /&gt;
&lt;br /&gt;
* Le projet, en plus d'un robot principal suivant un être vivant, doit intégrer des robots suiveurs de robots, capables de communiquer entre eux et avec le robot principal.&lt;br /&gt;
* Certains capteurs de distances doivent être utilisés pour éviter une collision avec un obstacle quelconque.&lt;br /&gt;
* Le robot principal doit intégrer une caméra thermique pour suivre sa cible. Puisque ce composant n'existe pas sur notre simulateur, on le simulera avec une caméra classique, suivant un objet rouge représentant un corps chaud. &lt;br /&gt;
&lt;br /&gt;
L'objectif n'étant pas de construire un robot de zéro, nous somme reparti d'une base existante intégrant les éléments essentiels au projet. En fin de projet, le but sera de coller le plus possible à une situation réelle, que nous aurions pu obtenir en utilisant le matériel fourni.&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Poulain |Matthieu Poulain]], [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago de Almeida Ribeiro]], [[Utilisateur:‎SamuelT |Samuel Tauleigne]], [[Utilisateur:‎ Mickael | Mickaël Faure]], [[Utilisateur:‎Léane |Léane Geoffroy]], [[Utilisateur:‎Louis.sage |Louis Sage]], [[Utilisateur:‎Raphaele.milan |Raphaele Milan]], [[Utilisateur:‎Clément Luton |Clément Luton]]&lt;br /&gt;
&lt;br /&gt;
==Objectifs de départ (en situation de confinement)==&lt;br /&gt;
&lt;br /&gt;
*Choisir le bon simulateur&lt;br /&gt;
&lt;br /&gt;
*Simuler une personne&lt;br /&gt;
&lt;br /&gt;
*Choisir la bonne technologie de suivi pour le robot maître&lt;br /&gt;
&lt;br /&gt;
*Choisir la bonne technologie de suivi pour les robots esclaves&lt;br /&gt;
&lt;br /&gt;
==Éléments du projet==&lt;br /&gt;
*[[Robots suiveurs 3 - Choix du simulateur | Choix du simulateur]]&amp;lt;br&amp;gt;&lt;br /&gt;
*[[Robots suiveurs 3 - Tutoriels | Tutoriels simulateur]] &amp;lt;br&amp;gt;&lt;br /&gt;
*[[Robots suiveurs 3 - Tableau de Bord | Déroulement du projet - Tableau de Bord ]]&amp;lt;br&amp;gt;&lt;br /&gt;
*[[Robots suiveurs 3 - Codes  | Accès aux Codes]]&amp;lt;br&amp;gt;&lt;br /&gt;
*[[Robots suiveurs 3 - Capteurs  | Description des capteurs]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Étapes suivies==&lt;br /&gt;
 &lt;br /&gt;
Pour une explication plus détaillée du déroulement du projet, référez-vous à la partie [[Robots suiveurs 3 - Tableau de Bord | Déroulement du projet - Tableau de Bord ]].&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Réalisation d’un robot pilotable manuellement avec les touches du clavier&lt;br /&gt;
*Réalisation d’un robot suiveur basé sur des capteurs de distance&lt;br /&gt;
*Réalisation d’un robot suiveur basé sur une caméra pour simuler une caméra thermique&lt;br /&gt;
*Réalisation d’un robot suiveur basé sur des protocoles de communication&lt;br /&gt;
&lt;br /&gt;
==Résultat final==&lt;br /&gt;
&lt;br /&gt;
Au final, nous avons quatre robots:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
*Un robot simulant un humain. Il est contrôlable via le clavier et est entièrement rouge pour simuler la source de chaleur. Son controller s'appelle [[Robots suiveurs 3 - Code Contrôle au Clavier | RobotHumain]]&lt;br /&gt;
&lt;br /&gt;
*Un robot qu’on appelle robot maître. Il se dirige grâce à une caméra qui détecte la couleur rouge et communique avec un des robots esclaves pour diriger ce dernier. Son controller s'appelle [[Robots suiveurs 3 - Code RobotCamera | RobotCamera]].&lt;br /&gt;
&lt;br /&gt;
*Un robot mixte qui est à la fois maître et esclave. Il se dirige en communiquant avec le robot maître et communique en même temps avec le dernier robot. Son controller s'appelle [[Robots suiveurs 3 - Code emitter-receiver | RobotEmitterReceiver]].&lt;br /&gt;
&lt;br /&gt;
*Un robot esclave. Il se dirige en communiquant avec le robot mixte. Son controller s'appelle [[Robots suiveurs 3 - Code RobotReceiver| RobotReceiver]].&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Chacun des robots est équipé de capteurs de distance qui leurs permettent d’éviter des obstacles, de contrôler la vitesse à l’approche d’obstacle et d'empêcher les collisions entre robots. &lt;br /&gt;
&lt;br /&gt;
Les robots se suivent à la fil indienne et leur ordre dépend de leur controller: robot humain, robot maître, robot mixte puis robot esclave.&lt;br /&gt;
&lt;br /&gt;
GIF FONCTIONNEMENT + dépôt du monde complet&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10934</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10934"/>
		<updated>2020-05-12T14:18:40Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Evitement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
=== Fusion de Code ===&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons choisi d'exporter les robots édités des différentes simulations dans une nouvelle scène. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|500px|thumb|right|Importer un robot]]  [[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie gestion de l'émetteur et émission de message du controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] (partie communication) au controller utilisé pour suivre le robot rouge (partie détection de couleur).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;br /&gt;
&lt;br /&gt;
=== Evitement ===&lt;br /&gt;
&lt;br /&gt;
Les robots, en fonction de leur position dans la file, ayant des fonctions différentes (suivi d’un robot par analyse colorimétrique ou suivi d’un robot par communication sans fil), il est nécessaire d’adapter le code d’évitement pour ne pas interférer avec les fonctions de suivi. Ainsi la fonction d'évitement se base toujours sur le même principe, mais l’implémentation se fait de façon différente pour chaque controller, avec des contraintes plus ou moins complexes. &lt;br /&gt;
&lt;br /&gt;
Tous les robots évitent les obstacles grâce aux capteurs de distance, mais ils doivent différencier les robots qu’ils suivent des obstacles quelconques. Pour cela, le robot maître utilise la quantité de pixels rouges dans l’image de la câmera au moment de la détection de l’obstacle, pendant que le maître-esclave et l'esclave utilisent la force du signal de communication. Dans ce dernier cas, la vérification est faite même avant la détection des obstacles, de façon à arrêter les robots. &lt;br /&gt;
&lt;br /&gt;
De plus, on a aussi implémenté une fonction pour réduire la vitesse des robots au fur et à mesure qu’ils s’approchent de son but (robot à suivre), en utilisant un produit en croix. &lt;br /&gt;
&lt;br /&gt;
À la fin, on avait les controllers : [[Robots suiveurs 3 - Code Contrôle au Clavier |Clavier_Control]], [[Robots suiveurs 3 - Contrôleur Maître | maître]], [[Robots suiveurs 3 - Contrôleur Maître-Esclave | maître-esclave]] et [[Robots suiveurs 3 - Contrôleur Esclave | esclave]].&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3&amp;diff=10933</id>
		<title>Robots suiveurs 3</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3&amp;diff=10933"/>
		<updated>2020-05-12T14:16:10Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Résultat final */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Robot suiveur 2019/2020&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Le but du projet est de faire suivre une personne par une file indienne de robots.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Présentation du projet ==&lt;br /&gt;
&lt;br /&gt;
Dans la continuité du travail ayant été réalisé les années précédentes sur les sujets Robots Suiveurs 1 et 2, notre objectif initial était, dans cette 3ème itération du projet, de poursuivre leur développement tout en améliorant les fonctionnalités disponibles. Cependant, suite à l'apparition du covid-19 et au confinement s'en suivant, le matériel devint indisponible. Pour répondre à cette contrainte, il a fallu se tourner vers les simulateurs pour robotique.&amp;lt;br&amp;gt;&lt;br /&gt;
Le projet initial avait pour but de programmer des robots capables de suivre une personne en détectant la source de chaleur qu'elle émet. Le cahier des charges de base était l'utilisation d'une caméra thermique et de faire communiquer le robot principale avec les autres robots pour les faire suivre le robot principal.&amp;lt;br&amp;gt;&lt;br /&gt;
Il a donc fallu dans un premier temps déterminer quel simulateur était le plus adapté à notre utilisation, puis adapter notre cahier des charges en fonction des  technologies disponibles sur le simulateur.&lt;br /&gt;
L'objectif est donc de respecter le cahier des charges suivant :&lt;br /&gt;
&lt;br /&gt;
* Le projet, en plus d'un robot principal suivant un être vivant, doit intégrer des robots suiveurs de robots, capables de communiquer entre eux et avec le robot principal.&lt;br /&gt;
* Certains capteurs de distances doivent être utilisés pour éviter une collision avec un obstacle quelconque.&lt;br /&gt;
* Le robot principal doit intégrer une caméra thermique pour suivre sa cible. Puisque ce composant n'existe pas sur notre simulateur, on le simulera avec une caméra classique, suivant un objet rouge représentant un corps chaud. &lt;br /&gt;
&lt;br /&gt;
L'objectif n'étant pas de construire un robot de zéro, nous somme reparti d'une base existante intégrant les éléments essentiels au projet. En fin de projet, le but sera de coller le plus possible à une situation réelle, que nous aurions pu obtenir en utilisant le matériel fourni.&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Poulain |Matthieu Poulain]], [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago de Almeida Ribeiro]], [[Utilisateur:‎SamuelT |Samuel Tauleigne]], [[Utilisateur:‎ Mickael | Mickaël Faure]], [[Utilisateur:‎Léane |Léane Geoffroy]], [[Utilisateur:‎Louis.sage |Louis Sage]], [[Utilisateur:‎Raphaele.milan |Raphaele Milan]], [[Utilisateur:‎Clément Luton |Clément Luton]]&lt;br /&gt;
&lt;br /&gt;
==Objectifs de départ (en situation de confinement)==&lt;br /&gt;
&lt;br /&gt;
*Choisir le bon simulateur&lt;br /&gt;
&lt;br /&gt;
*Simuler une personne&lt;br /&gt;
&lt;br /&gt;
*Choisir la bonne technologie de suivi pour le robot maître&lt;br /&gt;
&lt;br /&gt;
*Choisir la bonne technologie de suivi pour les robots esclaves&lt;br /&gt;
&lt;br /&gt;
==Éléments du projet==&lt;br /&gt;
*[[Robots suiveurs 3 - Choix du simulateur | Choix du simulateur]]&amp;lt;br&amp;gt;&lt;br /&gt;
*[[Robots suiveurs 3 - Tutoriels | Tutoriels simulateur]] &amp;lt;br&amp;gt;&lt;br /&gt;
*[[Robots suiveurs 3 - Tableau de Bord | Déroulement du projet - Tableau de Bord ]]&amp;lt;br&amp;gt;&lt;br /&gt;
*[[Robots suiveurs 3 - Codes  | Accès aux Codes]]&amp;lt;br&amp;gt;&lt;br /&gt;
*[[Robots suiveurs 3 - Capteurs  | Description des capteurs]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Étapes suivies==&lt;br /&gt;
 &lt;br /&gt;
Pour une explication plus détaillée du déroulement du projet, référez-vous à la partie [[Robots suiveurs 3 - Tableau de Bord | Déroulement du projet - Tableau de Bord ]].&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Réalisation d’un robot pilotable manuellement avec les touches du clavier&lt;br /&gt;
*Réalisation d’un robot suiveur basé sur des capteurs de distance&lt;br /&gt;
*Réalisation d’un robot suiveur basé sur une caméra pour simuler une caméra thermique&lt;br /&gt;
*Réalisation d’un robot suiveur basé sur des protocoles de communication&lt;br /&gt;
&lt;br /&gt;
==Résultat final==&lt;br /&gt;
&lt;br /&gt;
Au final, nous avons quatre robots:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
*Un robot simulant un humain. Il est contrôlable via le clavier et est entièrement rouge pour simuler la source de chaleur. Son controller s'appelle [[Robots suiveurs 3 - Code Contrôle au Clavier |Clavier_Control]]&lt;br /&gt;
&lt;br /&gt;
*Un robot qu’on appelle robot maître. Il se dirige grâce à une caméra qui détecte la couleur rouge et communique avec un des robots esclaves pour diriger ce dernier. Son controller s'appelle [[Robots suiveurs 3 - Contrôleur Maître | maître]].&lt;br /&gt;
&lt;br /&gt;
*Un robot mixte qui est à la fois maître et esclave. Il se dirige en communiquant avec le robot maître et communique en même temps avec le dernier robot. Son controller s'appelle [[Robots suiveurs 3 - Contrôleur Maître-Esclave | maître-esclave]].&lt;br /&gt;
&lt;br /&gt;
*Un robot esclave. Il se dirige en communiquant avec le robot mixte. Son controller s'appelle [[Robots suiveurs 3 - Contrôleur Esclave | esclave]].&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Chacun des robots est équipé de capteurs de distance qui leurs permettent d’éviter des obstacles, de contrôler la vitesse à l’approche d’obstacle et d'empêcher les collisions entre robots. &lt;br /&gt;
&lt;br /&gt;
Les robots se suivent à la fil indienne et leur ordre dépend de leur controller: robot humain, robot maître, robot mixte puis robot esclave.&lt;br /&gt;
&lt;br /&gt;
GIF FONCTIONNEMENT + dépôt du monde complet&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10932</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10932"/>
		<updated>2020-05-12T14:14:06Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Evitement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
=== Fusion de Code ===&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons choisi d'exporter les robots édités des différentes simulations dans une nouvelle scène. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|500px|thumb|right|Importer un robot]]  [[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie gestion de l'émetteur et émission de message du controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] (partie communication) au controller utilisé pour suivre le robot rouge (partie détection de couleur).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;br /&gt;
&lt;br /&gt;
=== Evitement ===&lt;br /&gt;
&lt;br /&gt;
Les robots, en fonction de leur position dans la file, ayant des fonctions différentes (suivi d’un robot par analyse colorimétrique ou suivi d’un robot par communication sans fil), il est nécessaire d’adapter le code d’évitement pour ne pas interférer avec les fonctions de suivi. Ainsi la fonction d'évitement se base toujours sur le même principe, mais l’implémentation se fait de façon différente pour chaque controller, avec des contraintes plus ou moins complexes. &lt;br /&gt;
&lt;br /&gt;
Tous les robots évitent les obstacles grâce aux capteurs de distance, mais ils doivent différencier les robots qu’ils suivent des obstacles quelconques. Pour cela, le robot maître utilise la quantité de pixels rouges dans l’image de la câmera au moment de la détection de l’obstacle, pendant que le maître-esclave et l'esclave utilisent la force du signal de communication. Dans ce dernier cas, la vérification est faite même avant la détection des obstacles, de façon à arrêter les robots. &lt;br /&gt;
&lt;br /&gt;
De plus, on a aussi implémenté une fonction pour réduire la vitesse des robots au fur et à mesure qu’ils s’approchent de son but (robot à suivre), en utilisant un produit en croix. &lt;br /&gt;
&lt;br /&gt;
À la fin, on avait les controllers : [[Robots suiveurs 3 - Code Contrôle au Clavier |Clavier_Control]], [[Robots suiveurs 3 - Controlêur Maître | maître]], [[Robots suiveurs 3 - Controlêur Maître-Esclave | maître-esclave]] et [[Robots suiveurs 3 - Controlêur Esclave | esclave]].&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10931</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10931"/>
		<updated>2020-05-12T14:13:47Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Fusion des méthodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
=== Fusion de Code ===&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons choisi d'exporter les robots édités des différentes simulations dans une nouvelle scène. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|500px|thumb|right|Importer un robot]]  [[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie gestion de l'émetteur et émission de message du controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] (partie communication) au controller utilisé pour suivre le robot rouge (partie détection de couleur).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;br /&gt;
&lt;br /&gt;
=== Evitement ===&lt;br /&gt;
&lt;br /&gt;
Les robots, en fonction de leur position dans la file, ayant des fonctions différentes (suivi d’un robot par analyse colorimétrique ou suivi d’un robot par communication sans fil), il est nécessaire d’adapter le code d’évitement pour ne pas interférer avec les fonctions de suivi. Ainsi la fonction d'évitement se base toujours sur le même principe, mais l’implémentation se fait de façon différente pour chaque controller, avec des contraintes plus ou moins complexes. &lt;br /&gt;
&lt;br /&gt;
Tous les robots évitent les obstacles grâce aux capteurs de distance, mais ils doivent différencier les robots qu’ils suivent des obstacles quelconques. Pour cela, le robot maître utilise la quantité de pixels rouges dans l’image de la câmera au moment de la détection de l’obstacle, pendant que le maître-esclave et l'esclave utilisent la force du signal de communication. Dans ce dernier cas, la vérification est faite même avant la détection des obstacles, de façon à arrêter les robots. &lt;br /&gt;
&lt;br /&gt;
De plus, on a aussi implémenté une fonction pour réduire la vitesse des robots au fur et à mesure qu’ils s’approchent de son but (robot à suivre), en utilisant un produit en croix. &lt;br /&gt;
&lt;br /&gt;
À la fin, on avait les controllers : [[Robots suiveurs 3 - Code Contrôle au Clavier |Clavier_Control]], [Robots suiveurs 3 - Controlêur Maître | maître], [Robots suiveurs 3 - Controlêur Maître-Esclave | maître-esclave] et [Robots suiveurs 3 - Controlêur Esclave | esclave]&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10930</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10930"/>
		<updated>2020-05-12T14:10:12Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Fusion de Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
=== Fusion de Code ===&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons choisi d'exporter les robots édités des différentes simulations dans une nouvelle scène. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|500px|thumb|right|Importer un robot]]  [[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie gestion de l'émetteur et émission de message du controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] (partie communication) au controller utilisé pour suivre le robot rouge (partie détection de couleur).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10929</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10929"/>
		<updated>2020-05-12T14:09:32Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Fusion de Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
=== Fusion de Code ===&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons choisi d'exporter les robots édités des différentes simulations dans une nouvelle scène. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|500px|thumb|right|Importer un robot]]  [[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie gestion de l'émetteur et émission de message du controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] (partie communication) au controller utilisé pour suivre le robot rouge (partie détection de couleur).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10919</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10919"/>
		<updated>2020-05-12T13:01:39Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Fusion de Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
=== Fusion de Code ===&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela nous avons exporté les robots des différentes simulations sur la scène créée. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier. &lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie gestion de l'émetteur et émission de message du controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] (partie communication) au controller utilisé pour suivre le robot rouge (partie détection de couleur).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|500px|thumb|right|Importer un robot]]&lt;br /&gt;
[[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10918</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10918"/>
		<updated>2020-05-12T13:01:16Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Fusion des méthodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
=== Fusion de Code ===&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela nous avons exporté les robots des différentes simulations sur la scène créée. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier. &lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie gestion de l'émetteur et émission de message du controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] (partie communication) au controller utilisé pour suivre le robot rouge (partie détection de couleur).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|300px|thumb|right|Importer un robot]]&lt;br /&gt;
[[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10917</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10917"/>
		<updated>2020-05-12T12:33:26Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Fusion des méthodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela nous avons exporté les robots des différentes simulations sur la scène créée. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier. &lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie gestion de l'émetteur et émission de message du controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] (partie communication) au controller utilisé pour suivre le robot rouge (partie détection de couleur).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:import_robot.jpg|300px|thumb|right|Importer un robot]]&lt;br /&gt;
[[Fichier:export_robot.jpg|300px|thumb|left|Exporter un robot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10916</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10916"/>
		<updated>2020-05-12T12:27:31Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Fusion des méthodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour se faire suivre des robots en les faisant communiquer. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu ajouter les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pour celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, existant en tant qu'exemple dans le logiciel. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu ajouter les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet un message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable de ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et de 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;br /&gt;
&lt;br /&gt;
== Fusion des méthodes ==&lt;br /&gt;
Une fois l’ensemble des codes fonctionnel, nous nous sommes lancés dans la mise en place d’une simulation comprenant l’ensemble de ces derniers.&lt;br /&gt;
&lt;br /&gt;
Pour cela nous avons exporté les robots des différentes simulations sur la scène créée. Dans le monde où le robot a été créé, il faut faire un clic droit sur le nom du robot dans la scene tree et après cliquer sur “Export”. Cela crée un fichier .wbo à sauvegarder là où vous le voulez et, dans le nouveau monde, cliquer sur “Import...” dans la fenêtre d’ajout de nœuds pour aller chercher le fichier. &lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite implémenté les codes nécessaires à chacun des robots et harmonisé les fonctionnements. Plus précisément, il a fallu ajouter la partie gestion de l'émetteur et émission de message du controller [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]] (partie communication) au controller utilisé pour suivre le robot rouge (partie détection de couleur).&lt;br /&gt;
&lt;br /&gt;
Une fois cette fusion faite, il manquait encore la fonction d’évitement des obstacles que nous avons mises en place à ce moment.&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Fichier:Import_robot.jpg&amp;diff=10915</id>
		<title>Fichier:Import robot.jpg</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Fichier:Import_robot.jpg&amp;diff=10915"/>
		<updated>2020-05-12T12:26:33Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Fichier:Export_robot.jpg&amp;diff=10914</id>
		<title>Fichier:Export robot.jpg</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Fichier:Export_robot.jpg&amp;diff=10914"/>
		<updated>2020-05-12T12:26:06Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Code_D%C3%A9tection_couleur_(Robot_suivi)&amp;diff=10907</id>
		<title>Robots suiveurs 3 - Code Détection couleur (Robot suivi)</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Code_D%C3%A9tection_couleur_(Robot_suivi)&amp;diff=10907"/>
		<updated>2020-05-12T11:39:02Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;webots/Robot.hpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Added a new include file&lt;br /&gt;
#include &amp;lt;webots/Motor.hpp&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/Keyboard.hpp&amp;gt;  // Ajout de la bibliothèque gérant les événements clavier.&lt;br /&gt;
#define TIME_STEP 64&lt;br /&gt;
&lt;br /&gt;
#define MAX_SPEED 6.28&lt;br /&gt;
&lt;br /&gt;
// All the webots classes are defined in the &amp;quot;webots&amp;quot; namespace&lt;br /&gt;
using namespace webots;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv) {&lt;br /&gt;
Robot *robot = new Robot();&lt;br /&gt;
&lt;br /&gt;
 // get a handler to the motors and set target position to infinity (speed control)&lt;br /&gt;
 Motor *leftMotor = robot-&amp;gt;getMotor(&amp;quot;left wheel motor&amp;quot;);&lt;br /&gt;
 Motor *rightMotor = robot-&amp;gt;getMotor(&amp;quot;right wheel motor&amp;quot;);&lt;br /&gt;
 leftMotor-&amp;gt;setPosition(INFINITY);&lt;br /&gt;
 rightMotor-&amp;gt;setPosition(INFINITY);&lt;br /&gt;
&lt;br /&gt;
 // Initialisation des moteurs à une vitesse nulle&lt;br /&gt;
 leftMotor-&amp;gt;setVelocity(0);&lt;br /&gt;
 rightMotor-&amp;gt;setVelocity(0);&lt;br /&gt;
&lt;br /&gt;
// Initialisation de l'objet clavier&lt;br /&gt;
 Keyboard keyboard = Keyboard();&lt;br /&gt;
 keyboard.enable(50); // Activation de la détection des événements. La suite du code ne marchera pas sans cette option&lt;br /&gt;
&lt;br /&gt;
 while (robot-&amp;gt;step(TIME_STEP) != -1){&lt;br /&gt;
 &lt;br /&gt;
   int key = keyboard.getKey(); // Détecte le code clavier retourné en fonction de la touche pressée&lt;br /&gt;
 &lt;br /&gt;
   &lt;br /&gt;
   if (key == -1) { // Si le code retourné est -1, aucune touche n'est enfoncée, il faut donc arrêter le robot&lt;br /&gt;
           leftMotor-&amp;gt;setVelocity(0);&lt;br /&gt;
           rightMotor-&amp;gt;setVelocity(0);&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
    while (key &amp;gt; 0) {&lt;br /&gt;
      switch (key) {&lt;br /&gt;
        &lt;br /&gt;
        case 'Z': // Cas Z enfoncé : On applique la vitesse maximale pour avancer&lt;br /&gt;
           leftMotor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
           rightMotor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
           &lt;br /&gt;
          break;&lt;br /&gt;
        case 'S': //Cas S enfoncé : On applique la vitesse maximale négative pour reculer&lt;br /&gt;
           leftMotor-&amp;gt;setVelocity(-MAX_SPEED);&lt;br /&gt;
           rightMotor-&amp;gt;setVelocity(-MAX_SPEED);&lt;br /&gt;
          break;&lt;br /&gt;
        case 'Q': //Cas Q enfoncé : On applique une vitesse à une roue et l'inverse à l'autre pour pivoter à gauche. Au delà de 0.5 fois la vitesse maximale appliquée, la simulation de déplacement du robot saccade.&lt;br /&gt;
          leftMotor-&amp;gt;setVelocity(-0.49*MAX_SPEED);&lt;br /&gt;
           rightMotor-&amp;gt;setVelocity(0.49*MAX_SPEED);&lt;br /&gt;
          break;&lt;br /&gt;
        case 'D': //Cas D enfoncé : On applique une vitesse à une roue et l'inverse à l'autre pour pivoter à droite. Au delà de 0.5 fois la vitesse maximale appliquée, la simulation de déplacement du robot saccade.&lt;br /&gt;
          leftMotor-&amp;gt;setVelocity(0.49*MAX_SPEED);&lt;br /&gt;
           rightMotor-&amp;gt;setVelocity(-0.49*MAX_SPEED);&lt;br /&gt;
          break;&lt;br /&gt;
&lt;br /&gt;
        //Cas A et E enfoncé : On applique une vitesse à une roue et une vitesse moins élevée à l'autre pour pivoter tout en avançant. Au delà de 0.75 fois la vitesse maximale appliquée, la simulation du déplacement du robot saccade aussi.&lt;br /&gt;
        case 'A': &lt;br /&gt;
             leftMotor-&amp;gt;setVelocity(0.5*MAX_SPEED);&lt;br /&gt;
             rightMotor-&amp;gt;setVelocity(0.75*MAX_SPEED);&lt;br /&gt;
          break;&lt;br /&gt;
          case 'E':&lt;br /&gt;
             leftMotor-&amp;gt;setVelocity(0.75*MAX_SPEED);&lt;br /&gt;
             rightMotor-&amp;gt;setVelocity(0.5*MAX_SPEED);&lt;br /&gt;
          break;&lt;br /&gt;
        default: //Pour toute autre touche on arrête le robot&lt;br /&gt;
           leftMotor-&amp;gt;setVelocity(0);&lt;br /&gt;
           rightMotor-&amp;gt;setVelocity(0);&lt;br /&gt;
          break;&lt;br /&gt;
      }&lt;br /&gt;
      key = keyboard.getKey(); // Actualisation de la sortie clavier.&lt;br /&gt;
      &lt;br /&gt;
      &lt;br /&gt;
       &lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
 delete robot;&lt;br /&gt;
&lt;br /&gt;
 return 0;&lt;br /&gt;
}&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Code_Tutoriel_Communication&amp;diff=10896</id>
		<title>Robots suiveurs 3 - Code Tutoriel Communication</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Code_Tutoriel_Communication&amp;diff=10896"/>
		<updated>2020-05-12T06:29:04Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Le contrôleur et la communication */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Pour ce tutoriel, on partira 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 la 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 [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], mais ont des comportements différents en fonction de leur noms. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:emitter_receiver.gif|400px|thumb|left|fonctionnement des robots (cliquez pour jouer le GIF)]]&lt;br /&gt;
&lt;br /&gt;
[[Fichier:console_emitter_receiver.jpg|400px|thumb|right|Messages sur le console]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Le contrôleur et la communication ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il faut ajouter les bibliothèques pour l’émetteur et le récepteur. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/emitter.h&amp;gt;&lt;br /&gt;
#include &amp;lt;webots/receiver.h&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
WbDeviceTag communication; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
communication = wb_robot_get_device(&amp;quot;emitter&amp;quot;); &lt;br /&gt;
wb_emitter_set_channel(communication, COMMUNICATION_CHANNEL); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
communication = wb_robot_get_device(&amp;quot;receiver&amp;quot;);&lt;br /&gt;
wb_receiver_enable(communication, TIME_STEP); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En C++, cela devient : &lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Emitter *emitter = robot-&amp;gt;getEmitter(&amp;quot;emitter&amp;quot;);&lt;br /&gt;
emitter-&amp;gt;setChannel(COMMUNICATION_CHANNEL); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Receiver *receiver = robot-&amp;gt;getReceiver(&amp;quot;receiver&amp;quot;);&lt;br /&gt;
receiver-&amp;gt;setChannel(COMMUNICATION_CHANNEL); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On remarque que, dans ce cas, l’habilitation du récepteur est faite en choisissant le canal de communication. &lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
const char *message = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
wb_emitter_send(communication, message, strlen(message) + 1);  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
/* is there at least one packet in the receiver's queue ? */&lt;br /&gt;
if (wb_receiver_get_queue_length(communication) &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
     /* read current packet's data */&lt;br /&gt;
     const char *buffer = wb_receiver_get_data(communication);&lt;br /&gt;
&lt;br /&gt;
     if (message_printed != 1) {&lt;br /&gt;
          /* print null-terminated message */&lt;br /&gt;
          printf(&amp;quot;Communicating: received \&amp;quot;%s\&amp;quot;\n&amp;quot;, buffer);&lt;br /&gt;
          message_printed = 1;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     /* fetch next packet */&lt;br /&gt;
     wb_receiver_next_packet(communication);&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
&lt;br /&gt;
     if (message_printed != 2) {&lt;br /&gt;
          printf(&amp;quot;Communication broken!\n&amp;quot;);&lt;br /&gt;
          message_printed = 2;&lt;br /&gt;
     }&lt;br /&gt;
} &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En C++  :&lt;br /&gt;
&lt;br /&gt;
* '''Émetteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
const char *message = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
emitter-&amp;gt;send(message, strlen(message) + 1); &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Récepteur :'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
if (receiver-&amp;gt;getQueueLength() &amp;gt; 0) &lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
     /* read current packet's data */&lt;br /&gt;
     const char *buffer = (const char*)receiver-&amp;gt;getData();&lt;br /&gt;
     const double *position= receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
&lt;br /&gt;
     /* print null-terminated message */&lt;br /&gt;
     if (message_printed != 1) {&lt;br /&gt;
          printf(&amp;quot;Communicating: received \&amp;quot;%s\&amp;quot;\n&amp;quot;, buffer);&lt;br /&gt;
          message_printed = 1;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     /* fetch next packet */&lt;br /&gt;
     receiver-&amp;gt;nextPacket();&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
&lt;br /&gt;
     if (message_printed != 2) &lt;br /&gt;
     {&lt;br /&gt;
          printf(&amp;quot;Communication broken!\n&amp;quot;);&lt;br /&gt;
          message_printed = 2;&lt;br /&gt;
     }&lt;br /&gt;
} &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10895</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10895"/>
		<updated>2020-05-12T06:28:26Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* IV) Communication entre robots */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== I) Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== II) Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== III) Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== IV) Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour faire suivre des robots esclaves à un robot maître, en utilisant la communication entre eux. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu additionner les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pou celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, trouvé dans un monde de base homonyme. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu additionner les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet une message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable pour ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir le canal de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit de faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== V) Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== V) Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10894</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10894"/>
		<updated>2020-05-12T06:27:21Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Fonctions Disponibles (en C++) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du buffer de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infra-red&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire buffer, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength (ou getSignalStrength() en C++). Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction (ou getEmitterDirection() en C++). Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie le nombre d'octets de données présents dans le paquet de tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10893</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10893"/>
		<updated>2020-05-12T06:25:17Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Receiver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du buffer de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infra-red&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire buffer, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength (ou getSignalStrength() en C++). Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction (ou getEmitterDirection() en C++). Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10892</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10892"/>
		<updated>2020-05-12T06:23:17Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Receiver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du buffer de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infra-red&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire buffer, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength (ou getSignalStrength() en C++). Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction (ou getEmitterDirection() en C++). Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10891</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10891"/>
		<updated>2020-05-12T06:22:48Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Receiver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du buffer de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infra-red&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire buffer, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength (ou getSignalStrength() en C++). Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10890</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10890"/>
		<updated>2020-05-12T06:21:37Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Receiver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du buffer de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infra-red&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire buffer, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10889</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10889"/>
		<updated>2020-05-12T06:20:39Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Receiver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du buffer de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infra-red&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10888</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10888"/>
		<updated>2020-05-12T06:18:58Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Description des champs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du buffer de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10887</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10887"/>
		<updated>2020-05-12T06:16:31Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Receiver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&amp;lt;/br&amp;gt;&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10886</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10886"/>
		<updated>2020-05-12T06:16:10Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Description des champs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10885</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10885"/>
		<updated>2020-05-12T06:15:57Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Receiver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10884</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10884"/>
		<updated>2020-05-12T06:15:24Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Description des champs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10883</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10883"/>
		<updated>2020-05-12T06:13:59Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Receiver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré. Voir cette figure pour une illustration de la plage et de l'ouverture.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' taille (en octets) du buffer de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10882</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10882"/>
		<updated>2020-05-12T06:08:52Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Description des champs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infra-red&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré. Voir cette figure pour une illustration de la plage et de l'ouverture.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' staille (en octets) du tampon de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10881</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10881"/>
		<updated>2020-05-12T06:07:32Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Description des champs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| SFVec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| SFFloat&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| SFFloat&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG|vignette|center|Fonction de transfert du capteur de distance]]&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Méthode'''&lt;br /&gt;
| '''Paramètres'''&lt;br /&gt;
| '''Description'''&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infrarouge&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré. Voir cette figure pour une illustration de la plage et de l'ouverture.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' staille (en octets) du tampon de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10875</id>
		<title>Robots suiveurs 3 - Tableau de Bord</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Tableau_de_Bord&amp;diff=10875"/>
		<updated>2020-05-11T15:27:10Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* IV) Communication entre robots */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== I) Description du simulateur ==&lt;br /&gt;
&lt;br /&gt;
Le logiciel [https://cyberbotics.com/#cyberbotics Webots] est un simulateur robotique 3D OpenSource fonctionnant sous Windows, Mac OS et Linux.&lt;br /&gt;
&lt;br /&gt;
Ce logiciel est très facile à prendre en main car il suffit de l'installer, de le lancer et de jouer avec les exemples livrés avec le logiciel.&amp;lt;br&amp;gt;&lt;br /&gt;
Il existe aussi un [https://cyberbotics.com/doc/guide/tutorials?tab-language=c++ tutoriel] très facile d'accès, très documenté permettant de comprendre la logique du logiciel et d'être rapidement en capacité de créer sa propre simulation.&amp;lt;br&amp;gt;&lt;br /&gt;
Ce qui en fait aussi un logiciel très facile d'accès est la possibilité de l'utiliser avec plusieurs langages de programmation grâce à des API complètes.&amp;lt;br&amp;gt;&lt;br /&gt;
En effet, les robots peuvent être contrôlés via du C, C++, Python, Java et MATLAB. On peut aussi utiliser [https://www.ros.org/ ROS].&amp;lt;br&amp;gt;&lt;br /&gt;
Les tests sont aussi très agréables à réaliser puisqu'on peut interagir avec le robot et son environnement pendant le test.&lt;br /&gt;
&lt;br /&gt;
=== Création d'un espace de test 3D ===&lt;br /&gt;
&lt;br /&gt;
Le logiciel propose à l'utilisateur de créer un espace de test 3D en ajoutant toutes sortes d'éléments.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent être des formes élémentaires : alors le travail fait par l'utilisateur se rapprochera d'un travail de [https://fr.wikipedia.org/wiki/Conception_assist%C3%A9e_par_ordinateur CAO].&amp;lt;br&amp;gt;&lt;br /&gt;
Ces éléments peuvent aussi être des objets existant dans la [https://cyberbotics.com/doc/guide/objects base] fournie : du mobilier, des plantes, des fruits, des extincteurs, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour tous ces éléments, on peut configurer de nombreuses propriétés : leur masse, leur densité, les frottements auxquels ils sont soumis, leur taille, etc.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De même, pour les robots, il est possible d'en créer un à partir de rien mais beaucoup sont proposés dans la [https://cyberbotics.com/doc/guide/robots base de robots] : du petit robot éducatif [https://www.thymio.org/fr/ Thymio] au robot humanoïde Atlas de [https://www.bostondynamics.com/ Boston Dynamics].&lt;br /&gt;
&lt;br /&gt;
Et c'est la même chose pour les actionneurs et les capteurs : une base est fournie et décrite sur le site !&lt;br /&gt;
&lt;br /&gt;
=== Utilisation d'un controller ===&lt;br /&gt;
&lt;br /&gt;
Chaque robot peut être associé à un programme appelé controller dont le rôle est de définir le comportement du robot.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces controllers peuvent être écrits dans tous les langages supportés par Webots : C, C++, Python, Java, MATLAB. Dans les tutoriels, tous sont présentés mais nous avons choisi de travailler en C++ car tous les membres de l'équipe connaissaient ce langage. Notre objectif n'était pas d'apprendre un nouveau langage de programmation, et le C++ est tout de même très utilisé dans ce domaine.&amp;lt;br&amp;gt;&lt;br /&gt;
Au lancement de la simulation, le logiciel lancera un processus par controller utilisé sur chaque robot. On ne peut associer qu'un controller par robot (c'est l’exécutable qui est utilisé) mais on peut utiliser le même controller pour plusieurs robots : dans ce cas, des processus distincts seront créés pour chaque robot.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interface Graphique ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:WebotsGUI.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
L'interface graphique se découpe en plusieurs parties que l'on peut afficher dans différentes fenêtres.&amp;lt;br&amp;gt;&lt;br /&gt;
La fenêtre 3D permet d'afficher et de dérouler la simulation dans l'espace 3D créé plus tôt. Dans cette fenêtre, même pendant une simulation, on peut encore déplacer des objets, les faire tourner, les faire interagir pour tester le comportement de notre robot simulé.&amp;lt;br&amp;gt;&lt;br /&gt;
Le &amp;quot;Scene Tree&amp;quot; représente le monde 3D créé. Il comporte des blocs correspondant aux différents éléments créés ou importés tels que les objets ou les robots. En cliquant sur les flèches, il est possible de dérouler les propriétés accessibles sur un composant.&amp;lt;br&amp;gt;&lt;br /&gt;
La console, affichée par défaut en bas de l'écran permet de lire des informations de débug ou les résultats de compilation.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut aussi retrouver un éditeur de texte permettant de compiler le code écrit afin de le tester dans la simulation.&lt;br /&gt;
&lt;br /&gt;
[https://cyberbotics.com/doc/guide/the-user-interface Pour plus de détails sur les menus et l'interface graphique]&lt;br /&gt;
&lt;br /&gt;
== II) Déplacements contrôlés au clavier ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction===&lt;br /&gt;
&lt;br /&gt;
L'objectif de cette partie est d’implémenter la possibilité de contrôler un robot avec les touches classiques zqsd afin de permettre la réalisation de tests.&lt;br /&gt;
Pour ce faire, on faut créer un nouveau contrôleur : Wizards -&amp;gt; New Robot Controller.&lt;br /&gt;
Notre contrôleur sera nommé Clavier_Control et codé en C++. &lt;br /&gt;
Une fenêtre éditor s'ouvre alors. Pour gérer le contrôle des moteurs. Nous sommes partis de la base donnée en tutoriel à cette [https://www.cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots#extend-the-controller-to-speed-control adresse].&lt;br /&gt;
&lt;br /&gt;
Cette base donne les fondations pour pouvoir contrôler en vitesse les moteurs. C'est exactement ce dont nous avons besoin, puisque notre robot doit accélérer lorsqu'on le lui impose.&lt;br /&gt;
&lt;br /&gt;
=== Code===&lt;br /&gt;
&lt;br /&gt;
Le code suivant est commenté pour les parties liées au clavier. Le tutoriel concernant la gestion des moteurs sera explicité [[Robots suiveurs 3 - Code Tutoriel Contrôle moteurs | sur cette page]]&lt;br /&gt;
*[[Robots suiveurs 3 - Code Contrôle au Clavier |Voir le CODE]]&lt;br /&gt;
&lt;br /&gt;
L'idée générale derrière ce code est d'affecter aux moteurs une vitesse selon la touche enfoncée sur le clavier. On utilise Z et S pour respectivement avancer et reculer, Q et D pour pivoter à gauche ou à droite et enfin A et E pour avancer en pivotant légèrement.&lt;br /&gt;
Pour cela, on utilise un objet Keyboard existant dans la bibliothèque proposée par Webots.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
Le code du controller mis en place a pour but de permettre un contrôle manuel du robot. Cette fonction doit entre implantée en début de projet de façon assez rapide pour permettre aux autres équipes de réaliser des tests de façon simplifiée, en ayant la main sur les action du robot en développement.&lt;br /&gt;
&lt;br /&gt;
Les fonctions introduites ne sont pour autant pas Immuable, celles-ci pouvant être modifiées selon les besoins requis, les mouvement pouvant être adaptés.&lt;br /&gt;
On pourra de plus remarquer que l'utilisation du clavier nécessite d'avoir sélectionné la fenêtre de simulation 3D (en cliquant sur la scène 3D).&lt;br /&gt;
&lt;br /&gt;
== III) Robot Suiveur simple avec capteurs de distance ==&lt;br /&gt;
=== Description ===&lt;br /&gt;
[[Fichier:E_puck_capteurs.PNG|vignette|E_puck et ses capteurs]]&lt;br /&gt;
Dans cette partie, on devait réaliser un robot suiveur rudimentaire en utilisant 2 capteurs de distance afin de comprendre leur fonctionnement. le logiciel webots nous fourni déjà des robots préfait possédant une multitude de capteurs. On a donc utilisé le robot E-puck, possédant 2 roues et 8 capteurs de distances autour de lui (ainsi qu'une caméra, un émetteur et un récepteur).&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
*[[Code de robot suiveur via l'utilisation de capteurs | Code de robot suiveur via l'utilisation de capteurs ]]&lt;br /&gt;
Afin d'avoir un robot simple, on utilise seulement les 2 capteurs à l'avant du robot (un plutôt à droite et l'autre plutôt à gauche). Ces capteurs servent à détecter le robot de devant. On fixe un seuil de distance activant ou non 2 booléens &amp;quot;robot_a_droite/gauche&amp;quot;. On a donc 4 combinaisons différentes de ces booléens qui vont servir a commander notre robot:&lt;br /&gt;
     {| class=&amp;quot;wikitable alternance center&amp;quot;&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_droite&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | robot_a_gauche&lt;br /&gt;
 ! scope=&amp;quot;col&amp;quot; | résultat&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | faux&lt;br /&gt;
 | avancer&lt;br /&gt;
 |-&lt;br /&gt;
 | faux&lt;br /&gt;
 | vrai&lt;br /&gt;
 | tourner à gauche&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | vrai&lt;br /&gt;
 | stop&lt;br /&gt;
 |-&lt;br /&gt;
 | vrai&lt;br /&gt;
 | faux&lt;br /&gt;
 | tourner à droite&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
=== Résultats ===&lt;br /&gt;
Le résultat est plutôt satisfaisant vue sa simplicité. on remarque que les robots se suivent très bien les uns les autres vue qu'ils ont la même vitesse. Le comportement du premier robot est pas encore stable, mais comme il est censé suivre un humain, son fonctionnement va changer de toutes manières.&lt;br /&gt;
[[Fichier:Suiveur 1.gif|500px|center|4 robots suiveurs se suivant, le premier suit la caisse]]&lt;br /&gt;
&lt;br /&gt;
=== Suite ===&lt;br /&gt;
Les capteurs de distance on été utilisés ici pour suivre un robot, ou pourrait par la suite les utiliser pour éviter un obstacle. Il faudra pour cela éloigner les robots les uns des autres et leur faire suivre une commande à l'aide des autres parties réalisées.&lt;br /&gt;
&lt;br /&gt;
== IV) Communication entre robots ==&lt;br /&gt;
&lt;br /&gt;
'''Participants :'''&lt;br /&gt;
[[Utilisateur:‎Clément Luton |Clément Luton]] et [[Utilisateur:‎De-almeida-ribeiro.thiago |Thiago De Almeida Ribeiro]]&lt;br /&gt;
&lt;br /&gt;
Cette section a pour but d’expliquer comment utiliser le logiciel Webots pour faire suivre des robots esclaves à un robot maître, en utilisant la communication entre eux. La communication qui est permise par la simulation suit un protocole de communication série mais elle est transmise sans fil. &lt;br /&gt;
&lt;br /&gt;
Les deux premières sous-sections comportent les résultats auxquels on est arrivé dans les dates indiquées, pendant que la dernière section comporte les résultats finaux, avec le niveau de détail nécessaire pour comprendre le fonctionnement du code et du logiciel. Avant de continuer, il serait intéressant d’avoir lu le [[Robots suiveurs 3 - Code Tutoriel Communication | tutoriel d’explication de code sur les bases de communication sur Webots]] et la description des nodes Emitter et Receiver, sur la [[Robots suiveurs 3 - Capteurs | page de description des capteurs]]. &lt;br /&gt;
&lt;br /&gt;
=== Résultats initiaux (16/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Pour configurer la communication entre deux robots, au tout début, il a fallu additionner les robots au monde et exécuter la commande “Convert to Base Node(s)” (clique droit sur le robot dans le node tree). Cela a été nécessaire pour pouvoir changer quelques caractéristiques des robots, comme leur nom et la portée du signal émis (nécessaire pour le code en C mais pas pou celui en C++). &lt;br /&gt;
&lt;br /&gt;
Pour faire le code, on est parti du controller emitter_receiver, trouvé dans un monde de base homonyme. Nous avons eu deux démarches : une consistant à garder le code dans son langage, le C, est à l’adapter et une autre consistant à passer en C++ pour garder une cohésion avec le groupe entier qui code aussi en C++. Alors on a un [[Robots suiveurs 3 - Code Communication Initial (C) |code en C]] en un [[Robots suiveurs 3 - Code Communication Initial (C++) |code en C++]].&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas nous sommes arrivés à mettre en place une communication continue entre deux robots. Nous sommes capables de savoir si la communication se passe bien ou si elle est interrompue et nous avons réussi à transmettre au robot esclave la position relative (le robot esclave est utilisé comme origine d’un système de coordonnées) du robot maître. Nous allons utiliser ces données pour déplacer correctement le robot esclave. Dans ce moment, deux solutions s’offrent à nous :&lt;br /&gt;
&lt;br /&gt;
* Se déplacer selon l’axe des X puis l’axe des Z. &lt;br /&gt;
* Se déplacer selon l’hypoténuse formée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:deplacement_comm.png|300px|thumb|center|Schéma du déplacement]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats intérmédiaires (17/04/2020) ===&lt;br /&gt;
&lt;br /&gt;
Après un peu plus de réflexion, on a décidé d’utiliser un troisième approche pour le comportement suiveur (détaillé sur la prochaine section). On est partie du code en C++ écrit avant pour écrire le [[Robots suiveurs 3 - Code Communication Intermédiaire (maître) |code du robot maître]] et le [[Robots suiveurs 3 - Code Communication Intermédiaire (esclave) |code du robot esclave]]. On a pu contrôler le robot maître grâce au clavier et faire suivre le robot esclave grâce à la position du maître. La sphère blanche autour du robot maître représente la portée du signal de communication.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:suivi_position2.gif|400px|thumb|center|Le robot émetteur fait une ligne droite, le robot récepteur le suit]]&lt;br /&gt;
&lt;br /&gt;
=== Résultats finaux (05/05/2020) ===&lt;br /&gt;
&lt;br /&gt;
Maintenant on a deux robots esclaves et un robot maître. Le robot maître est contrôlé par le clavier et envoie sa position au premier esclave, celui-ci va suivre le maître et, à son tour, transmettre sa position au deuxième esclave, qui le suit.&lt;br /&gt;
&lt;br /&gt;
Au tout début, il a fallu additionner les 3 robots (e-pucks) à un monde créé préalablement. De plus, il est intéressant de réduire le pas de temps de la simulation (WorldInfo -&amp;gt; basicTimeStep -&amp;gt; 16) pour pouvoir augmenter sa précision et sa stabilité. &lt;br /&gt;
&lt;br /&gt;
Comme les trois robots fonctionnent de façon différente, il a fallu créer trois contrôleurs distincts : [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter&amp;quot;) |&amp;quot;emitter&amp;quot;]], pour le robot maître, [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;emitter-receiver&amp;quot;) |&amp;quot;emitter-receiver&amp;quot;]], pour le premier esclave, et [[Robots suiveurs 3 - Code Communication Final (controlêur &amp;quot;receiver&amp;quot;) |&amp;quot;receiver&amp;quot;]], pour le deuxième esclave. Pour concevoir les codes, on est parti du contrôleur [[Robots suiveurs 3 - Code “emitter_receiver”|“emitter_receiver”]], trouvé dans un [[Robots suiveurs 3 - Code Tutoriel Communication | monde de base homonyme]]. Comme ce dernier est écrit en C, il a fallu le traduire en C++ au préalable pour garder une cohésion avec le groupe. &lt;br /&gt;
&lt;br /&gt;
Le contrôleur “emitter” utilise un bout de code créé par d’autres intégrants du groupe pour permettre de contrôler le robot avec le clavier. De plus, il habilite et configure l'émetteur du robot et transmet une message quelconque. Le contrôleur “receiver” habilite et configure le récepteur du robot, affiche un message pour informer si la communication a été établie et permet de suivre un robot qui émet un message. Finalement, le contrôleur “emitter-receiver” est l'addition des deux contrôleurs antérieurs, sans la partie contrôle clavier. &lt;br /&gt;
&lt;br /&gt;
Pour le comportement suiveur, on utilise deux fonctions de base : “getEmitterDirection()” et “getSignalStrength()”. La première permet d’obtenir la position de l'émetteur par rapport au système de coordonnées du récepteur (vecteur normalisé avec 3 composants) et la deuxième la force du signal. Le bout de code suivant est responsable pour ce comportement.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
      const double *position=receiver-&amp;gt;getEmitterDirection();&lt;br /&gt;
      double signal=receiver-&amp;gt;getSignalStrength();&lt;br /&gt;
          &lt;br /&gt;
      if(signal&amp;gt;150) //Stop the robot if it's too close to the master&lt;br /&gt;
      {&lt;br /&gt;
        left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
      }&lt;br /&gt;
      else{&lt;br /&gt;
        //Following behavior&lt;br /&gt;
        if (position[0]&amp;lt;-0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
        else if(position[0]&amp;gt;0.1)&lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(0);&lt;br /&gt;
        }&lt;br /&gt;
        else &lt;br /&gt;
        {&lt;br /&gt;
          left_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
          right_motor-&amp;gt;setVelocity(MAX_SPEED);&lt;br /&gt;
        }&lt;br /&gt;
      } &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de la force du signal, il est possible de savoir si le récepteur est trop proche de l'émetteur, de façon à arrêter le robot esclave pour éviter une collision. En outre, la première coordonnée du vecteur position (axe rouge dans la figure ci dessous) permet de dire si le récepteur est approximativement derrière l'émetteur (-0,1 &amp;lt; position[0] &amp;lt; 0,1). Si c’est le cas, le robot doit aller tout droit, sinon, il doit tourner à gauche où à droite. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm0.jpg|400px|thumb|center|Système de coordonées]]&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement est illustré dans le GIF ci-dessous.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm1.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Jusqu’à ce moment, les robots étaient considérés sans défauts. Cela veut dire que l'on n'avait pas pris en compte le bruit dans la communication. Le récepteur possède deux variables qui peuvent être modifiées afin d’y ajouter le bruit :  &lt;br /&gt;
&lt;br /&gt;
*signalStrengthNoise : écart-type du bruit gaussien ajouté à la force du signal renvoyé par “getSignalStrength()”. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
&lt;br /&gt;
*directionNoise : écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par “getEmitterDirection()”. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
Vu que le logiciel ne possède pas de fonction de base pour effectuer cette modification (comme setChannel() pour choisir la chaîne de communication, par exemple), on doit modifier le node du récepteur directement. Pour pouvoir le faire, on doit de faire un clique droit sur le robot que l'on souhaite modifier dans la scene tree et après cliquer sur “Convert to Base Node(s)”. Après, il suffit d’aller sur “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et modifier les champs signalStrengthNoise et/ou directionNoise.&lt;br /&gt;
&lt;br /&gt;
Si on met un écart-type de 1 pour la direction, par exemple, on remarque que les robots continuent à suivre mais cela se fait d’une façon plus lente et irrégulière. Cela peut être un problème puisque le robot maître peut s’écarter des esclaves et la communication entre eux peut être coupée. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm2.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
L’ajout du bruit associé à la force du signal ne doit pas affecter le comportement suiveur, mais peut permettre une collision entre les robots. Si on met, par exemple, la valeur de 0,1, on remarque que cela peut arriver :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm3.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Cela peut être réglé en mettant 80, par exemple, au lieu de 150, dans la ligne de code ci-dessous :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 if(signal&amp;gt;150) //Stop the robot if it's too close to the master &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm4.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
Une deuxième solution serait d’utiliser les capteurs de distance du robot.&lt;br /&gt;
&lt;br /&gt;
Enfin, il est important de prendre en compte les type de signaux possibles pour l'émetteur et le récepteur : &amp;quot;radio&amp;quot;, &amp;quot;serie&amp;quot; ou &amp;quot;infra-red. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;serie&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Alors, si aucune modification n’est effectué, l'émetteur et le récepteur utilisent le type “radio” et les robots pourront communiquer même s’il y a un obstacle entre eux :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm5.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
En choisissant le type “infra-red”, cela ne serait pas possible. Pour faire cette modification il suffit de changer les champs “type” dans “Robot &amp;gt; children &amp;gt; DEF EPUCK_RECEIVER Receiver” et “Robot &amp;gt; children &amp;gt; DEF EPUCK_EMITTER Emitter” (après avoir fait un “Change to Base Node(s)”.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:comm6.gif|400px|thumb|center|Cliquez pour jouer le GIF]]&lt;br /&gt;
&lt;br /&gt;
== V) Mise en place de la scène ==&lt;br /&gt;
Pour modifier la scène nous nous sommes aidé du tutoriel disponible à cette [https://cyberbotics.com/doc/guide/tutorial-2-modification-of-the-environment adresse]. &amp;lt;br&amp;gt;&lt;br /&gt;
Comme dit précédemment l'interface graphique est plutôt intuitive et il est donc facile de modifier la scène. Tout se fait via le bouton Plus (Add) en haut à gauche entouré en rouge. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:ObjetsAdd.png ‎|500px|thumb|center|Modification scène]]&lt;br /&gt;
Une fois qu'on a cliqué dessus on peut choisir un élément de base (base nodes) ou des éléments déjà existants (Proto Nodes). Dans les éléments existants il y a des objets, des robots, des véhicules... Une fois l'élément choisi il va être placé au centre du sol. La touche MAJ en même temps qu'un clic gauche de la souris permet de le déplacer là où l'on souhaite. Cette manipulation est aussi possible via la fenêtre de paramètre de l'objet (accolade en rouge sur la photo).&amp;lt;br&amp;gt;&lt;br /&gt;
On peut ainsi choisir de déplacer l'objet via les paramètres de translation, de le tourner via la rotation et enfin de changer sa taille via scale.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour les objets déjà existants la méthode scale n'est pas directement accessible il faut faire un clic droit sur l'objet et sélectionner &amp;quot;convert to base nodes&amp;quot;. Une fois cette opération effectuée, les paramètres scale seront accessibles. &amp;lt;br&amp;gt;&lt;br /&gt;
Pour un objet de type solid on peut modifier la forme (Shape) via les paramètres (voir l'exemple du tutoriel situé en haut).&lt;br /&gt;
Pour changer le controller d'un robot voir le lien [https://ujm.webgroup.fr/index.php?title=Robots_suiveurs_3_-_Tutoriels#1.29_Ajouter_un_controller_existant_.C3.A0_un_robot suivant].&lt;br /&gt;
&lt;br /&gt;
== V) Robot avec détection de couleur ==&lt;br /&gt;
Le but est ici d'utiliser la caméra du robot E-Puck afin de de pouvoir suivre un objet de couleur, que l'on pourrai par exemple placer à l'arrière d'un robot pour que celui de derrière puisse le suivre. Nous avons dans un premier temps fait en sorte que le robot suive un objet rouge. Par la suite nous avons amélioré le système afin d'avoir plusieurs robot qui se suivent.&lt;br /&gt;
&lt;br /&gt;
=== Fonctionnement ===&lt;br /&gt;
Pour cela, nous utilisons des méthodes de la classe Camera permettant de capturer une image et de recueillir des informations sur le nombre de pixel rouge, vert ou bleu. Nous avons donc séparer l'image en 3 zones (milieu, gauche et droite) afin de compter le nombre de pixel d'une certaine couleur dans chacune de ces partie. Si ce derniers est supérieur au nombre de pixels des autres couleurs dans une zone, on effectue le déplacement correspondant (avancer, pivotage à gauche ou à droite). Nous avons aussi utiliser les capteurs de distance situés à l'avant du robot afin d’éviter une collision quand le robot se sera trop rapproché de l'objet qu'il suit. Voici notre premier essai, le robot suit uniquement un objet rouge qu'il faut déplacer à la main :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Suivi couleur.gif|500px|thumb|center|Suivi d'un cube de couleur rouge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nous avons ensuite ajouté des robots de couleurs différentes, dépendant tous d'un controller différent, afin que le premier robot (bleu) soit guidé par les commandes du clavier, que le deuxième (rouge) suive le robot bleu, le troisième (vert) suive le robot rouge, et le dernier (gris) suive le robot vert :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simulation suiveurs caméra.gif|500px|thumb|center|Suivi de robots de couleur]]&lt;br /&gt;
&lt;br /&gt;
Nous avons rajouté une fonctionnalité qui permet aux robots suiveurs de savoir où se trouve l'objet qu'il suivent (gauche, droite, ou devant). Ainsi, si l'objet suivi est sort du champs de vision, le robot va tourner sur le lui même en fonction de la position précédente de l'objet suivi. Si l'objet disparaît et qu'il se trouvait sur la gauche avant de disparaître, le robot va tourner sur lui même sur la gauche jusqu'à retrouver l'objet.&lt;br /&gt;
Voici les codes utilisés, comme le fonctionnement du des robots gris, vert et rouge est le même (seul la couleur à détecter change), nous ne mettons que le code du robot bleu (robot à suivre) et du robot rouge :&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suivi) |Code robot suivi]]&lt;br /&gt;
* [[Robots suiveurs 3 - Code Détection couleur (Robot suiveur) |Code robot suiveur]]&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10874</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10874"/>
		<updated>2020-05-11T15:22:03Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Émetteur-récepteur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| Vec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| String&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| Float&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| Float&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| Float&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG | vignette | Fonction de transfert du capteur de distance]]&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
Afin de faire communiquer des robots, nous utilisons des émmeteurs et récepteurs, qu'on modélise grâce aux nodes [https://www.cyberbotics.com/doc/reference/emitter?tab-language=c++ Emitter] et [https://www.cyberbotics.com/doc/reference/receiver?tab-language=c++ Receiver], respectivement. Nous allons décrire ici les bases de son fonctionnement. Pour plus d'information, veuillez accéder aux liens des nodes (vers le site de cyberbotics).&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infrarouge&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infrarouge&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré. Voir cette figure pour une illustration de la plage et de l'ouverture.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' staille (en octets) du tampon de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10873</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10873"/>
		<updated>2020-05-11T15:15:08Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Émetteur-récepteur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| Vec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| String&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| Float&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| Float&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| Float&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG | vignette | Fonction de transfert du capteur de distance]]&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infrarouge&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infrarouge&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré. Voir cette figure pour une illustration de la plage et de l'ouverture.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' staille (en octets) du tampon de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10872</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10872"/>
		<updated>2020-05-11T15:13:54Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Fonctions Disponibles (en C++) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| Vec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| String&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| Float&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| Float&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| Float&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG | vignette | Fonction de transfert du capteur de distance]]&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infrarouge&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infrarouge&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré. Voir cette figure pour une illustration de la plage et de l'ouverture.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' staille (en octets) du tampon de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception.&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10871</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10871"/>
		<updated>2020-05-11T15:13:04Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Émetteur-récepteur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| Vec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| String&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| Float&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| Float&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| Float&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG | vignette | Fonction de transfert du capteur de distance]]&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infrarouge&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infrarouge&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré. Voir cette figure pour une illustration de la plage et de l'ouverture.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' staille (en octets) du tampon de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fonctions Disponibles (en C++) ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual int send(const void *data, int size);&lt;br /&gt;
|Ajoute à la file d'attente de l'émetteur un paquet d'octets de taille situé à l'adresse indiquée par &amp;quot;data&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet au contrôleur de changer le canal de transmission.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel de l'émetteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setRange(double range);&lt;br /&gt;
| Permet au contrôleur de modifier la plage de transmission au moment de l'exécution.&lt;br /&gt;
|-&lt;br /&gt;
| double getRange() const;&lt;br /&gt;
| Renvoie la plage actuelle de l'émetteur&lt;br /&gt;
|-&lt;br /&gt;
| int getBufferSize() const;&lt;br /&gt;
| Renvoie la taille (en octets) du buffer de transmission.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Fonction'''&lt;br /&gt;
| '''Utilité'''&lt;br /&gt;
|-&lt;br /&gt;
| virtual void enable(int samplingPeriod);&lt;br /&gt;
| Démarre le récepteur à l'écoute des paquets de données entrants&lt;br /&gt;
|-&lt;br /&gt;
| virtual void disable();&lt;br /&gt;
| Arrête l'écoute en arrière-plan.&lt;br /&gt;
|-&lt;br /&gt;
| int getSamplingPeriod() const;&lt;br /&gt;
| Renvoie la période donnée dans la fonction wb_receiver_enable, ou 0 si le périphérique est désactivé.&lt;br /&gt;
|-&lt;br /&gt;
| int getQueueLength() const;&lt;br /&gt;
| Renvoie le nombre de paquets de données actuellement présents dans la file d'attente du récepteur&lt;br /&gt;
|-&lt;br /&gt;
| virtual void nextPacket();&lt;br /&gt;
| Supprime le paquet de tête. Le paquet suivant dans la file d'attente, le cas échéant, devient le nouveau paquet principal.&lt;br /&gt;
|-&lt;br /&gt;
| const void *getData() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception&lt;br /&gt;
|-&lt;br /&gt;
| int getDataSize() const;&lt;br /&gt;
| Renvoie les données du paquet en tête de la file d'attente de réception&lt;br /&gt;
|-&lt;br /&gt;
| double getSignalStrength() const;&lt;br /&gt;
| Renvoie la force du signal simulé au moment où le paquet a été transmis.&lt;br /&gt;
|-&lt;br /&gt;
| const double *getEmitterDirection() const;&lt;br /&gt;
| Renvoie un vecteur normalisé (longueur = 1) qui indique la direction de l'émetteur par rapport au système de coordonnées du récepteur.&lt;br /&gt;
|-&lt;br /&gt;
| virtual void setChannel(int channel);&lt;br /&gt;
| Permet à un récepteur de changer de canal de réception.&lt;br /&gt;
|-&lt;br /&gt;
| int getChannel() const;&lt;br /&gt;
| Renvoie le numéro de canal actuel du récepteur.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10870</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10870"/>
		<updated>2020-05-11T14:42:44Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Receiver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| Vec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| String&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| Float&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| Float&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| Float&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG | vignette | Fonction de transfert du capteur de distance]]&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infrarouge&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infrarouge&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré. Voir cette figure pour une illustration de la plage et de l'ouverture.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|center|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' staille (en octets) du tampon de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10869</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10869"/>
		<updated>2020-05-11T14:41:25Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Description des champs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| Vec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| String&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| Float&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| Float&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| Float&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG | vignette | Fonction de transfert du capteur de distance]]&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infrarouge&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infrarouge&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré. Voir cette figure pour une illustration de la plage et de l'ouverture.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur (voir cette figure dans cette section). Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' staille (en octets) du tampon de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ilustration_aperture.png|500px|thumb|left|Illustration de l'ouverture et de la portée de l'émetteur / récepteur infrarouge]]&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Fichier:Ilustration_aperture.png&amp;diff=10868</id>
		<title>Fichier:Ilustration aperture.png</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Fichier:Ilustration_aperture.png&amp;diff=10868"/>
		<updated>2020-05-11T14:40:09Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10867</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10867"/>
		<updated>2020-05-11T14:38:04Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Receiver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| Vec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| String&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| Float&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| Float&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| Float&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG | vignette | Fonction de transfert du capteur de distance]]&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infrarouge&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infrarouge&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré. Voir cette figure pour une illustration de la plage et de l'ouverture.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur (voir cette figure dans cette section). Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' staille (en octets) du tampon de réception. La taille des données reçues ne doit à aucun moment dépasser la taille de la mémoire tampon, sinon les données peuvent être perdues. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée. Si les données précédentes n'ont pas été lues lors de la réception de nouvelles données, les données précédentes sont perdues.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10866</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10866"/>
		<updated>2020-05-11T14:36:27Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Description des champs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| Vec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| String&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| Float&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| Float&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| Float&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG | vignette | Fonction de transfert du capteur de distance]]&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;br /&gt;
&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
&lt;br /&gt;
* '''type :''' type de signaux: &amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot; ou &amp;quot;infra-red&amp;quot;. Les signaux de type &amp;quot;radio&amp;quot; (par défaut) et &amp;quot;série&amp;quot; sont transmis sans tenir compte des obstacles. Cependant, les signaux de type &amp;quot;infra-red&amp;quot; tiennent compte des obstacles potentiels entre l'émetteur et le récepteur. Tout objet solide (solide, robots, etc ...) avec un objet englobant défini est un obstacle potentiel à une communication &amp;quot;infra-red&amp;quot;. La structure du robot émetteur ou récepteur lui-même ne bloquera pas une transmission &amp;quot;infra-red&amp;quot;. Actuellement, il n'y a pas de différence d'implémentation entre les types &amp;quot;radio&amp;quot; et &amp;quot;serie&amp;quot;.&lt;br /&gt;
* '''range :''' rayon de la sphère d'émission (en mètres). Un récepteur ne peut recevoir un message que s'il se trouve dans la sphère d'émission. Une valeur de -1 (par défaut) pour la plage est considérée comme une plage infinie.&lt;br /&gt;
* '''maxRange :''' définit la valeur maximale autorisée pour la plage. Ce champ définit la valeur maximale pouvant être définie à l'aide de la fonction wb_emitter_set_range. Une valeur de -1 (par défaut) pour maxRange est considérée comme infinie.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône d'émission (en radians); pour &amp;quot;infrarouge&amp;quot; uniquement. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées de l'émetteur et l'axe du cône coïncide avec l'axe z du système de coordonnées de l'émetteur. Un émetteur &amp;quot;infrarouge&amp;quot; ne peut envoyer des données qu'aux récepteurs actuellement situés dans son cône d'émission. Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie que les signaux émis sont omnidirectionnels. Pour les émetteurs &amp;quot;radio&amp;quot; et &amp;quot;série&amp;quot;, ce champ est ignoré. Voir cette figure pour une illustration de la plage et de l'ouverture.&lt;br /&gt;
* '''channel :''' canal de transmission. Il s'agit d'un numéro d'identification pour un émetteur &amp;quot;infra-red&amp;quot; ou d'une fréquence pour un émetteur &amp;quot;radio&amp;quot;. Normalement, un récepteur doit utiliser le même canal qu'un émetteur pour recevoir les données émises. Cependant, le canal spécial -1 permet de diffuser des messages sur tous les canaux. Le canal 0 (par défaut) est réservé pour communiquer avec un plugin physique. Pour la communication inter-robots, veuillez utiliser des numéros de canaux positifs.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en nombre de bits par seconde. Un baudRate de -1 (par défaut) est considéré comme infini et entraîne la transmission immédiate des données (dans un pas de temps de base) de l'émetteur au récepteur.&lt;br /&gt;
* '''byteSize :''' la taille d'octet est le nombre de bits requis pour transmettre un octet d'information. Il s'agit généralement de 8 (valeur par défaut), mais peut être supérieur si des bits de contrôle sont utilisés.&lt;br /&gt;
* '''bufferSize :''' spécifie la taille (en octets) du tampon de transmission. Le nombre total d'octets dans les paquets mis en file d'attente dans l'émetteur ne peut pas dépasser ce nombre. Un bufferSize de -1 (par défaut) est considéré comme une taille de buffer illimitée.&lt;br /&gt;
&lt;br /&gt;
=== Receiver === &lt;br /&gt;
&lt;br /&gt;
* '''type :''' idem que pour l'émetteur.&lt;br /&gt;
* '''aperture :''' angle d'ouverture du cône de réception (en radians); pour &amp;quot;infra-red&amp;quot; uniquement. Le récepteur ne peut recevoir que des messages d'émetteurs situés actuellement dans son cône de réception. L'apex du cône est situé à l'origine ([0 0 0]) du système de coordonnées du récepteur et l'axe du cône coïncide avec l'axe z du système de coordonnées du récepteur (voir cette figure dans cette section). Une ouverture de -1 (valeur par défaut) est considérée comme infinie, ce qui signifie qu'un signal peut être reçu de n'importe quelle direction. Pour les récepteurs &amp;quot;radio&amp;quot;, le champ d'ouverture est ignoré.&lt;br /&gt;
* '''channel :''' canal de réception. La valeur est un numéro d'identification pour un récepteur &amp;quot;infrarouge&amp;quot; ou une fréquence pour un récepteur &amp;quot;radio&amp;quot;. Normalement, l'émetteur et le récepteur doivent utiliser le même canal pour pouvoir communiquer. Cependant, le numéro de canal spécial -1 permet au récepteur d'écouter tous les canaux.&lt;br /&gt;
* '''baudRate :''' le débit en bauds est la vitesse de communication exprimée en bits par seconde. Elle doit être identique à la vitesse de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''byteSize :''' la taille en octets est le nombre de bits utilisés pour représenter un octet de données transmises (généralement 8, mais peut être supérieur si des bits de contrôle sont utilisés). Il doit être de la même taille que la taille des octets de l'émetteur. Actuellement, ce champ est ignoré.&lt;br /&gt;
* '''bufferSize :''' size (in bytes) of the reception buffer. The size of the received data should not exceed the buffer size at any time, otherwise data may be lost. A bufferSize of -1 (the default) is regarded as unlimited buffer size. If the previous data has not been read when new data is received, the previous data is lost.&lt;br /&gt;
* '''signalStrengthNoise :''' écart-type du bruit gaussien ajouté à la force du signal renvoyé par wb_receiver_get_signal_strength. Le bruit est proportionnel à la force du signal, par exemple, un signalStrengthNoise de 0,1 ajoutera un bruit avec un écart-type de 0,1 pour une force de signal de 1 et 0,2 pour une force de signal de 2.&lt;br /&gt;
* '''directionNoise :''' écart-type du bruit gaussien ajouté à chacune des composantes de la direction retournée par wb_receiver_get_emitter_direction. Le bruit ne dépend pas de la distance entre l'émetteur-récepteur.&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
	<entry>
		<id>https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10865</id>
		<title>Robots suiveurs 3 - Capteurs</title>
		<link rel="alternate" type="text/html" href="https://bacasable.arpitania.eu//index.php?title=Robots_suiveurs_3_-_Capteurs&amp;diff=10865"/>
		<updated>2020-05-11T14:17:44Z</updated>

		<summary type="html">&lt;p&gt;De-almeida-ribeiro.thiago : /* Émetteur-récepteur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le logiciel Webots dispose d'une large collection de capteurs déjà configurés disposant de méthodes associées. Le robot [https://fr.wikipedia.org/wiki/E-Puck E-puck] que nous utilisons dans ce projet dispose de différents capteurs prépositionnés :&lt;br /&gt;
&lt;br /&gt;
* 8 capteurs de distance infrarouge&lt;br /&gt;
* Camera couleur VGA&lt;br /&gt;
* Accéléromètre 3D (non utilisé)&lt;br /&gt;
* Émetteur-récepteur ZigBee&lt;br /&gt;
&lt;br /&gt;
Nous allons donc détailler dans cette partie le fonctionnement des capteurs utilisés.&lt;br /&gt;
&lt;br /&gt;
= Capteur de distance =&lt;br /&gt;
Afin de détecter des obstacles, nous utilisons des capteurs de distance qu'on modélise grâce au node [https://cyberbotics.com/doc/reference/distancesensor DistanceSensor]. Nous allons décrire ici son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
== Champs du node DistanceSensor ==&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| lookupTable&lt;br /&gt;
| Vec3f&lt;br /&gt;
| lookup table &lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| String&lt;br /&gt;
| {&amp;quot;generic&amp;quot;, &amp;quot;infra-red&amp;quot;, &amp;quot;sonar&amp;quot;, &amp;quot;laser&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| numberOfRays&lt;br /&gt;
| Int32&lt;br /&gt;
| [1, inf) &lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| Float&lt;br /&gt;
| [0, 2*pi]&lt;br /&gt;
|-&lt;br /&gt;
| gaussianWidth&lt;br /&gt;
| Float&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| resolution&lt;br /&gt;
| Float&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== lookupTable ==&lt;br /&gt;
[[Fichier:Lookuptable capteur distance.PNG | vignette | Fonction de transfert du capteur de distance]]&lt;br /&gt;
La LookUpTable est un tableau à 2 dimensions servant à faire la correspondance entre la distance en mètre mesurée par le capteur et la valeur de sortie du capteur. Cette table consiste en une liste de coordonnées de points qui, une fois reliés, nous donne la fonction de transfert du capteur. A chaque point est associé une valeur d'écart type pour son bruit associé.&lt;br /&gt;
&lt;br /&gt;
Les valeurs de la table sont pré-configurés pour correspondre à un capteur précis. On peut voir sur le graphique que plus la distance est faible, plus la valeur de sortie augmente vite. Afin d'éviter précisément des obstacles, et de simplifier la mesure des distance, nous avons modifié la table. En ne positionnant que deux points aux extrémités des intervalles, nous obtenons une droite affine. Nous avons donc une précision constante en fonction de la distance et les conversions distance/code sont plus simples. Il serait possible par la suite d'étudier l'influence du bruit sur les performances du robot. Nous pourrons aussi questionner la pertinence de ces modifications qui changent peut-être trop le fonctionnement des capteurs pour correspondre à la réalité.&lt;br /&gt;
&lt;br /&gt;
== Méthodes utilisées ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| void wb_distance_sensor_enable&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Active le capteur de distance ciblé.&lt;br /&gt;
|-&lt;br /&gt;
| double wb_distance_sensor_get_value&lt;br /&gt;
(WbDeviceTag tag)&lt;br /&gt;
| WbDeviceTag tag : tag du capteur afin de le cibler&lt;br /&gt;
| Renvoie la valeur associée à la distance mesurée du capteur ciblé.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&lt;br /&gt;
= Émetteur-récepteur =&lt;br /&gt;
&lt;br /&gt;
== Champs des nodes Emitter et Receiver ==&lt;br /&gt;
=== Emitter ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| range&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| maxRange&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|}&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
{| class=&amp;quot;wikitable left&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Nom'''&lt;br /&gt;
| '''Type'''&lt;br /&gt;
| '''Valeur par défaut'''&lt;br /&gt;
| '''Valeurs possibles'''&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| SFString&lt;br /&gt;
| &amp;quot;radio&amp;quot;&lt;br /&gt;
| {&amp;quot;radio&amp;quot;, &amp;quot;serial&amp;quot;, &amp;quot;infra-red&amp;quot;}&lt;br /&gt;
|-&lt;br /&gt;
| aperture&lt;br /&gt;
| SFFloat&lt;br /&gt;
| -1&lt;br /&gt;
| {-1 ,[0, 2*pi]}&lt;br /&gt;
|-&lt;br /&gt;
| channel&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| baudRate&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| byteSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| 8&lt;br /&gt;
| [8, inf)&lt;br /&gt;
|-&lt;br /&gt;
| bufferSize&lt;br /&gt;
| SFInt32&lt;br /&gt;
| -1&lt;br /&gt;
| {-1, [0, inf)}&lt;br /&gt;
|-&lt;br /&gt;
| signalStrengthNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|-&lt;br /&gt;
| directionNoise&lt;br /&gt;
| SFFloat&lt;br /&gt;
| 0&lt;br /&gt;
| [0, inf)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description des champs ==&lt;/div&gt;</summary>
		<author><name>De-almeida-ribeiro.thiago</name></author>
		
	</entry>
</feed>