Catégorie:RobotGEII
Sommaire
- 1 Description et présentation du Projet
- 2 Carte ultrason (Alexandre.N)
- 3 Carte gestion des moteurs (Johan)
- 4 Carte ultrason (Vincent)
- 5 Carte Codeur (Alexandre.L)
- 6 Gestion du déplacement du robot
- 7 système de fin de course (ballon) (Maxime)
Description et présentation du Projet
Présentation du championnat
Le concours de robotique des IUT GEII est une compétition organisée par l'IUT de Cachan. Cette rencontre a plusieurs objectifs qui supplantent la partie compétitive :
- La mise en œuvre des compétences des étudiants - La promotion de l'IUT GEII et des études techniques en générale - Un échange entre étudiants et avec les enseignants
L'état d'esprit de la compétition se veut être conviviale et favorise le fair-play.
Règle du jeu
Les robots seront placé sur une piste carré de 8m x 8m,recouverte de moquette bleue marine sur laquelle serons placés des obstacles de 15cm de haut.Les robots serons placés chacun dans un coin, l'objectif est de traverser le plus rapidement possible la piste d'un coin à son opposé en évitant les obstacles (qui changerons de positions à chaque manche) ainsi que les collisions avec les autres robots (ils doivent impérativement se contourner par la droite). Les robots ont 90 secondes pour réaliser leurs leurs objectif, au delà de ce délais, la manche s’arrête.
Structure du robot
le règlement détaillé est disponible ici:
Mécanique
Le robot sera construit à partir d’un kit imposé par le comité d’organisation, comprenant le châssis (support métallique en U), les moteurs, les roues, les engrenages et la batterie. Les parties liées à la motorisation ne doivent pas être modifiées. La batterie peut être remplacée à l’identique.
http://www.vgies.com/robot-iut-bot-base-mobile/
Design
Le design est libre : il donnera lieu à un prix du design, indépendamment de la course. La coque en plastique moulé blanc n’est pas obligatoire.
Alimentation
Le robot sera autonome en énergie. Il utilise obligatoirement la batterie 12 V 1.2 Ah au plomb gélifié fournie pour la partie motorisation. L’alimentation reste libre pour la partie commande.
Arrêt d'urgence
L’arrêt d’urgence fourni doit être opérationnel, rester facilement accessible et impérativement couper la partie puissance.
Prise jack
l'organisation fourni un jack de départ, il devra obligatoirement
être utilisé : au top départ, un étudiant de
l’équipe le retire, permettant au robot de
s’élancer.
Dimensions
Les dimensions maximales sont les suivantes; hauteur 30 cm, largeur 30 cm, longueur 40 cm. Le dispositif destiné à faire éclater le ballon ne peut sortir du gabarit que dans la zone d’arrivée. Le tube destiné à porter le ballon de couleur n'est pas a prendre en compte dans la taille du robot, c'est la seule exception.
Ballon
Chaque coin est identifié au moyen d’une couleur. Chaque robot en course porte un ballonde la même couleur que son coin d’arrivé. Le ballon est fourni. Il mesure au moins 10 cm de diamètre lorsqu’il est donné à l’étudiant qui a en charge de démarrer le robot. Le robot doit être doté d’un tube vertical dont l’extrémité haute est situé entre 30 cm et 31 cm au dessus de la moquette pour servir de support au ballon. Le robot doit être doté d’un dispositif d’accrochage à la base du ballon dans les 5 derniers centimètres du tube. Le ballon sera mis en place par l’étudiant en charge de démarrer le robot.
Indicateur d'arrivée
Lorsque le robot est arrivé à sa zone d’arrivée, il doit s’arrêter puis, une fois totalement arrêté faire éclater son ballon. C’est à l’instant précis où, alors qu’il est arrêté au dessus de sa zone d’arrivée et que son ballon éclate que l’arrivée
est considérée comme validée. Un robot qui éclate son ballon ou qui déploie le système
destiné à crever son ballon sans être arrivé ou avant d’être complètement immobile ne marquera aucun point quelque soit son rang.
Carte ultrason (Alexandre.N)
programme de test des capteurs US :
int trig = 36;
int echo = A9;
long lecture_echo;
long cm;
void setup()
{
pinMode(trig, OUTPUT);
digitalWrite(trig, LOW);
pinMode(echo, INPUT);
Serial.begin(9600);
}
void loop()
{
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
lecture_echo = pulseIn(echo, HIGH);
cm = lecture_echo / 58;
Serial.print("Distance : ");
Serial.print(cm);
Serial.println(" cm");
delay(100);
}
programme final des capteur US :
#include <util/delay.h>
#define distUSmini 30
/* _Trigger_
37 - PC0
36 - PC1
35 - PC2
34 - PC3
33 - PC4
32 - PC5
31 - PC6
_Echo_
8 - PK0
9 - PK1
10 - PK2
11 - PK3
12 - PK4
13 - PK5
14 - PK6
*/
boolean toggle1 = 0;
volatile unsigned long t[8];
unsigned long tfin, tdebut, d;
volatile boolean recpt;
volatile boolean newmesure = false;
volatile char numCapt;
volatile uint8_t USmode;
void setup() {
Serial.begin(115200);
pinMode(37, OUTPUT);
pinMode(36, OUTPUT);
pinMode(35, OUTPUT);
pinMode(34, OUTPUT);
pinMode(33, OUTPUT);
pinMode(32, OUTPUT);
pinMode(31, OUTPUT);
cli();
TCCR2A = 0;
TCCR2B = 0;
OCR2A = 156;
TCCR2B |= (1 << WGM12);
TCCR2B |= (1 << CS11);
TCCR2B |= (1 << CS10);
TCCR2B |= (1 << CS12);
TIMSK2 |= (1 << OCIE1A);
PCICR |= 1 << PCIE2;
sei();
}
ISR(TIMER2_COMPA_vect)
{
static boolean start = true;
if (start == true)
{
if (USmode == 0) numCapt = 7;
if (USmode == 1) numCapt = 0;
if (numCapt != 7) //mode1
{
numCapt++;
if (numCapt == 2) numCapt = 0; //à retirer quand 7 capteurs
}
TCCR2B &= ~((1 << CS12) | (1 << CS10));
OCR2A = 150;
if (numCapt == 7) // mode0
{
PORTC = 0b01111111;
PCMSK2 = 0b01111111;
}
else
{
PORTC = 1 << numCapt;
PCMSK2 = 1 << numCapt;
}
}
else
{
PORTC = 0;
recpt = false;
TCCR2B |= ((1 << CS12) | (1 << CS10));
OCR2A = 30;
}
start = !start;
}
ISR(PCINT2_vect)
{
if (recpt == false)
{
tdebut = micros();
recpt = true;
}
else
{
tfin = micros();
if ((tfin - tdebut) > 50)
{
t[numCapt] = tfin - tdebut;
recpt = false;
newmesure = true;
}
}
}
void loop() {
setUSmode(0);
static unsigned long dateAffichage = 0, dateActuelle;
dateActuelle = millis();
if (newmesure == true)
{
//t = tfin - tdebut;
if ((dateActuelle - dateAffichage) > 200)
{
//if
dateAffichage = dateActuelle;
//d = t / 58;
Serial.print("Duree 0: ");
Serial.print(t[0], DEC);
Serial.println(" us.");
Serial.print("Duree 1: ");
Serial.print(t[1], DEC);
Serial.println(" us.");
Serial.print("Duree 2: ");
Serial.print(t[2], DEC);
Serial.println(" us.");
Serial.print("Duree 3: ");
Serial.print(t[3], DEC);
Serial.println(" us.");
Serial.print("Duree 4: ");
Serial.print(t[4], DEC);
Serial.println(" us.");
Serial.print("Duree 5: ");
Serial.print(t[5], DEC);
Serial.println(" us.");
Serial.print("Duree 6: ");
Serial.print(t[6], DEC);
Serial.println(" us.");
Serial.print("Duree 7: ");
Serial.print(t[7], DEC);
Serial.println(" us.");
}
newmesure = false;
}
}
void setUSmode(uint8_t mode)
{
if (mode == 0) {
USmode = 0;
//numCapt=7;
}
if (mode == 1) {
USmode = 1;
//numCapt=0;
}
}
Carte gestion des moteurs (Johan)
Carte Moteur
Cette carte permet la transmission des commandes de l'arduino aux deux moteurs. Elle traduit les signaux envoyer par la carte arduino pour les deux moteurs. Cette carte est un module HG7881CP Stepper 2-Channel DC Motor Driver. Il coûte environ 3.5 euros.
En connectant cette carte au moteur et à l'arduino, on a pu piloter les moteurs et les calibrer. En effet, les moteurs n'ont pas exactement le même couple. Il faut donc trouver leurs vitesses minimales et maximales pour les calibrer. On a ainsi les même vitesses sur les deux moteurs.
Voici un programme qui fait faire une ligne droite au robot :
Carte Alimentation
Cette carte fait le lien entre la batterie et le reste du robot. Elle est composée de deux modules. On les a ajusté différement :
- Un transformateur 12V-5V - Un régulateur de 12V
Voici un module :
Le but recherché est de pouvoir alimenter la carte arduino, les autres cartes et les moteurs. De plus, cette solution est assez simple à mettre en place et peu coûteuse (environ 2euros/module).
Carte ultrason (Vincent)
Presentation
La carte ultrason joue un rôle essentiel dans les déplacements de notre robot, elle est chargée de détecter les obstacles de manière précise et rapide afin d'informer le robot sur leur position pour qu'il puisse réagir et les éviter. Pour détecter les obstacles nous utilisons le module HC-SR04 permettant l'acquisition d'une information de distance.
- Présentation du module HC-SR04 : Le HC-SR04 est un module ultrason permettant l'évaluation d'une distance de 2cm à 4m. La mesure est réalisée "sans contact". Le module est composé d'un émetteur et d'un récepteur ultrason ainsi qu'une électronique de contrôle. Le fonctionnement de ce module s'apparente à celui d'un sonar de sous marin et sa mise en œuvre est relativement simple car il est prêt à l'emploi et possède 4 pattes: un GND, un VCC, un triger pour effectuer la mesure et un Écho pour le résultat de la mesure.
Conception de la carte ultrason
Cahier des charges
Tout d'abord, pour la conception de cette carte, nous utiliseront 7 modules ultrason afin de donner le plus d'informations possible sur les obstacles positionnés sur la trajectoire du robot. Le module HC-SR04 n’étant pas répertorié par Eagle nous devons donc commencer par créer le composant, ainsi que son empreinte qui comportera la taille réelle du composant sur Eagle.
- Alimentation du micro-contrôleur séparée de l'alimentation des capteurs ultrason
- Utilisation d'un micro-contrôleur (ATtiny88) pour gérer plus facilement les mesures des capteurs
- Condensateur de découplage pour chaque capteur ultrason afin d'éviter le bruit
- Bornier SPI pour communiquer avec les autres cartes du robot
- Angle de 30° entre les capteurs pour gérer plus facilement le déplacements du robot
Ensuite nous devons choisir un microcontrôleur afin de piloter cette carte: on choisira un AT TINY 88 car il possede 2 port (C et D) dont on se servira pour gerer les 7 triger et les 7 echo des modules ultrason. Ce microcontrôleur permet aussi une communication SPI dont on se servira pour communiquer avec les autres cartes du robot.
Le bornier utilisé pour la liaison SPI doit répondre à des normes :
Schéma, board, typon et schéma de connexion de la carte ultrason
Voici les différents schémas utiles de la carte ultrason:
On peut voir sur le schéma éléctrique que les 7 modules ultrason sont reliés sur les deux ports du micro-contrôleur.
Voici le board de la carte ultrason.
Ici les typons utiles à la réalisation de la carte.
Voici le Schéma des connexions de la carte ultrason.
Voici les fichiers Eagle de la carte ultrason:
Programmation de la carte ultrason
Premiers tests
Après la réalisation de la carte ultrason, nous avons effectués plusieurs tests pour vérifier son bon fonctionnement. Tout d'abord nous avons constaté une erreur: sur l'empreinte du composant HC-SR04, nous avons inversé le GND et le VCC, ce qui a par la suite causé des problèmes sur la carte. Nous avons donc corrigé ce problème, et avons effectué d'autres tests comme celui de la continuité.
Nous avons ensuite testé le fonctionnement des 7 capteurs ultrason utilisé à l'aide du programme arduino si dessous qui nous transmettait par la liaison série la distance mesurée par le capteur:
/* Pinmapping */
const byte TRIGGER_PIN = 2; // Broche TRIGGER
const byte ECHO_PIN = 3; // Broche ECHO
/* Constantes */
const long MEASURE_TIMEOUT = 25000L; // 40Hz = 25ms = ~8m à 340m/s
/* setup() */
void setup() {
/* Pour l'affichage des résultats */
Serial.begin(9600);
/* Initialisation des broches */
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
digitalWrite(TRIGGER_PIN, LOW); // DOIT être à LOW au repos
/* Message d’accueil */
Serial.println(F("~~ HC-SR04 ~~"));
}
/* loop() */
void loop() {
/* 1) Lance une mesure de distance en envoyant une impulsion HIGH de 10µs sur la broche TRIGGER */
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
/* 2) Mesure le temps entre l'envoi de l'impulsion ultrasonique et son écho (si il existe) */
long measure = pulseIn(ECHO_PIN, HIGH, MEASURE_TIMEOUT);
/* 3) Calcul la distance à partir du temps mesuré */
long mm = measure / 2 * 0.34;
/* Affiche les résultats en mm, cm et m */
Serial.print(F("Distance: "));
Serial.print(mm);
Serial.print(F("mm ("));
Serial.print(mm / 10.0, 2);
Serial.print(F("cm, "));
Serial.print(mm / 1000.0, 2);
Serial.println(F("m)"));
/* Délai d'attente pour éviter d'afficher trop de résultats à la seconde */
delay(60);
}
programme de communication SPI :
Ce programme permet d'établir la communication entre la carte ultrason (esclave) et la carte Arduino (maître).
Pour vérifier le bon fonctionnement de la communication il suffit de programmer le micro-contrôleur de la carte ultrason pour qu'il transmette une valeur sur la liaison serie.
#include <SPI.h> //master
void setup (void)
{
Serial.begin(115200);
digitalWrite(SS, HIGH);
// ensure SS stays high for now
// Put SCK, MOSI, SS pins intooutput mode
// also put SCK, MOSI into LOWstate, and SS into HIGH state.
// Then put SPI hardware into Mastermode and turn SPI on
SPI.begin ();
// Slow down the master a bit
SPI.setClockDivider(SPI_CLOCK_DIV128);
}
// end of setup
void loop (void)
{
uint8_t c,a;
// enable Slave Select
digitalWrite(SS, LOW);
// SS is pin 10
// send test string
a=SPI.transfer (10);
digitalWrite(SS, HIGH);
Serial.println(a,DEC);
// disable Slave Select
delay (100);
// 1 seconds delay
}
Carte Codeur (Alexandre.L)
Comunication SPI arduino
Principe de la communication SPI sur Arduino
Une liaison SPI (Serial Peripheral Interface) est un bus de données série synchrone, qui opère en Full-duplex. Les circuits communiquent selon un schéma maître-esclaves, où le maître s'occupe totalement de la communication. Plusieurs esclaves peuvent coexister sur un même bus, dans ce cas, la sélection du destinataire se fait par le Slave Select.
on dispose donc des pattes suivantes:
- MOSI : Master Output Slave Input, le maître parle l'esclave écoute
- MISO : Master Input Slave Output, le maître écoute, l’esclave parle
- SLK : Serial Clock, Horloge de synchronisation généré par le maître
- SS : Slave Select, utilisé si on dispose de plusieurs esclaves pour sélectionner avec lequel on communique
Echanges de données en SPI:
Maintenant que le principe de fonctionnement de la liaison SPI est éclaircit, intéressons nous aux échanges de données
on notera que les données circulent de manière circulaire; le bit 7 du master arrive sur b0 du slave, tandis que b7 du slave est envoyé sur b0 du master. il y a un décalage des bits contenus dans le registre SPDR (registre qui stock les données recues et envoyées sur la liaison SPI).
programme minimum Arduino de communication SPI:
Avec ces quelques bases, nous pouvons comprendre le programme Arduino suivant qui établit une communication quelques peu rudimentaire, mais qui illustre les fonctions Arduino utilisées pour créer une communication SPI:
la carte Arduino Uno que nous utilisons possède déjà des pattes dédiées à la communication SPI:
- MOSI : Pin 11
- MISO : Pin 12
- SCLK : Pin 13
- SS : Pin 10
- N'oublions pas de connecter les masses Arduino ensembles pour que la tension de référence soit la même
Programme maître:
// Written by Nick Gammon
// February 2011
#include <SPI.h>
void setup (void)
{
digitalWrite(SS, HIGH); // ensure SS stays high for now
// Put SCK, MOSI, SS pins into output mode
// also put SCK, MOSI into LOW state, and SS into HIGH state.
// Then put SPI hardware into Master mode and turn SPI on
SPI.begin ();
// Slow down the master a bit
SPI.setClockDivider(SPI_CLOCK_DIV8);
Serial.begin(115200);
} // end of setup
void loop (void)
{
char c,r;
// enable Slave Select
digitalWrite(SS, LOW); // SS is pin 10
// send test string
for (const char * p = "Hello, world!\n" ; c = *p; p++)
Serial.write(SPI.transfer (c));
Serial.write('\n');
// disable Slave Select
digitalWrite(SS, HIGH);
delay (1000); // 1 seconds delay
} // end of loop
Programme esclave:
// Written by Nick Gammon
// February 2011
#include <SPI.h>
char buf [100];
volatile byte pos;
volatile boolean process_it;
void setup (void)
{
Serial.begin (115200); // debugging
// turn on SPI in slave mode
SPCR |= bit (SPE);
// have to send on master in, *slave out*
pinMode(MISO, OUTPUT);
// get ready for an interrupt
pos = 0; // buffer empty
process_it = false;
// now turn on interrupts
SPI.attachInterrupt();
} // end of setup
// SPI interrupt routine
ISR (SPI_STC_vect)
{
static uint8_t i=0;
byte c = SPDR; // grab byte from SPI Data Register
// add to buffer if room
if (pos < sizeof buf)
{
buf [pos++] = c;
// SPDR=i;
// i++;
// example: newline means time to process buffer
if (c == '\n')
process_it = true;
} // end of room available
} // end of interrupt routine SPI_STC_vect
// main loop - wait for flag set in interrupt routine
void loop (void)
{
if (process_it)
{
buf [pos] = 0;
Serial.println (buf);
pos = 0;
process_it = false;
} // end of flag set
} // end of loop
Conception et réalisation de la carte codeur
Pour concevoir et réaliser la carte, nous devons respecter les contraintes suivantes:
- pas de pistes au dos de la carte : la carte sera fixée et plaquée sur le châssis (à cause de l'espace occupé par les moteurs), le contact entre le dos de la carte et le châssis va créer des court-circuits si des pistes sont au dos. De plus pour des raisons de coût et de simplicité de réalisation cela est préférable.
- la position des codeurs sera fixe : ils seront placés précisément sous les roues dentées fixées sur les axes des moteurs.
- les pistes devrons être courtes : les grandeurs circulant sur la carte sont très faibles et seront donc facilement perturbées par les champs électriques et magnétiques.
- choix et emplacement du connecteur : ces derniers n'ont pas de contraintes, le connecteur sera placé simplement de la manière la plus avantageuse pour le routage, et à la fois de manière accessible pour le connecter facilement.
Conception: Schéma électrique et Routage
choix des composants:
- nous avons choisis un connecteur droit pour ça simplicité de branchement
- les codeurs seront des Tcut 1300 du constructeur Vishay
voici le schéma électrique:
Codeur et mesure
ce schéma est plutôt simple, il est constitué d'une partie qui alimente les codeurs et d'une partie qui récupère les mesures des codeurs.
Ces mesures sont renvoyé via le connecteur vers une autre carte qui analysera ces données.
Correspondance des pattes du connecteur (vue du board):
- Patte n°1 : mesure codeur EME1 (Gauche)
- Patte n°2 : +Vcc alimentation
- Patte n°3 : mesure codeur EME2 (droite)
- Patte n°4 : mesure codeur EME2 (Gauche)
- Patte n°5 : GND masse
- Patte n°6 : mesure codeur EME1 (droite)
on notera que les pistes sont relativement proches et que le connecteur va être difficile à souder mais cela reste envisageable. Des trous de perçage sont prévus sur la carte pour la fixer et la plaquer sur le chassi
Programme test de la carte codeur
programme de test : ce programme à pour but de valider ou non le bon fonctionnement des codeurs, il permet d'afficher le nombre d'encoches passées sur chaque roue. On peut ainsi tester si les mesures effectuées par la carte sont valides, le sens des roues etc...
Gestion du déplacement du robot
équations du positionnement
Le positionnement du robot sera calculé en traitant les informations de mesures reçues sur des petits déplacements, le fait d'effectuer ces mesures sur des petits déplacements limitera l'erreur de positionnement et augmentera la précision de calcul.
Il y a deux manières d'approximer la trajectoire parcourue par le robot :
- En utilisant des segments de droites : On considère alors que le robot va en ligne droite sur toute la période de calcul. Ceci revient à supposer que les deux roues ont une vitesse constante et identique sur cet portion de trajectoire. A la fin de cet portion, on corrige l'orientation du robot en fonction de la différence de distance parcourue par les deux roues.
- En utilisant des arcs de cercles : On considère alors que le robot se déplace et change d'orientation en suivant un arc de cercle pendant le temps . Ceci revient à considérer que chacune des roues a une vitesse constante sur la période mais que les vitesses des 2 roues ne sont pas identiques.
Et avec ces équations, obtenir à la position du robot (coordonnées x,y)
programme de test : ce programme à pour but de valider le calcul des équations ci-dessus. Grâce au nombre d'encoches comptées sur chaque roue,il permet d'afficher la position en x du robot, sa position en y (voir axes ci-dessus), sa position angulaire et le nombre d'encoches comptés. On peut ainsi tester si les calculs effectuées renvoient une distance et un angle valide.
Programmes de déplacement
Suite a ces programmes nous avons commencé à essayer de nous rapprocher un peu plus d'un premier objectif: rendre le robot capable de se déplacer précisément.
Nous avons donc travaillé sur un programme qui fait réaliser au robot un déplacement en ligne droite et s’arrête au bout d' 1 mètre.
La difficulté ici a été de maintenir une trajectoire rectiligne ce qui implique une correction de trajectoire en permanence à cause de certains facteurs (les roues ne tournent pas à la même vitesse, glissement...)
programme de déplacement sur 1m : Le robot se déplace en ligne droite sur 1 mètre, un mode de fonctionnement en commentaire permet d'augmenter sa vitesse progressivement au démarrage pour éviter les glissements, elle atteint une vitesse maximum constante, puis ralentit progressivement pour s’arrêter.
système de fin de course (ballon) (Maxime)
Pages dans la catégorie « RobotGEII »
Cette catégorie comprend 4 pages, dont les 4 ci-dessous.