Nonal le p'tit robal IUT GEII Marseille III Saint Jérôme

Nonal le p'tit robal

Compte rendu de développement

Sommaire

  1. Travail préliminaire
    1. Cahier des charges
    2. Solutions envisagées
    3. Technologies employées
  2. Aspect électronique
    1. Bus
    2. Carte mère
    3. Carte de commande des moteurs
    4. Carte de détection infrarouge
    5. Carte de détection ultrasons
  3. Aspect mécanique
    1. Améliorations apportées au chassis
    2. Supports des capteurs infrarouges
    3. Supports des capteurs de barrières
    4. Supports des capteurs ultrasons
  4. Aspect logiciel
    1. Concepts de programmation
    2. Algorithme
    3. Code source
  5. Evolution du projet
    1. Organisation du développement
    2. Remerciements

I. Travail préliminaire

  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.
Retour au sommaire

1. Cahier des charges

  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.
Retour au sommaire

2. Solutions envisagées

  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.
Retour au sommaire

3. Technologies employées

  Plusieurs choix de technologies se proposaient afin de réliser l'assemblage de ces éléments distincts :
  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.
Retour au sommaire

II. Aspect électronique

Il faut avant tout définir clairement combien de cartes on veut développer et leur(s) fonction(s).
Retour au sommaire

1. Bus

  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.
Retour au sommaire
 * Schéma fonctionnel
Schéma des diverses connexions sur le bus
Retour au sommaire
 * Brochage

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
Retour au sommaire

2. Carte mère

  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.
Retour au sommaire
 * Fonctions
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.
Retour au sommaire
 * Schéma électronique
Circuits de la carte mère
Retour au sommaire

3. Carte de commande des moteurs

  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é.
Retour au sommaire
 * Schéma fonctionnel
Schéma fonctionnel de la commande des moteurs
Retour au sommaire
 * Schéma électronique
Circuits de la commande des moteurs
Retour au sommaire

4. Carte de détection infrarouge

  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.
Retour au sommaire
 * Schéma fonctionnel
Schéma de principe des capteurs de suivi de ligne
Retour au sommaire
 * Schéma électronique
Comparateurs à seuils pour la détection infrarouge
Retour au sommaire

5. Carte de détection ulstrasons

  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.
Retour au sommaire
 * Schéma fonctionnel
Schéma fonctionnel de l'émission/réception ultrasons
Retour au sommaire
 * Schéma électronique
Comparateur à seuil pour la détection à droite
Retour au sommaire

III. Aspect mécanique

Vue d'ensemble des modifications mécaniques   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.
Retour au sommaire

1. Améliorations apportées au chassis

  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.
Retour au sommaire

2. Support des capteurs infrarouges

  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.

Pièce de départ Pièce après découpe

  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.
Retour au sommaire

3. Support des capteurs de barrières

Positionnement des capteurs de barrière   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.

Pièce de départ Pièce après découpe

  Les pièces sont prépércées, percées, pliées, l'équerre droite voit son extrémité arrondie et coudée.
Retour au sommaire

4. Support des capteurs ultrasons

Fixation des capteurs ultrasons   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.

Pièce de départ Pièce après découpe

  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.
Retour au sommaire

IV. Aspect logiciel

Retour au sommaire

1. Concepts de programmation

  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.
Retour au sommaire

2. Algorithme

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
Retour au sommaire

3. Code source

Retour au sommaire
 * nonal.h
/*
 * 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
Retour au sommaire
 * nonal.c
/*
 * 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
Retour au sommaire

V. Evolution du projet

Retour au sommaire

1. Organisation du développement

  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.
Retour au sommaire

2. Remerciements

  Nous tenons à remercier tout particulièrement :
Retour au sommaire

Garnier Nicolas, Mehani Olivier, Miette François
IUT GEII Marseille III Saint Jér&ocric;me