coupe de france de robotique 2013
TRANSCRIPT
Coupe de France de
robotique 2013
GRENOBLE 1 JACKY
SOMMAIRE
I-Description matérielle A)Capteurs
B)Actionneurs
C)Interfaces
II-Programmation du Robot A)FPGA
B)Fonctions principales
C)Sous fonctions
III-La commande
Émission/réception :
I. Description matérielle
A) Capteurs
1 Capteurs SHARP Afin de relever en instantanée les obstacles environnants, nous utilisons des capteurs
InfraRouge SHARP ( no :GP2Y0A02YK ) desquelles il sort un signal de type analogique.
Ceci nous renseigne sur la distance des obstacles.
Ces capteurs émettent un laser IR qui rebondit sur l'obstacle et qui est capté et mesuré
grâce à son intensité. Biensûr, les SHARP ne détectent qu'en ligne droite sans quoi le système
ne fonctionne pas.
Nous disposons de 3 SHARP installés sur la face avant du robot avec 3 angles
différents.
Ainsi, lorsque le robot avance, ces capteurs envoient les données concernants les
potentiels obstacles sur la trajectoire et permet ainsi une modification de cette dernière grâce à
la carte LABVIEW.
2 Capteurs de ligne blanche Afin de repérer le moment où nous atteignons la zone d'arrivée, nous avons installé un
détecteur de ligne blanche de type analogique. La référence de ce capteur est OPB702, c'est
un optocoupleur. Ainsi quand on a du blanc sous le robot, on reçoit un signal 5V lié au
réfléchissement du dioptre.
Le signal émit est comparé à une valeur de référence calculée à partir des conditions
( distance du capteur par rapport au sol et couleur ).
3 Codeurs Montés sur l'arbre ( voir description Moteurs ), les codeurs optiques ont une précision
de 2000 points par tours. Ils donnent les informations concernant la vitesse de rotation de
roues ainsi que leur sens ( marche Avant ou Arrière ) grâce à deux cercles de points
concentriques en quadrature ( décalage de π/2 ). Cependant on ne se servira que d'une voie car
nous commandons nous même le sens de rotation des moteurs ce qui rend cette information
superflue.
Ces informations permettent de traiter les consignes envoyées aux moteurs pour
corriger les trajectoires ( asservissement ).
B) Actionneurs
1 Carte sabertooth 2X10 Cette carte est le pilote de nos moteurs.
Nous avons choisi « R/C mode/Microcontroller mode select » comme configuration de la sabertooth, elle se commande par signal carré de fréquence 50Hz dont le temps à l'état haut doit être compris entre 1000 чs et 2000чs, un temps de 1500чs provoque l'arrêt.
2 Servomoteurs Nous utilisons deux servomoteurs commandés par le même type de signal que la carte sabertooth, traduite en une position angulaire de 0 à 180°. Ces deux actionneurs permettent de crever le ballon d'arrivée. Une lame est montée sur chacun d'eux. L'alimentation se fait en 5V
C) Interface
1 Carte d'interface des capteurs Sharp Nous avons conçu cette carte afin d'alimenter ces capteurs sans consommer de courant au détriment de la carte labview, les signaux sont reliés au port analogique de la carte, grâce à une nappe de fils.
2 Carte 5V Nous avons créé cette carte permettant d'alimenter les différents capteurs et actionneurs qui demandent une alimentation de 5V. Cette carte est alimentée par une batterie 12V. On utilise un7805 pour réguler notre tension à 5V
II. Programmation du robot Pour répondre aux exigences de la Coupe de France Robotique IUT-GEII nous avons décidé d’utiliser une
carte RIO de labview. Comme cette dernière nous était totalement inconnue, nous avons dû apprendre
toute la syntaxe de cette carte pour parvenir à contrôler notre robot.
Il s’agit d’un langage de haut niveau, c’est un dire un langage très éloigné de celui utilisé par les
microcontrôleurs, le programme devra donc passer par plusieurs couches de compilation avant de
pouvoir s’exécuter sur la carte.
A) FPGA *Le FPGA (Fied Progammable Gate Arrways) désigne le circuit intégré composé de cellules
programmables réalisant chacune une fonction. Ce circuit ne possède pas de microprocesseur, il s’agit
donc exclusivement de logique combinatoire.
*Langage de programmation graphique.
*Les temps de compilation sur ce circuit sont extrêmement longs, nous nous en sommes donc
servie de manière patrimoniale, car c’est uniquement le FPGA qui a accès aux entrées et sorties de la
carte.
FPGA
*Notre FPGA ci-dessus se contente de lire les entrées et les mettre à la disposition des autres
programmes ainsi que de générer les PWM des servomoteurs et moteurs .
B) Fonction principale Le MAIN est fonction principale qui coordonne les sous-VI*.
-Dans un premier temps, nous avons construit un programme simple permettant de démarrer le
robot puis traverser un terrain sans obstacle (homologation) puis de percer le ballon une fois arrivé
sur le méplat d’arrivé.
C) Sous fonctions
1 Commande moteur • Logo :
• Argument :
◦ Référence FPGA
◦ Entier : Vitesse, degré du virage
• Booléen : Crever
• Retour : Aucun
2 Percée de ballon • Argument :
◦ Référence FPGA
◦ Booléen : Crever
• Retour : booléen demande d'arrêt
Cette fonction permet de gérer les servomoteurs dédier au perçage du ballon grâce à
une commande tout ou rien.
L'instruction Crever en vert (vert pour booléen) est l'argument donné par le main
Référence en entrée est le lien vers le FPGA
Si la variable « Crever » est vraie on envoie la valeur 900 aux commandes des deux
servomoteurs via le FPGA sinon il leur envoie 2100 (ce sont les deux valeurs extrêmes de
commande des servomoteurs),
3 Homologation • Logo :
• Argument : Référence FPGA
• Retourne : booléen demande arrêt
Cette fonction permet d’avancer à pleine vitesse s'il n'y a pas d'obstacle, de ralentir un peu
quand il aperçoit un obstacle, et de signaler à la fonction principale la détection de l'arrivée
Le sous-programme compare la
valeur donnée par le capteur
sharp, si celle-ci est plus grande
que 0,7 (Plus l'obstacle est
proche plus cette valeur est
grande) on ralenti la consigne
de vitesse de moteurs en leur
envoyant 40 au lieu de 50.
III-La commande Émission/réception : Pour diriger le robot jusqu’au point d’arrivée, nous utilisons une balise émettrice, située à
l’arrivée, et une balise réceptrice, située sur le robot, utilisant des ondes infrarouges modulées
à 38kHz. La liaison est faite par les ports séries du microcontrôleur PIC18F4520.
CARTE D’ÉMISSION :
Voici le PCB de la carte d’émission réalisée par le logiciel PROTEL :
La carte ci-dessus est une carte d’émission infrarouge qui sera placée dans l’angle d’arrivée afin
de diriger notre robot. On émet un code. Elle sera visée sur un support et alimentée par batterie
ou alimentation externe selon les tests effectués sur place.
La carte d’émission est alimentée en 12V
continu et abaissé en 5V continu via un
régulateur 7805. On a mis un interrupteur pour
arrêter l’émission simplement.
On a rajouté des condensateurs de découplages
pour supprimer d’éventuelles composantes
alternatives.
On a mis une LED pour savoir si la carte est bien
alimentée.
On utilise un microcontrôleur PIC18F4520
auquel on a rajouté un quartz de 20MHz. On
programme le pic avec un PICKIT 3 via le
connecteur SIP6 placé au-dessus du pic sur
l’image. Puis, on a placé un bouton de reset (à
gauche de l’image). On sélectionne le code à
envoyer grâce au codeur 4bits placé sur le DIP18
à droite de l’image. On a mis un réseau de
résistances pour connecter le codeur au
microcontrôleur (SIP9 à droite de l’image).
On fait un ET logique entre la pwm à 38kHz et le code envoyé par
la liaison série RS232.
Cette opération est réalisée par une porte NAND : on inverse le
code et on fait un NAND entre le code inversé et la pwm.
Ceci permet de moduler le code émis à 38kHz.
Le signal décrit ci-dessus est envoyé sur des
transistors par le ULN2803 qui est en bas à
gauche de l’encadré. Il est alimenté en 12V et
inverse la sortie, ce qui permet de moins
consommer (le bit de stop de la RS232 dure plus
longtemps que le code et est à l’état haut) et pour
que les résistances chauffent moins.
Nous avons disposé 14 LEDs infrarouges pour
envoyer le code. Et nous avons rajouté une
deuxième LED de vie pour vérifier si on émet.
Si dessous le code de l’émission :
void init_POR (void);
void init_pwm (void);
void init_RS232 (void);
const uns8 tab[16] ={0Xcc,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
/******************************************************/
void main (void)
{
uns16 a;
uns8 code;
init_POR ();
init_pwm ();
init_RS232 ();
while (1)
{
code=PORTB & 0x3C; //code récupéré sur le port B et effacement des
2bits de poids
//fort et poids faible
code = code/4; //décalage du code sur les 4bits de poids faibles
code=tab[code]; //récupération du code dans le
tableau
TXREG=code; // Envoi du code
while (TRMT==0); //on attend que le code soit envoyer
for(a=0;a<3000;a ++); //tempo pour rallonger le bit de stop
}
}
/**********************************************************/
void init_POR (void)
{ ADCON1=0x0F;
TRISC.2=0; // RC2 en sortie (pwm)
TRISC.6=0; // RC6 en sortie (transmission)
TRISB=0xFF; // Port B en entrée (cavaliers sur RB2 à
RB5)
}
/***********************************************************/
void init_pwm (void)
{
PR2=131; // Fréquence de 38kHz
T2CON=0x04; // Pré-diviseur de 1
CCP1CON=0x0C; // Mode PWM
CCPR1L=PR2/2; // PWM 50%
}
/**************************************************************/
void init_RS232 (void)
{
SPBRG=129; //Fosc = 20MHZ et 2400 bauds
TXSTA=0x20; //sync=0, BRGH=0
RCSTA=0x90;
BAUDCON=0x00; //brg16=0
}
CARTE DE RÉCEPTION :
Le principe d’alimentation de la carte de réception est le même
que celle de la carte d’émission.
On utilise un microcontrôleur PIC18F4520 auquel on
a rajouté un quartz de 4MHz. On programme le pic
avec un PICKIT 3 via le connecteur SIP6 placé au-
dessus du pic sur l’image. On sélectionne le code à
envoyer grâce au codeur 4bits placé sur le DIP8 à
droite de l’image. On a mis des résistances pour
connecter le codeur au microcontrôleur.
On a placé sur les 8 pattes du port D du
microcontrôleur, 8 LEDs correspondantes aux 8
récepteurs.
On utilise un multiplexeur 74LS151 pour balayer tous les signaux
reçus par les TSOP. Les entrées de sélection sont reliées à 3 pattes du
pic. On relie la sortie la patte de réception du pic (RX) et les 8 entrées
sont reliées aux récepteurs infrarouges.
Ce composant est alimenté en 5V.
Nous avons disposé 8 récepteurs infrarouges TSOP1738 qui
captent une fréquence de 38kHz tout autour de la carte. Ils sont
alimentés en 5V.
Lorsqu’on reçoit, le code émit par notre carte émettrice, on
allume la LED placé à côté du récepteur qui reçoit.
void iniPORT (void);
void inivar (void);
void iniRS232 (void);
void tempo (void);
void initimer0(void);
void iniit(void) ;
void _highPriorityInt(void);
void _lowPriorityInt(void);
void test (void);
/*************************************************/
const uns8
tab[16]={0xcc,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
0x0f};
uns8 code, position,axe,posa1,posa2,dir,bernard;
bit mask;
/*****************************************************/
#include "int18XXX.h"
/*************************************************************/
#pragma origin 0x8
interrupt highPriorityIntServer(void)
{
_highPriorityInt();
}
/****************************************************************/
#pragma origin 0x18
interrupt lowPriorityIntServer(void)
{
_lowPriorityInt();
}
/*****************************************************/
void _highPriorityInt(void)
{ int_save_registers
nop();
if (RCIF==1) //si on reçoit quelque chose
{
if (RCREG==code) //si on reçoit le bon code
{
switch (position)
{
case 0 : axe |= 0x01; break; //on met a l'état haut la led qui
correspond
case 1 : axe |= 0x02; break;
case 2 : axe |= 0x04; break;
case 3 : axe |= 0x08; break;
case 4 : axe |= 0x10; break;
case 5 : axe |= 0x20; break;
case 6 : axe |= 0x40; break;
case 7 : axe |= 0x80; break;
default: break;
}
}
RCIF=0; //on remet le flag de la réception à 0
}
if (TMR0IF==1) //si le flag du timer 0 à 1
{
if (mask==0)
{
TMR0H=0xF0; //initialisation du timer0 a 61559.
TMR0L =0x77;
RCIE=0; // dévalide les it de réception
}
else
{
TMR0H=0xC0; //initialisation du timer0 a 49271
TMR0L =0x77;
RCIF=0; //on remet a 0 le flag de la réception
RCIE=1; // revalide les it de la réception
LATA.0=1; //juste pour tester les temps sur une sortie du pic
}
mask=!mask;
if ( position ==8) //si on est à la derniere valeur,
//on place axe sur les ports ou sont
les leds
{ // on remet le compteur à zéro
position=0; // on remet à zéro le code
//et sur les ports RA0...RA3 PUIS
RA4 PUIS RE0..RE2
axe=0; //on recommence du premier récepteur
}
else
{
position ++;
}
LATC=position; //bits de sélection de données
TMR0IF=0; //on remet le flag du timer 0 à 0
}
int_restore_registers // W, STATUS and BSR
}
/************************************************/
void _lowPriorityInt(void)
{
int_save_registers
int_restore_registers // W, STATUS and BSR
}
/***************** MAIN ******************************/
void main (void)
{
uns8 i;
mask=0;
iniPORT();
iniRS232 ();
inivar ();
LATD=0xFF; //à l'alimentation de la carte on allume toutes les leds
tempo ();
LATD=code; // puis on affiche le code
tempo ();
LATD=0; // puis on les éteints toutes
initimer0();
iniit() ;
position=0;
inivar ();
while (1);
}
/****************************************************/
void iniPORT (void)
{
ADCON1=0x0F;
TRISA=0x00;
LATA=0xff;
TRISB=0xff; // rb2 à rb5 cavaliers
LATB=0xFF;
TRISC=0xf0; // rc0= A /rc1= B /rc2= C /rc3=en /rc7= rx
LATC=0xFB;
TRISD=0x00;
LATD=0xFF; // PortD en sortie sur les leds
TRISE=0x00;
LATE=0x07;
}
/****************************************************/
void inivar (void)
{
uns8 A;
A= PORTB; // on récupère le port b dans une variable A
A = A & 0x3C; // Mettre les valeurs des cavaliers à 1, les autres à 0
A = A/4; // Mettre les valeurs des cavaliers en poids faibles
code = A ;
}
/****************************************************/
void tempo (void)
{
uns16 A;
for (A=0;A<50000;A++); //temporisation de environ 100ms
}
/************************************************/
void initimer0(void)
{
TMR0L =0x77;
TMR0H=0x80; // TMR0H=0xfb;
T0CON = 0b10000001;
TMR0IF=0;
}
/*******************************************/
void initimer1(void)
{
TMR1L =0x77;
TMR1H=0xb0;
T1CON = 0b11010001;
TMR1IF=0;
}
/****************************************/
void iniit(void)
{
PEIE=1; //validation de l'interruption du Port C
GIE =1; //validation des interruptions générales
IPEN =0; //validation de la priorité des interruptions
TMR0IE =1;
TMR0IP =1;
TMR0IF=0;
RCIP=1;
RCIE=1;
RCIF=0;
}
/***************************************************/
void iniRS232 (void)
{
TXSTA=0x24;
RCSTA=0x90;
BAUDCON=0;
SPBRG=103;
TXIF=0;
RCIF=0;
}