Robotique 2022

De troyesGEII
Aller à : navigation, rechercher

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

Terrain competition


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 !

Schema fonctionnel du projet
Algorithme de fonctionnement du programme


Etude des blocs de fonction

Alimentation

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".

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

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".
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.

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

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.
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.

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.

MCP3421.png

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

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.
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.

  • Lien vers carte Cytron : Lien
  • Datasheet Cytron : Lien

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.

(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.

Schéma électronique
Carte électronique


Organisation de la carte µcontrôlleur :

Organisation et câblage des différent systèmes


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.

Schéma carte surveillance de la batterie
Board carte surveillance de la batterie


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.

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.

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)
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.

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
Schema sur Pixymon

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)

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.

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)


+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.

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).


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

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
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.
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.

XBee

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é)


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.

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).


XBee Explorer

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.

Pièces 3D

Galerie du Robot

Robot.1.jpg
Robot.2.jpg
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 !