blog/content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/index.md
Louis Vallat c70ae62b47
feat: massive overhaul
Signed-off-by: Louis Vallat <contact@louis-vallat.fr>
2024-04-12 17:45:33 +02:00

287 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

+++
title = "Robot timide le robot qui fuit la lumière"
description = "Création d'un robot timide pour un projet scolaire."
date = 2022-05-19
[taxonomies]
tags = ["maker", "fablab", "robotique"]
+++
Création d'un robot timide pour un projet scolaire.
> Article cloné depuis [Eirlab](https://www.eirlab.net/2022/05/19/robot-timide-le-robot-qui-fuit-la-lumiere/)
Dans le cadre de loption Makers proposée en deuxième année à lENSEIRB-MATMECA,
en filière Informatique, un robot timide a vu le jour au sein dEirlab.
Cet article est un guide pour expliquer comment reproduire notre travail, dans
le plus pur esprit Maker.
<!-- more -->
![Une vue de 3/4 face du robot finalisé](images/robot_timide_header.jpg)
## Concept de base
Nous voulions mettre en oeuvre un robot qui détecterait en temps réel la
luminosité autour de lui et ce dans le but de se déplacer vers lendroit le
plus sombre de la pièce dans lequel il se trouve, et de sy cacher. Un autre
mode est aussi disponible, permettant non pas daller vers lendroit le plus
sombre, mais à linverse de fuir lendroit le plus lumineux, pour avoir deux
manières de voir le problème.
![Une vue de face du robot timide dans sa forme finale.](images/robot_timide_enseirb.jpg)
## Du matériel
Avant de pouvoir travailler sur une partie logicielle du projet, il faut
évidemment avoir une base physique pour accueillir et exécuter ce code.
À noter que ce projet na nécessité aucune dépense et a été réalisé entièrement
avec du matériel déjà disponible au sein du Fablab.
### Liste du matériel
Pour pouvoir reproduire ce projet, il vous faudra avoir en votre possession les
éléments suivants :
- 1x Arduino Uno (ou clone équivalent) cest la tête pensante de ce projet
- 1x Arduino Motor Shield pour contrôler les deux moteurs du robot
- 2x moteurs à courant continu, ici des FT DC 130D pour se mouvoir dans lespace
- 3x capteurs de distance à ultrasons HC-SR04 pour éviter de rencontrer des murs trop souvent
- 4x photo résistances une par côté, pour pouvoir détecter la luminosité autour de lui
- 4x résistances de 2kΩ pour le circuit des photo résistances, permettant davoir une amplitude optimale
- 1x pile 9 Volts pour alimenter tout le système
- 1x boîtier pour pile 9 Volts [OPTIONNEL] pour éviter de perdre lunique source dalimentation du robot
### Base du châssis
Le châssis est une plaque en bois, ici du contreplaqué de 5 millimètres
dépaisseur, qui a été usinée à laide de la découpeuse laser du Fablab. Elle
mesure 17×15,5 centimètres, et dispose de deux bords biseautés pour avoir une
vue frontale des obstacles que le robot pourrait rencontrer. Ici, ces biseaux
ont des angles de 20 degrés, sur 4,5 centimètres. La plaque de base est ensuite
percée pour accueillir les différents modules du robot. Les éléments les plus
légers ou risquant moins de se détacher sont fixés par un simple système de
mâchoire, prenant en étau la plaque de bois dans une forme de U.
![La forme de U pour prendre la plaque de base en mâchoire et tenir un capteur par pression.](images/u_shape.jpg)
### Alimentation
Pour lalimentation du robot, on vient envoyer 9 Volts dune source quelconque,
dune pile ou dune alimentation stabilisée par exemple, dans lentrée `VIN`
de lArduino, qui sera après régulée en interne pour donner les différents
rails dalimentation. Cette entrée dalimentation est connectée en interne au
port DC “barrel jack” de lArduino, donc avant les régulateurs de courant,
et prend donc des tensions entre 5 et 9 Volts.
Dans ce projet, nous utilisons une pile 9 Volts rechargeable dans un boîtier
vissé au châssis.
![Une vue de la pile 9 Volts que nous utilisons, rechargeable en micro USB.](images/pile9v.jpg)
### Moteurs
Les moteurs ici sont vissés au châssis, car juste pris en mâchoire ils ne
tiennent pas et se détachent à la moindre accélération.
Ils sont directement alimentés et pilotés via la carte Arduino Motor Shield,
qui permet de sélectionner leur vitesse sur une échelle de `0` à `255`,
dactionner les freins et de leur donner un sens de rotation, et ce très
simplement dans le code.
Des roues ont été imprimées en 3D pour aller sur les embouts des moteurs, et un
joint torique sert de pneu pour améliorer ladhérence du robot et éviter les
démarrage en “burn”.
### PCB
Au début de ce projet, nous avons utilisé une carte de prototypage électronique,
aussi appelé breadboard. Dans un second temps et pour éviter toute déconnexion
de câbles liée à une potentielle accélération violente, nous avons fait un PCB,
soudé manuellement sur une carte de prototypage prévu à cet effet.
![Une vue du dessus de notre PCB fait main.](images/pcb_irl.jpg)
Au niveau électronique, le PCB est routé de la manière suivante :
![Le routage du PCB sur une carte de protypage de type Breadboard.](images/pcb_fritzing.png)
Les différents composants viennent se connecter sur le PCB au moyen de
différentes broches femelles, pour que ce dernier puisse être détaché et modifié
sans devoir dessouder le moindre composant.
## Et du logiciel
Dun point de vue logiciel, notre projet est assez simple. En pseudo-algorithme,
on peut tout simplement le résumer à “on regarde parmi les 4 photo résistances
et on tourne ou avance vers celle ayant la valeur la plus sombre” dans le cas
`followDark` est à `true`. Si au contraire cette valeur est à `false`, alors
il ira dans la direction opposée à la photorésistance ayant la plus haute valeur.
Une mesure des distances en face des trois capteurs à ultrasons permet darrêter
le robot (presque) avant collision frontale, et le robot ne se déplacera pas
tant que lobjet en face est toujours présent, et donc en théorie tant quil a
trouvé lendroit le plus sombre.
```cpp
#define echo1Pin 5
#define trig1Pin 4
#define echo2Pin 7
#define trig2Pin 6
#define echo3Pin 10
#define trig3Pin 2
#define rotMot1Pin 12
#define brakeMot1Pin 9
#define vitMot1Pin 3
#define rotMot2Pin 13
#define brakeMot2Pin 8
#define vitMot2Pin 11
#define photoRes1Pin A2
#define photoRes2Pin A3
#define photoRes3Pin A4
#define photoRes4Pin A5
#define followDark false
long duration;
int distance;
void setup() {
Serial.begin(9600);
pinMode(rotMot1Pin, OUTPUT);
pinMode(brakeMot1Pin, OUTPUT);
pinMode(vitMot1Pin, OUTPUT);
pinMode(rotMot2Pin, OUTPUT);
pinMode(brakeMot2Pin, OUTPUT);
pinMode(vitMot2Pin, OUTPUT);
pinMode(photoRes1Pin, INPUT);
pinMode(photoRes2Pin, INPUT);
pinMode(photoRes3Pin, INPUT);
pinMode(photoRes4Pin, INPUT);
pinMode(trig1Pin, OUTPUT);
pinMode(echo1Pin, INPUT);
pinMode(trig2Pin, OUTPUT);
pinMode(echo2Pin, INPUT);
pinMode(trig3Pin, OUTPUT);
pinMode(echo3Pin, INPUT);
delay(3000);
}
void loop(){
byte echoPins[3] = {echo1Pin,echo2Pin,echo3Pin};
byte trigPins[3] = {trig1Pin,trig2Pin,trig3Pin};
long int durations[3] = {};
long int distances[3] = {};
for(int i = 0; i < 3; i++){
digitalWrite(trigPins[i], LOW);
delayMicroseconds(2);
digitalWrite(trigPins[i], HIGH);
delayMicroseconds(10);
digitalWrite(trigPins[i], LOW);
durations[i] = pulseIn(echoPins[i], HIGH);
distances[i] = durations[i] * 0.034 / 2;
}
int photoRes[4] = {};
Serial.print("Capteur infra : 1[");
photoRes[0] = analogRead(photoRes1Pin);
Serial.print(photoRes[0]);
Serial.print("] 2[");
photoRes[1] = analogRead(photoRes2Pin);
Serial.print(photoRes[1]);
Serial.print("] 3[");
photoRes[2] = analogRead(photoRes3Pin);
Serial.print(photoRes[2]);
Serial.print("] 4[");
photoRes[3] = analogRead(photoRes4Pin);
Serial.print(photoRes[3]);
for(int i = 0; i < 3; i++){
Serial.print("] - distance(cm) : ");
Serial.print(distances[i]);
}
Serial.println();
bool b = false;
for(int i = 0; i < 3; i++){
if (distances[i] < 30) {
b= true;
}
}
int photoResRef = photoRes[0];
bool photoStop = true;
int photoResMinPos = 0;
if (followDark){
int photoResMin = 1024;
for (int i = 0; i < 4; i++){
if (photoResMin > photoRes[i]){
photoResMin = photoRes[i];
photoResMinPos = i;
}
if (abs(photoResRef - photoRes[i]) > 20){
photoStop = false;
}
}
} else{
int photoResMax = 0;
for (int i = 0; i < 4; i++){
if (photoResMax < photoRes[i]){
photoResMax = photoRes[i];
photoResMinPos = (i + 2)%4;
}
if (abs(photoResRef - photoRes[i]) > 20){
photoStop = false;
}
}
}
Serial.println(photoResMinPos);
if (b || photoStop){
digitalWrite(brakeMot1Pin, HIGH);
digitalWrite(brakeMot2Pin, HIGH);
} else {
digitalWrite(brakeMot1Pin, LOW);
digitalWrite(brakeMot2Pin, LOW);
}
if (photoResMinPos == 0){
digitalWrite(rotMot1Pin, LOW);
digitalWrite(rotMot2Pin, LOW);
}
if (photoResMinPos == 1){
digitalWrite(rotMot1Pin, LOW);
digitalWrite(rotMot2Pin, LOW);
}
if (photoResMinPos == 2){
digitalWrite(rotMot1Pin, HIGH);
digitalWrite(rotMot2Pin, HIGH);
}
if (photoResMinPos == 3){
digitalWrite(rotMot1Pin, HIGH);
digitalWrite(rotMot2Pin, LOW);
}
analogWrite(vitMot1Pin, 150);
analogWrite(vitMot2Pin, 150);
}
```
## Remerciements
Merci au Fablab de lENSEIRB-MATMECA, Eirlab, pour nous avoir permis de
travailler sur ce projet et davoir contribué matériellement au projet.
Merci aussi aux différents Fabmanagers qui nous ont aidés tout au long du projet
en répondant à nos questions plus ou moins posées sous lemprise de la fatigue.
À la mémoire de Kaitlin Rooke.