RobotGEII 16-17
Sommaire
- 1 Présentation
- 2 Etude du Robot
- 3 Bibliographie/références
Présentation
Présentation projet
Ce projet consiste à réaliser un robot pour participer à la coupe de robotique des GEII. Pour fabriquer ce robot nous devons respecter un cahier des charges défini par le règlement(reglement).Le principe de ce concours est d'aller le plus rapidement possible d'un coin à l'autre d'une arène carrée de 8 metres de coté, tout en esquivant les obstacles jonchant le parcours et les autres robots.Une fois arrivé, le robot doit perser un ballon qui lui est attaché en début de course.
Cahier de charges fonctionnelles
Schema fonctionnelle de degrés II
shema fonctionnelle 1er degres
Solution technique
Pour fabriquer ce robot nous avion plusieurs choix pour procéder à l’évitement des obstacles, nous avons choisie de lier trois technologie pour éviter d’être influencer par les kart adverse lors de la course,nous allons donc utiliser des capteur infrarouge,de capteur ultrason et un caméra CMU cam 5. Pour contrôler tous les capteur ainsi que la caméra nous allons utiliser une carte rasberrie pi.Nous allons également utiliser la camera pour pour déterminer le coin d'arriver du robot grâce à une balise que la caméra reconnaîtra.
Etude du Robot
Batterie, Moteurs, Hacheurs
Description technique
...
Contrôle deux moteurs CC par un shield (L298P)
Pour commander les moteurs nous allons utiliser le pont H L298P [ datasheet].
Le composant est ci-dessous:
Pour faire des tests nous avons utlisé le Motor Shield For Arduino. En conectant ce shield à l'arduino nous pouvons commander les deux moteurs moteurs (commande du sens et de la vitesse).
- PWM
Nous allons utiliser le shild en mode PWM, on placera donc les jumpers en conséquence.
- Borne du moteur
Nous avons deux bornes (blues) pour connecter les moteurs CC. Les connecteurs mâles derrière sont identiques à celui des bornes blues.
- PWRIN
Les moteurs peuvent être alimentés par une alimentation externe lorsque le courant du moteur dépasse les limites fournies par l'Arduino (Il est conseillé de séparer les alimentations d’Arduino et des moteurs). Le switch entre la puissance externe et l'arduino est mis en oeuvre par deux jumpers .
PWRIN: Alimentation externe.
VIN: Alimentation du Arduino.
On placera donc les jumpers d’alimentation sur PWRIN.
On doit avoir quelque chose comme cela:
- Signal de contrôle Tableau de vérité
E1 | M1 | E2 | M2 | Texte de l’en-tête | |
---|---|---|---|---|---|
L | X | Moteur 1 desactivé | L | X | Moteur 2 desactivé |
H | H | Moteur 1 en arrière | H | H | Moteur 2 en arrière |
H | L | Moteur 1 en avant | H | L | Moteur 2 en avant |
PWM | X | Control vitesse PWM | PWM | X | Control vitesse PWM |
NOTE:
H: Niveau haut
L: Niveau bas
X: N'importe quel niveau.
Mode PWM
Commande | Moteur | Pin Arduino | Pin Atmega328p | Siginification |
---|---|---|---|---|
M1 | Gauge | 4 | PD4 | Contrôle du sens de rotation |
E1 (PWM) | Gauge | 5 | PD5 | Contrôle de la vitesse de rotation |
M2 | Droit | 7 | PD7 | Contrôle du sens de rotation |
E2 (PWM) | Droit | 6 | PD6 | Contrôle de la vitesse de rotation |
- Exemple de code
Nous allons gerer les moteurs par des signaux PWM (-255 a 255), le signe moins(-) indique motor en arrier et le plus(+) en avant. Cette code nous permet de gerer le deux motors par la fonction setVitesse(vG,vD). Dans la suit nous allons l'utiliser pour gerer le deplacement du robot.
#include <avr/io.h>//Librerie AVR
#define topPWM 255 //Valeur Max du PWM (8bits)
void initMoteur()//PWM sur PD5 et PD6
{
//fpwm = fq / (topPWM * p)
//fpwmi:frequence du PWM
//fq:frequance du quark
//topPWM: valeur maximun du PWM
//p:prediviseur
//Declaration de sorties
DDRD |= (1 << PD4);//Sens du motor Gauge
DDRD |= (1 << PD5);//PWM du motor Gauge
DDRD |= (1 << PD7);//Sens du motor Droit
DDRD |= (1 << PD6);//PWM du motor Droit
TCCR0B |= (1 << CS00) | (1 << CS01);//Prediviseur P=64
TCCR0A |= (1 << WGM00) | (1 << WGM01);//Mode FAST PWM
TCCR0A |= 1 << COM0A1;//PWM sur OC0A
TCCR0A |= 1 << COM0B1;//PWM sur OC0B
OCR0A = 0;//Valeur de comparaison pour A --> PD6
OCR0B = 0;//Valeur de comparaison pour B --> PD5
}
void setMoteurG(int16_t vit)//fontion pour gener le moteur gauge
{
if (vit < 0)
{
vit = -vit;
PORTD |= (1 << PD4);//Moteur Gauge en arrière
}
else PORTD &= ~ (1 << PD4);//Moteur Gauge en avant
if (vit > topPWM) vit = topPWM;//Si jamais on met une vauleur superior a 255, la vitesse maximun sera 255
OCR0B = vit;//Action sur le PWM --> PD5
}
void setMoteurD(int16_t vit)//fontion pour gener le moteur droit
{
if (vit < 0)
{
vit = -vit;
PORTD |= (1 << PD7);//Moteur Droite en arrière
}
else PORTD &= ~ (1 << PD7);//Moteur Droite en avant
if (vit > topPWM) vit = topPWM;//Si jamais on met une vauleur superior a 255, la vitesse maximun sera 255
OCR0A = vit;//Action sur le PWM --> PD6
}
void setVitesse(int16_t vG, int16_t vD)//cette fontion nous permet gerer les deux moteurs avec "une seule" ligne
{
setMoteurD(vD);
setMoteurG(vG);
}
int main()
{
initMoteur();
while(1)
{
setVitesse(100,100);//Example d'utlisation
}
}
Positionnement du robot: Explication du principe
Approximation par des segments de droites
....
Estimation de la position du robot
Carte Capteur
L'odométrie nous permettra d'estimer la position du robot en mouvement, des le debut et jusqu'à la détéction de la balise par la caméra. C'est à partir de la mesure des déplacements des roues, qu'on pourra reconstituer le mouvement du robot. En partant d'une position initiale connue et en intégrant les déplacements mesurés, on peut ainsi calculer à chaque instant la position courante du véhicule.
Pour mésurer le déplacement des roues, nous allons utiliser un encodeur, monté sur l'axe de chaque roue.
On doit obtenir:
1.LA VITESSE
2.LE SENS DE ROTATION DES ROUES
ENCODEUR DE BASE:
Ce montage basique permet de mesurer la vitesse de rotation à partir de la fréquance, mais il ne permet pas de connaitre le sens de rotation.
ENCODEUR EN QUADRATURE: Celui-ci nous permettra de connaitre à la fois le sens et la vitesse des roues. Il est composé d’un disque rotatif, 1 led infrarouge et 2 capteurs optique décalé un par rapport à l’autre de 90°. C’est justement ce décalage la qui va nous permettre de connaitre le sens de rotation de la roue. Suivant le sens de rotation, nous auront deux signaux déphasés en avance/retard de 90°.La vitesse sera déterminé en fonction de la fréquence.
Les signaux de sortie à l’oscilloscope
CAPTEUR TCUT 1300. Nous allons utiliser ce capteur il nous permettra d'avoir le sens et la vitesse de chaque roue.
The TCUT1300X01 is a compact transmissive sensor that
includes an infrared emitter and two phototransistor
detectors, located face-to-face in a surface mount package.
Schéma et dimensionement composants
Emiter: If = 10mA (Vf = 1.2V), Re = (5V-Vf)/If = 380 ohm.
Collector: Ic sat = 0.4mA (If = 10mA), Rmin = Vce /Ic = 12.5 kohm. Vce sat = 0.4V max (pour Ic sat = 0.4mA, If = 10mA ). On prendra Rc = 15 kohm.
Schéma et routage en Eagle
Réalisation carte (2 exemplaires)
- Carte simple face CMS.
Roue codeuse
Pour determiner la frequence des moteurs nous allons utiliser une Roue Codeuse et un capteur. Nous avons créé le roue sur le logiciel GEFAO et fabrication avec la machine charlyrobot. Vous trouverez ici le fichier de la roue (Fichier:RoueCodeuse.zip).
Valeurs recu par les capteurs
Cette roue sera placer sur l'arbre des motors et sur les deux capteurs, lorsque le moteur est en train de tourner les capteurs va nous envoyer une signal qui se resamblera à celui-ci:
- Si la roue en avant
Il faut remarquer que la signal 1 est en avance. Donc sur chaque front montant de la signal 1, la signal 2 est à 0. Et sur chanque front descendate de la signal 1, la signal 2 est à 1. Ce raisonnement sera utiliser dans le code du proogramme.
- Si la roue en arriere
Il faut remarquer que la signal 1 est en retard. Donc sur chaque front montant de la signal 1, la signal 2 est à 1. Et sur chanque front descendate de la signal 1, la signal 2 est à 0. Ce raisonnement sera aussi utiliser dans le code du proogramme.
Il faut remarquer que si le robot avance, la roue codeuse est en arriere et si le robot recule la roue codeuse est en avant. Ce effet est du aux engranages qui sont sur les moteurs et la roue.
Interruptions et timer
- Interruptions INT0 et INT1: Code example
Dans cette partie nous allons utiliser les interruptions et les timers. On utilisera les inturruptions (INT0 et INT1) pour dechancher un code a chaque fois que les dents de la roue codeuse travers le flux lumineuse du capteurs (sur le front montant et front descendant). Nous allons aussi utliser un timer qui sera dechanché sur un temps assez petit ( <10ms) pour calculer un deltaX, un deltaY et un detaTeta qui nous permetront de determiner la position du robot a chaque instante.
#include <avr/io.h>//Libreries AVR
volatile int8_t NbDentsD = 0; //Nombre de dents captés par le capteur **** de la roue codeuse Droit
volatile int8_t NbDentsG = 0; //Nombre de dents captés par le capteur **** de la Roue Codeuse Gauge
ISR(INT0_vect)
{
//Sur chaque roue nous avons un emeteur et deux recepteurs, ces deux seront lu sur le pate PD2 et PB0
uint8_t Pin2 = PIND & (1 << PD2); //INTERRUPTION INT0 sur PD2
uint8_t Pin8 = PINB & (1 << PB0);
if (Pin2 != 0)
{
if (Pin8 == 0) NbDentsD++;//Si la roue droit avance dont on aditionne le dents
else NbDentsD--;//sinon on soustrait les dents, car cela signifie que le roue est en arrière
}
else if (Pin2 == 0)
{
if (Pin8 != 0) NbDentsD++;
else NbDentsD--;
}
}
ISR(INT1_vect)
{
uint8_t Pin3 = PIND & (1 << PD3); //INTERRUPTION INT1 sur PD3
uint8_t Pin9 = PINB & (1 << PB1);
if (Pin3 != 0)
{
if (Pin9 == 0) NbDentsG++;//Si la roue gauge avance dont on aditionne le dents
else {
NbDentsG--;//sinon on soustrait les dents, car cela signifie que le roue est en arrière
}
}
else if (Pin3 == 0)
{
if (Pin9 != 0) NbDentsG++;
else {
NbDentsG--;
}
}
}
void int0()
{
//CONFIGURATION INTERRUPTION INT0
//Pin2 --> PD2--> INT0 entrée
EIMSK |= 1 << INT0; //Autorisation interruption INT0
EICRA |= 1 << ISC00; //Activation sur changement d'etat sur PD2
}
void int1()
{
//CONFIGURATION INTERRUPTION INT1
//PIN3 -->PD3--> INT1 entrée
EIMSK |= 1 << INT1; //Autorisation interruption INT1
EICRA |= 1 << ISC10; //Activation sur changement d'etat sur PD3
}
void sei_interruption()
{
sei(); //Autorisation global d'interruptions
}
int main()
{
int0();//Interruption 0
int1();//Interruption 1
sei_interruption();//Autorisation d'interruptions
while(1)
{
}
}
- TIMER 1
En faite nous allons calculer la position du robot en ajoutant de petits deltas de postition lequels seront calculer sur un temps suffisamment petit ( <10ms) pour eviter que l'erreur soit grand. On utilisera un drapeau pour eviter de faire de calculs sur dans le ISR(TIMER1_COMPA_vect), nous allons les faire plutot sur while(1), cela nous permettra de reduire l'erreur.
#include <avr/io.h>//Libreries AVR
void timer1()//CONFIGURATION DU TIMER1
{
//Tt1=(n*p)/fq
//Tt1: periode du timer
//n=valuer de comparaison (OCR1A)
//p:prediviseur
//fq:frequence du quark (arduino uno 16Mhz)
TCCR1B |= (1 << CS10) | (1 << CS11); //p=64
TCCR1B |= 1 << WGM12; //RAZ mode CTC
TIMSK1 |= 1 << OCIE1A; //Autorisation d'interruption de comparaison A
OCR1A = 7500; //Comparaison n=7500
}
ISR(TIMER1_COMPA_vect)
{
newCalc = true;
}
int main()
{
while (1)
{
if (newCalc == true)
{
//Calculs de la position
newCalc = false;
}
}
}
Suivons une ligne droite
On sait que le moteurs n'ont pas la vitesse, donc il faut essayer de faire cela par code. On va donc faire setVitesse(Vmax * cos(Teta + PI / 4.0), Vmax * sin(Teta + PI / 4.0)), les cos et sin nous permettra jouer sur la vitesse et de cette facon faire que le robot suis une ligne droit, il faut remarquer qu'il va pas s'arreter.
#include <avr/io.h>//Libreries AVR
#include <math.h>//Libreries Math pour les calculs de sinus, cosinus, etc;
#define topPWM 255 //Valeur Max du PWM (8bits)
float d = 51.17; //Rayon de la roue codeuse
float Delta_Dent = PI * d / 60.0; //Espacement entre chaque dent de la roue.VERIFICAR VERDADERO VALOR
float L = 230.0; //Distence entre les centre des roues.
volatile int8_t NbDentsD = 0; //Nombre de dents captés par le capteur **** de la roue codeuse Droit
volatile int8_t NbDentsG = 0; //Nombre de dents captés par le capteur **** de la Roue Codeuse Gauge
float Delta_D = 0;
float Delta_G = 0;
float Delta_moy = 0;
float Delta_dif = 0;
float Delta_teta = 0;
float Delta_X = 0;
float Delta_Y = 0;
float Position_X = 0;
float Position_X_precendent = 0;
float Position_Y = 0;
float Position_Y_precendent = 0;
float Teta = 0;
float Teta_precedent = 0;
float Teta_consigne = 0; //Angle qu'on veux attaindre
float X_consigne = 0; //Position en X qu'on veux attaindre
float Y_consigne = 0; //Position en Y qu'on veux attaindre
volatile boolean newCalc = true;//Drapeau qui nous permetra de
float Vmax = 0;
void int0()
{
//CONFIGURATION INTERRUPTION INT0
//Pin2 --> PD2--> INT0 entrée
EIMSK |= 1 << INT0; //Autorisation interruption INT0
EICRA |= 1 << ISC00; //Activation sur changement d'etat sur PD2
}
void int1()
{
//CONFIGURATION INTERRUPTION INT1
//PIN3 -->PD3--> INT1 entrée
EIMSK |= 1 << INT1; //Autorisation interruption INT1
EICRA |= 1 << ISC10; //Activation sur changement d'etat sur PD3
}
void timer1()//CONFIGURATION DU TIMER1
{
//Tt1=(n*p)/fq
//Tt1: periode du timer
//n=valuer de comparaison (OCR1A)
//p:prediviseur
//fq:frequence du quark (arduino uno 16Mhz)
TCCR1B |= (1 << CS10) | (1 << CS11); //p=64
TCCR1B |= 1 << WGM12; //RAZ mode CTC
TIMSK1 |= 1 << OCIE1A; //Autorisation d'interruption de comparaison A
OCR1A = 7500; //Comparaison n=7500
}
void initMoteur()//PWM sur PD5 et PD6
{
//fpwm = fq / (topPWM * p)
//fpwmi:frequence du PWM
//fq:frequance du quark
//topPWM: valeur maximun du PWM
//p:prediviseur
//Declaration de sorties
DDRD |= (1 << PD4);//Sens du motor Gauge
DDRD |= (1 << PD5);//PWM du motor Gauge
DDRD |= (1 << PD7);//Sens du motor Droit
DDRD |= (1 << PD6);//PWM du motor Droit
TCCR0B |= (1 << CS00) | (1 << CS01);//Prediviseur P=64
TCCR0A |= (1 << WGM00) | (1 << WGM01);//Mode FAST PWM
TCCR0A |= 1 << COM0A1;//PWM sur OC0A
TCCR0A |= 1 << COM0B1;//PWM sur OC0B
OCR0A = 0;//Valeur de comparaison pour A --> PD6
OCR0B = 0;//Valeur de comparaison pour B --> PD5
}
void sei_interruption()
{
sei(); //Autorisation global d'interruptions
}
ISR(INT0_vect)
{
//Sur chaque roue nous avons un emeteur et deux recepteurs, ces deux seront lu sur le pate PD2 et PB0
uint8_t Pin2 = PIND & (1 << PD2); //INTERRUPTION INT0 sur PD2
uint8_t Pin8 = PINB & (1 << PB0);
if (Pin2 != 0)
{
if (Pin8 == 0) NbDentsD++;//Si la roue droit avance dont on aditionne le dents
else NbDentsD--;//sinon on soustrait les dents, car cela signifie que le roue est en arrière
}
else if (Pin2 == 0)
{
if (Pin8 != 0) NbDentsD++;
else NbDentsD--;
}
}
ISR(INT1_vect)
{
uint8_t Pin3 = PIND & (1 << PD3); //INTERRUPTION INT1 sur PD3
uint8_t Pin9 = PINB & (1 << PB1);
if (Pin3 != 0)
{
if (Pin9 == 0) NbDentsG++;//Si la roue gauge avance dont on aditionne le dents
else {
NbDentsG--;//sinon on soustrait les dents, car cela signifie que le roue est en arrière
}
}
else if (Pin3 == 0)
{
if (Pin9 != 0) NbDentsG++;
else {
NbDentsG--;
}
}
}
ISR(TIMER1_COMPA_vect)
{
newCalc = true;
}
void setMoteurG(int16_t vit)//fontion pour gener le moteur gauge
{
if (vit < 0)
{
vit = -vit;
PORTD |= (1 << PD4);//Moteur Gauge en arrière
}
else PORTD &= ~ (1 << PD4);//Moteur Gauge en avant
if (vit > topPWM) vit = topPWM;//Si jamais on met une vauleur superior a 255, la vitesse maximun sera 255
OCR0B = vit;//Action sur le PWM --> PD5
}
void setMoteurD(int16_t vit)//fontion pour gener le moteur droit
{
if (vit < 0)
{
vit = -vit;
PORTD |= (1 << PD7);//Moteur Droite en arrière
}
else PORTD &= ~ (1 << PD7);//Moteur Droite en avant
if (vit > topPWM) vit = topPWM;//Si jamais on met une vauleur superior a 255, la vitesse maximun sera 255
OCR0A = vit;//Action sur le PWM --> PD6
}
void setVitesse(int16_t vG, int16_t vD)//cette fontion nous permet gerer les deux moteurs avec "une seule" ligne
{
setMoteurD(vD);
setMoteurG(vG);
}
int main()
{
int0();//Interruption 0
int1();//Interruption 1
timer1();//Timer 1
initMoteur();//PWM
sei_interruption();//Autorisation d'interruptions
while (1)//Boucle infinie
{
if (newCalc == true)
{
Delta_D = (NbDentsD * Delta_Dent);//pas de la roue droit à chaque declanchement du TIMER 1.
Delta_G = (NbDentsG * Delta_Dent); //pas de la roue gauge à chaque declanchement du TIMER 1.
NbDentsG = 0;//Remise à zéro à chaque declanchement du TIMER 1.
NbDentsD = 0;//Remise à zéro sà chaque declanchement du TIMER 1.
Delta_moy = (1 / 2.0) * (Delta_D + Delta_G);//pas du robot à chaque declanchement du TIMER 1.
Delta_dif = Delta_D - Delta_G;
Delta_teta = Delta_dif / L;//Calcul de Delta_teta en rad à chaque declanchement du TIMER 1.
Delta_X = Delta_moy * cos(Teta_precedent);//pas sur X du deplacement du robot à chaque declanchement du TIMER 1.
Delta_Y = Delta_moy * sin(Teta_precedent);//pas sur Y du deplacement du robot à chaque declanchement du TIMER 1.
Teta = Teta_precedent + Delta_teta;//Angle de desviation par rapport à l'axe X du robot.
Teta_precedent = Teta;//Angle de desviation precedent par rapport à l'axe X du robot.
Position_X = Position_X_precendent + Delta_X;//Potition actuelle du robot en X
Position_X_precendent = Position_X;//Position precedente du robot en X
Position_Y = Position_Y_precendent + Delta_Y;//Potition actuelle du robot en Y
Position_Y_precendent = Position_Y;//Position precedente du robot en Y
Vmax = 250;//valeur maximun qu'on impose aux moteurs
setVitesse(Vmax * cos(Teta + PI / 4.0), Vmax * sin(Teta + PI / 4.0));
newCalc = false;
}
}
}
Suivons une consigne
Cette fois nous pourrons donner une valeur en X ey Y et le robot sera capable d'arriver au point et s'arreté. La valeurs doit etre donnée en cm.
//Code precedente (suivons un ligne)
int main()
{
//Configurations
while (1)//Boucle infinie
{
if (newCalc == true)
{
//Calculs
X_consigne = 100;//valeur donné en cm
Y_consigne = 50;//valeur donné en cm
Teta_consigne = atan((Y_consigne - Position_Y / 50.0) / (X_consigne - Position_X / 50.0)) - Teta;//Nous divisons par 50 pour avoir les valeur en cm
Vmax = 250;//valeur maximun qu'on impose aux moteurs
setVitesse(Vmax * cos(Teta_consigne + PI / 4.0), Vmax * sin(Teta_consigne + PI / 4.0));
newCalc = false;
}
}
}
Detection d'obstacles
Caméra
Choix camera
Nous avons testé 3 cameras différentes, la PiCam, la CMUCam3 et la CMUCam5 Pixy
Nous avons choisi d'utiliser la CMUCam 5(site CMU cam 5) car elle est beaucoup plus simple d'utilisation que les deux autres. En effet, celle ci dispose d'une interface dre réglage, PixyMon, lui permettant d'enregistrer les signatures des objets à détecter, et de régler l'acquisition pour restreindre la détection à ces signatures précises. De plus, celle ci dispose d'un support mû par des servomoteurs permettant d'élargir son champ de vision.
Camera CMU cam 5
Tout d’abord nous avons réaliser une simple reconnaissance d'objet grâce au logiciel, il suffit pour cela de sélectionner l'objet en question. Nous avons ensuite choisie d'utiliser une balise lumineuse pour que la camera la repère le plus loin possible. balise test.
Grace à cette balise nous avons pu déterminer jusqu’ou la camera repérerait notre balise avec la taille maximum autoriser. Pour cela il suffisait d’éloigner la camera le plus possible et ensuite de faire un produit en croix.Nous avons relever que la camera pouvait capter correctement la balise dont le plus petit coté est de 3cm jusqu’à 1m20 donc on en a deduit que la camera capterait 21m.
Programme de gestion du cap
Nous avons réalisé un programme permettant de récupérer la position en X d'un objet par rapport à la caméra
//////////////////////////////////////////
// Fonction cap
//////////////////////////////////////////
/**************************************************************
Auteur : R.Ingardin
Description : indique le cap à suivre grace à la camera Pixy.
Entrées : Aucune
Sorties : Un int allant de -160 à 160. Une valeur nulle indique
que la cible se trouve au centre du champ de vision
de Pixy. Une valeur positive indique que la cible se
trouve à droite de Pixy, une valeur négative indique
la gauche.
***************************************************************/
int cap()
{
int compteur1;
uint16_t blocks;
/*Récupération des "blocs". Un bloc est une zone rectangulaire
définie par Pixy, possedant plusieurs caractéristiques (hauteur,
position en x/y, couleur...)*/
blocks = pixy.getBlocks();
/*Dans le cas ou un bloc est détecté, la caméra renverra la
position en x de celui ci. La valeur est centrée en zero.*/
if (blocks)
{
return(pixy.blocks[0].x - 159);
}
}
Cette fonction a été testée avec le main suivant
#include <SPI.h>
#include <Pixy.h>
Pixy pixy;
void setup()
{
Serial.begin(9600);
Serial.print("Starting...\n");
pixy.init();
}
int cap()
{
int compteur1;
uint16_t blocks;
blocks = pixy.getBlocks();
if ((blocks) && (pixy.blocks[0].x != 0))
{
return(pixy.blocks[0].x - 159);
}
}
void loop()
{
delay(100);
Serial.println(cap());
delay(500);
}
Il est nécessaire d'appeler les bibliothèques SPI.h et Pixy.h, et de déclarer et d'initialiser Pixy dans le setup. Ceprogramme ne permet cepandant pas l'usage des servomoteurs, limitant le champ de vision.
Mise à l’arrêt du robot et le pérsage du ballon
La mise à l’arrêt du robot et le perçage du ballon doivent avoir lieu simultaniément. Cela doit se produire quand le robot est arrivé dans le coin opposé.
Mise à l’arrêt du robot
Pour ce diriger vers le bon coin, le robot est guidé par la caméra qui suit la balise. Maintenant qu'il est guidé dans la bonne direction, nous devons procéder à une mise à l’arrêt rapide des qu il franchi le coin opposé. Le coin possède la particularité d'avoir une surface au sol de couleur blanche, alors que le reste du sol est bleu. Une solution évidente est d’utiliser le principe d’une diode émettrice infrarouge et d'un photo transistor récepteur infrarouge. Ainsi on pourra arrêter le robot quand il franchie une surface blanche.
Le capteur CNY70 : Nous pourrons utiliser ce capteur infrarouge pour détecter la couleur du sol.
Schéma et dimensionement composants
Emiter: If = 20mA (Vf = 1.15V), Re = (5V-Vf)/If = 195 ohm.
Collector: Ic = 0.5mA (pour If = 20mA, Vce = 5V, d = 2mm), Rc = Vce /Ic = 10 kohm.
Schéma et routage en Eagle
Réalisation carte
Pérsage du ballon
Nous avons testé deux moteurs ,un petit moteur et SM-S4303R et deux matériaux,le fer et le plastique pour faire la perçage:
Finalement nous avons choisi SM-S4303R,car le petit moteur est moins fort que SM-S4303R et utiliser SM-S4303R est plus facile de faire de l'aiguille pour exploser de ballon, pour l'aiguille,nous avons choisi le fer,à cause de fer est plus dure et utilisons le fer fait de la pointe d'aiguille est mieux.