RobotRamasseur2014-1 : Différence entre versions
(→Déplacement en suivant les lignes) |
|||
(46 révisions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
+ | <include nopre noesc src="/home/pedago/ppeip/include/video-RobotRamasseur1-2014-iframe.html" /> | ||
__TOC__ | __TOC__ | ||
<br style="clear: both;"> | <br style="clear: both;"> | ||
= Introduction = | = Introduction = | ||
− | + | Dans le cadre de ce bureau d’étude, notre groupe est chargé de concevoir un robot ramasseur de balle. En effet, le but final du projet est de jouer un match de foot entièrement avec des robots. Notre robot a pour rôle de repérer la balle, de se diriger vers cette dernière, de l'attraper et de la remettre au centre du terrain, et finalement d'aller se garer dans l'emplacement qui lui est prévu. Il a donc fallu concevoir et programmer notre robot afin qu'il effectue ces tâches. | |
− | |||
− | |||
− | |||
= Construction du robot = | = Construction du robot = | ||
Ligne 12 : | Ligne 10 : | ||
Afin de bien remplir son rôle, il est nécessaire au robot de pouvoir se diriger vers la balle grâce à l'infrarouge, d'attraper celle-ci puis de se diriger grâce aux lignes situées sur le terrain. Il est donc indispensable de construire le robot de manière à ce qu'il puisse effectuer ces manœuvres. Il a donc fallu poser différents capteurs tels que le capteur couleur, le capteur infrarouge, le capteur ultrason et le capteur "touch". Il a également fallu construire une pince adaptée pour attraper la balle, l’immobiliser et à la transporter jusqu'au centre du terrain. | Afin de bien remplir son rôle, il est nécessaire au robot de pouvoir se diriger vers la balle grâce à l'infrarouge, d'attraper celle-ci puis de se diriger grâce aux lignes situées sur le terrain. Il est donc indispensable de construire le robot de manière à ce qu'il puisse effectuer ces manœuvres. Il a donc fallu poser différents capteurs tels que le capteur couleur, le capteur infrarouge, le capteur ultrason et le capteur "touch". Il a également fallu construire une pince adaptée pour attraper la balle, l’immobiliser et à la transporter jusqu'au centre du terrain. | ||
+ | Ce robot sera le seul présent sur le terrain lorsqu'il devra y ramasser la balle. Sa vitesse d'action ou de déplacement n'a donc pas d'importance. | ||
− | |||
== 1ère et 2ème versions == | == 1ère et 2ème versions == | ||
Ligne 19 : | Ligne 17 : | ||
Nous avons attaqué la construction du robot par le système moteur, constitué des roues et de servomoteurs. | Nous avons attaqué la construction du robot par le système moteur, constitué des roues et de servomoteurs. | ||
− | Dans la première version, nous étions partis sur un servomoteur pour chaque paire de roues, avant et arrière, et de ce fait, le robot ne pouvait pas tourner. En effet, pour lui permettre de tourner, il est nécessaire de donner des vitesses différentes aux côtés gauche et droit du robot. Nous avons donc décidé de placer deux servomoteurs pour les deux roues avant et par la même occasion, un troisième moteur pour la pince. Cependant un autre problème se posait alors, celui de relier les deux roues d'un même côté entre elles. Le problème a facilement été résolu grâce à l’installation de chenilles, permettant à la force motrice appliquée à la roue avant d'entraîner la roue arrière . | + | Dans la première version, nous étions partis sur un servomoteur pour chaque paire de roues, avant et arrière, et de ce fait, le robot ne pouvait pas tourner. En effet, pour lui permettre de tourner, il est nécessaire de donner des vitesses différentes aux côtés gauche et droit du robot. Nous avons donc décidé de placer deux servomoteurs pour les deux roues avant et par la même occasion, un troisième moteur pour la pince. Cependant un autre problème se posait alors, celui de relier les deux roues d'un même côté entre elles. Le problème a facilement été résolu grâce à l’installation de chenilles, permettant à la force motrice appliquée à la roue avant d'entraîner la roue arrière. |
− | Puis nous avons continué d'assembler le robot afin que la structure motrice soit stable et solide . | + | Puis nous avons continué d'assembler le robot afin que la structure motrice soit stable et solide. |
Cette structure doit être capable de supporter le poids de la pince, de manière à ce que celle-ci ne fasse pas basculer vers l'avant le robot tout entier une fois qu'il est posé au sol. | Cette structure doit être capable de supporter le poids de la pince, de manière à ce que celle-ci ne fasse pas basculer vers l'avant le robot tout entier une fois qu'il est posé au sol. | ||
Ligne 30 : | Ligne 28 : | ||
</gallery> | </gallery> | ||
− | == | + | == Version finale du Robot == |
− | + | ||
+ | |||
+ | La version finale est une version plus stable avec une pince mieux construite, et l’ensemble des capteurs nécessaires au fonctionnement de notre robot disposés de manière à optimiser leur utilisation. | ||
+ | |||
+ | Au cours des tests du robot sur le vrai terrain, nous avons pu constater une défaillance d'un moteur des roues, celui-ci étant plus lent que l'autre. Le problème vient alors du fait que les deux moteurs ne tournent pas à la même vitesse, et donc le robot n'avancera pas droit, mais il aura tendance à dévier. Il nous était impossible arrivé à ce stade-là de remplacer le moteur; nous avons donc tenté de corriger le problème en appliquant des vitesses différentes aux deux moteurs dans le programme. | ||
+ | |||
+ | Nous allons maintenant détailler la construction et le placement de chaque élément de la version finale de notre robot. | ||
=== Fonctionnement et fabrication de la pince === | === Fonctionnement et fabrication de la pince === | ||
Ligne 38 : | Ligne 42 : | ||
Pour pouvoir mettre en place ce système, nous avons tout d'abord commencé par déplacer le servomoteur dédié à la pince, jusque-là pris entre les deux roues avant. | Pour pouvoir mettre en place ce système, nous avons tout d'abord commencé par déplacer le servomoteur dédié à la pince, jusque-là pris entre les deux roues avant. | ||
− | Un premier engrenage est lié au servomoteur de manière à ce que l'activation de celui-ci engendre une rotation de la roue. | + | Un premier engrenage est lié au servomoteur de manière à ce que l'activation de celui-ci engendre une rotation de la roue. À cette roue sera attaché le premier côté de la pince. Cet engrenage est collé a un autre engrenage, lui même lié à l'autre côté de la pince. Il était particulièrement important d'avoir un nombre pair de roues dentées, de manière à ce que les rotations des roues situées aux extrémités s'effectuent dans le même sens. C'est ce qui permet la fermeture des pinces. En effet, avec un nombre impair de roues dentées, une partie de la pince irait vers l’intérieur alors que l'autre la fuirait. Il serait alors impossible d’attraper la balle. |
+ | |||
+ | <br/> | ||
+ | |||
+ | [[Fichier:engrenage.jpg|200px|thumb|center|Système d’engrenage des pinces, zoom]][[Fichier:engrenage2.jpg|200px|thumb|center|Système d’engrenage des pinces]] | ||
+ | |||
− | Une fois le mécanisme conçu, il a fallu construire la pince elle-même. Nous avions d'abord opté pour une version uniquement construite à partir de bâtonnets assemblés entre eux. | + | Une fois le mécanisme conçu, il a fallu construire la pince elle-même. Nous avions d'abord opté pour une première version uniquement construite à partir de bâtonnets assemblés entre eux (voir photo). De plus la pince était alors trop petite pour capturer la balle. C'est pourquoi nous avons donc adopté une version plus stable, d'abord en agrandissant la pince, puis en ajoutant des jonctions afin de solidifier la structure et donner la forme voulue à la pince; jonctions auxquelles nous avons ajouté des terminaisons plus stables et rendant plus pratique la capture de la balle. |
− | + | <br/> | |
− | + | [[Fichier:1version.jpg|150px|thumb|center|1ère version de la pince]][[Fichier:pince ouverte.jpg|150px|thumb|center|Pince finale]] | |
=== Les différents capteurs et leurs placements === | === Les différents capteurs et leurs placements === | ||
Ligne 49 : | Ligne 58 : | ||
==== Le capteur couleur ==== | ==== Le capteur couleur ==== | ||
Ce capteur fixé à l'avant du robot et orienté vers le bas permet de distinguer les couleurs des marquages situés au sol. En effet, les marquages au sol, déterminés par concertation avec les autres équipes, sont les principales indications concernant les directions vers lesquelles notre robot doit se diriger. Notre robot devra suivre des lignes au sol afin de se repérer et de déposer la balle au milieu du terrain après l'avoir ramassé. | Ce capteur fixé à l'avant du robot et orienté vers le bas permet de distinguer les couleurs des marquages situés au sol. En effet, les marquages au sol, déterminés par concertation avec les autres équipes, sont les principales indications concernant les directions vers lesquelles notre robot doit se diriger. Notre robot devra suivre des lignes au sol afin de se repérer et de déposer la balle au milieu du terrain après l'avoir ramassé. | ||
+ | [[Fichier:capteurcouleur.jpg|150px|thumb|center|Capteur couleur]] | ||
==== Le capteur infrarouge ==== | ==== Le capteur infrarouge ==== | ||
Ligne 54 : | Ligne 64 : | ||
==== Le capteur ultrason ==== | ==== Le capteur ultrason ==== | ||
− | Le capteur ultrason est le capteur qui permet de détecter les objets matériels tels que les obstacles ou même la balle. Il est situé à l'avant du robot, un peu plus haut que la partie supérieure de la pince, afin que celle-ci n'obstrue pas le champ de vision du capteur. Son rôle principal est de détecter les obstacles afin de les éviter, et de détecter la distance du robot par rapport à la balle pour savoir quand celui-ci doit refermer ses pinces. | + | |
+ | [[Media:Ultrasons1.mp4|Vidéo : Le robot qui réagit face à un obstacle]] | ||
+ | |||
+ | Le capteur ultrason est le capteur qui permet de détecter les objets matériels tels que les obstacles ou même la balle. Il est situé à l'avant du robot, un peu plus haut que la partie supérieure de la pince, afin que celle-ci n'obstrue pas le champ de vision du capteur. Son rôle principal est de détecter les obstacles afin de les éviter, et de détecter la distance du robot par rapport à la balle pour savoir quand celui-ci doit refermer ses pinces. Il est programmé de manière à faire demi-tour lorsqu'il détecte un obstacle. | ||
==== Le capteur touch ==== | ==== Le capteur touch ==== | ||
Le capteur touch sert principalement à vérifier que la balle se trouve bien entre les pinces lorsque celles-ci se referment. Lorsque la balle est bien entre les pinces, ce capteur est enfoncé. C'est pour cette raison que nous l'avons placé sur la pince même. Ce capteur est utilisé en complément du capteur ultrason afin de repérer et d’attraper la balle correctement. Ainsi, si la pince se referme sans avoir réussi à attraper la balle, elle se rouvre automatiquement dès qu'elle s'aperçoit que le capteur n'a pas été enfoncé. | Le capteur touch sert principalement à vérifier que la balle se trouve bien entre les pinces lorsque celles-ci se referment. Lorsque la balle est bien entre les pinces, ce capteur est enfoncé. C'est pour cette raison que nous l'avons placé sur la pince même. Ce capteur est utilisé en complément du capteur ultrason afin de repérer et d’attraper la balle correctement. Ainsi, si la pince se referme sans avoir réussi à attraper la balle, elle se rouvre automatiquement dès qu'elle s'aperçoit que le capteur n'a pas été enfoncé. | ||
− | + | Ça capteur nous a posé quelques problèmes, la structure de la pince rendant son positionnement difficile. | |
− | + | En effet, nous pensions d'abord le fixer directement au robot afin qu'il soit stable. Seulement, avec déjà le capteur couleur et le capteur infrarouge positionnés à l'avant du robot, nous ne pouvions donc pas le placer à cet endroit. De plus, il nous était impossible de l'y fixer, car il aurait fallu fabriquer un système composé de plusieurs barres servant de raccord entre la structure du robot et le capteur; chose irréalisable par manque de place. | |
+ | Nous avons donc décidé de placer ce capteur directement sur la pince en compliquant un peu sa programmation. | ||
+ | |||
+ | |||
+ | [[Fichier:capteurdecontact.jpg|120px|thumb|center|Capteur de contact]] | ||
= Programmation du Robot = | = Programmation du Robot = | ||
− | |||
Nous avons opté pour la programmation du robot par le langage C, plutôt que par l'éditeur graphique. | Nous avons opté pour la programmation du robot par le langage C, plutôt que par l'éditeur graphique. | ||
Ligne 79 : | Ligne 95 : | ||
== Infrarouge == | == Infrarouge == | ||
+ | |||
+ | [[Media:Infrarouge1.mp4|Vidéo : Le robot qui cherche la balle grâce à l'infrarouge]] | ||
A l'origine, deux parties concernant ce capteur étaient prévues. Cependant, au cours de la réalisation du robot, nous nous sommes aperçues que lorsque le robot se déplace vers les buts, il a déjà la balle entre ses pinces, ce qui rend impossible une autre mesure au vu de la position du capteur. Cette action se fera donc grâce au capteur couleur. | A l'origine, deux parties concernant ce capteur étaient prévues. Cependant, au cours de la réalisation du robot, nous nous sommes aperçues que lorsque le robot se déplace vers les buts, il a déjà la balle entre ses pinces, ce qui rend impossible une autre mesure au vu de la position du capteur. Cette action se fera donc grâce au capteur couleur. | ||
Ligne 157 : | Ligne 175 : | ||
== Déplacement en suivant les lignes == | == Déplacement en suivant les lignes == | ||
+ | |||
+ | [[Media:suivreLignes1.mp4|Vidéo : Le robot qui suit les lignes]] | ||
Le robot doit commencer par se diriger vers le but le plus éloigné jusqu'à rencontrer une ligne médiane. Pour cela, nous avons décidé de le faire avancer tout droit jusqu'à, ou rencontrer un obstacle repéré par le capteur ultrasons (mur, but, ...), ou croiser une ligne médiane. S'il croise cette ligne, de couleur bleue, le relais est passé à la fonction suivante. | Le robot doit commencer par se diriger vers le but le plus éloigné jusqu'à rencontrer une ligne médiane. Pour cela, nous avons décidé de le faire avancer tout droit jusqu'à, ou rencontrer un obstacle repéré par le capteur ultrasons (mur, but, ...), ou croiser une ligne médiane. S'il croise cette ligne, de couleur bleue, le relais est passé à la fonction suivante. | ||
Ligne 173 : | Ligne 193 : | ||
Un problème majeur se pose alors : comment différencier une déviation, vue comme du noir, de la ligne du garage de couleur noire ? | Un problème majeur se pose alors : comment différencier une déviation, vue comme du noir, de la ligne du garage de couleur noire ? | ||
− | + | Nous avons dû modifier le code utilisé pour "corriger" la trajectoire du robot : alors qu'auparavant il ne prenait en compte que la couleur blanche, maintenant il prend toujours en compte le blanc mais également le noir. | |
+ | Cependant, ce code n'est pas encore optimisé : le robot ne tourne que dans une direction pour corriger sa trajectoire, et surtout il lui arrive encore de confondre quelques déviations comme son garage. | ||
+ | De plus les déviations arrivent assez souvent, le terrain étant un peu glissant et notre robot ayant un problème sur l'un de ses moteurs (voir partie Construction du robot, Version finale du Robot). | ||
+ | |||
+ | Ci-dessous, notre algorithme final. | ||
+ | bool arreter = false; | ||
+ | SetSensorColorFull(S1); | ||
+ | while (!arreter) | ||
+ | { | ||
+ | unsigned int rawData[], normData[]; | ||
+ | int scaledData[]; | ||
+ | int cval; | ||
+ | ReadSensorColorEx(S1, cval, rawData, normData, scaledData); | ||
+ | if (cval == INPUT_BLUECOLOR) | ||
+ | { | ||
+ | OnFwd(OUT_A, SPEEDSLOW); | ||
+ | OnFwd(OUT_B, SPEEDFAST); | ||
+ | ReadSensorColorEx(S1, cval, rawData, normData, scaledData); | ||
+ | } | ||
+ | else if (cval == INPUT_REDCOLOR || cval == INPUT_GREENCOLOR) | ||
+ | { | ||
+ | FaireDemiTour(); | ||
+ | } | ||
+ | else if (cval == INPUT_YELLOWCOLOR) | ||
+ | { | ||
+ | OnFwd(OUT_A, SPEEDSLOW); | ||
+ | OnFwd(OUT_B, SPEEDFAST); | ||
+ | Wait(500); | ||
+ | FaireDemiTour(); | ||
+ | } | ||
+ | else if (cval == INPUT_BLACKCOLOR || cval == INPUT_WHITECOLOR) | ||
+ | { | ||
+ | OnFwd(OUT_A, 0); | ||
+ | OnFwd(OUT_B, SPEEDFAST); | ||
+ | ReadSensorColorEx(S1, cval, rawData, normData, scaledData); | ||
+ | if (cval == INPUT_BLACKCOLOR) | ||
+ | { | ||
+ | Wait(200); | ||
+ | OnFwd(OUT_A, SPEEDSLOW); | ||
+ | OnFwd(OUT_B, SPEEDFAST); | ||
+ | Wait(100); | ||
+ | OnFwd(OUT_AB, 0); | ||
+ | ReadSensorColorEx(S1, cval, rawData, normData, scaledData); | ||
+ | } | ||
+ | if (cval == INPUT_BLACKCOLOR) | ||
+ | { | ||
+ | FaireDemiTour(); | ||
+ | arreter = true; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | == Ramassage de la balle == | ||
+ | |||
+ | L'étape du ramassage de balle nous a posé de nombreux problème. En effet, lorsque le robot avance vers la balle en suivant son signal infrarouge, il lui faut savoir quand s'arrêter et fermer sa pince. | ||
+ | |||
+ | Nous avons d'abord pensé à placer un capteur tactile, que la balle enfoncera lorsqu'elle se trouve entre les pinces. Cependant, il nous était impossible de placer ce capteur à la bonne hauteur avec la façon dont nous avons construit notre pince. Nous avons ensuite essayé de détecter la distance entre la balle et le robot à l'aide du capteur infrarouge. Malheureusement, la distance détectée était à chaque fois différente. Nous avons donc décidé d'utiliser le capteur ultrason pour trouver la distance de la balle par rapport au robot et avons finalement réussi à installer le capteur touch. | ||
+ | |||
+ | La distance par rapport à la balle est ainsi détectée par le capteur ultrason. En dessous d'un certain seuil, le robot avance un peu et referme ses pinces. Le capteur touch prend alors le relais en détectant si la balles se trouve bien entre les pinces (son bout est enfoncé). Si ce n'est pas le cas, le robot rouvre sa pince et continue sa recherche. | ||
+ | |||
+ | == Communication avec l'Arbitre == | ||
+ | |||
+ | Nous avons également programmé le robot de façon à ce qu'il puisse communiquer avec l'arbitre lors d'un match. | ||
+ | |||
+ | L'arbitre est un petit ordinateur dont le rôle est d'établir une connection Bluetooth avec cinq acteurs, correspondant aux deux cages de buts, aux deux joueurs et au ramasseur. | ||
+ | Il doit tout d'abord les enregistrer pour pouvoir communiquer avec eux par la suite. Puis il tente de les joindre par Bluetooth. | ||
+ | Après que la connection ait été établie, l'arbitre envoie des codes aux acteurs en fonction de ce qu'il veut savoir ou leur faire faire. | ||
+ | Ainsi, il commence par se renseigner sur le type de chaque acteur (pour vérifier que tous les acteurs sont bien là). Puis il va débuter le match et attendre un retour des cages de buts, lorsqu'un but a été marqué, etc. | ||
+ | |||
+ | Notre robot intervient après qu'un but ait été marqué et que les joueurs aient été se garer sur leurs emplacements respectifs. | ||
+ | Il reçoit alors un message de l'arbitre lui indiquant d'aller chercher la balle et de la replacer au centre du terrain. | ||
+ | Il doit également renvoyer un message à l'arbitre pour le prévenir lorsque la tâche a été accomplie. | ||
− | + | Pour réaliser cela, nous avons suivi l'algorithme indiqué sur la page de présentation, tout en faisant attention à ne pas oublier de convertir les messages reçus et les messages envoyés. | |
+ | Nous avons ainsi obtenu le programme ci-dessous : | ||
− | + | #define CODE_REQTYPE 0 // demander le type de l'acteur | |
+ | #define CODE_RAMASSER 1 // ordonne le placement de la balle | ||
+ | #define TYPE_RAMASSEUR 2 | ||
+ | #define CODE_BALLEOK 2 // la balle est placé au centre | ||
+ | #define BOITE_RAMASSEUR 1 | ||
+ | #define BOITE_ARBITRE (2+10) | ||
+ | string msg; | ||
+ | while (true) | ||
+ | { | ||
+ | ReceiveMessage(BOITE_RAMASSEUR, true, msg); | ||
+ | int res = StrToNum(msg); | ||
+ | if (res == CODE_REQTYPE) | ||
+ | { | ||
+ | msg = NumToStr(TYPE_RAMASSEUR); | ||
+ | SendMessage(BOITE_ARBITRE, msg); | ||
+ | } | ||
+ | else if (res == CODE_RAMASSER) | ||
+ | { | ||
+ | AllerVersBalle(); | ||
+ | AllerVersBut(); | ||
+ | SuivreLigneMediane(); | ||
+ | DeposerBalle(); | ||
+ | msg = NumToStr(CODE_BALLEOK); | ||
+ | SendMessage(BOITE_ARBITRE, msg); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Nous avons ensuite testé ce programme avec l'arbitre et notre robot. | ||
+ | Pour cela, nous avons d'abord dû enregistrer notre robot auprès de l'arbitre, pour qu'il puisse le reconnaître. | ||
+ | Puis, une fois le robot enregistré et le contact Bluetooth établi avec notre robot, l'arbitre a lancé le début d'un match "fictif" (notre robot étant le seul connecté en Bluetooth à ce moment-là) et le robot a bien rempli son rôle. | ||
+ | |||
+ | = Réalisation du terrain = | ||
+ | |||
+ | Pour réaliser le terrain, quatre plaques d'1,5m sur 1m et des rubans adhésifs de couleur nous ont été attribués. | ||
+ | |||
+ | Nous avons d'abord réfléchi à l'emplacement des différentes lignes sur le terrain. En effet, les robots et les buts ne font pas tous la même taille, et il faut que tous les robots puissent se déplacer et faire demi-tour et que les buts rentrent tous dans l'espace prévu sur le terrain. | ||
+ | De plus il a fallu ajouter un espace afin que chaque robot puisse se garer. Nous avons donc dû mesurer chacun de nos robots afin d’être sûr de laisser un espace suffisant au garage, mais aussi d'avoir la place de tourner lorsque l'on suit une ligne. C'est pourquoi le terrain sur lequel les robots effectuent le match ne recouvre en fait pas tous l’espace des plaques. | ||
− | + | Ces lignes ont ensuite été tracées au crayon gris sur les plaques, traits que l'on a ensuite recouvert de scotch de couleur. Enfin, les rubans ont été collés. | |
− | + | Nous avons décidé de garder les quatre plaques séparées et d'ensuite les assembler pour le jeu afin de faciliter leur rangement et leur transport. | |
− | |||
= Conclusion = | = Conclusion = | ||
− | + | ||
+ | Ce bureau d'étude nous a permis d'apprendre beaucoup de choses, à la fois comment construire un robot tout en faisant attention à l'emplacement des différents éléments et en respectant les contraintes techniques; | ||
+ | comment programmer ce robot de façon à lui faire effectuer des tâches précises; | ||
+ | comment s'adapter aux contraintes liées au matériel (moteur ralentit, robot réagissant au terrain final différemment du premier terrain) et gérer son temps correctement. | ||
+ | |||
+ | Nous avons également appris à gérer un wiki et à y inscrire régulièrement notre avancement. | ||
+ | Ce bureau d'étude nous a aussi permis d'avoir une première expérience de projet de groupe et d'apprendre à mieux connaître les autres, à partager notre opinion et écouter la leur. | ||
+ | C'était une expérience très enrichissante, et il a été d'une aide précieuse dans le choix de notre orientation future. |
Version actuelle datée du 28 mai 2015 à 17:30
Sommaire
Introduction
Dans le cadre de ce bureau d’étude, notre groupe est chargé de concevoir un robot ramasseur de balle. En effet, le but final du projet est de jouer un match de foot entièrement avec des robots. Notre robot a pour rôle de repérer la balle, de se diriger vers cette dernière, de l'attraper et de la remettre au centre du terrain, et finalement d'aller se garer dans l'emplacement qui lui est prévu. Il a donc fallu concevoir et programmer notre robot afin qu'il effectue ces tâches.
Construction du robot
Afin de bien remplir son rôle, il est nécessaire au robot de pouvoir se diriger vers la balle grâce à l'infrarouge, d'attraper celle-ci puis de se diriger grâce aux lignes situées sur le terrain. Il est donc indispensable de construire le robot de manière à ce qu'il puisse effectuer ces manœuvres. Il a donc fallu poser différents capteurs tels que le capteur couleur, le capteur infrarouge, le capteur ultrason et le capteur "touch". Il a également fallu construire une pince adaptée pour attraper la balle, l’immobiliser et à la transporter jusqu'au centre du terrain.
Ce robot sera le seul présent sur le terrain lorsqu'il devra y ramasser la balle. Sa vitesse d'action ou de déplacement n'a donc pas d'importance.
1ère et 2ème versions
Nous avons attaqué la construction du robot par le système moteur, constitué des roues et de servomoteurs.
Dans la première version, nous étions partis sur un servomoteur pour chaque paire de roues, avant et arrière, et de ce fait, le robot ne pouvait pas tourner. En effet, pour lui permettre de tourner, il est nécessaire de donner des vitesses différentes aux côtés gauche et droit du robot. Nous avons donc décidé de placer deux servomoteurs pour les deux roues avant et par la même occasion, un troisième moteur pour la pince. Cependant un autre problème se posait alors, celui de relier les deux roues d'un même côté entre elles. Le problème a facilement été résolu grâce à l’installation de chenilles, permettant à la force motrice appliquée à la roue avant d'entraîner la roue arrière.
Puis nous avons continué d'assembler le robot afin que la structure motrice soit stable et solide. Cette structure doit être capable de supporter le poids de la pince, de manière à ce que celle-ci ne fasse pas basculer vers l'avant le robot tout entier une fois qu'il est posé au sol.
Version finale du Robot
La version finale est une version plus stable avec une pince mieux construite, et l’ensemble des capteurs nécessaires au fonctionnement de notre robot disposés de manière à optimiser leur utilisation.
Au cours des tests du robot sur le vrai terrain, nous avons pu constater une défaillance d'un moteur des roues, celui-ci étant plus lent que l'autre. Le problème vient alors du fait que les deux moteurs ne tournent pas à la même vitesse, et donc le robot n'avancera pas droit, mais il aura tendance à dévier. Il nous était impossible arrivé à ce stade-là de remplacer le moteur; nous avons donc tenté de corriger le problème en appliquant des vitesses différentes aux deux moteurs dans le programme.
Nous allons maintenant détailler la construction et le placement de chaque élément de la version finale de notre robot.
Fonctionnement et fabrication de la pince
La pince a été fabriquée à partir d'un mécanisme d’engrenage. Pour pouvoir mettre en place ce système, nous avons tout d'abord commencé par déplacer le servomoteur dédié à la pince, jusque-là pris entre les deux roues avant.
Un premier engrenage est lié au servomoteur de manière à ce que l'activation de celui-ci engendre une rotation de la roue. À cette roue sera attaché le premier côté de la pince. Cet engrenage est collé a un autre engrenage, lui même lié à l'autre côté de la pince. Il était particulièrement important d'avoir un nombre pair de roues dentées, de manière à ce que les rotations des roues situées aux extrémités s'effectuent dans le même sens. C'est ce qui permet la fermeture des pinces. En effet, avec un nombre impair de roues dentées, une partie de la pince irait vers l’intérieur alors que l'autre la fuirait. Il serait alors impossible d’attraper la balle.
Une fois le mécanisme conçu, il a fallu construire la pince elle-même. Nous avions d'abord opté pour une première version uniquement construite à partir de bâtonnets assemblés entre eux (voir photo). De plus la pince était alors trop petite pour capturer la balle. C'est pourquoi nous avons donc adopté une version plus stable, d'abord en agrandissant la pince, puis en ajoutant des jonctions afin de solidifier la structure et donner la forme voulue à la pince; jonctions auxquelles nous avons ajouté des terminaisons plus stables et rendant plus pratique la capture de la balle.
Les différents capteurs et leurs placements
Le capteur couleur
Ce capteur fixé à l'avant du robot et orienté vers le bas permet de distinguer les couleurs des marquages situés au sol. En effet, les marquages au sol, déterminés par concertation avec les autres équipes, sont les principales indications concernant les directions vers lesquelles notre robot doit se diriger. Notre robot devra suivre des lignes au sol afin de se repérer et de déposer la balle au milieu du terrain après l'avoir ramassé.
Le capteur infrarouge
Ce capteur est situé juste à coté du capteur couleur et dirigé vers l'avant. C'est ce capteur qui permettra de détecter la balle et les buts. C'est le capteur principal utilisé pour se diriger dans la première phase d'action. Il devra être programmé de sorte à ce qu'il distingue les deux buts de la balle car tous deux émettent un signal infrarouge.
Le capteur ultrason
Vidéo : Le robot qui réagit face à un obstacle
Le capteur ultrason est le capteur qui permet de détecter les objets matériels tels que les obstacles ou même la balle. Il est situé à l'avant du robot, un peu plus haut que la partie supérieure de la pince, afin que celle-ci n'obstrue pas le champ de vision du capteur. Son rôle principal est de détecter les obstacles afin de les éviter, et de détecter la distance du robot par rapport à la balle pour savoir quand celui-ci doit refermer ses pinces. Il est programmé de manière à faire demi-tour lorsqu'il détecte un obstacle.
Le capteur touch
Le capteur touch sert principalement à vérifier que la balle se trouve bien entre les pinces lorsque celles-ci se referment. Lorsque la balle est bien entre les pinces, ce capteur est enfoncé. C'est pour cette raison que nous l'avons placé sur la pince même. Ce capteur est utilisé en complément du capteur ultrason afin de repérer et d’attraper la balle correctement. Ainsi, si la pince se referme sans avoir réussi à attraper la balle, elle se rouvre automatiquement dès qu'elle s'aperçoit que le capteur n'a pas été enfoncé.
Ça capteur nous a posé quelques problèmes, la structure de la pince rendant son positionnement difficile. En effet, nous pensions d'abord le fixer directement au robot afin qu'il soit stable. Seulement, avec déjà le capteur couleur et le capteur infrarouge positionnés à l'avant du robot, nous ne pouvions donc pas le placer à cet endroit. De plus, il nous était impossible de l'y fixer, car il aurait fallu fabriquer un système composé de plusieurs barres servant de raccord entre la structure du robot et le capteur; chose irréalisable par manque de place. Nous avons donc décidé de placer ce capteur directement sur la pince en compliquant un peu sa programmation.
Programmation du Robot
Nous avons opté pour la programmation du robot par le langage C, plutôt que par l'éditeur graphique.
Structure du programme
Nous avons d'abord commencé par réfléchir au parcours effectué par notre robot lors de sa mission. Cela nous a permis de découper notre programme en fonctions. Chaque fonction réalise une action (attraper la balle, etc). Nous avons ainsi pu classer la première partie des actions effectuées dans la catégorie capteur "Infrarouge" et la seconde dans la catégorie "Déplacement en suivant les lignes".
Plus tard, une mise au point avec les autres équipes a été faite, permettant d'affiner le découpage. Le robot doit ainsi :
- Aller vers la balle et la saisir (capteur infrarouge)
- Se diriger vers le but le plus éloigné jusqu'à rencontrer une ligne médiane (capteurs couleur et ultrason)
- Suivre la ligne médiane jusqu'à trouver son garage et retourner au centre du terrain (capteur couleur)
- Déposer la balle au sol et repartir se garer. (capteur couleur)
Nous avons fait le choix d'exécuter les fonctions les unes après les autres, le rôle de ramasseur de balles du robot ne nécessitant pas d'effectuer des actions simultanément.
Infrarouge
Vidéo : Le robot qui cherche la balle grâce à l'infrarouge
A l'origine, deux parties concernant ce capteur étaient prévues. Cependant, au cours de la réalisation du robot, nous nous sommes aperçues que lorsque le robot se déplace vers les buts, il a déjà la balle entre ses pinces, ce qui rend impossible une autre mesure au vu de la position du capteur. Cette action se fera donc grâce au capteur couleur.
Pour permettre au robot d'aller vers la balle, nous avons commencé par le faire suivre sa direction. Cela s'est cependant avéré être un mauvais choix : en effet, la direction du signal est donnée par la somme des signaux infrarouges, or sur le terrain il y a également deux buts émettant eux aussi dans l'infrarouge. Le robot se serait ainsi dirigé vers ce signal, c'est-à-dire là où il n'y a ni balle, ni buts. Une seconde approche de ce problème est de considérer la continuité des signaux : la balle émet en continu, contrairement aux buts qui, en boucle, émettent pendant plusieurs secondes puis s'interrompent une seconde. Il a donc fallu réussir à isoler le signal continu.
Pour cela, nous avions à disposition 5 signaux reçus par le capteur, chacun correspondant à une direction :
- A gauche vers l'arrière
- A gauche vers l'avant
- En face
- A droite vers l'avant
- A droite vers l'arrière
Les signaux varient entre 0 et 255.
Notre première solution a été d'utiliser un tableau du langage C à cinq cases, initialisé aux valeurs des cinq signaux, et un entier retenant le nombre de signaux qui ne se sont jamais éteints (le tableau permet de savoir quelle direction prendre une fois le signal continu trouvé). Ensuite, dans une boucle, on lit les signaux et on met à jour les valeurs du tableau dès qu'un signal est égal à 0. Cela nous permet ainsi d'éliminer les signaux dès qu'ils arrêtent de transmettre, jusqu'à ce qu'il n'en reste plus qu'un (le signal continu). Enfin, on tourne ou on avance en fonction de la direction du signal.
Ci-dessous, l'algorithme correspondant :
Déclaration du tableau à 5 cases "tab" et de l'entier "cpt" Initialiser le tableau avec les valeurs des 5 signaux Tant que cpt plus grand que 1 initialiser cpt à 0 Lecture du capteur infrarouge (récupération des nouvelles valeurs des signaux) (Pour chaque signal) Si le signal est égal à 0 et que la case de tab correspondante est différente de 0 alors mettre 0 dans la case de tab Pour un indice i allant de 0 à 5 si le tab à l'indice i est différent de 0 incrémenter cpt Fin Pour Fin Tant que Si une case de tab correspondante à la gauche est différente de 0 alors tourner à gauche Si une case de tab correspondante à la droite est différente de 0 alors tourner à droite sinon avancer tout droit
Cependant, nous observions un problème récurrent : il était parfois nécessaire d'agiter la balle pour que le robot la détecte pour la première fois. Nous nous sommes ensuite aperçues que ce problème venait de notre algorithme qui ne prenait pas en compte la taille de la balle. En effet, celle-ci étant assez large, elle se retrouvait parfois sur deux signaux du capteur à la fois. Nous avons ainsi dû modifier notre algorithme de façon à prendre en compte ces cas-là.
Si la balle se trouve sur deux signaux en même temps, alors elle sera sur deux signaux consécutifs. Pour implémenter cette solution, nous avons déclaré un nouvel entier "allume", initialisé à -1, dont le rôle est de retenir l'indice dans le tableau du dernier signal allumé. S'il est différent de -1 à la fin, au moins un signal a repéré la balle. Nous avons également géré les cas d'erreurs, c'est-à-dire lorsque la balle est sur deux signaux non-consécutifs ou sur plus de deux signaux à la fois.
Cet algorithme fonctionne toujours pour différencier la balle des buts, car si on repère un but sur un signal non-consécutif à celui de la balle, cela est vu comme une erreur et on recommence alors la démarche (on pourra se diriger vers la balle lorsqu'on sera dans l'intervalle de temps pendant lequel le signal infrarouge du but est éteint). Sinon si le but se trouve derrière ou à coté de la balle, ils sont dans la même direction donc cela n'a pas d'importance.
Dans cet algorithme nous avons également rajouté la gestion de l'ultrason pour détecter la distance par rapport à la balle et savoir quand fermer la pince; ainsi que le capteur touch, pour savoir si la balle a été attrapée correctement.
Ci-dessous, l'algorithme final :
Tant que vrai Lecture du capteur infrarouge (récupération des nouvelles valeurs des signaux) Assignation d'un signal à une case de tableau, pour les 5 signaux Initialiser cpt à 0 et allume à -1 Pour chaque signal (indice i allant de 0 à 5) Si allume est plus grand ou égal à 0 (un signal a été repéré plus tôt) et la valeur de la case actuelle du tableau est supérieure à 0 (un signal est repéré maintenant) et le signal repéré maintenant n'est pas consécutif au signal repéré avant et qu'il ne correspond pas aux cases 0 et 4 du tableau Alors on sort du pour (on recommence le tant que) Si la valeur de la case actuelle du tableau est supérieure à 0 (un signal est repéré maintenant) Alors on donne l'indice de la case actuelle à allume et on incrémente cpt. Si cpt est plus grand que 2 alors on sort du pour (trois capteurs étaient allumés, on recommence le tant que) Fin pour Si allume est plus grand ou égal à 0 (un signal au moins a été repéré plus tôt) et que i correspond au nombre de signaux (on a parcouru tout le tableau donc on n'a pas eu de problème) Alors on sort du tant que Fin Tant que Si une case de tab correspondante à la gauche est différente de 0 alors tourner à gauche Si une case de tab correspondante à la droite est différente de 0 alors tourner à droite Sinon si le capteur ultrason ne détecte rien en face avancer tout droit Sinon On avance un peu, on ferme la pince. Si on détecte la balle dans les pinces grâce au capteur touch Alors on arrête Sinon on ouvre la pince et on recommence
Déplacement en suivant les lignes
Vidéo : Le robot qui suit les lignes
Le robot doit commencer par se diriger vers le but le plus éloigné jusqu'à rencontrer une ligne médiane. Pour cela, nous avons décidé de le faire avancer tout droit jusqu'à, ou rencontrer un obstacle repéré par le capteur ultrasons (mur, but, ...), ou croiser une ligne médiane. S'il croise cette ligne, de couleur bleue, le relais est passé à la fonction suivante.
Le robot se déplace alors en suivant cette ligne jusqu'à détecter une autre ligne. Suivant sa couleur, l'action effectuée est différente :
- Si c'est le contour du terrain (couleur rouge) ou un ligne devant un but (couleur verte), alors il fait demi-tour et continue de suivre la ligne médiane.
- Si c'est le centre du terrain (couleur jaune), alors il fait un quart de tour et suit de nouveau la ligne médiane.
- Si c'est un garage (couleur noire), alors c'est forcément le sien; Les garages des joueurs se trouvent à l'intersection d'une ligne devant un but et du contour du terrain, alors que celui du ramasseur se trouve au bout d'une ligne médiane. Il est nécessaire pour le robot de trouver son garage avant de déposer sa balle, car sinon celui-ci ne sait pas où aller se garer et ne peut plus chercher le long des lignes médianes, la balle étant au centre du terrain.
Après avoir trouvé le garage, le robot fait demi-tour et suit la ligne médiane jusqu'au centre du terrain, puis il y dépose la balle. Après cela, il recule un peu, fait demi-tour et suit la ligne médiane jusqu'à son garage. Pour se garer, il lui suffit juste d'avancer le long de la ligne du garage puis de faire demi-tour.
Nous avons également donné au robot la capacité de corriger légèrement sa trajectoire s'il suit déjà une ligne médiane et que son capteur couleur voit du blanc, c'est-à-dire le terrain lui-même. Cela lui sera utile s'il croise perpendiculairement la ligne médiane : sans cela, il continuerait d'avancer tout droit et n'arriverait pas à la suivre.
Au cours des tests sur le vrai terrain, nous nous sommes rendu compte que le robot ne voyait pas du blanc lorsqu'il dévie de sa ligne de couleur comme sur le terrain en papier, mais du noir. En effet, les lignes étant larges, lorsque le robot dévie, son capteur couleur voit à la fois la ligne et le blanc du terrain, ce qu'il interprète alors comme du noir.
Un problème majeur se pose alors : comment différencier une déviation, vue comme du noir, de la ligne du garage de couleur noire ? Nous avons dû modifier le code utilisé pour "corriger" la trajectoire du robot : alors qu'auparavant il ne prenait en compte que la couleur blanche, maintenant il prend toujours en compte le blanc mais également le noir. Cependant, ce code n'est pas encore optimisé : le robot ne tourne que dans une direction pour corriger sa trajectoire, et surtout il lui arrive encore de confondre quelques déviations comme son garage. De plus les déviations arrivent assez souvent, le terrain étant un peu glissant et notre robot ayant un problème sur l'un de ses moteurs (voir partie Construction du robot, Version finale du Robot).
Ci-dessous, notre algorithme final.
bool arreter = false; SetSensorColorFull(S1); while (!arreter) { unsigned int rawData[], normData[]; int scaledData[]; int cval; ReadSensorColorEx(S1, cval, rawData, normData, scaledData); if (cval == INPUT_BLUECOLOR) { OnFwd(OUT_A, SPEEDSLOW); OnFwd(OUT_B, SPEEDFAST); ReadSensorColorEx(S1, cval, rawData, normData, scaledData); } else if (cval == INPUT_REDCOLOR || cval == INPUT_GREENCOLOR) { FaireDemiTour(); } else if (cval == INPUT_YELLOWCOLOR) { OnFwd(OUT_A, SPEEDSLOW); OnFwd(OUT_B, SPEEDFAST); Wait(500); FaireDemiTour(); } else if (cval == INPUT_BLACKCOLOR || cval == INPUT_WHITECOLOR) { OnFwd(OUT_A, 0); OnFwd(OUT_B, SPEEDFAST); ReadSensorColorEx(S1, cval, rawData, normData, scaledData); if (cval == INPUT_BLACKCOLOR) { Wait(200); OnFwd(OUT_A, SPEEDSLOW); OnFwd(OUT_B, SPEEDFAST); Wait(100); OnFwd(OUT_AB, 0); ReadSensorColorEx(S1, cval, rawData, normData, scaledData); } if (cval == INPUT_BLACKCOLOR) { FaireDemiTour(); arreter = true; } } }
Ramassage de la balle
L'étape du ramassage de balle nous a posé de nombreux problème. En effet, lorsque le robot avance vers la balle en suivant son signal infrarouge, il lui faut savoir quand s'arrêter et fermer sa pince.
Nous avons d'abord pensé à placer un capteur tactile, que la balle enfoncera lorsqu'elle se trouve entre les pinces. Cependant, il nous était impossible de placer ce capteur à la bonne hauteur avec la façon dont nous avons construit notre pince. Nous avons ensuite essayé de détecter la distance entre la balle et le robot à l'aide du capteur infrarouge. Malheureusement, la distance détectée était à chaque fois différente. Nous avons donc décidé d'utiliser le capteur ultrason pour trouver la distance de la balle par rapport au robot et avons finalement réussi à installer le capteur touch.
La distance par rapport à la balle est ainsi détectée par le capteur ultrason. En dessous d'un certain seuil, le robot avance un peu et referme ses pinces. Le capteur touch prend alors le relais en détectant si la balles se trouve bien entre les pinces (son bout est enfoncé). Si ce n'est pas le cas, le robot rouvre sa pince et continue sa recherche.
Communication avec l'Arbitre
Nous avons également programmé le robot de façon à ce qu'il puisse communiquer avec l'arbitre lors d'un match.
L'arbitre est un petit ordinateur dont le rôle est d'établir une connection Bluetooth avec cinq acteurs, correspondant aux deux cages de buts, aux deux joueurs et au ramasseur. Il doit tout d'abord les enregistrer pour pouvoir communiquer avec eux par la suite. Puis il tente de les joindre par Bluetooth. Après que la connection ait été établie, l'arbitre envoie des codes aux acteurs en fonction de ce qu'il veut savoir ou leur faire faire. Ainsi, il commence par se renseigner sur le type de chaque acteur (pour vérifier que tous les acteurs sont bien là). Puis il va débuter le match et attendre un retour des cages de buts, lorsqu'un but a été marqué, etc.
Notre robot intervient après qu'un but ait été marqué et que les joueurs aient été se garer sur leurs emplacements respectifs. Il reçoit alors un message de l'arbitre lui indiquant d'aller chercher la balle et de la replacer au centre du terrain. Il doit également renvoyer un message à l'arbitre pour le prévenir lorsque la tâche a été accomplie.
Pour réaliser cela, nous avons suivi l'algorithme indiqué sur la page de présentation, tout en faisant attention à ne pas oublier de convertir les messages reçus et les messages envoyés. Nous avons ainsi obtenu le programme ci-dessous :
#define CODE_REQTYPE 0 // demander le type de l'acteur #define CODE_RAMASSER 1 // ordonne le placement de la balle #define TYPE_RAMASSEUR 2 #define CODE_BALLEOK 2 // la balle est placé au centre #define BOITE_RAMASSEUR 1 #define BOITE_ARBITRE (2+10) string msg; while (true) { ReceiveMessage(BOITE_RAMASSEUR, true, msg); int res = StrToNum(msg); if (res == CODE_REQTYPE) { msg = NumToStr(TYPE_RAMASSEUR); SendMessage(BOITE_ARBITRE, msg); } else if (res == CODE_RAMASSER) { AllerVersBalle(); AllerVersBut(); SuivreLigneMediane(); DeposerBalle(); msg = NumToStr(CODE_BALLEOK); SendMessage(BOITE_ARBITRE, msg); } }
Nous avons ensuite testé ce programme avec l'arbitre et notre robot. Pour cela, nous avons d'abord dû enregistrer notre robot auprès de l'arbitre, pour qu'il puisse le reconnaître. Puis, une fois le robot enregistré et le contact Bluetooth établi avec notre robot, l'arbitre a lancé le début d'un match "fictif" (notre robot étant le seul connecté en Bluetooth à ce moment-là) et le robot a bien rempli son rôle.
Réalisation du terrain
Pour réaliser le terrain, quatre plaques d'1,5m sur 1m et des rubans adhésifs de couleur nous ont été attribués.
Nous avons d'abord réfléchi à l'emplacement des différentes lignes sur le terrain. En effet, les robots et les buts ne font pas tous la même taille, et il faut que tous les robots puissent se déplacer et faire demi-tour et que les buts rentrent tous dans l'espace prévu sur le terrain. De plus il a fallu ajouter un espace afin que chaque robot puisse se garer. Nous avons donc dû mesurer chacun de nos robots afin d’être sûr de laisser un espace suffisant au garage, mais aussi d'avoir la place de tourner lorsque l'on suit une ligne. C'est pourquoi le terrain sur lequel les robots effectuent le match ne recouvre en fait pas tous l’espace des plaques.
Ces lignes ont ensuite été tracées au crayon gris sur les plaques, traits que l'on a ensuite recouvert de scotch de couleur. Enfin, les rubans ont été collés.
Nous avons décidé de garder les quatre plaques séparées et d'ensuite les assembler pour le jeu afin de faciliter leur rangement et leur transport.
Conclusion
Ce bureau d'étude nous a permis d'apprendre beaucoup de choses, à la fois comment construire un robot tout en faisant attention à l'emplacement des différents éléments et en respectant les contraintes techniques; comment programmer ce robot de façon à lui faire effectuer des tâches précises; comment s'adapter aux contraintes liées au matériel (moteur ralentit, robot réagissant au terrain final différemment du premier terrain) et gérer son temps correctement.
Nous avons également appris à gérer un wiki et à y inscrire régulièrement notre avancement. Ce bureau d'étude nous a aussi permis d'avoir une première expérience de projet de groupe et d'apprendre à mieux connaître les autres, à partager notre opinion et écouter la leur. C'était une expérience très enrichissante, et il a été d'une aide précieuse dans le choix de notre orientation future.