Nonal le p'tit robal
Compte rendu de développement
- Travail préliminaire
- Cahier des charges
- Solutions envisagées
- Technologies employées
- Aspect électronique
- Bus
- Carte mère
- Carte de commande des moteurs
- Carte de détection infrarouge
- Carte de détection ultrasons
- Aspect mécanique
- Améliorations apportées au chassis
- Supports des capteurs infrarouges
- Supports des capteurs de barrières
- Supports des capteurs ultrasons
- Aspect logiciel
- Concepts de programmation
- Algorithme
- Code source
- Evolution du projet
- Organisation du développement
- Remerciements
Avant de se lancer dans ce projet, il a été nécessaire de réfléchir à certains aspects. Avoir une plateforme matérielle imposée nous à restreint une partie du travail. Restait cependant à analyser le cahier des charges (rappelé ci dessous). Les besoins ont ainsi été définis clairement et plusieurs solutions proposées. Restait alors le choix de la technologie qui nous permettrait de donner vie à tout cet amas d'électronique.
Le concept est une course de robots motorisés (sur roues). Le robot doit donc parcourir une piste à la plus grande vitesse possible afin d'arriver le premier au bout. Cependant, d'autres contraintes apportent du piment à la chose. Tout d'abord, la piste n'est pas droite, elle peut tourner. De plus la piste peut croiser celle du robot adverse, dans ce cas, les robots se doivent de respecter le code de la route et la priorité à droite est de mise. Enfin, afin de symboliser l'atteinte du but, le robot arrivant en fin de course doit faire tomber une barre, tout en évitant absolument que la barre un peu plus loin de l'imite.
Afin d'utiliser les moteurs de façons optimale, il a été décidé de les commander en PWM (Pulse Width Modulation), c'est à dire par la rapport cyclique des signaux qui leur sont envoyés.
Pour le suivi de ligne, le classique émetteur/récepteur infrarouge a été retenu afin de localiser la ligne blanche au sol. Un problème cependant : à grande vitesse, le robot perd trop facilement la ligne de vue. Afin de régler ce prblème, quatre capteurs ont été rajoutés. De cette maniè on peut corriger plus efficacement la trajectoire en fonction de la vitesse à laquelle on sort de la piste, et on peut se permettre d'accélerer (en moyenne) le robot.
La priorité à droite est gérée par des capteurs ultrasons (et de l'émetteur associé). On utilise deux couples E/C afin de détecter la présence d'un objet à droite (pour s'arrêter) et à gauche (afin de redémarrer dès que la voie est libre).
La détection de fin de piste est réalisée à l'aide de simples interrupteurs, munis de barres les rendant plus sensibles. La pression de ces capteurs, combinée avec l'inertie du robot en mouvment, sur la premiè barrière est suffisante pour la faire tomber, sans pour autant enmporter la seconde.
Le cahier des charges et donc parfaitement respecté avec ces diverses solutions.
Plusieurs choix de technologies se proposaient afin de réliser l'assemblage de ces éléments distincts :
- Un aspect modulaire ou plutô compact et tout intégré pour la réalisation.
- Une gestion des évènements/capteurs en logique numérique ou bien encore microprogrammée.
Au final, nous avons retenu l'aspect modulaire, par l'usage d'un bus (5 connecteurs DIN 41612) et la conception d'une carte par fonctionnalité. Pour la gestion d'évènements, une solution à base de PIC (16F877, déjà disponibles à l'IUT) à fait l'objet de nos préférencres. Ces deux choix nous ont permis de bien séparer chaque partie. De plus, ce choix est le plus intéressant en termes de réparation (si une carte tombre en panne, il suffit de ne changer que cette carte) et d'évolution (l'ajout de nouvelles cartes-fonctions est possible et le programme développé pour le PIC est libre et facilement évolutif). Une fois ce choix fait, la décision du type de signaux circulant sur le bus à destination du PIC s'est portée sur du compatible TTL.
Il faut avant tout définir clairement combien de cartes on veut développer et leur(s) fonction(s).
Ayant choisi un aspect modulaire, chaque carte peut être développée à part, une carte par fonction. Il suffit juste d'éviter les courts circuits sur le bus. Ainsi, il a fallu définir sur quelles broches circulaient quels signaux. Il a de plus fallu adapter ce brochage à la carte PIC de l'IUT.
|
Din 41612 A |
Mappage |
PIC |
Din 41612 C |
|
Pin |
Signal |
|
|
Signal |
Pin |
1 |
GND |
GND |
GND |
GND |
1 |
2 |
|
|
|
|
2 |
3 |
|
RB2 |
RB5 |
Niveau US D |
3 |
4 |
|
RB1 |
RB4 |
Niveau US G |
4 |
5 |
|
RB0 |
|
|
5 |
6 |
|
|
|
|
6 |
7 |
Recepteur US D |
|
|
Capteur IR 1 |
7 |
8 |
Emetteur US + |
|
|
Capteur IR 2 |
8 |
9 |
Emetteur US - |
|
|
Capteur IR 3 |
9 |
10 |
Recepteur US G |
|
|
Capteur IR 4 |
10 |
11 |
|
|
|
Capteur IR 5 |
11 |
12 |
|
|
|
Capteur IR 6 |
12 |
13 |
|
|
|
|
13 |
14 |
Moteur D |
|
|
Moteur D |
14 |
15 |
Moteur G |
|
|
Moteur G |
15 |
16 |
+12V Moteurs |
|
|
+12V Moteurs |
16 |
17 |
GND Moteurs |
|
|
GND Moteurs |
17 |
18 |
|
|
|
|
18 |
19 |
Niveau IR 4 |
RD3 |
RD7 |
Jack |
19 |
20 |
Niveau IR 3 |
RD2 |
RD6 |
Barrière |
20 |
21 |
Niveau IR 2 |
RD1 |
RD5 |
Niveau IR 6 |
21 |
22 |
Niveau IR 1 |
RD0 |
RD4 |
Niveau IR 5 |
22 |
23 |
|
RC3 |
RC7 |
|
23 |
24 |
PWM G |
RC2 / CCP1 |
RC6 |
|
24 |
25 |
PWM D |
RC1 / CCP2 |
RC5 |
|
25 |
26 |
|
RC0 |
RC4 |
|
26 |
27 |
|
RA5 |
RA2 |
|
27 |
28 |
|
RA4 |
RA1 |
|
28 |
29 |
|
RA3 |
RA0 |
|
29 |
30 |
+12V |
+12V |
+12V |
+12V |
30 |
31 |
+5V |
|
|
+5V |
31 |
32 |
GND |
GND |
GND |
GND |
32 |
Afin de rationaliser l'ensemble des connections (capteurs, alimentations, moteurs), une carte "mère" a été développée. En plus de centraliser toutes les connections entre le bus et les autres éléments du robot, elle génère aussi le +5V nécessaire à l'alimentation des carte à partir du +12V fourni par les batteries.
La carte mè ne comporte pas réellement de fonction évoluées... En plus de recevoir les connexions, elle ne sert qu'à générer le +5V pour le bus, ainsi qu'à afficher le bon fonctionnement du régulateur à l'aide d'une LED.
Le PIC 16F877 permet de générer des signaux PWM en natif. Cependant ils ne sont pas directement aptes à donner de la puissance à des moteurs. Cette carte prélève donc les signaux PWM en provenance du port C du PIC sur le bus, les amplifie en puissance et les renvoie sur les bus, au niveau de la connection des moteurs. Elle assure aussi un isolement par optocoupleurs
Nota : il a été originellement prévu d'utiliserune alimentation séparée pour le moteurs, afin d'éviter les parasites. Cependant, après essais, le parasitage étant minime, cette idée a été abandonnée. Il reste cependant sur la carte mère la possibilité de réactiver cette fonctionnalité.
Pour la détection infrarouge, des boîtiers intégrant émetteurs et récepteurs ont été choisis. Cette carte consiste juste en 6 comparateurs, qui génèrent des signaux compatibles TTL indiquant (selon une valeur de référence) la position des capteurs (au dessus d'une ligne blanche ou non).
But:
Détecter la ligne.
Solution:
Les capteurs les plus apropriés semblent être les capteurs infrarouges,
sensibles à la réflexion sur une surface proche, et donc capables de
distinguer une surface claire d'une surface foncée.
Le phototransistor en entrée est passant lorsqu'il reçoit le signal
infrarouge localisé émis par la diode IR qui lui est associée.
Un amplificateur opérationnel déclenche sa sortie collecteur ouvert
au dessus d'un certain seuil, en sortie, une résistance et une DEL sur
le 5V de la carte nous permettent de garder une compatibilité TTL et de
disposer d'une signalisation de fonctionnement.
La carte ultrasons comporte un oscillateur (à 40KHz) et 2 comparateurs. Ces derniers "mesurent" le signal récupéré par les récépteur et transmet cette information sur le bus.
But:
Obtenir une détection fiable de l'adversaire lorsqu'il passe devant le robot.
Les capteurs à ultrasons on l'air les mieux appropriés à la tàche, étant donné qu'ils permettent
de faire une détection à distance fiable et directive.
Notre montage sera un détecteur de
distance, la sortie sera active en deça d'une certaine distance, au delà d'un certain seuil. Le circuit est constitué d'un oscillateur commun aux deux émetteurs, et de deux circuits de
traitement du signal en retour, un pour chaque récepteur.
Le circuit est constitué d'un oscillateur commun aux deux émetteurs,et de deux circuits de
traitement du signal en retour, un pour chaque récepteur.
L'oscillateur travaille dans la bande d'ultrasons émise par les émetteurs, centrée sur 40 KHz.
Le signal n'ayant pas à être d'un type particulier, et comme seule sa fréquence importe, elle
même avec une certaine plage de tolérance, nous avons opté pour un oscillateur à portes logiques, peu coûteux mais permettant d'avoir en sortie une puissance convenable pour les émetteurs.
La fréquence se calcule à partir de la période, qui est de 2*R*C en principe, mais qui est
augument&eaucte;e de 10% en pratique.
Avec les valeurs choisies, on a donc une fréquence pouvant aller jusqu'à 45KHz avec les 10 à 20% de tolérance sur la valeur des composants.
Deux portes servent au circuit oscillant, les quatre autres permettent de réaliser un étage de
puissance.
Le montage comporte deux sorties déphasées de 180°.
Cette précaution ne perturbe en rien le montage si chaque capteur est branché sur une sortie, mais permet en cas de
perturbations extérieures et de mauvaise réception, de multiplier l'amplitude du signal par deux
en branchant les deux émetteurs en parallèle sur les deux sorties.
Cette configuration permet en
plus de ne plus avoir de valeur moyenne sur le signal de sortie, ce qui est conseillé par le
constructeur de l'émetteur.
Il est à noter qu'une fois le signal émis par l'émetteur, il se retrouve à être sinusoïdal dans
l'air, alors qu'il était carré au départ.
On dispose donc d'un émeteur faible coût, à fréquence ajustable, et disposant de deux amplitudes
de sortie.
Le signal en retour doit avant tout être amplifié. Mais malgrè la sélectivité des récepteurs, quelques fréquences parasites sont captées.
Pour s'affranchir de leur présence, et éviter de les
amplifier par la suite, on dispose en entrée un filtre passe haut d'odre 1, qui coupe les
fréquences en dessous de 20KHz.
L'amplificateur en sortie se charge de faire une coupure des hautes fréquences (cf. caractéristique gain/bande).
Celui-ci, non inverseur, a un
gain réglable entre 16 et 516, permettant une bonne marge de réglage.
Le signal est ensuite
redressé en simple alternance, pour être ensuite lissé.
Une résistance permet alors au
condensateur de se décharger, étant donné que le montage en aval a une impédance d'entrée très
élevée.
Ce dernier est un ampli-op monté en comparateur, la tension de réfèrence étant variable
de 1,72V à 4,17V.
La sortie de l'AO, de type collecteur ouvert, est racordée au +5V par le biais
d'une résistance et d'une LED, pour nous permettre de disposer d'une compatibilité TTL et d'une visualisation en façade.
La plateforme robotisée imposée n'étant pas totalement opérationnelle, des modifications et des ajouts ont du être faits afin qu'elle satisfasse pleinement nos besoins.
Le robot requière différentes pièces, qui complettent la structure de base du robot pour accueillir les capteurs et les décorations.
La position des capteurs doit être réglable avec une grande marge, facilement et rapidement.
Les capteurs exposés aux chocs doivent être protégés contre toute détérioration.
Certains défauts de conception du chassis ont d'abord été corrigés. Il s'agissait principalement d'un problème d'axe des roues. Ce dernier n'étant pas centré, il produisait un fort frottement avec les roues, les emp&eacirc;chant même de tourner. Une solution peu élégante mais efficace a été de tordre légèrement la pièce de métal sur laquelle venait se poser les roues. Le chassis a par ailleurs été réhaussé afin qu'il frotte moins sur la moquette, et donc qu'il ne ralentisse pas inutilement le robot. Une roue folle a été placée à l'arriè du chassis dans le même but de réduction de frottements.
Il nous faut une position réglable horizontalement sur un même axe et en hauteur.
Les capteurs sont pour celà fixés sur un même rail composé de deux parties symétriques. Celles-ci sont fixées aux deux extrêmités sur la structure en plastique, au plus près des moteurs pour éviter des mouvements correctifs de trop grande amplitude.
La pièce est successivement pré-percée à 1mm, percée à 3mm, ébavurée puis pliée pour être plus rigide et renforcée par la même occasion la coque contre les chocs latéraux.
Les contacteurs servant à détecter les barrières sont placés à l'avant. Ils sont fixés grâce à des équerres. Celle de droite à été conçue afin d'éviter qu'un robot adverse puis, par mégarde, emporter le contacteur. Des lames de bakélite ont été ajoutées afin d'augmenter la sensibilité de chaque capteur (ie: la barrière appuie sur la bakélite qui joue un rôle de levier sur le contacteur).
La lamelle est ralongée d'une tige de bakélite de 8 cm. pour la souder, il a fallu d'abord enlever le verni et péétamer.
Pour fixer ces capteurs, deux équerres sont fixées sur la face avant. Celle de droite comporte une extension pour protéger le capteur en cas de choc avec l'adversaire.
Les pièces sont prépércées, percées, pliées, l'équerre droite voit son extrémité arrondie et coudée.
Hauteur et position angulaire horizontale réglables pour s'adapter au robot adverse.
On profite de la fixation des pieds pour y rajouter la pièce. Le pied est taraudé pour accueillir le nouveau boulon de 3mm.
Chaque capteur (émetteur + récepeur) est soudé sur une plaque de bakélite, elle même fixée sur la pièce dont elle est isolée électriquement.
La pièce est prépercée, percée, fraisée pour créer une lumière sur 4 cm puis pliée.
L'évolution du robot sur la piste s'éfectue en trois phases. Tant que le jack est en place ou qu'il a heurté la barrière, il ne fait rien. Sinon, il doit rouler en suivant la ligne blanche et détecter (au sol) si il est dans un passage où il peut rencontrer un autre robot (ie: où il doit prendre les capteurs ultrason en compte).
La phase intéressante est celle où le robot bouge. La gestion de cette phase se fait dans une boucle. Au cours de cette boucle le logiciel met à jour l'état des capteurs infrarouges, calcule la position de la ligne et, éventuellement prend en compte les récepteurs ultrasons. Une fois toutes ces informations à jour, le rapport cyclique de chaque moteur est défini, puis attribué, juste avant le retour au début de la boucle.
Action getlinepos
(recupere la position de la ligne)
Ve : llp, rlp [pointeurs sur octet]
(left & right line position)
lastls [entier]
(last line state)
Vr : [entier]
(constante indiquant la position de la ligne)
Av : lllp, lrlp [octets]
(last llp & rlp)
Debut
| lllp <- *llp
| lrlp <- *rlp
| *llp <- 0
| *rlp <- 0
|
| Lecture des capteurs,
| Si un capteur est sur une ligne blanche
| | Marquer ce capteur (OU logique)
| | dans l'octet correspondant au cote du capteur
| FinSi
|
| Si on n'a localise la ligne nulle part
| | On decide qu'elle est la ou elle etait juste avant
| FinSi
|
| Si la ligne est a plusieurs endroite
| |ET ce n'est pas que au centre
| | Renvoyer qu'on croise une ligne
| Sinon
| | En fonction de la position de la ligne,
| | Renvoyer la position (constante) adquate
| FinSi
|
| (on ne devrait jamais arriver ici)
| Renvoyer qu'il y a eu une erreur
Fin
Action principale
lvit, rvit [entiers]
(rapport cyclique des moteurs)
linestate, lls [entiers]
(etats actuel et precedent de la ligne)
llp, rlp [octets]
(position actuelle de la ligne)
ishere, washere [octets]
(etats actuel et precedent de la detection de barriere)
usd, usdd [entiers sur 32 bits]
(etats et temporisation pour la detection a droite)
Debut
| Initialiser le PIC
|
| TantQue le jack est en place
| | Ne rien faire
| FinTantQue
|
| TantQue la barriere n'est pas encore tombee (ie: washere=0)
| | lls <- linestate
| | linestate <- getlinepos(&llp, &rlp, lls) (ou est la ligne ?)
| |
| | Selon linestate
| | | Regler la vitesse des moteurs pour corriger
| | | la trajectoire (avec lvit et rvit)
| | |
| | | Cas ligne blanche croisee (cas particulier)
| | | | Si juste avant on en croisait pas une ligne
| | | | |blanche (verification de lls)
| | | | | Si on detectait deja a droite (ie: usd>0)
| | | | | | Arreter de detecter (ie: usd <- 0)
| | | | | Sinon
| | | | | | Commencer la detection (ie: usd <- 1)
| | | | | FinSi
| | | | FinSi
| | | FinCas
| | FinSelon
| |
| | Si on detecte a droite, mais on n'est pas a l'arret (ie: usd>0 ET usdd=0)
| | | Incrementer usd
| | | Si on a atteint le temps limite (ie: usd>USDMAX)
| | | | Arreter de detecter (ie: usd <- 0)
| | | FinSi
| | FinSi
| |
| | Si on detecte A GAUCHE et on etait a l'arret (ie: ddrl>0)
| | | On ne prend plus les ultrasons en compte (ie: usd <- 0, usdd <- 0)
| | SinonSi usd>0 ET on detecte A DROITE
| | |OU on est a l'arret (ie: usdd>0)
| | | Arreter les moteur (avec lvit et rvit)
| | | Incrementer usdd
| | | Si on a atteint le temps limite (ie: usdd>USDDMAX)
| | | | On ne prend plus les ultrasons en compte
| | | FinSi
| | FinSi
| |
| | Si on heurte la barriere ET c'est la premiere fois (ie: ishere=0)
| | | ishere <- 1
| | SinonSi on ne heurte pas la barriere ET on l'a heurtee avant (ie: ishere=1)
| | | washere <- 1
| | FinSi
| |
| | Mettre le moteur gauche a la vitesse lvit
| | Mettre le moteur droit a la vitesse rvit
| FinTantQue
|
| Arreter les moteurs
| TantQue VRAI
| | Ne rien faire
| FinTantQue
Fin
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <16F877.h>
#use delay(clock=4000000)
#fuses XT,NOWDT
/*
* debug flags
*/
#undef DEBUG
#ifndef DEBUG
#define DBGUS
#endif
/*
* suivi de ligne
* 0 normal
* 1 tout bourrin
* 2 3x3
*/
#define FLMODE 1
/*
* timeout de la detection a droite en nombres de cycles
* et aussi du temps d'attente
* 1 cycle (a) = 0.000275s (2.75E-4s)
* nbcycles=t/a avec t = nombre de secondes
* 10s -> 36364
* nota : 40% d'erreur ! mais bon flemme de corriger
*/
#define USDMAX 18182 //~7s
#define USDDMAX 18182 //~7s
/*
* suivi de ligne
* 0 si blanc
* 1 si vert
*/
#define FL PIN_D0
#define ML PIN_D1
#define MML PIN_D2
#define MMR PIN_D3
#define MR PIN_D4
#define FR PIN_D5
//constantes de position de ligne
#define L_O 1
#define L_M 2
#define L_F 4
#define L_ALL L_F+L_M+L_O
#define LINE_OK 0
#define LINE_X 1
#define LINE_GNL 2
#define LINE_GNR 3
#define LINE_OTL 4
#define LINE_OTR 5
#define LINE_ERR 6
/*
* jack pour le demarrage
* 0 si jack en place
* 1 si jack enleve
*/
#define JACK PIN_D7
/*
* detection à droite
* 1 si detection
* 0 si RAS
*/
#define DDRR PIN_B5
#define DDRL PIN_B4
/*
* detection de barriere
* 0 si barriere collisionnee
* 1 si barriere pas collisionnee
*/
#define BARRIERE PIN_D6
//vitesse PWM des moteurs
#define PWM_ADONF 0
#define PWM_STOP 100
#if FLMODE == 0
#define OFFSET 20
#define PWM_STD 50
#define PWM_FST PWM_STD - OFFSET
#define PWM_SLW PWM_STD + OFFSET
#elif FLMODE == 1
#define OFFSET 5
#define PWM_STD 45
#define PWM_SLW PWM_STD + OFFSET
#define PWM_SWR PWM_STD + OFFSET + OFFSET + OFFSET
#define PWM_MIN PWM_STD + OFFSET
#define PWM_FST PWM_STD - OFFSET
#define PWM_FTR PWM_STD - OFFSET - OFFSET - OFFSET
#define PWM_MAX PWM_STD - OFFSET
#elif FLMODE == 2
#define OFFSET 15
#define PWM_STD 40
#define PWM_FST PWM_STD - OFFSET
#define PWM_SLW PWM_STD + OFFSET
#endif
//debug
#define OUTDBG output_a
#define DBG0 PIN_A0
#define DBG1 PIN_A1
#define DBG2 PIN_A2
#define DBG3 PIN_A3
#define DBG4 PIN_B0
#define DBG5 PIN_A5
//fonctions
#define LMOT set_pwm1_duty
#define RMOT set_pwm2_duty
void initpic();
#IF FLMODE == 1
int getlinepos(char * llp, char * rlp, int lastls);
#ENDIF
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "H:\NONAL\nonal.h"
void main()
{
int rvit, lvit;
int linestate=LINE_OK, lls;
char llp=L_O, rlp=L_O;
int ishere=0, washere=0;
int32 usd=0, usdd=0;
initpic();
#ifdef DEBUG
output_high(DBG4);
#endif
while(!input(JACK));
#ifdef DEBUG
output_low(DBG4);
#endif
while(!washere)
{
#if FLMODE == 0
if(!input(MMR) && input(MML))
{
rvit=PWM_SLW;
lvit=PWM_FST;
}
else if(!input(MML) && input(MMR))
{
lvit=PWM_SLW;
rvit=PWM_FST;
}
else
{
lvit=PWM_STD;
rvit=PWM_STD;
}
#elif FLMODE == 1
lls=linestate;
linestate=getlinepos(&llp,&rlp,lls);
#ifdef DEBUG
OUTDBG(0);
#endif
switch(linestate)
{
case LINE_OTL:
#ifdef DEBUG
output_high(DBG3);
#endif
lvit=PWM_SWR;
rvit=PWM_FTR;
break;
case LINE_GNL:
#ifdef DEBUG
output_high(DBG0);
#endif
lvit=PWM_SLW;
rvit=PWM_FST;
break;
case LINE_OK:
#ifdef DEBUG
output_high(DBG1);
#endif
if(llp==L_O && rlp!=L_O)
{
lvit=PWM_SLW;
rvit=PWM_FST;
}
else if(rlp==L_O && llp!=L_O)
{
rvit=PWM_SLW;
lvit=PWM_FST;
}
else
{
lvit=PWM_STD;
rvit=PWM_STD;
}
break;
case LINE_GNR:
#ifdef DEBUG
output_high(DBG2);
#endif
lvit=PWM_FST;
rvit=PWM_SLW;
break;
case LINE_OTR:
#ifdef DEBUG
output_high(DBG5);
#endif
lvit=PWM_FTR;
rvit=PWM_SWR;
break;
case LINE_ERR:
#ifdef DEBUG
output_high(DBG4);
#endif
lvit=rvit=PWM_STD;
break;
case LINE_X:
if(lls!=LINE_X)
{
if (usd) usd=0; //nouvelle ligne et deja une
else usd=1; //nouvelle ligne et pas deja une
}
lvit=rvit=PWM_STD;
}
#elif FLMODE == 2
if((!input(MMR) || !input(MR) || !input(FR)) && (input(MML) || input(ML) || input(FL)))
{
rvit=PWM_SLW;
lvit=PWM_FST;
}
else if((!input(MML) || !input(ML) || !input(FL)) && (input(MMR) || input(MR) || input(FR)))
{
lvit=PWM_SLW;
rvit=PWM_FST;
}
else
lvit=rvit=PWM_STD;
#endif
//detection a droite w/ ultrasons
if(usd && !usdd)
{
usd++;
if(usd>=USDMAX) usd=0;
}
if(usdd && input(DDRL))
usdd=0;
else if(usd && input(DDRR) || usdd)
{
lvit=rvit=PWM_STOP;
usdd++;
if(usdd>=USDDMAX)
usdd=0;
}
#ifdef DBGUS
if(input(DDRL)) output_high(DBG3);
else output_low(DBG3);
if(input(DDRR)) output_high(DBG4);
else output_low(DBG4);
if (linestate==LINE_X) output_high(DBG0);
else output_low(DBG0);
if(usd)
output_high(DBG1);
else
output_low(DBG1);
if(usdd)
output_high(DBG2);
else
output_low(DBG2);
#endif
//barriere
if(input(BARRIERE) && !ishere)
{
ishere=1;
delay_us(10000); //anti rebond
}
else if(!input(BARRIERE) && ishere)
washere=1;
RMOT(rvit);
LMOT(lvit);
}
RMOT(PWM_STOP);
LMOT(PWM_STOP);
while(1);
}
void initpic()
{
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(FALSE);
setup_psp(PSP_DISABLED);
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,99,1);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
set_pwm1_duty(PWM_STOP);
set_pwm2_duty(PWM_STOP);
}
#if FLMODE == 1
int getlinepos(char * llp, char * rlp, int lastls)
{
char lllp, lrlp;
lllp=*llp;
lrlp=*rlp;
*llp=0;
*rlp=0;
if(!input(FL)) *llp += L_F;
if(!input(ML)) *llp += L_M;
if(!input(MML)) *llp += L_O;
if(!input(FR)) *rlp += L_F;
if(!input(MR)) *rlp += L_M;
if(!input(MMR)) *rlp += L_O;
if(*llp==0 && *rlp==0)
{
if(lllp<=L_O && lrlp<=L_O || lastls==LINE_X)
{
*llp=L_O;
*rlp=L_O;
}
else if(lllp>=L_F) *llp=L_F;
else if(lrlp>=L_F) *rlp=L_F;
else if(lllp>=L_M) *llp=L_M;
else if(lrlp>=L_M) *rlp=L_M;
else if(lllp>=L_O) *llp=L_O;
else if(lrlp>=L_O) *rlp=L_O;
}
if((*llp>=L_O && *rlp>L_O) || *llp>L_O && *rlp>=L_O) return LINE_X;
if(*llp==L_F) return LINE_OTL;
if(*rlp==L_F) return LINE_OTR;
if(*llp==L_M) return LINE_GNL;
if(*rlp==L_M) return LINE_GNR;
if(*llp<=L_O || *rlp<=L_O) return LINE_OK;
//never reached
return LINE_ERR;
}
#endif
L'aspect modulaire de la solution envisagée à permis une bonne organisation du travail. De plus chacun de nous s'est penché plus précisément sur un aspect afin de mieux le développer.
Nous tenons à remercier tout particulièrement :
- M. Moulin, sans qui nous n'aurions pas participé à ce concours
- Les techniciens de l'IUT qui ont eu la patience (énorme) de supporter toutes nos questions et d'y répondre
- Alex Hairabian sans qui Nonal n'aurait pas un look aussi kitch !
- Batman qui a encore attérit n'importe où
- Les créateurs d'Ulysse 31, et surtout de Nono le petit robot...
- Les autres, sérieux ou non, que nous aurions oubliés
Garnier Nicolas, Mehani Olivier, Miette François
IUT GEII Marseille III Saint Jér&ocric;me