Je vais donc me lancer dans la construction d'un robot à évitement d'obstacles quasi minimal. Il ne sert à priori à rien d'autre qu'à faire des tests et valider des hypothèses. En commençant la construction, je me suis décidé également à le faire le plus petit possible, et devant sa simplicité, je me dis que tant qu'à faire, je peux tenter de lui donner la plus grande autonomie envisageable. Je vais donc maintenant vous décrire ma démarche.
Durant le sujet, les images seront cliquables pour avoir une version haute résolution.
Le robot : R.Damil.
Je vous présente donc R.Damil, mon mini robot. Ses dimensions sont relativement réduites : 70mm de long, 95mm de haut, et 85mm de large. Il est assez léger, puisque sa masse est de 335g, batteries incluses.
La conception est simple: il s'agit d'un robot basique à conduite différentielle, à deux roues motrices, et avec deux roulettes omnidirectionnelles pour la stabilité. Les roues font 65mm de diamètre, et sont entraînées par des servomoteurs à rotation continue basés sur les Futuba S148.
Ce sont d'assez gros servomoteurs, avec 45g pièce. Je les ai assemblés de la façon la plus compacte possible :

Sur la photo, on peut voir que les servomoteurs sont fixés sur des équerres en plastique avec des vis et écrous, et ces équerres sont fixées de la même manière sur une planchette de bois de 5mm d'épaisseur, qui correspond au fond du châssis du robot. Cela suffit à maintenir le tout en place, et le plastique autorise un peu de flexibilité, ce qui permettra plus ou moins d'amortir les vibrations.
Sur la photo, vous pouvez voir un logement à piles AA à coté, pour la référence en taille.
J'ai alors fixé la roulette, une petite d'un demi pouce, en plastique (ce que j'avais sous la main):


J'ai fixé une paroi en bois sur l’arrière du robot, qui me servira à installer le logement des batteries et
le capteur à ultrasons. Cette planchette de bois se visse sur le reste du châssis par 3 vis à bois, par en dessous. J'en profite pour visser le logement à batteries dessus. Voici le résultat :


Il suffit alors de refermer le logement avec son couvercle, sur laquelle j’accroche la mini breadboard avec de l’adhésif double face.
Je connecte alors les câbles :
- Le VCC et le Ground, qui proviennent directement de la batterie. L'alimentation des servomoteurs et du capteur sont directement prises ici;
- L'alimentation du convertisseur analogique-numerique, et la tension de référence sont connectés au VCC;
- La masse du convertisseur analogique-numerique à la masse générale;
- Les fils de contrôle des servos sur les broches numériques 5 et 6 car elles sont PWM;
- Le fil de signal du capteur sur la broche A0 du ATmega.

Il suffit maintenant de passer à la partie programmation du robot.
Le code est simple : si le robot trouve un obstacle tout près, il recule. Entre tout près et près, il tourne. Plus loin que près, il avance. Je ne donne pas de valeur en cm, car j'utilise la valeur brute du capteur sans me préocuper de la distance réelle. J'ai juste essayé quelques valeurs en mettant ma main devant le capteur, et j'en ai choisi deux qui me plaisaient, 300 et 200. Le capteur IR renvoie une valeur d'autant plus faible que l'objet et loin, et en plus l'échelle n'est pas linéaire. Donc je ne m’embête pas à faire des calculs, la valeur brute suffit à savoir si l'obstacle est proche ou non.
Voici le code complet :
#include <Servo.h> Servo s1;//gauche Servo s2;//droite int s1Pin=5; int s2Pin=6; int rangeFinderPin=A0;//broche du capteur d'obstacles à distance void setup() { s1.attach(s1Pin); s2.attach(s2Pin); } void s1Forward() { s1.write(180); } void s1Backward() { s1.write(0); } void s1Stop() { s1.write(90); } void s2Forward() { s2.write(0); } void s2Backward() { s2.write(180); } void s2Stop() { s2.write(90); } void moveForward() { s1Forward(); s2Forward(); } void moveBackward() { s1Backward(); s2Backward(); } void turnLeft() { s1Backward(); s2Forward(); } void turnRight() { s1Forward(); s2Backward(); } void stopMotors() { s1Stop(); s2Stop(); } void motorsTest() { moveForward(); delay(1000); moveBackward(); delay(1000); turnLeft(); delay(1000); turnRight(); delay(1000); stopMotors(); delay(1000); } int readRawDistanceOnce() { return analogRead(rangeFinderPin); } int readAvgRawDistance(int count, int delay1) { int i=0; int sum=0; for(i=0;i<count;i++) { sum=sum+readRawDistanceOnce(); delay(delay1); } return sum/count; } void r1() { int dist=readAvgRawDistance(10, 2); if(dist>250) { moveBackward(); } else if (dist >180) { turnLeft(); } else { moveForward(); } delay(2); } void loop() { r1(); }
A noter que la position neutre du moteur, c'est l'angle 90°. J'ai donc mis les servo à 90 avec le code ci dessus, et j'ai ajusté la petite vis de réglage jusqu'à ce que le servo soit immobile. A ce moment, j'ai pu utiliser la fonction de déplacement r1() dans la boucle principale du robot. Vous noterez que j'ai fait plein de sous-fonctions, car en fait il m'a fallu déterminer quelle valeur correspondait à quel sens. Mais on peut aussi modifier les valeurs saisies pour changer la vitesse du robot dans un sens comme dans l'autre. Cette programmation évite d'avoir à tout modifier si on décide de faire ce genre de modifications.
A partir de là, j'ai pu tester le robot :http://www.youtube.com/watch?v=Y-W6V6ugtqk
Comme vous pouvez le voir, il fonctionne. Ce n'est peut être pas tout à fait parfait, mais ça marche

En pratique, j'ai du rajouter une roulette à l'arrière, car quand le robot tournait, il basculait vers l'arrière. Une autre solution serait une tête de brosse à dents, ainsi le robot ne basculerait pas car les poils résisteraient à la compression, mais cela ne générerait pas beaucoup de frottement, car les poils résisteraient assez peu à la flexion.
Dans le prochain post je détaillerai un peu plus l'électronique, et discuterai de l'autonomie.