Robotique 2022 : Différence entre versions
(→Programmation) |
|||
(103 révisions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 7 : | Ligne 7 : | ||
= Analyse du projet = | = Analyse du projet = | ||
− | Avant de développer notre projet, nous devons poser sur le papier tous les éléments à penser, et | + | Avant de développer notre projet, nous devons poser sur le papier tous les éléments à penser : les éléments mécaniques qui comptent les conceptions 3D, la schématisation des différents systèmes électroniques et autres. Il est important de bien s'informer sur la compétition et la réalisation de notre robot, sur la faisabilité du projet. Et il faudra s'adapté aux nombreuses contraintes. |
<br /> | <br /> | ||
== La compétition == | == La compétition == | ||
− | Le principe de la compétition, 2 robots s'affrontent sur un terrain de tennis | + | Le principe de la compétition, 2 robots s'affrontent sur un terrain de tennis, le but est d'envoyer du côté adversaire plus de balle (une par une) que l'autre en 90s et d’éclater un ballon attacher au sommet de son robot à la fin du temps imparti. De nombreuses règles sont a respecté durant le jeu, certaines imposent des contraintes techniques à la réalisation de notre robot tel que les dimensions de celui-ci, le système de perçage du ballon, d'autres sont pour la sécurité comme la réglementation de la batterie, un bouton d'arrêt d'urgence et le système de perçage du ballon qui doit être démontable. |
− | <br> | + | <br /> |
=== Déroulement de la compétition === | === Déroulement de la compétition === | ||
− | + | Début de la compétions avec un contrôle technique et démonstration devant un jury.Puis les match de 90 secondes, nous sommes sur un terrain de 8x4m donc nous avons pour chaque équipe un carré de 4x4m. Durant ce temps, nous devrons envoyer le maximum de balle du côté adverse, et arriver aux 90s, le système d'éclatement de ballon s’exécute ainsi que le robot devra s’immobilise. La qualification marche par un système de point sur le nombre de balle et les bonus puis un certain nombre de participant au dessus un seuil de point passeront à la phase suivante. | |
− | |||
+ | === Le terrain === | ||
+ | [[Fichier:Terrain2022.png|cadre|centré|Terrain competition]] | ||
+ | <br /> | ||
=== Quelques contraintes lié au règlement === | === Quelques contraintes lié au règlement === | ||
* Le gabarit du projet sera en 40x30x30 | * Le gabarit du projet sera en 40x30x30 | ||
* Le robot doit avoir une faible consommation en veille | * Le robot doit avoir une faible consommation en veille | ||
− | * Des systèmes de protection doivent être mis en | + | * Des systèmes de protection doivent être mis en œuvre (limitation de courant/protection) |
* Le robot ne doit pas composer un danger une fois au repos | * Le robot ne doit pas composer un danger une fois au repos | ||
* Une démonstration des dispositifs de sécurité doit être effectué avant la mise en jeu | * Une démonstration des dispositifs de sécurité doit être effectué avant la mise en jeu | ||
Ligne 58 : | Ligne 60 : | ||
<br/> | <br/> | ||
Le Schéma fonctionnel présente les grandes fonctions à développer durant notre projet, nous devrons définir quelles technologies adopter pour chaque fonction afin d’avoir un robot qui remplit au mieux sa fonction qui est de gagner la compétition ! | Le Schéma fonctionnel présente les grandes fonctions à développer durant notre projet, nous devrons définir quelles technologies adopter pour chaque fonction afin d’avoir un robot qui remplit au mieux sa fonction qui est de gagner la compétition ! | ||
− | [[Fichier:Schema bloc robotique.png| | + | [[Fichier:Schema bloc robotique.png|thumb|left|Schema fonctionnel du projet]] |
− | + | [[Fichier:Algorithme programme.png|thumb|center|Algorithme de fonctionnement du programme]] | |
+ | <br/> | ||
=== Etude des blocs de fonction === | === Etude des blocs de fonction === | ||
==== Alimentation ==== | ==== Alimentation ==== | ||
− | L'alimentation du robot se fait à l'aide d'une batterie, elle est suffisante pour le projet, permet d'alimenter l'ensemble des fonctions. | + | [[Fichier:LM2596.jpg|thumb|100px|LM2596]] |
+ | L'alimentation du robot se fait à l'aide d'une batterie composé de 4 cellules Lithium-ion disposées en série pour obtenir une tension d'environ 12.4v, elle est suffisante pour le projet, permet d'alimenter l'ensemble des fonctions. Cependant, certains modules comme le micro-contrôleur utilisera une tension de 5v pour fonctionner. Nous devons alors abaisser la tension.</br> | ||
+ | Pour cela, nous utiliserons un abaisseur de tension "LM2596".<br/><br/> | ||
+ | Celui-ci, à l'aide d'un potentiomètre, permet d'abaisser la tension jusqu'à 5v. Son principe de fonctionnement est simple, il s'agit d'un hacheur abaisseur dont le potentiomètre fait varier le rapport cyclique du hacheur ce qui fait varier sa tension. | ||
+ | |||
==== Détection de lignes ==== | ==== Détection de lignes ==== | ||
− | Au moment d'avancer vers la zone adverse, il faut savoir reconnaitre les différentes lignes et en particulier, celle qui est au centre. Il est très important de savoir l'identifié pour éviter de la traverser. Traverser cette ligne est contraire au règlement. Pour cela, nous utiliserons | + | [[Fichier:QRE1113 .jpg|thumb|150px|Capteur QRE1113]] |
+ | Au moment d'avancer vers la zone adverse, il faut savoir reconnaitre les différentes lignes et en particulier, celle qui est au centre. Il est très important de savoir l'identifié pour éviter de la traverser. Traverser cette ligne est contraire au règlement. Pour cela, nous utiliserons 4 capteurs de lumière (capteurs opto-électroniques) situé sous le robot et placé de façon à ce qu'ils puissent repérer uniquement la grosse ligne et non les autres pour éviter les "faux positifs". | ||
<br/> A savoir que la caméra Pixy est également en mesure de détecter des lignes, mais cela est plus complexe à exploiter et la faible résolution de la caméra permet surtout de trouver des objets volumineux. | <br/> A savoir que la caméra Pixy est également en mesure de détecter des lignes, mais cela est plus complexe à exploiter et la faible résolution de la caméra permet surtout de trouver des objets volumineux. | ||
+ | <br/>Les capteurs utilisés sont des QRE1113, ils retournent une valeur logique (0 ou 5v) en fonction de s'il est sur du blanc ou non. Cela en fait un grand avantage pour le branchement et l'interprétation des résultats. | ||
+ | |||
+ | * Lien vers le capteur : [https://www.sparkfun.com/products/9454 Lien Sparkfun] | ||
+ | |||
==== Perçage du ballon ==== | ==== Perçage du ballon ==== | ||
− | Le système de perçage de ballon possède plusieurs contraintes, nous devons avoir un système qui est protéger | + | Le système de perçage de ballon possède plusieurs contraintes, nous devons avoir un système qui est soi protéger soit enlevable donc qui ne présente pas de danger lorsqu'il est au repos. L'idée ici retenu a été d'utiliser un disque fin associer à un moteur à courant continu et un servo-moteur. Le moteur CC va entrainer le disque à haute vitesse et le servo moteur va déplacer vers le haut un bras qui permettra au disque de toucher le ballon et ainsi de l'éclater au bout des 90s de jeu. |
+ | |||
==== Détection des balles ==== | ==== Détection des balles ==== | ||
+ | [[Fichier:CNY.png|thumb|150px|CNY70 présent sur la carte]] | ||
Pour détecter la balle, nous avons pour cela plusieurs façons, déjà nous pouvons également utiliser la caméra Pixy pour détecter la balle par sa couleur et ainsi orienter le robot pour qu’il puisse s’y diriger.<br/> | Pour détecter la balle, nous avons pour cela plusieurs façons, déjà nous pouvons également utiliser la caméra Pixy pour détecter la balle par sa couleur et ainsi orienter le robot pour qu’il puisse s’y diriger.<br/> | ||
Nous pouvons aussi mesurer une distance, à l’aide d’un capteur de distance, à ultra-son, ou laser (lidar) nous pouvons chercher la présence d’un objet sur le terrain en faisant une différence de distance sur plusieurs points. Si la différence est supérieure à la taille d’une balle, c’est qu’il s’agit probablement d’une balle et donc nous pouvons diriger le robot. | Nous pouvons aussi mesurer une distance, à l’aide d’un capteur de distance, à ultra-son, ou laser (lidar) nous pouvons chercher la présence d’un objet sur le terrain en faisant une différence de distance sur plusieurs points. Si la différence est supérieure à la taille d’une balle, c’est qu’il s’agit probablement d’une balle et donc nous pouvons diriger le robot. | ||
Ligne 75 : | Ligne 89 : | ||
Ici, la solution retenue a été d'utiliser exclusivement la caméra Pixy, simple à mettre en œuvre, elle permet de voir facilement les balles via un profil de couleur enregistrer au préalable. A savoir qu'une caméra Pixy se doit d'être correctement configurée pour détecter correctement les nuances de couleurs et donc, les objets. | Ici, la solution retenue a été d'utiliser exclusivement la caméra Pixy, simple à mettre en œuvre, elle permet de voir facilement les balles via un profil de couleur enregistrer au préalable. A savoir qu'une caméra Pixy se doit d'être correctement configurée pour détecter correctement les nuances de couleurs et donc, les objets. | ||
<br/><br/> | <br/><br/> | ||
+ | |||
Autre chose, il faut aussi détecter la réception de la balle dans son enceinte pour vérifier que le robot a bien capturé cette-dernière !<br/> | Autre chose, il faut aussi détecter la réception de la balle dans son enceinte pour vérifier que le robot a bien capturé cette-dernière !<br/> | ||
− | Pour cela, il suffit de créer une barrière lumineuse à l'aide de capteurs et émetteurs infrarouges situés de part et d'autres de l'enceinte, l'un émet et l'autre reçoit, l'information reçu sera alors analogique, il faudra alors simplement vérifier les seuils de lumières reçu par l'info analogique reçu dans le microcontrôleur.<br/> | + | Pour cela, il suffit de créer une barrière lumineuse à l'aide de capteurs (ici des CNY70) et émetteurs infrarouges situés de part et d'autres de l'enceinte, l'un émet et l'autre reçoit, l'information reçu sera alors analogique, il faudra alors simplement vérifier les seuils de lumières reçu par l'info analogique reçu dans le microcontrôleur.<br/> |
− | Nous aurions pu utiliser un comparateur, mais un problème empêche cela, c'est que la différence de tension est assez faible lorsqu'il y a présence ou absence de balle dû à l'environnement. Le capteur infrarouge est aussi sensible à la lumière alentour. Ce problème a été résolu en mesurant le seuil à l'initialisation du robot. | + | [[Fichier:Robotique2022 CapteursBalleRealisation2.jpg|thumb|150px|Cartes de détection de présence de balle]] |
+ | Nous aurions pu utiliser un comparateur, mais un problème empêche cela, c'est que la différence de tension est assez faible lorsqu'il y a présence ou absence de balle dû à l'environnement. Le capteur infrarouge est aussi sensible à la lumière alentour. Ce problème a été résolu en mesurant le seuil à l'initialisation du robot.<br/> | ||
+ | <br/> | ||
+ | [[Fichier:MCP3421.png|thumb]] | ||
+ | Cependant, lors de la mise en oeuvre du projet, nous nous sommes rendus compte qu'il était difficile la mise en place du système sur la carte faute de manque de broche disposant d'un Convertisseur Analogique Numérique. Nous utiliserons alors un CAN fonctionnant en I2C (image ci-contre). Il s'agit d'un boitier en SOT23-6 donc assez petit qu'on a dû soudé sur une carte. | ||
+ | * Vin = Broche d'entrée analogique à convertir | ||
+ | * Vss = Masse | ||
+ | * Vdd = 5v | ||
+ | * SDA/SCL = Pour la communication I2C. | ||
+ | |||
+ | A savoir que nous avons ajouté un condensateur de 100nF entre les broches VDD et VSS en amont du convertisseur pour lisser le courant. | ||
+ | |||
+ | * Datasheet CNY70 : [https://www.vishay.com/docs/83751/cny70.pdf Datasheet] | ||
+ | * Datasheet MCP3421 [http://ww1.microchip.com/downloads/en/devicedoc/22003e.pdf Datasheet] | ||
+ | <br/><br/><br/> | ||
+ | |||
==== Système d'envoi de balle ==== | ==== Système d'envoi de balle ==== | ||
− | Pour envoyer une balle, il existe nombreuses solutions, nous pouvons faire deux rouleaux tournant à haute vitesse pour propulser la balle, comme le fonctionnement des lanceurs de balle de Tennis. Mais ici nous avons choisi de réaliser un | + | Pour envoyer une balle, il existe nombreuses solutions, nous pouvons faire deux rouleaux verticaux tournant à haute vitesse pour propulser la balle, comme le fonctionnement des lanceurs de balle de Tennis. Mais ici nous avons choisi de réaliser un rouleau horizontal tournant rapidement. Le rouleau s'abaissera pour laisser le robot reculer et la balle se fera propulser grâce à l'inertie du rouleau. |
+ | |||
==== Déplacement du robot ==== | ==== Déplacement du robot ==== | ||
+ | [[Fichier:MD13S a-512x512.jpg|200px|thumb|Contrôleur du moteur (Carte Cytron)]] | ||
Le robot possède deux moteurs à balais (rien à voir avec celui de la buanderie), ils consomment jusqu'à 30A et 13A en continue, ces moteurs fonctionnent sur une plage de tension assez large, 6 à 30v. Mais pour ainsi les contrôlés correctement, nous utiliserons une carte Cytron. | Le robot possède deux moteurs à balais (rien à voir avec celui de la buanderie), ils consomment jusqu'à 30A et 13A en continue, ces moteurs fonctionnent sur une plage de tension assez large, 6 à 30v. Mais pour ainsi les contrôlés correctement, nous utiliserons une carte Cytron. | ||
<br/>La gestion des moteurs se fait à l'aide de signaux PWM et Haut/Bas sur la carte Cytron.<br/> | <br/>La gestion des moteurs se fait à l'aide de signaux PWM et Haut/Bas sur la carte Cytron.<br/> | ||
Un fil envoi l'info de vitesse, un autre celui du sens de rotation. Ces cartes se gèrent très facilement avec un microcontrôleur tant qu'il est capable de générer un signal PWM. | Un fil envoi l'info de vitesse, un autre celui du sens de rotation. Ces cartes se gèrent très facilement avec un microcontrôleur tant qu'il est capable de générer un signal PWM. | ||
+ | |||
+ | * Lien vers carte Cytron : [https://www.cytron.io/p-13amp-6v-30v-dc-motor-driver Lien] | ||
+ | * Datasheet Cytron : [https://docs.google.com/document/d/1icu1GVDxZhUn3ADSUc3JknNcmUMdPcsnJ4MhxOPRo-I/view Lien] | ||
+ | |||
==== Repérage du robot ==== | ==== Repérage du robot ==== | ||
Lors du développement, en particulier lorsqu'on souhaite orienter le robot face à la zone adverse, il faut avoir une notion de l'espace. Ici nous avons fait le choix d'utiliser un magnétomètre pour savoir en temps réel l'angle du robot par rapport au champ magnétique terrestre. Cela à l'avantage d'être facile a mettre en œuvre et demande peu de ressources. | Lors du développement, en particulier lorsqu'on souhaite orienter le robot face à la zone adverse, il faut avoir une notion de l'espace. Ici nous avons fait le choix d'utiliser un magnétomètre pour savoir en temps réel l'angle du robot par rapport au champ magnétique terrestre. Cela à l'avantage d'être facile a mettre en œuvre et demande peu de ressources. | ||
Ligne 89 : | Ligne 125 : | ||
Donc pour faire cela, nous avons utiliser un MPU9250 qui fonctionne à l'aide d'un bus I2C et retourne directement les valeurs du champ magnétique qu'il faut ensuite interpréter pour en déduire l'angle. | Donc pour faire cela, nous avons utiliser un MPU9250 qui fonctionne à l'aide d'un bus I2C et retourne directement les valeurs du champ magnétique qu'il faut ensuite interpréter pour en déduire l'angle. | ||
<br /> | <br /> | ||
+ | * Lien du MPU9250 : [https://www.sparkfun.com/products/retired/13762 Lien Sparkfun] | ||
+ | (Contient les informations relatives à son utilisation) | ||
=== Conception cartes électronique === | === Conception cartes électronique === | ||
Le robot a besoin de plusieurs cartes pour fonctionner, nous avons alors besoin de réaliser deux cartes, l'une s'occupera de gérer l'ensemble du robot et une autre de gérer la batterie (et de la protéger elle ainsi que le robot). Pour cela, nous utiliserons le logiciel Eagle pour les réalisés. Dans un souci de temps, notre projet n'a pas eu à faire l'étude et la conception des cartes, simplement leurs routages et leurs fabrications. | Le robot a besoin de plusieurs cartes pour fonctionner, nous avons alors besoin de réaliser deux cartes, l'une s'occupera de gérer l'ensemble du robot et une autre de gérer la batterie (et de la protéger elle ainsi que le robot). Pour cela, nous utiliserons le logiciel Eagle pour les réalisés. Dans un souci de temps, notre projet n'a pas eu à faire l'étude et la conception des cartes, simplement leurs routages et leurs fabrications. | ||
<br /> | <br /> | ||
− | ==== Carte de gestion ==== | + | ==== Carte de gestion Robot ==== |
+ | La carte de gestion du robot a été conçu sur le logiciel Eagle, celle-ci comporte l'ensemble des éléments indispensable au fonctionnement de notre robot, composés de nombreux connecteurs (Entrées analogiques, sorties PWM, connecteurs couplé à un transistor pour délivré une tension de 12v et du courant à destination de moteur à courant continu).<br/> | ||
+ | Basé sur un microcontrôleur Atmega 2560, elle est suffisamment performante pour remplir entièrement son rôle dé réussir la compétition. | ||
+ | |||
+ | [[Fichier:Carte Gestion.png|thumb|none|right|700px|Schéma électronique]] | ||
+ | [[Fichier:BoardGestion.png|thumb|none|left|700px|Carte électronique]] | ||
<br /> | <br /> | ||
− | : | + | '''Organisation de la carte µcontrôlleur : ''' |
− | + | [[Fichier:CablageCarte.png|vignette|centré|Organisation et câblage des différent systèmes ]] | |
− | : | + | <br/> |
− | <br /> | + | ==== Carte de gestion Batterie ==== |
− | ==== Carte de | + | Cette carte à pour bute d'informer sur l’état. Si elle est complètement décharger ou si il y a des problèmes éventuel causer par le câblage ou l'alimentation des différents systèmes. En raison de manque temps cette carte n'a pas été réaliser. |
− | + | ||
− | : | + | [[Fichier:SchemaBatterie2022.png|cadre|gauche|700px|Schéma carte surveillance de la batterie]] |
− | + | [[Fichier:BoardBatterie.png|cadre|centre|700px|Board carte surveillance de la batterie]] | |
− | : | ||
<br /> | <br /> | ||
=== Programmation === | === Programmation === | ||
− | ==== Magnétomètre (MPU9250) ==== | + | ==== Les essais ==== |
− | ==== Capteurs de proximités (VL53L1) ==== | + | ===== Magnétomètre (MPU9250) ===== |
− | ==== Capteurs de présence de la balle ==== | + | Il s'agit d'un module (MPU9250) composé de 9 axes, celui-ci peut se gérer via une communication SPI ou I2C (aka TWI), il nous permettra de savoir si le robot est en mouvement grâce à l'accéléromètre intégrer. Nous pourrons déduire également l'angle du composant via l'utilisation du magnétomètre qui permet de savoir l'orientation du robot par rapport à au champ magnétique terrestre. |
− | ==== Caméra Pixy2 ==== | + | Toutes ces informations sont récupérables via les protocoles de communication précédemment cités. |
− | ==== Moteurs (Cytron) ==== | + | |
+ | '''Code de test :''' | ||
+ | ===== Capteurs de proximités (VL53L1) ===== | ||
+ | Le capteur de proximité fonctionne avec une onde lumineuse qui se reflète contre une surface, celle-ci permettra au capteur d'en déterminer la distance de façon très précise. Celui-ci détecte les éléments proches, il sera utilisé pour détecter les parois pour alors les éviter. | ||
+ | Il fonctionne avec un protocole de communication I2C (aka TWI), donc il pourra communiquer sur le même bus que le module comportant le magnétomètre. | ||
+ | |||
+ | '''Code de test :''' | ||
+ | ===== Capteurs de présence de la balle ===== | ||
+ | La programmation pour les capteurs de présence de balle va être assez simple, ici nous avons simplement deux capteurs infrarouges mis face à face, il y a un fil qui retourne au robot qui donne l'information analogique du capteur qui reçoit la lumière. Il faudra cependant faire attention car la valeur de tension du capteur qui reçoit varie en fonction des conditions environnantes (pollution lumineuse de l'environnement), il faudra alors déterminer une valeur seuil à chaque démarrage pour ensuite se comparer à elle pour savoir s'il y a une balle ou non dans le logement. | ||
+ | |||
+ | |||
+ | |||
+ | Cependant, par soucis de place sur la carte de gestion réalisée, nous utiliserons un convertisseur analogique/numérique fonctionnant en I2C (Le MCP3421). | ||
+ | Comme pour l'ensemble des composants fonctionnant en I2C, celui-ci a été mis sur le même bus que les autres composants I2C (Magnétomètre/Capteur de proximité). Ainsi pour pouvoir l'exploiter il faudra identifier son adresse qui par défaut est l'adresse "x69" après un i2c_detect (utilitaire permettant d'identifier les adresses I2C des composants sur un bus). | ||
+ | |||
+ | |||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed"> | ||
+ | Code d'essaie | ||
+ | <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="C++"> | ||
+ | #include <avr/io.h> | ||
+ | #include <Wire.h> | ||
+ | #include <VL53L1X.h> | ||
+ | |||
+ | VL53L1X Sensor1; | ||
+ | VL53L1X Sensor2; | ||
+ | |||
+ | // SCL = 19; //I2C serial clok input | ||
+ | |||
+ | void setup() { | ||
+ | |||
+ | Wire.begin(); | ||
+ | Wire.setClock(400000); | ||
+ | Serial.begin(9600); | ||
+ | sensor(); | ||
+ | |||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | |||
+ | Serial.print(Sensor1.read()); | ||
+ | Serial.print(" Capteur gauche "); | ||
+ | Serial.println(VL53L1X::rangeStatusToString(Sensor1.ranging_data.range_status)); | ||
+ | Serial.print(Sensor2.read()); | ||
+ | Serial.print(" Capteur droite "); | ||
+ | Serial.println(VL53L1X::rangeStatusToString(Sensor2.ranging_data.range_status)); | ||
+ | |||
+ | } | ||
+ | |||
+ | void sensor() { | ||
+ | |||
+ | pinMode(4, OUTPUT); // Shut digital input LOW active | ||
+ | pinMode(5, OUTPUT); | ||
+ | digitalWrite(4, LOW); | ||
+ | digitalWrite(5, LOW); | ||
+ | |||
+ | // Initalisiert I2C | ||
+ | delay(500); | ||
+ | Wire.begin(); | ||
+ | Wire.beginTransmission(0x29); | ||
+ | |||
+ | digitalWrite(4, HIGH); | ||
+ | delay(150); | ||
+ | Sensor1.init(); | ||
+ | Serial.println("01"); | ||
+ | delay(100); | ||
+ | Sensor1.setAddress(0x33); | ||
+ | Serial.println("02"); | ||
+ | |||
+ | digitalWrite(5, HIGH); | ||
+ | delay(150); | ||
+ | Sensor2.init(); | ||
+ | Serial.println("03"); | ||
+ | delay(100); | ||
+ | Sensor2.setAddress(0x35); | ||
+ | Serial.println("04"); | ||
+ | |||
+ | Sensor1.setDistanceMode(VL53L1X::Long); | ||
+ | Sensor1.setMeasurementTimingBudget(50000); | ||
+ | Sensor1.startContinuous(50); | ||
+ | Sensor1.setTimeout(100); | ||
+ | |||
+ | Sensor2.setDistanceMode(VL53L1X::Long); | ||
+ | Sensor2.setMeasurementTimingBudget(50000); | ||
+ | Sensor2.startContinuous(50); | ||
+ | Sensor2.setTimeout(100); | ||
+ | |||
+ | delay(150); | ||
+ | Serial.println("addresses set"); | ||
+ | |||
+ | Serial.println ("I2C scanner. Scanning ..."); | ||
+ | byte count = 0; | ||
+ | |||
+ | for (byte i = 1; i < 120; i++) | ||
+ | { | ||
+ | |||
+ | Wire.beginTransmission (i); | ||
+ | if (Wire.endTransmission () == 0) | ||
+ | { | ||
+ | Serial.print ("Found address: "); | ||
+ | Serial.print (i, DEC); | ||
+ | Serial.print (" (0x"); | ||
+ | Serial.print (i, HEX); | ||
+ | Serial.println (")"); | ||
+ | count++; | ||
+ | delay (1); // maybe unneeded? | ||
+ | } // end of good response | ||
+ | } // end of for loop | ||
+ | Serial.println ("Done."); | ||
+ | Serial.print ("Found "); | ||
+ | Serial.print (count, DEC); | ||
+ | Serial.println (" device(s)."); | ||
+ | |||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | </div> | ||
+ | |||
+ | ===== Caméra Pixy2 ===== | ||
+ | La caméra Pixy2 est assez facile à mettre en œuvre, celle-ci propose directement une bibliothèque très bien fournie pour pouvoir prendre en main rapidement sa caméra. Pour utiliser celle-ci, il suffit d'intégrer la bibliothèque, créer un nouvelle objet Pixy2, et utilisé les méthodes associés.<br/> | ||
+ | Celle-ci fonctionne via le protocole de communication SPI (Serial Peripheral Interface) de l'AVR utilisé, dans un premier temps les tests étaient effectués sur un Arduino Mega, donc sur le connecteur prévu, ensuite nous avons dû pensé à un connecteur pour la carte électronique qui reprend ces branchements.<br/><br/> | ||
+ | '''Différentes méthodes exploités''' | ||
+ | * getBlocks() - Retourne le nombre d'objet que la Caméra a detecté | ||
+ | Les méthodes suivantes seront précédées de : .ccc.blocks[indice de l'objet]. | ||
+ | * m_x & m_y | ||
+ | Retournent la position en X et Y sur l'image de l'objet (0 à 316 et 0 à 208 respectivement), cela est utile à savoir pour pouvoir correctement orienter le robot et la camera vers l'objet quand celui-ci n'est plus centré. (La caméra étant sur un axe, celle-ci peut pivoté de haut en bas) | ||
+ | * m_width m_height | ||
+ | Ces deux méthodes retournent la dimension sur l'image de l'objet, cela sera utile pour déterminer si celui-ci est carré en faisant un ratio des deux. (Une balle vu par la caméra est représenté par un carré). | ||
+ | <br/> | ||
+ | D'autres méthodes peuvent être utilisé pour optimiser le programme tel que "m_age" ou "m_signature" pour éventuellement identifier plusieurs objets et affiné la fiabilité de reconnaissance. De plus, la camera se doit d'être correctement configuré avant le début de la programmation pour éviter tout faux-positifs. | ||
+ | <br/><br/> | ||
+ | * Lien vers la bibliothèque Pixy : [https://pixycam.com/downloads-pixy2/ Lien Pixycam] | ||
+ | |||
+ | '''Code de test :''' | ||
+ | ===== Moteurs (Cytron) ===== | ||
+ | Le déplacement du robot a été la première partie a être programmé, celle-ci étant aussi la plus simple car cela se fait par l'intermédiaire de la carte Cytron. | ||
+ | [[Fichier:Cytron2022.png|vignette|Carte Cytron]] | ||
+ | Comme visible sur l'image ci-contre, nous avons 4 branchements dont 3 utiles. (NC n'étant relié à rien sur la carte) | ||
+ | * GND - La masse commune | ||
+ | * PWM - Contrôle la vitesse de rotation des moteurs via une MLI | ||
+ | * DIR - Sens de rotation des moteurs selon l'état logique envoyé | ||
+ | <br/> | ||
+ | Le sens de rotation va dépendre de comment est branché le moteur aux bornes MA et MB, il faudra alors faire un petit code pour vérifier le fonctionnement, le sens de rotation, pour ensuite mettre cela en œuvre dans le programme. | ||
+ | |||
+ | '''Code de test :''' | ||
+ | ===== Démarrage à distance + Éclatement ballon (Nom composant)===== | ||
+ | [[Fichier:PhotoTransistor2022.png|thumb|Schéma électronique]] | ||
+ | Composant en forme de fourche fonctionnant en photo-transistor, une piece 3D viens s'incérer pour bloquer le signal lumineux du transistor. Pour démarrer on tire la pièce, la lumière passe et la 2em fourche (diode) retransmet un signal analogique. Dans notre cas on a ajouté des résistances pour faire un comparateur et transformer en donnée numérique. | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed"> | ||
+ | Code d'essaie | ||
+ | <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="C++"> | ||
+ | #include <avr/io.h> | ||
+ | #include <util/delay.h> | ||
+ | #include <Servo.h> | ||
+ | |||
+ | Servo servoR; // declaration objet | ||
+ | unsigned long t; // variable temps | ||
+ | |||
+ | const int PWM1 = 5; // servo moteur | ||
+ | const int PWM2 = 28; // moteur courant continue | ||
+ | //const int Bt = ; | ||
+ | |||
+ | void setup(){ | ||
+ | |||
+ | Serial.begin(9600); | ||
+ | servoR.attach(PWM1); | ||
+ | pinMode(PWM2,OUTPUT); | ||
+ | pinMode(Bt, INPUT); | ||
+ | |||
+ | } | ||
+ | |||
+ | void loop(){ | ||
+ | |||
+ | servoR.write(150); // position initiale | ||
+ | // tempo | ||
+ | //if( | ||
+ | t = millis(); | ||
+ | if( t >= 5000){ //5000 = 5s, 90s = 90 000 ms | ||
+ | moteurScie(PWM2); | ||
+ | delay(500); | ||
+ | servoMoteur(); | ||
+ | /*delay(2000); | ||
+ | digitalWrite(PWM2, HIGH); | ||
+ | delay(500); | ||
+ | servoR.write(80); | ||
+ | delay(2000); | ||
+ | digitalWrite(PWM2, LOW);*/ | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | void servoMoteur(){ | ||
+ | servoR.write(80); | ||
+ | delay(1000); | ||
+ | servoR.write(150); | ||
+ | } | ||
+ | |||
+ | void moteurScie(int pin){ | ||
+ | digitalWrite(pin, HIGH); | ||
+ | } | ||
+ | |||
+ | |||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | </div> | ||
+ | |||
+ | ==== Développement du programme principal ==== | ||
+ | Une fois que nous avons testé l'ensemble des parties et modules que nous comptions utiliser pour notre robot, nous devons ensuite mettre cela en production et écrire les lignes de codes. Nous verrons que cela n'était pas si simple qu'un assemblage de bloc car il est nécessaire d'avoir une réflexion sur chaque fonction mise en œuvre et de réfléchir à chacune d'elle ensemble. Par exemple, réfléchir à comment mettre en lien l'orientation du robot avec le magnétomètre, ou encore l'orientation de la Pixy & Robot avec la position de l'objet sur la caméra.<br/> | ||
+ | |||
+ | ===== Mise en place de la liaison série ===== | ||
+ | Pour pouvoir voir en temps réel les valeurs du programme pour pouvoir déboguer facilement le programme en voyant son état et les variables, il faut alors mettre en place une liaison série.<br/><br/> | ||
+ | Plusieurs façon s'offre à nous, dans un premier temps nous avons utiliser des fonctions liés au bibliothèque puis une version plus bas niveau avec une gestion par les registres. | ||
+ | <div class="toccolours mw-collapsible mw-collapsed"> | ||
+ | Code liaison série avec bibliothèque Arduino | ||
+ | <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="C++"> | ||
+ | void setup() { | ||
+ | Serial.begin(9600); | ||
+ | } | ||
+ | void loop() { | ||
+ | Serial.println("Message"); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | Voici le code a utilisé pour mettre en place une liaison série à 9600 baud. A savoir que si l'on souhaite utiliser un autre branchement série tel que UART1 ou UART2 si le micro-contrôleur en possède plusieurs il faudra remplacer serial par '''serial1''' ou '''serial2'''. | ||
+ | </div> | ||
+ | </div> | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed"> | ||
+ | Code liaison série avec gestion des registres | ||
+ | <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="C++"> | ||
+ | #define DEV_BOARD false | ||
+ | |||
+ | void uartInit(void) { // Fonction d'initialisation de la liaison UART pour la communication série | ||
+ | #if DEV_BOARD | ||
+ | UCSR0B |= (1 << TXEN0); // Activer la transmition pour l'utilisation via USB | ||
+ | UBRR0 = 103; | ||
+ | #else | ||
+ | UCSR1B |= (1 << TXEN1); // Activer la transmition pour le XBee | ||
+ | UBRR1 = 103; // Configurer l'UART sur 9600 bauds | ||
+ | #endif // DEV_BOARD | ||
+ | } | ||
+ | |||
+ | void uartPutChar(char c) { | ||
+ | #if DEV_BOARD | ||
+ | while (!(UCSR0A & (1 << UDRE0))); | ||
+ | UDR0 = c; | ||
+ | #else | ||
+ | while (!(UCSR1A & (1 << UDRE1))); | ||
+ | UDR1 = c; | ||
+ | #endif // DEV_BOARD | ||
+ | } | ||
+ | |||
+ | void uartPutString(char * str) { // Fonction qui permet d'envoyer tous les caractères d'un tableau | ||
+ | while (*str) { | ||
+ | uartPutChar(*str++); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void uartPutString(int nbr){ // Fonction qui permet de convertir un entier en chaine de caractère | ||
+ | char buffer[sizeof(nbr)*8+1]; | ||
+ | dtostrf(nbr,8,2,buffer); | ||
+ | uartPutString(buffer); | ||
+ | } | ||
+ | |||
+ | void uartPutString(float nbr){ // Fonction qui permet de convertir un nombre à virgule flotant en chaine de caractère | ||
+ | char buffer[sizeof(nbr)*8+1]; | ||
+ | dtostrf(nbr,8,2,buffer); | ||
+ | uartPutString(buffer); | ||
+ | } | ||
+ | |||
+ | void uartNewLine(){ // Intègre une nouvelle ligne | ||
+ | uartPutString("\n\r"); | ||
+ | } | ||
+ | void uartSeparator(){ // Intègre une séparation | ||
+ | uartNewLine(); | ||
+ | uartPutString("-------------------------------"); | ||
+ | uartNewLine(); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | Voici le code a utilisé pour mettre en place une liaison série à 9600 baud. Nous avons utilisé une condition lié au compilateur pour configurer notre programme correctement en fonction de si le code est à destination de la carte de gestion ou un Arduino Mega. | ||
+ | </div> | ||
+ | </div> | ||
+ | |||
+ | La liaison série sera en lien avec un module XBee qui permettra de transmettre sur un autre dispositif (Raspberry Pi ou Ordinateur distant) pour afficher les informations du robot. Cela nous permettra de toujours pouvoir déboguer le programme tout en étant sur la carte de gestion. | ||
+ | |||
+ | |||
+ | ===== Vitesse de translation & rotation ===== | ||
+ | Pour que nous pouvons orienter et diriger facilement notre robot, il sera idéal de contrôler les moteurs via deux vitesses, une de translation et une de rotation. La vitesse de translation va permettre de faire avancer ou reculer le robot. La vitesse de rotation permettra de lui donner une orientation. | ||
+ | <br/> | ||
+ | L'avantage est que nous pourrons uniquement orienter le robot sans le faire forcément avancer. | ||
+ | <br/><br/> | ||
+ | L'idée ici est la suivante : | ||
+ | <br/> | ||
+ | Moteur gauche = Vitesse de translation + Vitesse de rotation<br/> | ||
+ | Moteur droit = Vitesse de translation - Vitesse de rotation | ||
+ | <br/><br/> | ||
+ | On comprend avec cela comment cela peut fonctionner. | ||
+ | |||
+ | ===== Orientation du Robot par rapport à la camera ===== | ||
+ | [[Fichier:Pixymon explication.png|thumb|Schema sur Pixymon|250px]] | ||
+ | L'un des premiers soucis est de savoir correctement se diriger vers la caméra. Pour faire cela, nous avons fais appel à la caméra Pixy et aux moteurs du robot. | ||
+ | Nous avions déjà réaliser la partie pour avoir une vitesse angulaire et de translation du robot, nous savons également déjà utiliser la camera Pixy, il ne manque plus qu'au développement de l'algorithme. | ||
+ | |||
+ | |||
+ | Comme le montre l'image ci-contre, l'idée est de pivoter le robot vers la gauche et la droite par rapport à l'axe vert. Si l'objet (la balle) detecté n'est pas au centre, on oriente le robot en jouant avec les moteurs. L'axe rose lui permettra d'orienté la camera Pixy de façon à ce que la balle se trouve toujours au centre de la camera. | ||
+ | |||
+ | ==== +I2C (ou TWI) ==== | ||
+ | [[Fichier:Bus TWI2022.png|thumb|400px|Trame du protocole TWI]] | ||
+ | Une petite parenthèse sur l'I2C lors de la programmation, ce terme revient souvent mais il serait pratique d'expliquer de quoi on parle exactement. Nous entendons beaucoup parler de l'I2C lorsque nous cherchons des modules pour fabriquer des systèmes. | ||
+ | |||
+ | Nous parlons ici plus précisement de TWI (Two Wire Interface), I2C étant le nom d'une marque déposé. | ||
+ | |||
+ | Le TWI est un protocole de communication (plus précisement, un Bus de communication) fonctionnant sur deux fils, SDA et SCL, le premier étant le fil qui va transmettre les données, le second est l'horloge pour que tous les modules soient synchronisés. On peut comparer le TWI avec le protocole SPI qui fonctionne à peut près de la même façon.<br/><br/> | ||
+ | L'I2C utilise un système de maitre à esclave, le mode le plus simple qu'on utilisera est la situation à un seul maitre et plusieurs esclaves. | ||
+ | Le maitre ici sera le micro-contrôleur Atmega 2560, celui-ci ira récupérer les informations sur les modules esclaves (Magnétomètre, Capteur de proximité, etc), il peut également les configurer, mais dans ce mode, c'est le maitre qui donne les instructions aux modules. Il existe un mode où plusieurs maitre sont présent, mais ici nous en aurons pas l'intérêt. Globalement cela signifie que dans notre montage, nous pouvons mettre tous nos composants fonctionnant en TWI, en série. | ||
+ | <br/><br/> | ||
+ | Pour utiliser le protocole facilement, nous utiliserons la bibliothèque Arduino '''Wire''' qui permet de simplifier la communication avec des modules TWI. A savoir que chaque micro-contrôleur possède deux broches dédiés au TWI, sur l'Atmega 2560 il s'agit des broches 20 (SDA) et 21 (SCL). | ||
+ | <br/><br/> | ||
+ | Autre information à savoir, lorsque nous mettons en œuvre plusieurs modules similaire, leurs adresses sont les même car il existe que 128 valeurs possibles pour l'adresse avec le protocole TWI (car sur la trame l'adresse est sur 7 bits), donc les constructeurs associent à chaque module similaire, une adresse fixe. Celle-ci peut être modifié via le programme mais il faudra alors utilisé une broche du module qui permet la modification de l'adresse (Pour le VL53L1X il s'agit de la broche XSHUT) | ||
+ | |||
+ | |||
+ | *Lien vers la bibliothèque Wire : [https://www.arduino.cc/en/reference/wire Lien Arduino] | ||
+ | |||
+ | ==== +Environnement de travail ==== | ||
+ | Une partie sur le téléversement, les outils utilisés pour cela sont différents que ceux fournis, nous expliquerons ce choix ici. Dès le départ du projet, il fallait mettre en œuvre un workflow, cela consiste à choisir les outils qui seront utilisés dans le projet afin d'optimiser la façon de travailler. | ||
+ | ===== Prototypage ===== | ||
+ | Lorsque nous avons commencer à mettre en abîme notre projet, il fallait trouver un idée pour pondre des schemas et prototypes. Nous avons alors utilisé le logiciel gratuit (et site internet) Draw.io, cela nous a permis de créer rapidement des schémas fonctionnels et prototypes de programmations. <br/><br/> | ||
+ | Il y a d'autres logiciels ou site internet pour réaliser cela qui peuvent satisfaire les même besoins tel que Lucidchart, XMind ou encore Gleek. | ||
+ | *Lien vers Draw.io : [https://app.diagrams.net/ Lien Draw.io] | ||
+ | |||
+ | ===== Programmation ===== | ||
+ | Lors du début de la programmation, il fallait poser des bases solides pour échanger le code facilement. Nous avons alors utiliser '''Github''', un outil très pratique pour avoir une collaboration du code entre étudiant. L'intégration se fait facilement sur nombreux IDE (Interface de développement). Nous avons alors pu programmer de chacun de nos côtés des parties différentes du programme tout en assemblant en temps réel grâce à cet outil.<br/> | ||
+ | De plus, cela permet de revenir en arrière, de voir dans le temps l'évolution du code, la participation de chacun des contributeurs dans le code et également pouvoir le partager et faire participer des membres extérieurs du projet pour apporter des modifications (optimisations/ajouts/etc).<br/> | ||
+ | <br/> | ||
+ | Pour que le programme soit compréhensible au mieux, il sera aussi indispensable de respecter des conventions et de documenté le code (commentaire par exemple). | ||
+ | *Lien vers le Github du projet : [https://github.com/Wasabules/Projet-Robotique-IUT Lien Github] | ||
+ | <br/> | ||
+ | '''Interface de développement''' | ||
+ | |||
+ | De plus, durant la programmation nous avons utilisé plusieurs IDE tel que l'IDE Arduino, Visual Studio Code avec l'extension PlateformIO et Microchip Studio (IDE Spécialisé dans les µC (Microcontrôleur) AVR). | ||
+ | Arduino a été utilisé pour des tests basiques, VS Code (Visual Studio Code) pour programmer le code principal, et Microchip Studio lorsque nous avons migré sur la carte électronique avec le µC embarqué. | ||
+ | <br/><br/> | ||
+ | L'avantage de VS Code, c'est que l'on peut avoir une auto complétion très puissante en compagnie d'autres extensions, cette IDE part la présence d'extension en fait un IDE très puissant pour nombreux langages. Cependant, un peu moins adapté lorsque nous souhaitons envoyer un programmer sur un µC sur carte.<br /> | ||
+ | C'est la raison de l'utilisation de Microchip Studio, nous avons possibilité de débugueur notre programme facilement, voir les bits, tous les registres accessibles, une auto complétion orienté pour de l'AVR. Lors de la configuration du projet dans l'IDE, nous devons sélectionner le µC de destination, cela permettra ensuite d'avoir facilement tous les registres. | ||
+ | <br/><br/> | ||
+ | '''Optimisation''' | ||
+ | |||
+ | Parlons également un peu Optimisation, lors du début de la programmation, nous avons utilisé essentiellement des fonctions lié à des bibliothèques et beaucoup de condition. Mais au fil du temps nous pourrons optimiser notre code en : | ||
+ | * Limiter l'utilisation de bibliothèque et s'approcher d'un fonctionnement natif (Utiliser les registres DDR/PORT/PIN au lieu de fonction "digitalWrite" etc) | ||
+ | * Préférer utiliser des "define" au lieu des constantes, il s'agit d'un outil lié au compilateur, toutes les constantes définies avec "define" seront directement remplacé dans le code lors de la compilation, ce qui fait que cela n'utilisera pas de Mémoire vive inutilement au fonctionnement | ||
+ | * Utiliser des conditions lié au compilateur, lorsque nous faisons du code, beaucoup de celui-ci ne sert que pour débugueur (affichage de texte, lumières, etc). En utilisant des conditions #if ou #ifdef dans le programme, cela permet au compilateur de retirer le code inutile quand nous sommes pas en trains de débugueur | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed"> | ||
+ | Code d'exemple sur le #ifdef | ||
+ | <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="C++"> | ||
+ | |||
+ | #define DEBUG | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | Serial.begin(9600); | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | #ifdef DEBUG | ||
+ | Serial.print("A"); | ||
+ | #else | ||
+ | Serial.print("B"); | ||
+ | #endif // DEBUG | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Comme "DEBUG" est définit, alors le message affiché sera "A" | ||
+ | Le compilateur retirera le code de "B" lors de la compilation, ce qui économisera du code. | ||
+ | </div> | ||
+ | </div> | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed"> | ||
+ | Code d'exemple sur le #if | ||
+ | <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="C++"> | ||
+ | |||
+ | #define DEBUG 1 | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | Serial.begin(9600); | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | #if DEBUG=1 | ||
+ | Serial.print("A"); | ||
+ | #else | ||
+ | Serial.print("B"); | ||
+ | #endif // DEBUG | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Comme "DEBUG" vaut 1 la condition est validé, alors le message affiché sera "A". | ||
+ | Le compilateur retirera le code de "B" lors de la compilation, ce qui économisera du code. | ||
+ | </div> | ||
+ | </div> | ||
+ | |||
+ | '''Téléversement du programme''' | ||
+ | [[Fichier:Atmel ICE.jpg|thumb|200px|Image d'un Atmel ICE]] | ||
+ | L'autre point important, est que pour téléverser notre programme dans la carte de gestion, nous avons ici utilisé un Atmel ICE, il s'agit d'un programmateur/simulateur/débugueur ultra performant permettant de travailler avec l'Atmega2560 de façon efficace et cela pour plusieurs raisons : | ||
+ | * La compilation & téléversement se font en une moins d'une seconde malgré le code important | ||
+ | * L'outil fonctionne en MicroUSB et est également compatible avec tous les ordinateurs, permettant de travailler facilement chez soit | ||
+ | * Il possède des fonctions de Debug via le debugWire ou via JTAG. Malheureusement ici nous avons ni l'un ni l'autre, le connecteur JTAG n'est pas présent sur la carte et le µC ne supporte pas le protocole debugWire. | ||
+ | |||
+ | ===== Suivi du projet ===== | ||
+ | [[Fichier:Trello exemple.png|thumb|200px|Projet robotique sur Trello]] | ||
+ | Pour assurer durant le projet que chacun puisse avancer et réaliser des tâches, dès le début, nous avons mis en place l'outil '''Trello''', très utile, celui-ci permet de voir les tâches à réaliser, terminer ou à étudier. Cela se compose d'un tableau avec plusieurs colonnes avec un titre pour chaque colonne.<br/> | ||
+ | Chaque colonne se compose d'éléments avec titres, descriptions, lien et autres éléments, en soit ici il s'agit que chaque éléments soit en lien avec une fonction. | ||
+ | * Lien vers Trello : [https://trello.com/ Lien Trello] | ||
+ | |||
+ | ==== XBee ==== | ||
+ | [[Fichier:Xbee-s2c-th-pcb.jpg|thumb|200px|Module XBee S2C]] | ||
+ | Afin de déboguer à distance le robot, nous avons décidé d'utiliser un module XBee qui va permettre de recevoir une communication série sans fil. Cela fonctionne à l'aide de deux modules XBee, l'un branché sur la carte de gestion, et l'autre connecter à un ordinateur/raspberry pi ou autre système. Cela va permettre depuis la carte de gestion, d'envoyer les données des variables contenu dans le programme. | ||
+ | ===== Configuration du XBee ===== | ||
+ | Pour configurer ces modules, nous devons utiliser le logiciel '''XCTU''', celui-ci nous permettra de configurer : | ||
+ | * Le PAN et Canal de communication | ||
+ | * Le mode de fonctionnement des modules XBee | ||
+ | * Leurs adresses (Adresse du Module et éventuellement celle de destination) | ||
+ | * Un éventuelle chiffrement de communication AES (Avec saisi d'une clé) | ||
+ | <br/> | ||
+ | La communication peut s'effectuer dans les deux sens, nous pouvons contrôler le robot depuis un ordinateur en envoyant des instructions. De plus, le XBee possèdes des entrées/sorties analogiques et digital utilisable, mais ici nous les utiliserons pas. | ||
+ | <br/> | ||
+ | Pour que deux modules puissent communiquer, ils doivent avoir le même canal de communication et le même ID de réseau (PAN), ils doivent aussi posséder leurs adresses et au besoin si chiffrement AES activé, les même clés de chiffrement sur les modules.<br/> | ||
+ | Par ailleurs au besoin, il peut être utile d'indiqué l'adresse de destination sur les XBee. | ||
+ | <br/><br/> | ||
+ | * Lien vers XCTU : [https://www.digi.com/products/embedded-systems/digi-xbee/digi-xbee-tools/xctu Lien Digi] | ||
+ | |||
+ | ===== Utilisation XBee ===== | ||
+ | Dans notre situation, nous allons uniquement utiliser le XBee pour transmettre une communication série, pouvoir voir en temps réel l'état du robot. A savoir, sauf configuration contraire, que le Baudrate du module est configuré à 9600 sans bit de parité.<br/><br/> | ||
+ | '''Côté Microcontrôleur'''<br/> | ||
+ | Au niveau du µC, le module XBee doit lié entre ses branches Data In et Data Out avec RX et TX du µC (ou Arduino). Dans l'idée TX avec Data IN et RX avec Data Out. Les données transmises de l'ordinateur vers l'Arduino sortiront par "Data Out" et iront vers la broche "Rx" du microcontrôleur. | ||
+ | <br/> | ||
+ | A savoir que sur un microcontrôleur il peut y avoir plusieurs interfaces UART, donc choisir correctement la bonne interface (éviter UART0 si sur platine Arduino car celle-ci fonctionne avec la prise USB). | ||
+ | * Exemple de mise en place de liaison série : [[Robotique_2022#Mise_en_place_de_la_liaison_s.C3.A9rie|Lien Wikigeii]] | ||
+ | <br/>[[Fichier:XBee Explorer.jpg|thumb|200px|XBee Explorer]] | ||
+ | '''Côté Ordinateur/Raspberry'''<br/> | ||
+ | Au niveau de l'ordinateur, le module est sur une platine (XBee Explorer, image ci-contre) doté d'un connecteur MicroUSB. Au bout du câble, la platine est reconnue comme une interface série utilisable directement dans des terminaux compatibles. | ||
+ | <br/> | ||
+ | A savoir, il existe des outils très utile pour mettre en forme les données reçus pour du débogage lorsque qu'il commence à y avoir beaucoup de donnée à interpréter. | ||
+ | <br/> Le logiciel se nomme Serial Studio, gratuit, libre et open-source, disponible directement depuis le dépot Github et compatible Linux/Windows/Mac. | ||
+ | * Lien vers Serial Studio : [https://serial-studio.github.io/ Lien Github] | ||
=== Pièces 3D === | === Pièces 3D === | ||
+ | |||
+ | <gallery mode="packed-hover"> | ||
+ | Image:Mât robot.png| Mât du robot | ||
+ | Image:DémarrageDistance3D.png| Système de démarrage à distance | ||
+ | Image:DemarrageDistance.jpg| Système de démarrage à distance sur chassis | ||
+ | Image:Support perçage ballon 2022.png| Système de perçage du ballon | ||
+ | Image:Support capteur présence balle.png| Support pour capteur de présence de balle | ||
+ | Image:Support carte Régulateur DC-DC.png| Support pour module de régulation DC-DC | ||
+ | Image:Capteur balle mur.png| Support pour le capteur des obstacles/murs | ||
+ | Image:Châssis du robot.png| Châssis robot | ||
+ | Image:Logement balle.png| Logeur de balle | ||
+ | |||
+ | </gallery> | ||
+ | |||
+ | = Galerie du Robot = | ||
+ | [[Fichier:Robot.1.jpg|vignette|gauche]] | ||
+ | [[Fichier:Robot.2.jpg|vignette|centre]] | ||
+ | [[Fichier:RobotFini.png|vignette|gauche|Esthétique final]] | ||
+ | |||
+ | = Retour d'expérience compétition de Robotique Cachan = | ||
+ | La compétition de robotique fut vraiment un événement à faire ! Rencontrer des étudiants de GEII de toutes les écoles a été une chose vraiment très enrichissante et surtout de pouvoir voir comment les autres écoles ont réalisé leurs robots. Seule notre école utilisait un système de rouleau pour attraper et envoyer la balle. Les autres écoles utilisaient plutôt soit un système de deux brosses verticales pour attraper la balle, ou alors un système de cage qui s'abaisse pour ensuite lâcher la balle avec un palet. | ||
+ | |||
+ | Les technologies aussi étaient très différentes, là où nous sommes parties sur un système tout-en-un, l'IUT de Cherbourg est plutôt parti sur deux robots possédants des cartes intermédiaires pour remonter au maximum des informations logiques au microcontrôleur. Une école utilisait d'ailleurs de la logique programmable, comme quoi, un robot n'utilisant pas de microcontrôleur peut fonctionner. | ||
+ | |||
+ | Cependant, nous aurons retenu plusieurs choses de la compétition, notamment : | ||
+ | * Le terrain est éclairé par des lumières bleues permettant de faire ressortir le jaune des balles | ||
+ | * Une moquette verte était situé autour du terrain, ce qui pouvait déranger la caméra Pixy | ||
+ | * La caméra Pixy est vraiment très sensible aux conditions lumineuses, un simple nuage peut tout faire changer, d'ailleurs le contraste entre les couleurs comme le jaune et le vert est assez faible | ||
+ | |||
+ | Et pour le robot, s'il était à améliorer il y aura : | ||
+ | * Des capteurs de lignes vraiment très en avant sur le robot, savoir rapidement s'il y a une ligne est extrêmement important, les capteurs sur notre robot étaient beaucoup trop reculés ce qui faisait que celui-ci dépassait la ligne | ||
+ | * Bien gérer la détection de la ligne centrale, reculer ou faire des tours ne suffit pas, il faut que cela soit plus intelligent et prendre en compte son orientation | ||
+ | * Vérifier absolument qu'il est impossible de saisir 2 balles en même temps, notre robot a été disqualifié plusieurs fois parce qu'il contrôlait plus d'une balle | ||
+ | * Ajouter des capteurs de proximité à l'avant et à l'arrière en plus des capteurs sur les côtés, car il est difficile de savoir quand le robot est contre un mur ou dos à un mur avec juste des capteurs sur les côtés. | ||
+ | * Ou alors, mettre les capteurs à 35° plutôt que 45°, cela fait un gain de 20° vers l'avant, ce qui permet de vraiment bien détecter un mur devant lui. | ||
+ | * Peut-être mettre la caméra Pixy au plus bas, car si elle est trop haute, elle voit le tapis vert qui entour le terrain et peut faire un faux positif en pensant voir une balle. | ||
+ | * L'orientation de la caméra pour centrer la balle sur l'axe vertical n'est pas nécessaire, une position fixe peut permettre de voir assez largement le terrain tout en assurant qu'elle soit assez basse pour ne pas regarder l'extérieur du terrain et donc voir par exemple, une personne avec un t-shirt jaune ou une pancarte jaune au loin et penser à une balle. | ||
+ | |||
+ | Voilà pour le retour d'expérience, si cela était à refaire, nous le referions et nous le souhaitons aux futurs étudiants de GEII de pouvoir aux aussi y participer, car c'est vraiment une expérience superbe ! |
Version actuelle datée du 12 juin 2022 à 21:01
Sommaire
- 1 Groupe : Lecoq Geoffrey et Blin Timothy
- 2 Présentation du projet
- 3 Analyse du projet
- 4 Développement du projet
- 5 Galerie du Robot
- 6 Retour d'expérience compétition de Robotique Cachan
Groupe : Lecoq Geoffrey et Blin Timothy
Présentation du projet
Le projet a pour objectif la conception d'un robot autonome pour participer à une compétition de robotique où plusieurs robots s'affronteront et où celui qui marquera le plus de point gagne ! Nous passerons alors beaucoup de temps pour analyser déjà l'ensemble (règles, contraintes, fonctions à étudier), pour ensuite passer à son développement. C'est un projet vraiment pluridisciplinaire car nous devrons développer un programme, concevoir des cartes, de la modélisation 3D, des systèmes électroniques (utilisation de comparateur, mise en œuvre de différents montages électroniques, etc).
Le projet demande également beaucoup d'autonomie, car comme dans chaque projet de réalisation, nous sommes confrontés à des choses nouvelles dont nous devons nous documentés. L'usage de capteur, certains microcontrôleurs par exemple.
Analyse du projet
Avant de développer notre projet, nous devons poser sur le papier tous les éléments à penser : les éléments mécaniques qui comptent les conceptions 3D, la schématisation des différents systèmes électroniques et autres. Il est important de bien s'informer sur la compétition et la réalisation de notre robot, sur la faisabilité du projet. Et il faudra s'adapté aux nombreuses contraintes.
La compétition
Le principe de la compétition, 2 robots s'affrontent sur un terrain de tennis, le but est d'envoyer du côté adversaire plus de balle (une par une) que l'autre en 90s et d’éclater un ballon attacher au sommet de son robot à la fin du temps imparti. De nombreuses règles sont a respecté durant le jeu, certaines imposent des contraintes techniques à la réalisation de notre robot tel que les dimensions de celui-ci, le système de perçage du ballon, d'autres sont pour la sécurité comme la réglementation de la batterie, un bouton d'arrêt d'urgence et le système de perçage du ballon qui doit être démontable.
Déroulement de la compétition
Début de la compétions avec un contrôle technique et démonstration devant un jury.Puis les match de 90 secondes, nous sommes sur un terrain de 8x4m donc nous avons pour chaque équipe un carré de 4x4m. Durant ce temps, nous devrons envoyer le maximum de balle du côté adverse, et arriver aux 90s, le système d'éclatement de ballon s’exécute ainsi que le robot devra s’immobilise. La qualification marche par un système de point sur le nombre de balle et les bonus puis un certain nombre de participant au dessus un seuil de point passeront à la phase suivante.
Le terrain
Quelques contraintes lié au règlement
- Le gabarit du projet sera en 40x30x30
- Le robot doit avoir une faible consommation en veille
- Des systèmes de protection doivent être mis en œuvre (limitation de courant/protection)
- Le robot ne doit pas composer un danger une fois au repos
- Une démonstration des dispositifs de sécurité doit être effectué avant la mise en jeu
- Le démarrage du robot se faire à distance, via un lien physique
- La technologie utilisée par la batterie est également limité à du Li-ion ou LifePo4, ici la batterie est fournit donc pas de souci
- Le boitier de protection de la batterie doit faire 3mm d'épaisseur et un moyen d'aération doit être prévu.
- Le système de tire doit pouvoir être bloqué, se cacher et se rétracter si dépassement de sa zone de fonctionnement entre les matchs et chaque tir.
- Le système qui permet d’éclater le ballon doit posséder une sécurité ou doit être amovible.
Matériel à disposition
La compétition en elle même impose certaines contraintes, cependant, pour la réalisation de notre projet, nous devrons utiliser du matériel mis à notre disposition. Cela nous permet d'éviter de refaire ce qui a déjà été fait précédemment. Comme nous sommes que 2 dans ce projet, nous pourrons alors également reprendre des choses déjà réalisé des années précédentes. Tout cela mène à différentes autres contraintes supplémentaires que nous devons penser.
La batterie
Celle-ci est fournie par le département, une batterie de 12.8v (4 piles LifePo4 mises en séries) permettra d’alimenter l’ensemble du robot, moteur, capteurs, contrôleurs. L’utilisation d‘abaisseur de tension sera indispensable pour les éléments exploitants des plus faibles tensions.
Abaisseur de tension
Comme la batterie a une tension de 12.8v et que nous avons des éléments qui ont besoin de différentes tensions telles que 5v et 3.3v, nous avons besoin d’un abaisseur de tension. Nous avons le choix ici de le fabriquer nous-mêmes ou d’utiliser un abaisseur déjà réaliser. En fonction du temps disponible, nous verrons pour la réalisation de l’abaisseur.
Carte de gestion Atmega 2560
Nous avons un projet avec beaucoup de capteurs et moteurs à gérer, afin de ne pas avoir de souci de port à disposition, nous utiliserons un Atmega 2560, de plus, le prototypage pourra être facilement effectué grâce à une carte Arduino Mega qui possède ce microcontrôleur. Avec une mémoire flash de 256kb, 86 entrées/sorties exploitables, il fait de lui un microcontrôleur parfait pour du prototypage, on verra à l’avenir si celui-ci s’avère surdimensionné ou s’il est suffisant. De plus, nous pourrons exploiter le Protocol ISP pour utiliser la caméra Pixy2
Les moteurs
Ces derniers sont gérés à l’aide de Carte Cytron (Lien ici), il s’agit d’un driver de moteur permettant de contrôler des moteurs à balais avec un courant de 13A continu et jusqu’à 30A en pointe. Permets de faire fonctionner des moteurs situés sur une plage de tension de 6 à 30v.
Camera Pixy
La caméra comme présentée ci-contre permet la détection de couleurs et donc d’objets, elle va nous permettre durant le projet de détecter les balles pour diriger notre robot vers ces dernières et ainsi pouvoir les lancer de l’autre côté.
Elle fonctionne sur un système d’apprentissage et retourne la position de l’objet sur l’écran.
Nous devrons alors faire correspondre la position de la balle sur l’écran par rapport à une position sur le terrain.
Afin de tester en temps réel la camera, nous ferons usage du logiciel Pixymon sur ordinateur.
Celle-ci sera gérer avec l'Atmega directement par le bus ISP
Développement du projet
Une fois que nous avons bien analyser l'ensemble, nous pouvons déjà commencer à imaginer une première structure de projet avec chaque grandes fonctions que notre robot devra respecté.
Le Schéma fonctionnel présente les grandes fonctions à développer durant notre projet, nous devrons définir quelles technologies adopter pour chaque fonction afin d’avoir un robot qui remplit au mieux sa fonction qui est de gagner la compétition !
Etude des blocs de fonction
Alimentation
L'alimentation du robot se fait à l'aide d'une batterie composé de 4 cellules Lithium-ion disposées en série pour obtenir une tension d'environ 12.4v, elle est suffisante pour le projet, permet d'alimenter l'ensemble des fonctions. Cependant, certains modules comme le micro-contrôleur utilisera une tension de 5v pour fonctionner. Nous devons alors abaisser la tension.</br>
Pour cela, nous utiliserons un abaisseur de tension "LM2596".
Celui-ci, à l'aide d'un potentiomètre, permet d'abaisser la tension jusqu'à 5v. Son principe de fonctionnement est simple, il s'agit d'un hacheur abaisseur dont le potentiomètre fait varier le rapport cyclique du hacheur ce qui fait varier sa tension.
Détection de lignes
Au moment d'avancer vers la zone adverse, il faut savoir reconnaitre les différentes lignes et en particulier, celle qui est au centre. Il est très important de savoir l'identifié pour éviter de la traverser. Traverser cette ligne est contraire au règlement. Pour cela, nous utiliserons 4 capteurs de lumière (capteurs opto-électroniques) situé sous le robot et placé de façon à ce qu'ils puissent repérer uniquement la grosse ligne et non les autres pour éviter les "faux positifs".
A savoir que la caméra Pixy est également en mesure de détecter des lignes, mais cela est plus complexe à exploiter et la faible résolution de la caméra permet surtout de trouver des objets volumineux.
Les capteurs utilisés sont des QRE1113, ils retournent une valeur logique (0 ou 5v) en fonction de s'il est sur du blanc ou non. Cela en fait un grand avantage pour le branchement et l'interprétation des résultats.
- Lien vers le capteur : Lien Sparkfun
Perçage du ballon
Le système de perçage de ballon possède plusieurs contraintes, nous devons avoir un système qui est soi protéger soit enlevable donc qui ne présente pas de danger lorsqu'il est au repos. L'idée ici retenu a été d'utiliser un disque fin associer à un moteur à courant continu et un servo-moteur. Le moteur CC va entrainer le disque à haute vitesse et le servo moteur va déplacer vers le haut un bras qui permettra au disque de toucher le ballon et ainsi de l'éclater au bout des 90s de jeu.
Détection des balles
Pour détecter la balle, nous avons pour cela plusieurs façons, déjà nous pouvons également utiliser la caméra Pixy pour détecter la balle par sa couleur et ainsi orienter le robot pour qu’il puisse s’y diriger.
Nous pouvons aussi mesurer une distance, à l’aide d’un capteur de distance, à ultra-son, ou laser (lidar) nous pouvons chercher la présence d’un objet sur le terrain en faisant une différence de distance sur plusieurs points. Si la différence est supérieure à la taille d’une balle, c’est qu’il s’agit probablement d’une balle et donc nous pouvons diriger le robot.
Ici, la solution retenue a été d'utiliser exclusivement la caméra Pixy, simple à mettre en œuvre, elle permet de voir facilement les balles via un profil de couleur enregistrer au préalable. A savoir qu'une caméra Pixy se doit d'être correctement configurée pour détecter correctement les nuances de couleurs et donc, les objets.
Autre chose, il faut aussi détecter la réception de la balle dans son enceinte pour vérifier que le robot a bien capturé cette-dernière !
Pour cela, il suffit de créer une barrière lumineuse à l'aide de capteurs (ici des CNY70) et émetteurs infrarouges situés de part et d'autres de l'enceinte, l'un émet et l'autre reçoit, l'information reçu sera alors analogique, il faudra alors simplement vérifier les seuils de lumières reçu par l'info analogique reçu dans le microcontrôleur.
Nous aurions pu utiliser un comparateur, mais un problème empêche cela, c'est que la différence de tension est assez faible lorsqu'il y a présence ou absence de balle dû à l'environnement. Le capteur infrarouge est aussi sensible à la lumière alentour. Ce problème a été résolu en mesurant le seuil à l'initialisation du robot.
Cependant, lors de la mise en oeuvre du projet, nous nous sommes rendus compte qu'il était difficile la mise en place du système sur la carte faute de manque de broche disposant d'un Convertisseur Analogique Numérique. Nous utiliserons alors un CAN fonctionnant en I2C (image ci-contre). Il s'agit d'un boitier en SOT23-6 donc assez petit qu'on a dû soudé sur une carte.
- Vin = Broche d'entrée analogique à convertir
- Vss = Masse
- Vdd = 5v
- SDA/SCL = Pour la communication I2C.
A savoir que nous avons ajouté un condensateur de 100nF entre les broches VDD et VSS en amont du convertisseur pour lisser le courant.
Système d'envoi de balle
Pour envoyer une balle, il existe nombreuses solutions, nous pouvons faire deux rouleaux verticaux tournant à haute vitesse pour propulser la balle, comme le fonctionnement des lanceurs de balle de Tennis. Mais ici nous avons choisi de réaliser un rouleau horizontal tournant rapidement. Le rouleau s'abaissera pour laisser le robot reculer et la balle se fera propulser grâce à l'inertie du rouleau.
Déplacement du robot
Le robot possède deux moteurs à balais (rien à voir avec celui de la buanderie), ils consomment jusqu'à 30A et 13A en continue, ces moteurs fonctionnent sur une plage de tension assez large, 6 à 30v. Mais pour ainsi les contrôlés correctement, nous utiliserons une carte Cytron.
La gestion des moteurs se fait à l'aide de signaux PWM et Haut/Bas sur la carte Cytron.
Un fil envoi l'info de vitesse, un autre celui du sens de rotation. Ces cartes se gèrent très facilement avec un microcontrôleur tant qu'il est capable de générer un signal PWM.
Repérage du robot
Lors du développement, en particulier lorsqu'on souhaite orienter le robot face à la zone adverse, il faut avoir une notion de l'espace. Ici nous avons fait le choix d'utiliser un magnétomètre pour savoir en temps réel l'angle du robot par rapport au champ magnétique terrestre. Cela à l'avantage d'être facile a mettre en œuvre et demande peu de ressources.
Donc pour faire cela, nous avons utiliser un MPU9250 qui fonctionne à l'aide d'un bus I2C et retourne directement les valeurs du champ magnétique qu'il faut ensuite interpréter pour en déduire l'angle.
- Lien du MPU9250 : Lien Sparkfun
(Contient les informations relatives à son utilisation)
Conception cartes électronique
Le robot a besoin de plusieurs cartes pour fonctionner, nous avons alors besoin de réaliser deux cartes, l'une s'occupera de gérer l'ensemble du robot et une autre de gérer la batterie (et de la protéger elle ainsi que le robot). Pour cela, nous utiliserons le logiciel Eagle pour les réalisés. Dans un souci de temps, notre projet n'a pas eu à faire l'étude et la conception des cartes, simplement leurs routages et leurs fabrications.
Carte de gestion Robot
La carte de gestion du robot a été conçu sur le logiciel Eagle, celle-ci comporte l'ensemble des éléments indispensable au fonctionnement de notre robot, composés de nombreux connecteurs (Entrées analogiques, sorties PWM, connecteurs couplé à un transistor pour délivré une tension de 12v et du courant à destination de moteur à courant continu).
Basé sur un microcontrôleur Atmega 2560, elle est suffisamment performante pour remplir entièrement son rôle dé réussir la compétition.
Organisation de la carte µcontrôlleur :
Carte de gestion Batterie
Cette carte à pour bute d'informer sur l’état. Si elle est complètement décharger ou si il y a des problèmes éventuel causer par le câblage ou l'alimentation des différents systèmes. En raison de manque temps cette carte n'a pas été réaliser.
Programmation
Les essais
Magnétomètre (MPU9250)
Il s'agit d'un module (MPU9250) composé de 9 axes, celui-ci peut se gérer via une communication SPI ou I2C (aka TWI), il nous permettra de savoir si le robot est en mouvement grâce à l'accéléromètre intégrer. Nous pourrons déduire également l'angle du composant via l'utilisation du magnétomètre qui permet de savoir l'orientation du robot par rapport à au champ magnétique terrestre. Toutes ces informations sont récupérables via les protocoles de communication précédemment cités.
Code de test :
Capteurs de proximités (VL53L1)
Le capteur de proximité fonctionne avec une onde lumineuse qui se reflète contre une surface, celle-ci permettra au capteur d'en déterminer la distance de façon très précise. Celui-ci détecte les éléments proches, il sera utilisé pour détecter les parois pour alors les éviter. Il fonctionne avec un protocole de communication I2C (aka TWI), donc il pourra communiquer sur le même bus que le module comportant le magnétomètre.
Code de test :
Capteurs de présence de la balle
La programmation pour les capteurs de présence de balle va être assez simple, ici nous avons simplement deux capteurs infrarouges mis face à face, il y a un fil qui retourne au robot qui donne l'information analogique du capteur qui reçoit la lumière. Il faudra cependant faire attention car la valeur de tension du capteur qui reçoit varie en fonction des conditions environnantes (pollution lumineuse de l'environnement), il faudra alors déterminer une valeur seuil à chaque démarrage pour ensuite se comparer à elle pour savoir s'il y a une balle ou non dans le logement.
Cependant, par soucis de place sur la carte de gestion réalisée, nous utiliserons un convertisseur analogique/numérique fonctionnant en I2C (Le MCP3421). Comme pour l'ensemble des composants fonctionnant en I2C, celui-ci a été mis sur le même bus que les autres composants I2C (Magnétomètre/Capteur de proximité). Ainsi pour pouvoir l'exploiter il faudra identifier son adresse qui par défaut est l'adresse "x69" après un i2c_detect (utilitaire permettant d'identifier les adresses I2C des composants sur un bus).
Code d'essaie
#include <avr/io.h>
#include <Wire.h>
#include <VL53L1X.h>
VL53L1X Sensor1;
VL53L1X Sensor2;
// SCL = 19; //I2C serial clok input
void setup() {
Wire.begin();
Wire.setClock(400000);
Serial.begin(9600);
sensor();
}
void loop() {
Serial.print(Sensor1.read());
Serial.print(" Capteur gauche ");
Serial.println(VL53L1X::rangeStatusToString(Sensor1.ranging_data.range_status));
Serial.print(Sensor2.read());
Serial.print(" Capteur droite ");
Serial.println(VL53L1X::rangeStatusToString(Sensor2.ranging_data.range_status));
}
void sensor() {
pinMode(4, OUTPUT); // Shut digital input LOW active
pinMode(5, OUTPUT);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
// Initalisiert I2C
delay(500);
Wire.begin();
Wire.beginTransmission(0x29);
digitalWrite(4, HIGH);
delay(150);
Sensor1.init();
Serial.println("01");
delay(100);
Sensor1.setAddress(0x33);
Serial.println("02");
digitalWrite(5, HIGH);
delay(150);
Sensor2.init();
Serial.println("03");
delay(100);
Sensor2.setAddress(0x35);
Serial.println("04");
Sensor1.setDistanceMode(VL53L1X::Long);
Sensor1.setMeasurementTimingBudget(50000);
Sensor1.startContinuous(50);
Sensor1.setTimeout(100);
Sensor2.setDistanceMode(VL53L1X::Long);
Sensor2.setMeasurementTimingBudget(50000);
Sensor2.startContinuous(50);
Sensor2.setTimeout(100);
delay(150);
Serial.println("addresses set");
Serial.println ("I2C scanner. Scanning ...");
byte count = 0;
for (byte i = 1; i < 120; i++)
{
Wire.beginTransmission (i);
if (Wire.endTransmission () == 0)
{
Serial.print ("Found address: ");
Serial.print (i, DEC);
Serial.print (" (0x");
Serial.print (i, HEX);
Serial.println (")");
count++;
delay (1); // maybe unneeded?
} // end of good response
} // end of for loop
Serial.println ("Done.");
Serial.print ("Found ");
Serial.print (count, DEC);
Serial.println (" device(s).");
}
Caméra Pixy2
La caméra Pixy2 est assez facile à mettre en œuvre, celle-ci propose directement une bibliothèque très bien fournie pour pouvoir prendre en main rapidement sa caméra. Pour utiliser celle-ci, il suffit d'intégrer la bibliothèque, créer un nouvelle objet Pixy2, et utilisé les méthodes associés.
Celle-ci fonctionne via le protocole de communication SPI (Serial Peripheral Interface) de l'AVR utilisé, dans un premier temps les tests étaient effectués sur un Arduino Mega, donc sur le connecteur prévu, ensuite nous avons dû pensé à un connecteur pour la carte électronique qui reprend ces branchements.
Différentes méthodes exploités
- getBlocks() - Retourne le nombre d'objet que la Caméra a detecté
Les méthodes suivantes seront précédées de : .ccc.blocks[indice de l'objet].
- m_x & m_y
Retournent la position en X et Y sur l'image de l'objet (0 à 316 et 0 à 208 respectivement), cela est utile à savoir pour pouvoir correctement orienter le robot et la camera vers l'objet quand celui-ci n'est plus centré. (La caméra étant sur un axe, celle-ci peut pivoté de haut en bas)
- m_width m_height
Ces deux méthodes retournent la dimension sur l'image de l'objet, cela sera utile pour déterminer si celui-ci est carré en faisant un ratio des deux. (Une balle vu par la caméra est représenté par un carré).
D'autres méthodes peuvent être utilisé pour optimiser le programme tel que "m_age" ou "m_signature" pour éventuellement identifier plusieurs objets et affiné la fiabilité de reconnaissance. De plus, la camera se doit d'être correctement configuré avant le début de la programmation pour éviter tout faux-positifs.
- Lien vers la bibliothèque Pixy : Lien Pixycam
Code de test :
Moteurs (Cytron)
Le déplacement du robot a été la première partie a être programmé, celle-ci étant aussi la plus simple car cela se fait par l'intermédiaire de la carte Cytron.
Comme visible sur l'image ci-contre, nous avons 4 branchements dont 3 utiles. (NC n'étant relié à rien sur la carte)
- GND - La masse commune
- PWM - Contrôle la vitesse de rotation des moteurs via une MLI
- DIR - Sens de rotation des moteurs selon l'état logique envoyé
Le sens de rotation va dépendre de comment est branché le moteur aux bornes MA et MB, il faudra alors faire un petit code pour vérifier le fonctionnement, le sens de rotation, pour ensuite mettre cela en œuvre dans le programme.
Code de test :
Démarrage à distance + Éclatement ballon (Nom composant)
Composant en forme de fourche fonctionnant en photo-transistor, une piece 3D viens s'incérer pour bloquer le signal lumineux du transistor. Pour démarrer on tire la pièce, la lumière passe et la 2em fourche (diode) retransmet un signal analogique. Dans notre cas on a ajouté des résistances pour faire un comparateur et transformer en donnée numérique.
Code d'essaie
#include <avr/io.h>
#include <util/delay.h>
#include <Servo.h>
Servo servoR; // declaration objet
unsigned long t; // variable temps
const int PWM1 = 5; // servo moteur
const int PWM2 = 28; // moteur courant continue
//const int Bt = ;
void setup(){
Serial.begin(9600);
servoR.attach(PWM1);
pinMode(PWM2,OUTPUT);
pinMode(Bt, INPUT);
}
void loop(){
servoR.write(150); // position initiale
// tempo
//if(
t = millis();
if( t >= 5000){ //5000 = 5s, 90s = 90 000 ms
moteurScie(PWM2);
delay(500);
servoMoteur();
/*delay(2000);
digitalWrite(PWM2, HIGH);
delay(500);
servoR.write(80);
delay(2000);
digitalWrite(PWM2, LOW);*/
}
}
void servoMoteur(){
servoR.write(80);
delay(1000);
servoR.write(150);
}
void moteurScie(int pin){
digitalWrite(pin, HIGH);
}
Développement du programme principal
Une fois que nous avons testé l'ensemble des parties et modules que nous comptions utiliser pour notre robot, nous devons ensuite mettre cela en production et écrire les lignes de codes. Nous verrons que cela n'était pas si simple qu'un assemblage de bloc car il est nécessaire d'avoir une réflexion sur chaque fonction mise en œuvre et de réfléchir à chacune d'elle ensemble. Par exemple, réfléchir à comment mettre en lien l'orientation du robot avec le magnétomètre, ou encore l'orientation de la Pixy & Robot avec la position de l'objet sur la caméra.
Mise en place de la liaison série
Pour pouvoir voir en temps réel les valeurs du programme pour pouvoir déboguer facilement le programme en voyant son état et les variables, il faut alors mettre en place une liaison série.
Plusieurs façon s'offre à nous, dans un premier temps nous avons utiliser des fonctions liés au bibliothèque puis une version plus bas niveau avec une gestion par les registres.
Code liaison série avec bibliothèque Arduino
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("Message");
}
Voici le code a utilisé pour mettre en place une liaison série à 9600 baud. A savoir que si l'on souhaite utiliser un autre branchement série tel que UART1 ou UART2 si le micro-contrôleur en possède plusieurs il faudra remplacer serial par serial1 ou serial2.
Code liaison série avec gestion des registres
#define DEV_BOARD false
void uartInit(void) { // Fonction d'initialisation de la liaison UART pour la communication série
#if DEV_BOARD
UCSR0B |= (1 << TXEN0); // Activer la transmition pour l'utilisation via USB
UBRR0 = 103;
#else
UCSR1B |= (1 << TXEN1); // Activer la transmition pour le XBee
UBRR1 = 103; // Configurer l'UART sur 9600 bauds
#endif // DEV_BOARD
}
void uartPutChar(char c) {
#if DEV_BOARD
while (!(UCSR0A & (1 << UDRE0)));
UDR0 = c;
#else
while (!(UCSR1A & (1 << UDRE1)));
UDR1 = c;
#endif // DEV_BOARD
}
void uartPutString(char * str) { // Fonction qui permet d'envoyer tous les caractères d'un tableau
while (*str) {
uartPutChar(*str++);
}
}
void uartPutString(int nbr){ // Fonction qui permet de convertir un entier en chaine de caractère
char buffer[sizeof(nbr)*8+1];
dtostrf(nbr,8,2,buffer);
uartPutString(buffer);
}
void uartPutString(float nbr){ // Fonction qui permet de convertir un nombre à virgule flotant en chaine de caractère
char buffer[sizeof(nbr)*8+1];
dtostrf(nbr,8,2,buffer);
uartPutString(buffer);
}
void uartNewLine(){ // Intègre une nouvelle ligne
uartPutString("\n\r");
}
void uartSeparator(){ // Intègre une séparation
uartNewLine();
uartPutString("-------------------------------");
uartNewLine();
}
Voici le code a utilisé pour mettre en place une liaison série à 9600 baud. Nous avons utilisé une condition lié au compilateur pour configurer notre programme correctement en fonction de si le code est à destination de la carte de gestion ou un Arduino Mega.
La liaison série sera en lien avec un module XBee qui permettra de transmettre sur un autre dispositif (Raspberry Pi ou Ordinateur distant) pour afficher les informations du robot. Cela nous permettra de toujours pouvoir déboguer le programme tout en étant sur la carte de gestion.
Vitesse de translation & rotation
Pour que nous pouvons orienter et diriger facilement notre robot, il sera idéal de contrôler les moteurs via deux vitesses, une de translation et une de rotation. La vitesse de translation va permettre de faire avancer ou reculer le robot. La vitesse de rotation permettra de lui donner une orientation.
L'avantage est que nous pourrons uniquement orienter le robot sans le faire forcément avancer.
L'idée ici est la suivante :
Moteur gauche = Vitesse de translation + Vitesse de rotation
Moteur droit = Vitesse de translation - Vitesse de rotation
On comprend avec cela comment cela peut fonctionner.
Orientation du Robot par rapport à la camera
L'un des premiers soucis est de savoir correctement se diriger vers la caméra. Pour faire cela, nous avons fais appel à la caméra Pixy et aux moteurs du robot. Nous avions déjà réaliser la partie pour avoir une vitesse angulaire et de translation du robot, nous savons également déjà utiliser la camera Pixy, il ne manque plus qu'au développement de l'algorithme.
Comme le montre l'image ci-contre, l'idée est de pivoter le robot vers la gauche et la droite par rapport à l'axe vert. Si l'objet (la balle) detecté n'est pas au centre, on oriente le robot en jouant avec les moteurs. L'axe rose lui permettra d'orienté la camera Pixy de façon à ce que la balle se trouve toujours au centre de la camera.
+I2C (ou TWI)
Une petite parenthèse sur l'I2C lors de la programmation, ce terme revient souvent mais il serait pratique d'expliquer de quoi on parle exactement. Nous entendons beaucoup parler de l'I2C lorsque nous cherchons des modules pour fabriquer des systèmes.
Nous parlons ici plus précisement de TWI (Two Wire Interface), I2C étant le nom d'une marque déposé.
Le TWI est un protocole de communication (plus précisement, un Bus de communication) fonctionnant sur deux fils, SDA et SCL, le premier étant le fil qui va transmettre les données, le second est l'horloge pour que tous les modules soient synchronisés. On peut comparer le TWI avec le protocole SPI qui fonctionne à peut près de la même façon.
L'I2C utilise un système de maitre à esclave, le mode le plus simple qu'on utilisera est la situation à un seul maitre et plusieurs esclaves.
Le maitre ici sera le micro-contrôleur Atmega 2560, celui-ci ira récupérer les informations sur les modules esclaves (Magnétomètre, Capteur de proximité, etc), il peut également les configurer, mais dans ce mode, c'est le maitre qui donne les instructions aux modules. Il existe un mode où plusieurs maitre sont présent, mais ici nous en aurons pas l'intérêt. Globalement cela signifie que dans notre montage, nous pouvons mettre tous nos composants fonctionnant en TWI, en série.
Pour utiliser le protocole facilement, nous utiliserons la bibliothèque Arduino Wire qui permet de simplifier la communication avec des modules TWI. A savoir que chaque micro-contrôleur possède deux broches dédiés au TWI, sur l'Atmega 2560 il s'agit des broches 20 (SDA) et 21 (SCL).
Autre information à savoir, lorsque nous mettons en œuvre plusieurs modules similaire, leurs adresses sont les même car il existe que 128 valeurs possibles pour l'adresse avec le protocole TWI (car sur la trame l'adresse est sur 7 bits), donc les constructeurs associent à chaque module similaire, une adresse fixe. Celle-ci peut être modifié via le programme mais il faudra alors utilisé une broche du module qui permet la modification de l'adresse (Pour le VL53L1X il s'agit de la broche XSHUT)
- Lien vers la bibliothèque Wire : Lien Arduino
+Environnement de travail
Une partie sur le téléversement, les outils utilisés pour cela sont différents que ceux fournis, nous expliquerons ce choix ici. Dès le départ du projet, il fallait mettre en œuvre un workflow, cela consiste à choisir les outils qui seront utilisés dans le projet afin d'optimiser la façon de travailler.
Prototypage
Lorsque nous avons commencer à mettre en abîme notre projet, il fallait trouver un idée pour pondre des schemas et prototypes. Nous avons alors utilisé le logiciel gratuit (et site internet) Draw.io, cela nous a permis de créer rapidement des schémas fonctionnels et prototypes de programmations.
Il y a d'autres logiciels ou site internet pour réaliser cela qui peuvent satisfaire les même besoins tel que Lucidchart, XMind ou encore Gleek.
- Lien vers Draw.io : Lien Draw.io
Programmation
Lors du début de la programmation, il fallait poser des bases solides pour échanger le code facilement. Nous avons alors utiliser Github, un outil très pratique pour avoir une collaboration du code entre étudiant. L'intégration se fait facilement sur nombreux IDE (Interface de développement). Nous avons alors pu programmer de chacun de nos côtés des parties différentes du programme tout en assemblant en temps réel grâce à cet outil.
De plus, cela permet de revenir en arrière, de voir dans le temps l'évolution du code, la participation de chacun des contributeurs dans le code et également pouvoir le partager et faire participer des membres extérieurs du projet pour apporter des modifications (optimisations/ajouts/etc).
Pour que le programme soit compréhensible au mieux, il sera aussi indispensable de respecter des conventions et de documenté le code (commentaire par exemple).
- Lien vers le Github du projet : Lien Github
Interface de développement
De plus, durant la programmation nous avons utilisé plusieurs IDE tel que l'IDE Arduino, Visual Studio Code avec l'extension PlateformIO et Microchip Studio (IDE Spécialisé dans les µC (Microcontrôleur) AVR).
Arduino a été utilisé pour des tests basiques, VS Code (Visual Studio Code) pour programmer le code principal, et Microchip Studio lorsque nous avons migré sur la carte électronique avec le µC embarqué.
L'avantage de VS Code, c'est que l'on peut avoir une auto complétion très puissante en compagnie d'autres extensions, cette IDE part la présence d'extension en fait un IDE très puissant pour nombreux langages. Cependant, un peu moins adapté lorsque nous souhaitons envoyer un programmer sur un µC sur carte.
C'est la raison de l'utilisation de Microchip Studio, nous avons possibilité de débugueur notre programme facilement, voir les bits, tous les registres accessibles, une auto complétion orienté pour de l'AVR. Lors de la configuration du projet dans l'IDE, nous devons sélectionner le µC de destination, cela permettra ensuite d'avoir facilement tous les registres.
Optimisation
Parlons également un peu Optimisation, lors du début de la programmation, nous avons utilisé essentiellement des fonctions lié à des bibliothèques et beaucoup de condition. Mais au fil du temps nous pourrons optimiser notre code en :
- Limiter l'utilisation de bibliothèque et s'approcher d'un fonctionnement natif (Utiliser les registres DDR/PORT/PIN au lieu de fonction "digitalWrite" etc)
- Préférer utiliser des "define" au lieu des constantes, il s'agit d'un outil lié au compilateur, toutes les constantes définies avec "define" seront directement remplacé dans le code lors de la compilation, ce qui fait que cela n'utilisera pas de Mémoire vive inutilement au fonctionnement
- Utiliser des conditions lié au compilateur, lorsque nous faisons du code, beaucoup de celui-ci ne sert que pour débugueur (affichage de texte, lumières, etc). En utilisant des conditions #if ou #ifdef dans le programme, cela permet au compilateur de retirer le code inutile quand nous sommes pas en trains de débugueur
Code d'exemple sur le #ifdef
#define DEBUG
void setup()
{
Serial.begin(9600);
}
void loop()
{
#ifdef DEBUG
Serial.print("A");
#else
Serial.print("B");
#endif // DEBUG
Comme "DEBUG" est définit, alors le message affiché sera "A" Le compilateur retirera le code de "B" lors de la compilation, ce qui économisera du code.
Code d'exemple sur le #if
#define DEBUG 1
void setup()
{
Serial.begin(9600);
}
void loop()
{
#if DEBUG=1
Serial.print("A");
#else
Serial.print("B");
#endif // DEBUG
Comme "DEBUG" vaut 1 la condition est validé, alors le message affiché sera "A". Le compilateur retirera le code de "B" lors de la compilation, ce qui économisera du code.
Téléversement du programme
L'autre point important, est que pour téléverser notre programme dans la carte de gestion, nous avons ici utilisé un Atmel ICE, il s'agit d'un programmateur/simulateur/débugueur ultra performant permettant de travailler avec l'Atmega2560 de façon efficace et cela pour plusieurs raisons :
- La compilation & téléversement se font en une moins d'une seconde malgré le code important
- L'outil fonctionne en MicroUSB et est également compatible avec tous les ordinateurs, permettant de travailler facilement chez soit
- Il possède des fonctions de Debug via le debugWire ou via JTAG. Malheureusement ici nous avons ni l'un ni l'autre, le connecteur JTAG n'est pas présent sur la carte et le µC ne supporte pas le protocole debugWire.
Suivi du projet
Pour assurer durant le projet que chacun puisse avancer et réaliser des tâches, dès le début, nous avons mis en place l'outil Trello, très utile, celui-ci permet de voir les tâches à réaliser, terminer ou à étudier. Cela se compose d'un tableau avec plusieurs colonnes avec un titre pour chaque colonne.
Chaque colonne se compose d'éléments avec titres, descriptions, lien et autres éléments, en soit ici il s'agit que chaque éléments soit en lien avec une fonction.
- Lien vers Trello : Lien Trello
XBee
Afin de déboguer à distance le robot, nous avons décidé d'utiliser un module XBee qui va permettre de recevoir une communication série sans fil. Cela fonctionne à l'aide de deux modules XBee, l'un branché sur la carte de gestion, et l'autre connecter à un ordinateur/raspberry pi ou autre système. Cela va permettre depuis la carte de gestion, d'envoyer les données des variables contenu dans le programme.
Configuration du XBee
Pour configurer ces modules, nous devons utiliser le logiciel XCTU, celui-ci nous permettra de configurer :
- Le PAN et Canal de communication
- Le mode de fonctionnement des modules XBee
- Leurs adresses (Adresse du Module et éventuellement celle de destination)
- Un éventuelle chiffrement de communication AES (Avec saisi d'une clé)
La communication peut s'effectuer dans les deux sens, nous pouvons contrôler le robot depuis un ordinateur en envoyant des instructions. De plus, le XBee possèdes des entrées/sorties analogiques et digital utilisable, mais ici nous les utiliserons pas.
Pour que deux modules puissent communiquer, ils doivent avoir le même canal de communication et le même ID de réseau (PAN), ils doivent aussi posséder leurs adresses et au besoin si chiffrement AES activé, les même clés de chiffrement sur les modules.
Par ailleurs au besoin, il peut être utile d'indiqué l'adresse de destination sur les XBee.
- Lien vers XCTU : Lien Digi
Utilisation XBee
Dans notre situation, nous allons uniquement utiliser le XBee pour transmettre une communication série, pouvoir voir en temps réel l'état du robot. A savoir, sauf configuration contraire, que le Baudrate du module est configuré à 9600 sans bit de parité.
Côté Microcontrôleur
Au niveau du µC, le module XBee doit lié entre ses branches Data In et Data Out avec RX et TX du µC (ou Arduino). Dans l'idée TX avec Data IN et RX avec Data Out. Les données transmises de l'ordinateur vers l'Arduino sortiront par "Data Out" et iront vers la broche "Rx" du microcontrôleur.
A savoir que sur un microcontrôleur il peut y avoir plusieurs interfaces UART, donc choisir correctement la bonne interface (éviter UART0 si sur platine Arduino car celle-ci fonctionne avec la prise USB).
- Exemple de mise en place de liaison série : Lien Wikigeii
Côté Ordinateur/Raspberry
Au niveau de l'ordinateur, le module est sur une platine (XBee Explorer, image ci-contre) doté d'un connecteur MicroUSB. Au bout du câble, la platine est reconnue comme une interface série utilisable directement dans des terminaux compatibles.
A savoir, il existe des outils très utile pour mettre en forme les données reçus pour du débogage lorsque qu'il commence à y avoir beaucoup de donnée à interpréter.
Le logiciel se nomme Serial Studio, gratuit, libre et open-source, disponible directement depuis le dépot Github et compatible Linux/Windows/Mac.
- Lien vers Serial Studio : Lien Github
Pièces 3D
Galerie du Robot
Retour d'expérience compétition de Robotique Cachan
La compétition de robotique fut vraiment un événement à faire ! Rencontrer des étudiants de GEII de toutes les écoles a été une chose vraiment très enrichissante et surtout de pouvoir voir comment les autres écoles ont réalisé leurs robots. Seule notre école utilisait un système de rouleau pour attraper et envoyer la balle. Les autres écoles utilisaient plutôt soit un système de deux brosses verticales pour attraper la balle, ou alors un système de cage qui s'abaisse pour ensuite lâcher la balle avec un palet.
Les technologies aussi étaient très différentes, là où nous sommes parties sur un système tout-en-un, l'IUT de Cherbourg est plutôt parti sur deux robots possédants des cartes intermédiaires pour remonter au maximum des informations logiques au microcontrôleur. Une école utilisait d'ailleurs de la logique programmable, comme quoi, un robot n'utilisant pas de microcontrôleur peut fonctionner.
Cependant, nous aurons retenu plusieurs choses de la compétition, notamment :
- Le terrain est éclairé par des lumières bleues permettant de faire ressortir le jaune des balles
- Une moquette verte était situé autour du terrain, ce qui pouvait déranger la caméra Pixy
- La caméra Pixy est vraiment très sensible aux conditions lumineuses, un simple nuage peut tout faire changer, d'ailleurs le contraste entre les couleurs comme le jaune et le vert est assez faible
Et pour le robot, s'il était à améliorer il y aura :
- Des capteurs de lignes vraiment très en avant sur le robot, savoir rapidement s'il y a une ligne est extrêmement important, les capteurs sur notre robot étaient beaucoup trop reculés ce qui faisait que celui-ci dépassait la ligne
- Bien gérer la détection de la ligne centrale, reculer ou faire des tours ne suffit pas, il faut que cela soit plus intelligent et prendre en compte son orientation
- Vérifier absolument qu'il est impossible de saisir 2 balles en même temps, notre robot a été disqualifié plusieurs fois parce qu'il contrôlait plus d'une balle
- Ajouter des capteurs de proximité à l'avant et à l'arrière en plus des capteurs sur les côtés, car il est difficile de savoir quand le robot est contre un mur ou dos à un mur avec juste des capteurs sur les côtés.
- Ou alors, mettre les capteurs à 35° plutôt que 45°, cela fait un gain de 20° vers l'avant, ce qui permet de vraiment bien détecter un mur devant lui.
- Peut-être mettre la caméra Pixy au plus bas, car si elle est trop haute, elle voit le tapis vert qui entour le terrain et peut faire un faux positif en pensant voir une balle.
- L'orientation de la caméra pour centrer la balle sur l'axe vertical n'est pas nécessaire, une position fixe peut permettre de voir assez largement le terrain tout en assurant qu'elle soit assez basse pour ne pas regarder l'extérieur du terrain et donc voir par exemple, une personne avec un t-shirt jaune ou une pancarte jaune au loin et penser à une balle.
Voilà pour le retour d'expérience, si cela était à refaire, nous le referions et nous le souhaitons aux futurs étudiants de GEII de pouvoir aux aussi y participer, car c'est vraiment une expérience superbe !