Robots pompiers
Sommaire
- 1 Présentation
- 2 Décomposition initiale du travail
- 3 Prise en main des plateformes
- 4 Programmation carte Raspberry Pi 3
- 5 Interface Web
- 6 Choix des capteurs
- 7 Code informatique
- 8 Notes tableaux J101
Présentation
Objectifs pédagogiques
Les objectifs pédagogiques de l'option Robotique sont les suivantes :
- découvrir la robotique en s'appuyant sur une démarche pratique et concrète ;
- savoir mettre en œuvre des capteurs analogiques et numériques ;
- acquérir des notions sur la commande des moteurs et leur asservissement ;
- maîtriser les spécificités des interfaces de puissance à base de commutation (hacheurs, pont en H) ;
- prendre conscience des difficultés pratiques et technologiques de mise en œuvre de robots ;
- mettre en œuvre une démarche de reverse-engineering pour la prise en main du matériel ;
- savoir programmer des scénarios de comportement prenant en compte l’environnement ;
- bonne pratique de programmation C ou Python : commentaires, noms intelligibles de variables ou fonctions, utilisation d'un dépôt Git...
- méthodologie de gestion de projet, en groupe : gestion des ressources, gestion du temps, plan de tests...
- s’initier à une démarche de Design Thinking pour la conception de projet.
Modalités d'évaluation
Les modalités d'évaluation du module seront :
- avancée du projet : intérêt porté au projet, travail pendant et en dehors des séances, efficacité du travail en groupe, utilisation des outils demandés...
- utilisation des outils et notamment mise à jour du Wiki ;
- présentation + démonstration technique finale du projet ;
- examen écrit (QCM, sans document) - jeudi 12 mai ;
Outils à utiliser
- wiki : explication et documentation du projet ;
- projet GitLab (serveur de TSE) : sauvegarde et suivi de version des différents code ;
- ToDoList avec les missions de chaque étudiant, au fur et à mesure des séances ;
Missions des robots pompiers
Les robots pompiers devront réaliser les actions suivantes :
- départ de la base du robot 1 ;
- exploration de l'environnement en évitant les obstacles ;
- évaluation des paramètres environnementaux : taux de CO2, température, rayonnement UV...
- si détection de paramètres anormaux, communication vers les robots 2 et 3 ;
- cheminement des robots 2 et 3 jusqu'au point de sinistre, à partir des informations fournies par le robot 1 ;
En fonction de l'avancée du projet, d'autres types d'action pourront être ajoutés.
Décomposition initiale du travail
Première partie :
- S'approprier les plateformes (Maître et Esclaves) : batteries, test moteurs, communication UART entre PC et Teensy
- Programmation Raspberry + Caméra
- Définir précisément quels capteurs utiliser (en fonction du matériel mis à disposition)
Prise en main des plateformes
Alimentation
- Le robot maître :
- Il possède un convertisseur de tension 9-18 à 5VDC. Il s'alimente à l'aide d'une batterie de 9.6V composée de 8 cellules Ni-Mh, la tension maximale est d'environ 10.7V.
- Les moteurs fonctionnent jusqu'à un maximum de 7.2V, ils consomment chacun à 0.5A en fonctionnement à vide et jusqu'à 1.3A en fonctionnement nominal (à un couple de 2 kgf-cm) : Documentation du moteur
- Les robots esclaves ont deux sources d'alimentation :
- La partie logique est alimentée par une pile 9V au travers d'une carte TRACO POWER (4.5-9V -> 3.3V). Celle-ci alimente la carte Teensy et la carte Sparkfun ESP32 Thing.
- La partie puissance est alimentée par un ensemble de 8 piles Ni-Mh, qui délivre 9.6V. Elle est connectée au PCB à l'aide du connecteur d'alimentation situé dans l'angle inférieur gauche.
- Les deux parties sont séparées sur le PCB à l'aide du cavalier placé du côté du coté du connecteur d'alimentation.
Programmation des cartes
- ESP32 :
- - Ajouter le support de la carte dans l'IDE Arduino en insérant ce lien dans Fichier → Préférences → URL de gestionnaire de carte supplémentaire : https://dl.espressif.com/dl/package_esp32_index.json
- - Dans Outils → Type de carte → Gestionnaire de cartes, rechercher et installer ESP32
- - Dans Outils → Type de carte sélectionner la carte ESP32
- Teensy :
- - Installer le support de la carte dans l'IDE Arduino via ce lien
Déplacement du robot
- Pour gérer le déplacement via le terminal on a utilisé le code pour une plateforme holonome 4 moteurs.
- Procédure de test de la chaine d'alimentation, contrôle et asservissement des moteurs:
- Téléverser ce code fourni sur la carte Teensy. La pleine vitesse citée plus tard est définie par paramVitesse dans les paramètres globaux en début de code.
- Téléverser un programme vide dans l'ESP32
- Connecter la broche Rx de la Teensy sur le pin Tx de l'ESP32, inversement pour Tx. En effet, les deux cartes sont branchées en parallèle, la carte ESP32 étant logiquement transparente, elle nous permet simplement d'envoyer des commandes série sur la Teensy
- Connecter un PC à la carte ESP32 via le port micro USB
- Ouvrir une console série (par exemple la série arduino) sur le port concerné et tester les moteurs avec les commandes suivantes :
- -
av1pour démarrer le moteur 1 à pleine vitesse, (resp. av2, ...) - -
am1pour démarrer le moteur 1 à demi vitesse, (resp. am2, ...) - -
stpour stopper tous les moteurs
- -
- Tester les mouvements entiers :
- Robot 4 moteurs :
- -
avdpour déplacer le robot en avant à pleine vitesse - -
ardpour déplacer le robot en arrière à pleine vitesse - -
drpour déplacer le robot sur la gauche à pleine vitesse - -
gapour déplacer le robot sur la droite à pleine vitesse - -
rdpour faire tourner le robot sur lui même dans le sens anti-trigo (à droite) - -
rgpour faire tourner le robot sur lui même dans le sens trigo (à gauche) - -
stpour stopper le robot
- Robot 3 moteurs :
- -
ahXXXpour définir la direction XXX (en degrés) de déplacement du robot - -
ho3pour avancer dans la direction définie précédemment
Dans notre cas, le pont en H n°3 sur le robot "3 moteurs" ne fonctionnait pas. Le pont en H n°4 étant libre, il a été utilisé en remplacement. De plus, afin d'avoir la même configuration sur les deux robots "3 moteurs", le pont en H n°4 a été utilisé pour le moteur 3 sur les deux robots.
Le code précédent a ensuite été modifié pour répondre aux attentes du projet.
Odométrie
Pour connaître la position du robot, on utilise deux informations couplées : calcul de la position depuis les codeurs incrément aux des moteurs et en parallèle un accéléromètre contenu dans la centrale inertielle.
Pour connaître la position angulaire du robot, on utilise deux informations couplées : le magnétomètre et en parallèle un gyromètre, tous deux contenus dans la centrale inertielle.
Utilisation d'une centrale à inertie pour le calcul du déplacement effectué par le robot maître : MPU9250 10dof. Cette centrale à inertie est composée d'un gyromètre, d'un accéléromètre et d'un magnétomètre. La communication se fait via un bus I²C.
Robot maître
Capteurs incrémentaux
La documentation pour les capteurs des moteurs du robot maitre étant absente, nous avons mesuré le nombre d'incrémentations pour un tour de roue : 710 (noté NbFTrans).
Avec le périmètre de la roue qui est de 18.5cm, nous pouvons ainsi calculer la distance parcourue en fonction de la vitesse de rotation => ici la position des roues en fonction de la position initiale.
translation2 = Perim * posM2 / NbFTrans ;
Ce code correspond au déplacement réalisé par la roue 2. Nous faisons une moyenne avec celle-ci et la roue 3.
Couplage des données
L'utilisation d'une centrale à inertie pour coupler les données d'odométrie s'est avérée être impossible sur le robot maitre. En effet les pins réservés pour la communication I2C sont respectivement le 18 et 19 et le 29 et 30. Le pin 18 est utilisé pour le capteur incrémental du moteur, et un des pins de l'autre I2C est utilisé par un des ponts en H.
Nous n'avons donc pas pu coupler les données d'odométrie sur le robot maitre, cela résulte dans une imprécision principalement lorsque le robot avance il dévie légèrement. Cela est corrigeable à l'aide de la caméra. Dans l'idéal, nous aurions pu utiliser une approche similaire aux robots esclaves pour avoir une odométrie fiable.
Odométrie
Pour connaître la position estimée du robot, on utilise les capteurs incrémentaux.
- Distance
- Pour l'estimation de la distance parcourue par le robot, nous avons mesuré le temps nécessaire pour 1 tour de roue. On a multiplié cette information par la fréquence d'incrémentation des capteurs. Nous avons mesuré cette information à l'oscilloscope. La fréquence varie en fonction de la vitesse des moteurs. Dons notre cas si on applique la formule suivante :
Temps pour 1 tour de roue * fréquence du signal émis par le capteur = Nombre de fronts nécessaire pour 1 tour de roue
on a 0.78 sec * 910 Hz = 709.8 Nombre de fronts.
- Rotation
- On utilise le même procédé pour estimer un angle. On mesure le temps nécessaire pour que le robot réalise 1 tour complet sur lui même, puis on multiplie cette information par la fréquence d'incrémentation des capteurs. Dans notre cas elle est identique que précédemment car la vitesse de rotation des roues est la même que pour estimer la distance. Dons notre cas si on applique la formule suivante :
Temps pour 1 tour du robot sur lui même * fréquence du signal émis par le capteur = Nombre de fronts nécessaire pour 1 tour de roue
on a 2.25 sec * 910 Hz = 20470.5 =Nombre de fronts.
Voici le code complet pour le pilotage du robot avec les fonction d'odométries incluses.
La fonction odometrieApprox utilise les données énoncées précédemment et réalise un produit en croix pour estimer une translation et une rotation.
Tests
Plusieurs tests expérimentaux ont été effectués afin de déterminer la précision de notre odométrie et la pertinence de la mesure obtenu en sortie.
Dans un premier temps pour la mesure en translation nous avons fait se déplacer le robot maître le long d'une ligne dont la longueur était connue ( ici 2m).
Nous avons effectués 5 mesures pour un trajet théorique de 2 mètres.
Résultats (en cm) : 189, 190, 192, 200, 204 => ce qui nous donne une moyenne de 195 cm ce qui semble assez convenable.
Puis pour les mesures de rotation nous avons marquer la position zéro d'une roue et ensuite mesurer à l'aide d'un rapporteur l'angle de rotation réel du robot. Nous avons pris 2 mesures d'angle pour chaque commande d'angle, c'est à dire un demi-tour, 30° à gauche (sens trigonométrique) , 330° à gauche (équivalent à 30° à droite).
Résultats :
Pour 180° => 159°, 160°
Pour 30° => 38°, 44°
Pour 330° => 334°, 325°
Problèmes rencontrés : Le robot ne se déplaçait pas de façon parfaitement droite en translation, il déviait légèrement vers la gauche. On suppose alors que toutes les roues ne tournent pas à la même vitesse malgré qu'elles soient toutes alimentées de la même manière. De plus il faut noter que par moment les roues ont tendance à patiner et elles ne s'arrêtent pas nettement lors d'un stop, il y a un temps d'arrêt des moteurs.
Tout cela influence les mesures effectuées et rend difficile de connaître avec précision la distance réellement parcourue par le robot.
Robots esclaves
Position Absolue
Différentes erreurs peuvent entacher la précision de l'odométrie. Elles peuvent venir du robot lui-même (erreur systématiques), comme par exemple une erreur sur le diamètre des roues ou encore une erreur provenant des codeurs. Les erreurs peuvent aussi provenir de l'environnement dans lequel le robot évolue (erreurs non systématiques). On retrouve notamment comme source d'erreur, un sol qui n'est pas plat ou qui est irrégulier, le glissement des roues, ou encore un obstacle. c'est pourquoi il faut mettre en place une fusion de données pour obtenir des résultats plus fiables. Pour cela, on décide de fusionner la valeur de la vitesse obtenue grâce à l'accéléromètre avec celle obtenue par les codeurs des moteurs. On se base ici sur la vitesse car une double intégration de l'accélération pour obtenir une position aurait apporté trop d'erreurs à notre résultat. Différentes méthodes existent pour réaliser une fusion de données, comme le filtre de kalman ou le filtre complémentaire. Dans notre cas, nous utiliserons un filtre complémentaire car le filtre de kalman est plus complexe à réaliser dans le temps imparti bien qu'il soit plus performant.
- filtre complémentaire
En entrée on retrouve l'accélération en x et la vitesse de rotation d'un des moteurs du robot. On intègre l'accélération pour avoir une vitesse et on exprime la vitesse du codeur en m/s pour avoir des unités homogènes.
Ensuite, on filtre passe bas la vitesse issue de l'accéléromètre car celui-ci est plus précis en basse fréquence. Pour le codeur, on filtre la donnée en passe haut car il est plus sensible en haute fréquence.
On obtient donc l'équation de la vitesse suivante :
Pour déterminer la vitesse du robot à partir d'un seul codeur, la meilleur solution est de réaliser différentes mesures de la rapidité du robot sur une distance donnée. Le but est d'en déduire une équation ne dépendant que d'un coefficient que l'on multiplie à la vitesse de rotation en m/s d'un des moteurs. Pour cela, nous avons réalisé 10 mesures pour lesquelles nous avons relevé le temps mis par le robot pour traverser 2m et la vitesse d'un des codeurs. Grâce au temps mesuré, en peut calculer la vitesse moyenne du robot ainsi que la médiane en m/s pour les 10 mesures. On obtient une médiane de 0.4122 m/s. En divisant ce résultat par la vitesse du moteur on obtient le coefficient directeur.
La vitesse du robot a donc pour expression :
Cela nous permet donc d'obtenir une valeur de la vitesse cohérente avec la structure du robot. Celui-ci étant triangulaire, il n'est pas possible de ne prendre en compte que la vitesse d'un moteur car ils ne sont pas parallèles.
- tests
Maintenant la fonction de vitesse trouvée, on l'implémente dans le code d'asservissement des moteurs (sur la carte teensy). En faisant rouler le robot, on s'est aperçu que la valeur de la vitesse calculée divergeait.
Testons maintenant la sortie des deux filtres indépendamment.
Pour le codeur, la sortie est stable et constante. En revanche, la vitesse issue du filtre de l'accéléromètre est fortement bruitée et les valeurs sont aléatoires. Cela provient des fortes vibrations provoquées par les roues suédoises du robot. Cette données est donc inexploitable et rend la fusion de données inutilisables dans ce cas.
Nous avons donc été contraint d'abandonner le filtre complémentaire pour l'odométrie car la structure du robot ne nous permettait pas d'utiliser l'accéléromètre à cause des fortes vibrations du robot. Nous n'utilisons donc que la position issue du codeur d'un des moteurs.
Nous nous baserons pour la suite sur la position des codeurs pour calculer la distance parcourue par le robot.
- asservissement en position
Pour déterminer le nombre d'incréments que le codeur doit compter sur une distance donnée, nous cherchons une relation entre la distance à parcourir et un coefficient fixe. Pour cela, résonnons expérimentalement. Il faut dans un premier temps récupérer le nombre d'incréments que le codeur détecte sur une distance fixe (5 m). On réalise cette expérience n fois. On calcul ensuite le nombre d'incréments sur 1 cm puis on en déduit la moyenne avec toutes les valeurs issues de l'expérimentation. Cela nous permet d'obtenir la relation suivante :
Nombre d'incréments à parcourir = 18.7096*distance à parcourir(cm)
On obtient l'asservissement en boucle fermé suivant :
Position Angulaire
Afin de connaître avec précision la position angulaire, on utilise les données de deux capteur de la centrale inertielle. Le magnétomètre nous indique la position du nord en mesurant l'intensité du champs magnétique terrestre. Tandis que le gyromètre nous indique la vitesse de déplacement du robot autour de ses axes. Il faudra ensuite intégrer cette vitesse pour en déduire une position. Testons donc la sortie des deux filtres.
Afin de déduire la position du robot par rapport à un point fixe (le nord), on réalise l'arc-tangente des composantes X et Y du magnétomètre. On prends en compte les cas au delà de +/-90° et aussi dans le cas de la division par 0. Le but est d'avoir une valeur comprise entre ]-180°;180°].
Après avoir implémenté la lecture de la position du magnétomètre à l'arrêt, une étude du bruit a été réalisé afin d'analyser le bruit généré par le capteur qui peut potentiellement atteindre la valeur finale (après le filtre complémentaire (passe-bas pour le magnétomètre)).
L'étude a été réalisé avec une fréquence d'échantillonnage de 50hz. Voici les valeurs récupérées :
- moy = 88.6552°
- ecart_type = 0.4730°
Il semble s'agir d'un bruit blanc gaussien puisque l'autocovariance est nulle partout sauf en 0. On ne peut donc pas réellement agir pour contrer le bruit. Il faudra donc prendre en compte l'impact du bruit et notamment son écart-type autour de la moyenne lors de la lecture de la position.
Afin de combiner les deux données, un filtre complémentaire sera utilisé. En effet, le magnétomètre est plus précis en basse fréquence tandis que le gyromètre est plus précis en hautes-fréquences. De plus le filtre passe-haut, permettra de supprimer l'erreur continue qui peut apparaître suite à l'intégration.
On s'appuie sur le schéma suivant :
Après avoir fait la transformée en Z, on obtient :
La constante de temps Tau a été choisie après plusieurs expérimentations. Elle a été fixé à 15*Te.
Néanmoins, un problème apparaît. En effet, la combinaison des deux données utilise un filtre récursif RII. On utilise donc la valeur précédente de l'échantillon pour faire le calcul de la valeur suivante. Néanmoins lorsque le robot passe de +180° à -179°, la valeur obtenue repasse par 0° à cause de la valeur précédente de l'angle qui était positive et qui s'ajoute à une valeur négative.
La solution adoptée a été de faire varier l'angle uniquement entre -90° et +90° et d'appliquer le filtre complémentaire dessus. On peut ensuite déduire la portion dans laquelle on se situe à l'aide du signe du magnétomètre selon X. Cette idée est illustrée ci-dessous :
Il faut néanmoins aussi inverser le sens de l'angle sorti par le gyromètre lorsque la composante selon X est négative sinon le gyromètre vient ralentir encore plus le système (en ajoutant un angle dans le sens opposé au mouvement).
Après avoir notre angle, on fait une distinction entre les différents cas pour assigner de nouveau une valeur entre +180° et -180°.
Asservissement de la position angulaire
Un asservissement de la position angulaire a été implémenté afin de permettre au robot de tourner de manière précise et également afin de corriger la déviation du robot lorsque celui-ci cherche à rouler droit en faisant tourner ses roues à la même vitesse.
Voici la boucle d'asservissement :
On assimile le système des moteurs à un premier ordre puisque c'est généralement le cas des moteurs. L'asservissement en vitesse réalisé par les années précédentes est un proportionnel simple qui ne change pas l'ordre du système et on le réutilise. On rajoute un asservissement proportionnel pour la position angulaire. Tout cela (mesure odométrie + asservissement) est réalisé sur la teensy directement puisque le connecteur I²C est présent et cela facilite l'intégration de l'asservissement.
Le robot suit donc bien la position de commande. Il est à noter que la valeur reste entre +/-180°, c'est pour cela qu'à 180° en commande, la valeur semble osciller beaucoup alors qu'en réalité, la valeur est stable. Une marge a aussi été introduite, ainsi lorsque la position du robot est à +/- 3° de marge, l'accélération du robot est coupée afin de ne pas accélérer sur des données liées au bruit.
Programmation carte Raspberry Pi 3
Installation d'un système d'exploitation
- Téléchargement de l’image sur le site de Raspbian
- Utilisation de Balena Etcher pour flasher l’image sur la carte SD
On aurait aussi pu passer par l'utilitaire Raspberry Pi Imager, qui se charge de télécharger automatiquement l'OS et de flasher la carte SD.
- Premier boot du Raspberry Pi : configuration initiale
Utilisation de la caméra
- Si la liaison de la Raspberry avec un écran en HDMI ne se fait pas, il faut modifier le fichier config.txt (hdmi_group et hdmi_mode) de la carte micro SD de la Raspberry, pour forcer l'envoi sur le port HDMI même si rien n'est détecté à l'autre bout du câble.
- Mettre à jour le système et activer la caméra avec le menu "Configuration du Raspberry Pi"
- Dans le terminal, lancer
sudo raspi-configet activer la caméra dans le menu Interfaces. Redémarrer ensuite la Raspberry. - Premiers tests en local avec :
raspistill -o photo.jpg(enregistrement d’une photo avec retardateur de 5sec), puisraspivid -o video.h264vidéo) - Premier stream avec :
raspivid -o - -t 0 -w 800 -h 600 -fps 12 | cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8080/}' :demux=h264sur Raspberry, et avec VLC sur PC : menu Ouvrir un flux réseau, y mettre :rtsp://@IPpi:8080/ - Installation de Mjpg-Streamer :
cd ~ sudo apt-get install libjpeg9-dev git clone https://github.com/jacksonliam/mjpg-streamer.git sudo apt-get install cmake CFLAGS+="-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s" make sudo make install cd ~/mjpg-streamer/mjpg-streamer-experimental./mjpg_streamer -i "./input_uvc.so -f 15" -o "./output_http.so -w ./www"
- Lancement du serveur Mjpg Streamer sur le port 8080
cd ~/mjpg-streamer/mjpg-streamer-experimental ./mjpg_streamer -i "./input_uvc.so -f 15" -o "./output_http.so -w ./www"
Utilisation du port série
Il est nécessaire d'activer et d'accorder les droits d'accès au port série :
raspi-config > Interface options > Serial Port > Enable sudo chmod 666 /dev/ttyS0
Choix de l'environnement serveur
Pour la gestion back sur le Raspberry, nous avons d'abord pensé utiliser un programme C++ proche du matériel et de la série. Cependant, la gestion web était alors largement compliquée. Nous avons retenu d'utilisation d'un serveur node.js pour servir la page web et transmettre les commandes d'avancement comme les remontées d'alertes.
Interface Web
Principe de fonctionnement
Afin de télépiloter le robot maître, nous utilisons une interface homme-machine via une page web. Le serveur et le client communiquent à l’aide d’une connexion socket.
Le flux vidéo est fourni par un serveur mjpg streamer, indépendant du serveur NodeJS.
Front
La page web servie est en HTML, et contient un script JS. D’une part, le retour caméra est incrusté à l’aide de la simple ligne suivante :
<img width="320" height="240" src="http://192.168.246.107:8080/?action=stream">
Au clic d’un bouton, il émet un évènement sur le socket. S'il reçoit un message d'alerte sur le socket, il modifie en conséquence la couleur de l'alerte correspondante
Back
Le serveur web est en NodeJS. Outre servir la page web aux clients qui se connecte, il reçoit les évènements par le socket ouvert avec chacun d’eux. Il les transmet sur le port série. Lorsqu'il commence à recevoir des données d'alerte sur le port série, il envoie un message pour afficher l'alerte sur le client.
Dans les deux cas, des timers sont déclenchés pour stopper le robot ou le déclanchement des alertes en cas de déconnexion WiFi.
Nous avons utilisé la bibliothèque NodeJS SerialPort pour la gestion des entrées/sorties sur le port série.
sudo apt install nodejs
Installation du serveur
Dans un terminal du Raspberry, exécuter à l’emplacement des fichiers du serveur :
npm i
Lancement des serveurs au démarage
Pour la mise en route des serveurs automatiquement lors du boot de la carte, nous avons modifié le fichier /etc/rc.local pour y placer juste avant la ligne exit 0 :
sudo ./home/pi/Documents/script
script contient :
#!/bin/bash cd /home/pi/mjpg-streamer/mjpg-streamer/mjpg-streamer-experimental ./mjpg_streamer -i "./input_uvc.so -f 15" -o "./output_http.so -w ./www" & cd /home/pi/Desktop/Server sudo node server.js
Tests serveur
On peut ensuite tester l'envoi et la réception de trames UART depuis la Raspberry :
- Ouvrir un terminal, lancer mjpg streamer et le serveur
- Vérifier que l'appui sur des boutons du serveur côté client engendre l'envoie de trames depuis la broche Tx de la carte à l'aide d'un oscilloscope
- Vérifier que des données sont bien reçues, via l'interface graphique du serveur ou via le terminal en observant les données reçues provenant d'une carte ESP 32 Thing avec un code adapté pour le test
Choix des capteurs
Centrale inertielle
Pour récupérer les données d'odométrie, la centrale inertielle choisie est le MPU-9250. Elle est déjà disponible à Télécom et est relativement simple d'utilisation. Cette centrale à inertie est composée d'un gyromètre, d'un accéléromètre et d'un magnétomètre. La puce est en réalité divisée en deux parties. La partie MPU-9250 (doc fonctionnement, doc description des registres) gère le gyromètre et l'accéléromètre tandis que la partie AK8963 (doc fonctionnement + registres) gère le magnétomètre. Les documentations techniques sont aussi disponibles dans le dossier /robots-pompier/Code/MPU-9250 du dépôt gitlab du projet.
Le capteur est alimenté en 3.3V et communique en I2C. Les données sont disponible au mieux au format 16bits et utilisent le complément à 2.
Le gyromètre mesure une vitesse angulaire et est fonctionnel sur 3 axes (Rot X, Rot Y, Rot Z). La pleine échelle (PE) du capteur est programmable. Les valeurs disponibles sont +/-250, +/-500, +/-1000 et +/-2000 °/sec. Le capteur n'ajoute pas d'offset lors de la mesure et il y a une relation linéaire entre les grandeurs mesurées et la valeur de sortie. Pour calibrer correctement, le capteur, les valeurs de vitesse angulaire du capteur à l'arrêt ont été mesuré sur chaque axe, puis moyennée et finalement soustraite à la valeur lue par le capteur. En effet, à l'arrêt le capteur doit mesurer une vitesse angulaire nulle. Lors de l'utilisation du capteur, la valeur mesurée peut être lue directement. Il n'y a pas besoin de vérifier l'état d'un bit en particulier. Les valeurs de sorties évoluent entre +/-32768. On peut donc avoir la gradeur lue en faisant : V(°/sec) = V * PE / 32768 . La pleine échelle choisie dans un premier temps est +/- 1000 °/s. Elle a permis de réaliser des tests mais n'est pas forcément pertinente. Il faudra donc penser à l'ajuster pour les prochaines années.
L'accéléromètre mesure une accélération sur 3 axes (X, Y, Z). La pleine échelle (PE) du capteur est programmable. Les valeurs disponibles sont +/-2g, +/-4g et +/-8g. Le capteur n'ajoute pas d'offset lors de la mesure et il y a une relation linéaire entre les grandeurs mesurées et la valeur de sortie. Lors de l'utilisation du capteur, la valeur mesurée peut être lue directement. Il n'y a pas besoin de vérifier l'état d'un bit en particulier. Les valeurs de sorties évoluent entre +/-32768. On peut donc avoir la gradeur lue en faisant : A(g) = A * PE / 32768 . La pleine échelle choisie dans un premier temps est +/- 4 g. Elle a permis de réaliser des tests mais n'est pas forcément pertinente. Il faudra donc penser à l'ajuster pour les prochaines années.
Le magnétomètre mesure l'intensité du champs magnétique terrestre sur 3 axes (X, Y, Z). Il faut faire attention à bien éloigner le capteur des sources de champs magnétiques, notamment les moteurs. La sensibilité du capteur est de 0.15uT/LSB en mode 16bits. La pleine échelle (PE) du capteur est de +/- 4912uT. Le capteur n'ajoute pas d'offset lors de la mesure et il y a une relation linéaire entre les grandeurs mesurées et la valeur de sortie. Les valeurs de sorties évoluent entre +/-32760. On peut donc avoir la gradeur lue en faisant : M(uT) = M * PE / 32760 . Il faut faire attention à vérifier que le bit DRDY du registre ST1 (adresse : 02H) est à 1 avant de récupérer la mesure. Il faut également bien calibrer le capteur afin de déterminer, l'offset et corriger le défaut sur la sensibilité. Un code MATLAB est disponible dans le GitLab du projet pour cela sous /robots-pompier/Code/MPU-9250/Calibration matlab. Il faut faire déplacer le capteur dans l'espace (sous forme de '8' dans les 3 directions) et récupérer les données du capteur. Il faut ensuite renseigner ces valeurs sous MATLAB et récupérer la correction.
Voici les mesures avant et après calibration (vue axe XY, YZ, ZX).
Les adresses I2C du module sont : 0x0C pour le magnétomètre (AK8963) et 0x68 pour le gyromètre et l'accéléromètre (MPU-9250).
Capteur de température
Étude de la diffusion de la température en cas d'incendie
Lors d'un incendie, le rayonnement est la principale source de transmission de la chaleur. Un tableau fournit par le ministère permet d'estimer la densité de flux thermique radiatif en fonction de la distance à la flamme:
On utilise ensuite la loi de Stéphan afin de déterminer la température:
A l'aide d'Excel, on obtient les résultats suivants:
Choix du capteur
Nous avons choisi le capteur AOSONG AM2302 qui permet de mesurer la température ainsi que le taux d'humidité de l'air, fonction dont on ne servira pas. Ce capteur permet de mesurer des températures de -40°C à 80°C.
D'après le modèle :
On n’a que 4 points donc on est peu précis mais on obtient un ordre de grandeur de l’ordre de 23m -27m pour ressentir 80°C en cas d’incendie, le choix d’un capteur mesurant jusqu’à une température de 80°C est donc cohérent avec le cas d’étude. Détecter un incendie environ 25m avant de l’atteindre dans un bâtiment est acceptable pour un robot, sachant qu’on a en plus des capteurs pour le gaz et la fumée (MQ9 et MQ135). On a une température de 60°C à 30m du feu environ (ça chute vite). On placera un seuil d'alerte à 60°C pour détecter les potentiels feux (le robot serait à une distance théorique de 30m du feu ce qui semble correct et réaliste).
ATTENTION : On ne prend pas en compte la convexion et la conduction, on a seulement le rayonnement dans ce modèle simplifié. On aura donc une température un peu plus élevée dans la réalité.
Capteur UV
Pour mesurer l'indice UV, nous avons considéré le capteur SI1145 qui fonctionne par I²C, nous l'avions testé et était fonctionnel. Malheureusement lors d'un autre essai, son alimentation et sa masse ont été malencontreusement inversés ce qui a rendu le capteur hors service. Nous avons donc redirigé notre choix vers les UV sensor Grove v1.1 qui ne fonctionnent pas en I²C mais à l'aide de 3 fils (GND, VCC, Signal). Il fournit des valeurs d'UV cohérentes lors de nos tests (indice UV entre 2 et 3). Nous placerons le seuil d'alerte à 6 pour prévenir d'un risque élevé.
Capteur de gaz toxiques
Choix du capteur
Nous avons choisi le capteur MQ9 qui est un capteur coûtant peu cher et offrant une performance acceptable à condition de l'avoir calibré correctement avant utilisation. Il permet de mesurer la concentration en CO (Monoxyde de carbone) afin de permettre au robot maître de prévenir un danger d'intoxication au gaz carbonique. Il permet également de mesurer la concentration en CH4 afin de pouvoir détecter de potentielles fuites de gaz.
Il fonctionne à l'aide de 3 fils (GND, VCC, Signal).
La concentration en CH4 devient dangereuse à partir de 50 000 ppm (limite d’explosivité), mais une concentration au-delà de 1000 ppm (500 fois supérieure à ce que l'on trouve pour un air pur) ne laisse aucun doute quand à une fuite de gaz. On placera donc la limite à 1000 ppm.
Pour le CO, on placera la limite à 200 ppm, stade à partir duquel une exposition de deux ou trois heures provoque des maux de têtes (--> besoin de vigilance). Le capteur MQ9 permet de mesurer le CO de 10 ppm à 1000 ppm, et le CH4 de 100 ppm à 10 000 ppm donc il convient pour notre projet.
Étalonnage du capteur
La datasheet permet d'étalonner le capteur, à l'aide d'Excel on détermine une courbe de tendance à utiliser pour obtenir nos valeurs.
Note: Rs est la valeur renvoyée par le capteur, R0 est déterminée grâce à la datasheet, et les courbes d'étalonnage fournies servent à retrouver les concentrations en ppm des différents gaz.
Capteur de CO2
Le CO2 présente également des dangers pour les personnes, on équipe ainsi le robot d'un capteur de CO2. Les seuils de danger du CO2 sont les suivants:
On va donc placer une alerte à 2000 ppm pour le CO2. Nous avions initialement choisi le capteur XENSIV PAS CO2 qui correspondait à ces critères (mesure le CO2 entre 0 ppm et 32 000 ppm), mais son prix a soudainement grimpé pour des raisons d'approvisionnement. Nous nous sommes donc rabattus sur un autre modèle: le CCS811 qui permet de mesurer le taux de CO2 pour des valeurs comprises en 400 ppm et 8192 ppm (il donne pour résultat 400 ppm par défaut pour les valeurs inférieures ou égales à 400 ppm).
Télémètres
Le robot maître étant dirigé par caméra, on ne l'équipera que d'un télémètre pour assister le pilote lors de la détection d'obstacles frontaux. Les robots esclaves eux vont être équipés de télémètres pour pouvoir détecter les obstacles dans leur direction de mouvement. Pour le robot maître, on met une alerte en place pour un obstacle détecté à 20 cm du robot et on bloque le robot si il se trouve à 10 cm de l'obstacle et qu'il souhaite se déplacer vers l'obstacle. Pour le robot esclave, on force le robot esclave à changer de trajectoire 15 cm avant l'obstacle afin de lui laisser le temps d'éviter la collision.
SRF
Dans la série des télémètres SRF, nous disposons des modèles SRF08, SRF10 et SRF04. Les modèles SRF08 et SRF10 fonctionnent à l'aide de l'I²C, le modèle SRF04 lui fonctionne par voie analogique à l'aide de 4 fils (echo, trigger, GND, supply). SRF08 peut détecter les objets jusqu'à 6m avec un angle de détection de 55°, le SRF10 peut détecter les objets jusqu'à 6m avec un angle de détection de 72°, le SRF04 peut détecter jusqu'à 3m avec un angle de détection de 30°. La distance minimale de détection des 3 capteurs est de 3 cm. Ces 3 capteurs conviennent à notre utilisation.
US-020
C'est un capteur qui fonctionne avec 4 fils (echo, trigger, GND, Alim), son angle de détection est de 15°, il permet de mesurer les obstacles entre 2cm et 7m. L'angle de détection est plutôt faible mais il pourrait servir sur les robots esclaves pour surveiller les angles du robot.
VMA360
C'est un capteur qui fonctionne avec 4 fils (echo, trigger, GND, Alim), il a un angle de détection de 15°, il permet de mesurer les obstacles entre 2cm et 4,5m. L'angle de détection est plutôt faible mais il pourrait servir sur les esclaves pour surveiller les angles du robot.
Tableau récapitulatif
On estime possible d'alimenter tous ces capteurs avec les batteries prévues au vu des courants d'alimentation qu'elles fournissent.
Librairies Arduino
Nous avons dû installer des librairies Arduino pour faire fonctionner les capteurs : "DFRobot_CCS811" pour le capteur de CO2 CCS811; "DHT Sensor Library" pour le capteur de température; "Adafruit Circuit Playground" et "Adafruit Unified Sensor" pour les capteurs d'Adafruit.
Il faut également avoir installé une librairie dans le gestionnaire de cartes pour pouvoir utiliser l'ESP32 Thing (carte utilisée pour acquérir les données des capteurs et pilote la Teensy). Lien du site officiel pour réaliser cette manipulation: https://learn.sparkfun.com/tutorials/esp32-thing-hookup-guide.
Code informatique
Vous trouverez ci-joint les codes finaux pour les ESP32 du maitre et des 2 esclaves. Fichier:Codes Esp Final.zip
Robot maître
Communication entre la Raspberry et l'ESP32
Dans le sens Raspberry vers ESP32
| Commande | |
|---|---|
| Stop | st
|
| Avancer | av
|
| Demi tour | dt
|
| Rotation à droite de 30° | rd
|
| Rotation à gauche de 30° | rg
|
| Appel des robots esclaves | ap
|
Dans le sens ESP32 vers Raspberry
| Alerte | |
|---|---|
| CO | C1
|
| CO2 | C2
|
| CH4 | C4
|
| Température Haute | TH
|
| UV | UV
|
| Distance à l'avant du robot | DA
|
| Erreur : en cas de commande av non exécutée car distance avant trop faible | er
|
Communication vers le robot esclave
Pour réaliser cette tâche, on va utiliser le protocole ESPNow.
Présentation du protocole ESPNOW
C'est un protocole développé par Espressif, il permet à des appareils de communiquer par le Wi-Fi. Le protocole est similaire à la connexion sans fil basse puissance 2.4 GHz. Un appariement entre les appareils doit être réalisé avant la communication, après cet appariement la connexion est d'égal à égal sans handshake requis. C'est-à-dire que cette communication est persistante, même si l'un des appareils est mis hors-tension, la communication reprendra automatiquement dès sa remise sous tension.
Le protocole supporte: Les communications unicast cryptées et non-cryptées - Les appareils cryptés et non-cryptés - Les Payload (partie donnée de la trame) de 250 bytes maximum - Les fonctions de vérification d’envoi de la trame (succès de l'envoi ou échec de l'envoi)
Ses limitations sont: 10 appareils cryptés maximum appareillés - 20 appareils non-cryptés maximum appareillés - 250 octets maximum par envoi de données pour le payload
La communication est unidirectionnelle, elle repose sur un principe maitre-esclave (le maitre envoi les informations et l'esclave les reçois). On peut avoir un maitre pour plusieurs esclaves ou plusieurs maitres pour un esclave.
ESP32 Maître vers ESP32 Esclave
| Commande | |
|---|---|
| Avancer d'une distance de XXX centimètres | avXXX
|
| Rotation à droite d'un angle XXX en degrés | rdXXX
|
| Rotation à gauche d'un angle XXX en degrés | rgXXX
|
Pour faire demi-tour, on envoie un rd180.
Schéma récapitulatif des différentes communications
Robots esclaves
Notes tableaux J101
Sauvegarde des notes des tableaux de la J101 le 7 avril 2022.
