Академический Документы
Профессиональный Документы
Культура Документы
1 sur 9
http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...
Aprs mon robot viteur d'obstacles, je me suis fabriqu un robot suiveur de ligne. Ca ne sert rien mais c'est un classique
amusant faire.
Le principe est simple : un chssis motoris suit une ligne noire. Des dtecteurs observent la position de la ligne et donnent les
ordres de correction correspondants au robot.
31/07/2014 23:08
2 sur 9
http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...
l'Arduino. Les capteurs peuvent tre fixs aux extrmits. Un patin tflon sert de "troisime roue" l'extrmit de l'ensemble.
Les moteurs sont pilots via une carte de commande base sur un pont en H L298 pilote par l'Arduino. C'est un peu un marteau
pour craser une mouche vu que deux transistors auraient aussi bien fait l'affaire.
Ce projet ne devait me prendre qu'une aprs-midi, mon ide tant de coller deux capteurs devant le robot (un de part et d'autre de
la ligne), crire les 10 lignes de code correspondantes (ligne sur le capteur droit : on tourne gauche et vice-versa) et hop!
Mais a s'est rvl un tantinet plus difficile...
Premier essai
Pour ce premier essai, on a deux capteurs l'avant du robot, assez loin des moteurs, et un code simple : on avance vitesse
constante et si la ligne est dtecte on bloque le moteur situ du ct du capteur. a marche... plus ou moins.
Dj, la dmarche du robot est trs hache puisqu'il zigzague en "butant" sur la ligne en permanence. Ensuite, comme les capteurs
sont loin des moteurs, ils font de grandes embardes et perdent rgulirement la ligne. Enfin, le robot a la curieuse manie de
tourner trs bien gauche, mais trs mal droite... Il fallait donc revoir tout a.
Deuxime essai
Pour le deuxime essai, j'ai tout d'abord modifi les capteurs : au lieu de 2, j'en ai 4 en ligne. J'ai tout ralis la main mais a peut
aussi s'acheter tout fait (http://www.alpha-crucis.com/fr/capteurs/341-qtr-8rc-reflectance-sensor-array-3700386709616.html) . De
plus les capteurs sont placs l'arrire du robot, qui devient donc l'avant, bien plus prs des moteurs, rduisant la vitesse de leur
mouvement latral par rapport l'axe davance.
Le comportement du robot est plus "intelligent" : si la ligne est dtecte par un des capteurs centraux (petite erreur), on tourne
doucement en freinant lgrement une roue et en acclrant l'autre. Les petites corrections sont donc bien plus douces. Par contre
si la ligne est dtecte par un des capteurs latraux (grande erreur) on braque en bloquant une roue et en acclrant l'autre. Ca fait
une embarde mais comme un des capteurs centraux passe trs vite sur la ligne, initiant le comportement "petite erreur",
l'embarde est assez vite lisse.
Le robot marche beaucoup mieux! Les lignes droites sont bien mieux ngocies et les tournants ne gnrent plus de perte de la
ligne intempestive... Dans un sens seulement. En effet, tout comme dans la version prcdente, le robot tourne trs bien droite
mais trs mal gauche (c'est invers puisqu'on a retourn le robot).
Aprs moult recherches dans le code, les branchements, les engrenages, j'ai fini par comprendre qu'un des moteurs tait plus
faiblard que l'autre et tournait moins vite avec la mme valeur de PWM. J'ai donc introduit une variable de trim pour galiser leur
vitesse.
Et enfin, j'ai eu un comportement efficace et cohrent dans les deux sens pendant toute une soire!
Et le lendemain matin, patatras... La ligne tait trs mal dtecte et le robot la perdait au premier tournant.
J'ai fini par me rendre l'vidence : moteurs trop bas de gamme, masse (plus de 800g) et donc inertie trop importante, je n'allais
pas m'en sortir avec ce matriel. J'ai donc recommenc.
Version 2
31/07/2014 23:08
3 sur 9
http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...
Le chssis
J'ai tout d'abord chang les moteurs. J'ai opt pour deux servos rotation continue : ce n'est pas cher et a marche trs bien, mme
si a n'atteint pas des vitesses bien grandes.
Exit galement la batterie NiMH, j'alimente dsormais l'ensemble avec un botier contenant 6 piles AA.
Ct chssis, il a bien rduit en taille. J'ai fait au plus simple : les servos sont colls avec du double-face sur une plaque qui
accueille galement le pack de piles sur lequel s'ajoute l'Arduino, le tout fix avec du velcro pour pouvoir tre transport d'un
projet l'autre.
Sur le dos de l'Arduino, un shield maison porte un rgulateur de tension LM317 dlivrant 6 volts pour alimenter les servos ainsi
que leurs deux connecteurs. Le LM317 est connect au pack de piles via une broche. On aurait peut-tre pu utiliser le Vin de
l'Arduino pour l'alimenter mais je n'ai trouv nulle part de renseignement fiable sur l'intensit maximale qui peut y passer, j'ai
donc jou la scurit.
A l'avant, on retrouve le capteur maison inchang avec ses quatre dtecteurs.
Au final la structure est plus simple et surtout plus lgre avec peine 400g, soit la moiti du poids de la version prcdente.
Le comportement
J'ai quelques dtails prs repris le comportement de la premire version.
Si un des capteurs centraux dtecte la ligne, on freine le moteur situ du mme ct pour recentrer. Si un des capteurs latraux voit
la ligne, on bloque compltement la roue pour corriger plus violemment. Petite amlioration, la roue reste bloque jusqu' ce qu'un
des capteurs centraux ait vu la ligne et prenne le relais avec la correction douce. Ainsi on s'assure que la ligne est toujours
recentre.
J'ai galement dot le robot de la capacit ngocier des croisements de ligne. Si les quatre capteurs voient la ligne en mme
temps, c'est qu'on est sur un croisement. Le robot continue alors tout droit jusqu' ce que les deux capteurs extrmes revoient le
blanc, indiquant qu'on est sorti du croisement. Le comportement par dfaut reprend alors son cours.
Comme le montre la vido en tte d'article, a marche merveille. Pour amliorer encore, on pourrait prendre des moteurs plus
rapides et un dtecteur 5 capteurs pour toujours dtecter la position exacte de la ligne.
Le code
La fonction "tourne" accepte deux arguments, la vitesse des moteurs gauche et droite. L'arrt correspond la valeur 90, la vitesse
maximum environ 105 dans un sens (j'ai pris 110 par scurit) et 75 dans l'autre sens. Comme les servos sont tte-bche et pour
simplifier la gestion des valeurs de vitesse dans le reste du code, on "retourne" la valeur envoye au servo droit avec la fonction
map().
#include <Servo.h> // bibliotheque servo
// capteurs
int
int
int
int
droite = 0;
gauche = 0;
ddroite = 0;
ggauche = 0;
31/07/2014 23:08
4 sur 9
http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...
// servos
Servo myservo1;
Servo myservo2;
// vitesses
int avance
= 110; // avance normale
int ralenti = 95; // vitesse pour tourner lentement
int stoppe = 90; // arret
void setup(){
// Serial.begin(9600);
// servo
myservo1.attach(9); // servo droite sur le pin 9
myservo2.attach(10); // servo gauche sur le pin 10
myservo1.write(stoppe); // on arrete les servos
myservo2.write(stoppe);
delay(5000); // petit dlai avant dmarrage
}
void loop(){
lecture();
while ((gauche <=seuil && droite <= seuil && ddroite <= seuil && ggauche <= seuil)){
// si tout est ok on avance
tourne(avance,avance);
lecture();
}
if(gauche >= seuil && droite >= seuil && ddroite >= seuil && ggauche >= seuil){ //
croisement
while (ddroite >= seuil || ggauche >= seuil){ // on attend que les capteurs
extremes soient nouveau dans le blanc
tourne(avance,avance);
lecture();
}
}
if (ggauche > seuil){ // si capteur extreme gauche on tourne a fond jusqu' ce que le
capteur central gauche ait rcupr la ligne
while (gauche < seuil) {
tourne(stoppe,avance);
gauche = analogRead(capteurGauche);
}
}
if (ddroite > seuil){ // // si capteur extreme droit on tourne a fond jusqu' ce que
le capteur central droit ait rcupr la ligne
while (droite < seuil) {
tourne(avance,stoppe);
droite = analogRead(capteurDroite);
}
}
if (gauche > seuil && ggauche <= seuil && ddroite <= seuil){ // si le capteur centre
gauche et lui seul voit la ligne on tourne doucement
tourne(ralenti,avance);
31/07/2014 23:08
5 sur 9
http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...
}
if(droite > seuil && ggauche <= seuil && ddroite <= seuil){ // si capteur centre droit
on tourne doucement
tourne(avance,ralenti);
}
}
void tourne(int vitesseGauche, int vitesseDroite) { // on transmet la vitesse de
rotation aux servos
vitesseDroite=map(vitesseDroite,180,0,0,180); // on inverse le sens de rotation du
servo droit
myservo1.write(vitesseDroite);
myservo2.write(vitesseGauche);
// Serial.print(vitesseGauche);
// Serial.print("\t");
// Serial.println(vitesseDroite);
}
void lecture(){ // on lit les capteurs
ggauche = analogRead(capteurGGauche);
droite = analogRead(capteurDroite);
gauche = analogRead(capteurGauche);
ddroite = analogRead(capteurDDroite);
}
8 ractions
1 De alex - 03/04/2012, 09:47
bonjour,
j'aimerais refaire le robot suiveur de ligne avec arduino mais je bloque sur la PWM, pourriez-vous me montrer votre
premier code avec la PWM, s'il vous plait ?
merci
dans l'attente de votre rponse
cordialement
2 De Vincent Becker - 03/04/2012, 20:04
Bonjour,
Voici le code pour la version PWM. Les moteurs sont commands par un module avec un pont en H qui utilise deux pins
par moteur : un en HIGH ou LOW (digitalWrite) pour le sens de rotation, et un en analogique (analogWrite) pour la vitesse
avec une valeur comprise entre 0 (stop) et 255 ( fond).
Comme mes moteurs taient de trs mauvaise qualit, j'ai introduit un trim appliqu aux valeurs envoyes la fonction
tourne() pour en acclrer un par rapport l'autre.
La fonction hardstop met les moteurs en marche arrire pendant 5ms pour arrter net et viter que le robot parte sur son
inertie.
Enfin, la fonction lancement() met brivement les moteurs fond en marche avant pour les faire dcoller aprs un arrt,
sinon il leur arrivait de se bloquer si on leur envoyait une vitesse lente.
Bref tout ceci s'est rsolu avec les servos rotation libre. Mais si vous avez de bons moteurs, le PWM peut tre trs
efficace.
// capteurs
int capteurDDroite = A2; //analog pin 0
int capteurDroite = A3; //analog pin 0
int capteurGauche = A4; //analog pin 1
int capteurGGauche = A5; //analog pin 1
31/07/2014 23:08
http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...
6 sur 9
31/07/2014 23:08
7 sur 9
http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...
// hardstop(PoMG,moteurGauche);
tourne(0,accelere);
// ggauche = analogRead(capteurGGauche);
stoppe = 1;
}
if (ddroite > seuil){ // si capteur extreme droit on tourne a fond
// hardstop(PoMD,moteurDroite);
tourne((accelere+trim),0);
// ddroite = analogRead(capteurDDroite);
stoppe = 1;
}
if (gauche > seuil && ggauche <= seuil && ddroite <= seuil){ // si capteur centre gauche on tourne doucement pondr
par rapport aux capteurs extremes
lancement();
tourne((ralenti+trim),accelere);
// gauche = analogRead(capteurGauche);
// Serial.println("Droite");
// droite = analogRead(capteurDroite);
}
if(droite > seuil && ggauche <= seuil && ddroite <= seuil){ // si capteur gauche on tourne doucement
lancement();
tourne((accelere+trim),ralenti);
// droite = analogRead(capteurDroite);
// Serial.println("Gauche");
// gauche = analogRead(capteurGauche);
}
hardstopped = 0;
}
void lancement() {
if (stoppe == 1){
analogWrite(moteurDroite, demarrage);
analogWrite(moteurGauche, demarrage);
stoppe=0;
delay (5);
}
}
void hardstop(int polarite,int moteur){
if (!hardstopped){
digitalWrite(polarite, LOW) ; // On met les moteurs en marche arrire
analogWrite(moteur, demarrage);
delay (5);
digitalWrite(polarite, HIGH) ;
hardstopped = 1;
}
}
void tourne(int vitesseGauche, int vitesseDroite){
analogWrite(moteurDroite, vitesseDroite);
analogWrite(moteurGauche, vitesseGauche);
}
void lecture(){
ggauche = analogRead(capteurGGauche);
droite = analogRead(capteurDroite); // on lit les capteurs
gauche = analogRead(capteurGauche);
ddroite = analogRead(capteurDDroite);
}
3 De alex - 05/04/2012, 17:21
31/07/2014 23:08
http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...
8 sur 9
31/07/2014 23:08
9 sur 9
http://www.bricobidules.com/index.php?post/2012/02/21/Un-suiveur-d...
Haut de page
Accueil Billets rcents
Archives
Google+
YouTube
Propuls par Dotclear
31/07/2014 23:08