Robot mobile autonome, guide vocal du laboratoire de robotique de l'Université des Mascareignes.
đ„ Voir les vidĂ©os · đ Installation · đ Documentation
đŹ
â¶ïž MARC â Construction d'un robot compagnon (Partie 1)
La construction du robot, de la mécanique à l'électronique.
- Ă propos
- Aperçu
- Architecture matérielle
- Matériel
- Conception 3D
- Architecture logicielle (ROS 2)
- Navigation et localisation
- Structure du dépÎt
- Installation
- Utilisation
- Documentation
- Auteur
MARC est un projet de fin d'études développé en 3Úme année d'Informatique Appliquée à l'Université des Mascareignes (Maurice), en partenariat avec l'Université de Limoges.
L'objectif : créer un robot guide capable de se déplacer de maniÚre autonome entre les stations du laboratoire de robotique, de dialoguer en langage naturel grùce à un Grand ModÚle de Langage, et d'exprimer des émotions via une matrice LED. Le tout supervisé depuis une interface web temps réel.
Le robot est entiÚrement conçu à partir de zéro : modélisation 3D sur Onshape, impression 3D, électronique custom, firmware embarqué et stack logiciel ROS 2 complet.
- đ§ Navigation autonome par vision : localisation absolue par marqueurs ArUco, fusionnĂ©e avec l'odomĂ©trie (cap IMU + distance parcourue)
- đșïž Planification de chemin : trajets calculĂ©s par Dijkstra sur un graphe de points de passage sĂ»rs, qui contourne les obstacles fixes connus
- đïž Pipeline vocal complet : Speech-to-Text â LLM cloud (Ministral via Ollama) â Text-to-Speech français
- đ§ Sortie JSON structurĂ©e : le LLM gĂ©nĂšre directement des commandes exĂ©cutables
- đ Interface web HTTPS temps rĂ©el : envoi de destinations, journal d'Ă©vĂ©nements, Push-To-Talk, mises Ă jour SSE
- đ Matrice LED RGB 64Ă32 avec plusieurs expressions GIF (neutre, clignement, suspicieux, triste, amour, disparition)
- đ§© Architecture ROS 2 modulaire : 8 nĆuds indĂ©pendants, lancĂ©s en une commande
- đĄ Perception de proximitĂ© : 3 capteurs ultrasoniques HC-SR04 remontĂ©s en continu
- âïž Tentative auto-Ă©quilibrante PID documentĂ©e et analysĂ©e (mode finalement Ă©cartĂ© pour la navigation au sol â voir le rapport)
Le systÚme est distribué en trois couches :
âââââââââââââââââââââââââââââââââââââââââââââââ
â Couche temps rĂ©el â Arduino Mega 2560 â
â Moteurs NEMA 23 · TB6600 · BNO085 (SPI) â
â 3Ă HC-SR04 · capteurs IR · tĂ©lĂ©commande IR â
â Envoie : Y:yaw · D:distance · U:c:g:d â
â Reçoit : C:move:turn · M:mode â
ââââââââââââââââââââŹâââââââââââââââââââââââââââ
â UART 115 200 bauds
â (/dev/ttyACM0)
ââââââââââââââââââââŽâââââââââââââââââââââââââââ
â Couche applicative â Raspberry Pi 4 â
â ROS 2 : 8 nĆuds (vision, localisation, â
â navigation, mission, voix, LED, web, sĂ©rie)â
â CamĂ©ra IMX219 (ArUco) · Flask HTTPS + SSE â
ââââââââââââââââââââŹâââââââââââââââââââââââââââ
â daemon Ollama local â cloud
ââââââââââââââââââââŽâââââââââââââââââââââââââââ
â Intelligence distante â
â ministral-3:14b-cloud via Ollama â
â Sortie JSON structurĂ©e â
âââââââââââââââââââââââââââââââââââââââââââââââ
| Composant | Référence / détail |
|---|---|
| MicrocontrĂŽleur | Arduino Mega 2560 |
| Ordinateur de bord | Raspberry Pi 4 Model B (1 Go RAM) |
| Moteurs | Pas-Ă -pas NEMA 23 Ă2 (Ă roue 20 cm, 200 pas/tr, 1/4 micro-pas) |
| Drivers moteurs | TB6600 Ă2 â STEP/DIR/ENA : G (7/5/3), D (8/6/4) |
| Centrale inertielle | BNO085 â SPI, CS 47, INT A4, RST A5 |
| CamĂ©ra | IMX219 (Arducam) â dĂ©tection ArUco |
| Capteurs proximitĂ© | 3Ă HC-SR04 â centre (22/23), gauche (24/25), droite (26/27), portĂ©e 80 cm |
| Capteurs ligne | 3 capteurs IR â pins 49 (G), 40 (C), 48 (D) (mode hĂ©ritĂ©) |
| Affichage | Matrice LED RGB 64Ă32 (HUB75) |
| TĂ©lĂ©commande | RĂ©cepteur IR (pin 46) â rĂ©glage PID, pilotage manuel |
| Alimentation | Double batterie Li-ion 12 V 3S indépendantes (moteurs / Pi) |
đĄ La modĂ©lisation 3D complĂšte a Ă©tĂ© rĂ©alisĂ©e sur Onshape et le robot a Ă©tĂ© imprimĂ© en 3D au laboratoire de l'UDM.
L'intĂ©gralitĂ© de la mĂ©canique de MARC a Ă©tĂ© modĂ©lisĂ©e sur Onshape puis imprimĂ©e en 3D au laboratoire de l'UDM. Le robot se dĂ©compose en 3 sous-ensembles : la coque externe esthĂ©tique, la structure interne porteuse, et la tĂȘte (matrice LED).
đ Voir le modĂšle 3D complet sur Onshape
Tous les fichiers source sont dans assets/3d-models/, aux formats STL (impression directe) et STEP (édition CAO).
đĄ Astuce : cliquez sur n'importe quel fichier
.stldirectement sur GitHub pour le visualiser en 3D dans votre navigateur.
Habillage esthétique du robot, imprimé en plusieurs morceaux pour respecter les contraintes du plateau d'impression.
| PiĂšce | STL | STEP |
|---|---|---|
| Colonne V3 | STL | STEP |
| Corps Bas â Avant | STL | STEP |
| Corps Bas â ArriĂšre | STL | STEP |
| Corps Haut â Avant | STL | STEP |
| Corps Haut â ArriĂšre | STL | STEP |
| Ătage 0 (base) | STL | STEP |
| Porte d'accĂšs | STL | STEP |
| Support capteurs IR | STL | STEP |
Squelette porteur qui supporte l'électronique, les moteurs et les batteries.
| PiĂšce | STL | STEP |
|---|---|---|
| Colonne V1 | STL | STEP |
| Coque interne | STL | STEP |
| Ătage 1 | STL | STEP |
| Ătage 2 | STL | STEP |
| Ătage 3 | STL | STEP |
| Bague de réduction | STL | STEP |
| Roue | STL | STEP |
| Part 8 | STL | STEP |
Module supĂ©rieur portant la matrice LED 64Ă32 (le « visage » de MARC).
| PiĂšce | STL | STEP |
|---|---|---|
| TĂȘte â partie basse | STL | STEP |
| TĂȘte â partie haute | STL | STEP |
| Cadre matrice LED | STL | STEP |
Le logiciel embarquĂ© sur le Raspberry Pi est un package ROS 2 (marc_nodes) composĂ© de 8 nĆuds qui communiquent par topics. Chaque responsabilitĂ© est isolĂ©e dans son propre nĆud, ce qui permet de lancer, tester et dĂ©boguer chaque brique sĂ©parĂ©ment.
ââââââââââââââââ
/aruco/detections â camera_node â camĂ©ra IMX219 + dĂ©tection ArUco
ââââââââââââââââââââââââââââ
âŒ
ââââââââââââââââââââ /pose ââââââââââââââââââ /nav_goal ââââââââââââââââââ
â localization_nodeââââââââââââ¶ â mission_node â ââââââââââââ¶ â navigation_nodeâ
â ArUco + odomĂ©trieâ â Dijkstra/grapheâ ââââââââââââ â go-to-goal â
ââââââââââââââââââââ ââââââââââââââââââ /goal_status âââââââââŹâââââââââ
âČ âČ âČ â /cmd_motor
/imu_yawâ /distanceâ /mission_station âŒ
â â /nav_status ââââââââââââââââââââââââââ
ââââŽâââââââââââŽââââ âČ â â firmware_node â
â firmware_node â ââââââââââââââââââ â â pont sĂ©rie /dev/ttyACM0â
â pont sĂ©rie â âââââââââââââââââââââŒââââââââââââââââââââââââââââââââââââââââââ
âââââââââââââââââââ â
âČ âââââââââŽââââââââââ /vocal_command ââââââââââââââ
/led_expression â webbridge_node â ââââââââââââââââ â voice_node â
âââââââââââââââââââ â Flask + web + â â STTâLLMâTTSâ
â led_node â ââââââââââââ â LLM + SSE â ââââââââââââââ
â matrice RGB 64Ă32â âââââââââââââââââââ
âââââââââââââââââââ
firmware_node â pont entre ROS 2 et l'Arduino sur le port sĂ©rie. Souscrit Ă /cmd_motor (Int32MultiArray [move, turn]) qu'il traduit en trames C:move:turn, et publie le cap /imu_yaw et la distance /distance lus depuis l'Arduino.
camera_node â capture le flux de la camĂ©ra IMX219, dĂ©tecte les marqueurs ArUco et publie les dĂ©tections (/aruco/detections).
localization_node â calcule la pose (x, y, cap) du robot par fusion : position absolue par recalage ArUco quand un marqueur connu est visible, intĂ©gration odomĂ©trique (cap IMU + distance) sinon. Publie /pose.
navigation_node â contrĂŽleur go-to-goal pur : amĂšne MARC Ă un point (x, y) par correction de cap puis avance, avec orientation finale optionnelle. GĂšre aussi un scan de localisation par rotation au dĂ©marrage Ă froid, jusqu'Ă acquĂ©rir une premiĂšre pose.
mission_node â le « cerveau de trajet » : Ă partir d'une station nommĂ©e ou d'un point libre, il planifie un chemin par waypoints (Dijkstra sur le graphe de points sĂ»rs de maps.py) et enchaĂźne les waypoints un par un vers navigation_node.
voice_node â pipeline vocal : wake word (« salut marc ») â Google STT â ministral-3:14b-cloud (Ollama local, JSON strict) â synthĂšse vocale française (edge-tts). Publie la commande finale sur /vocal_command.
webbridge_node â serveur Flask HTTPS qui hĂ©berge l'interface web, interprĂšte les commandes texte via le LLM, diffuse les Ă©vĂ©nements en temps rĂ©el (SSE) et relaie les destinations vers mission_node.
led_node â unique propriĂ©taire de la matrice LED. Tout nĆud qui veut afficher une expression publie sur /led_expression (love, neutral, suspicious, sad, blink, disappear, idle:<exp>, style:<n>), ce qui Ă©vite les conflits d'accĂšs GPIO.
L'origine est une intersection de carreaux choisie comme (0, 0). Convention : 0° = -Y, +90° = +X, sens trigonométrique.
Les marqueurs fixes (mur, plafond) servent à recaler la pose absolue. Leurs positions réelles sont centralisées dans maps.py :
| ID ArUco | Position (x, y) en m |
|---|---|
| 0 | (-2.07, 0.00) |
| 1 | (-2.08, 1.07) |
| 2 | (2.17, 1.05) |
| 3 | (-0.66, 2.45) |
| 4 | (2.17, -0.33) |
| 5 | (0.96, -3.39) |
| Station | Ăquipement | Position (x, y) | Cap final |
|---|---|---|---|
nao |
Robot humanoïde NAO | (-1.6, 0) | 90° |
vector |
Robot mobile Vector | (-1.5, 4.9) | 30° |
pepper |
Robot humanoĂŻde Pepper | Ă mesurer | â |
imp3d |
Imprimante 3D | Ă mesurer | â |
baxter |
Robot industriel Baxter | (1.8, 1.8) | 90° |
bras |
Bras Franka Panda | (1.8, -0.6) | -90° |
â ïž Les positions marquĂ©es Ă mesurer valentNonedansmaps.py. Tant qu'une station n'a pas de coordonnĂ©es,mission_noderefuse le trajet plutĂŽt que d'inventer une trajectoire.
L'évitement des obstacles fixes est assuré en amont par la planification : mission_node calcule un chemin qui ne passe que par des segments sûrs du graphe de waypoints. Les 3 capteurs HC-SR04 fournissent en plus une perception de proximité (distances centre/gauche/droite remontées à 10 Hz).
MARC/
âââ src/marc_nodes/ # Package ROS 2 (cĆur du robot)
â âââ launch/marc.launch.py # Lance les 8 nĆuds en une commande
â âââ marc_nodes/
â â âââ firmware_node.py # Pont sĂ©rie Arduino
â â âââ camera_node.py # CamĂ©ra IMX219 + dĂ©tection ArUco
â â âââ localization_node.py # Fusion ArUco + odomĂ©trie â /pose
â â âââ navigation_node.py # ContrĂŽleur go-to-goal
â â âââ mission_node.py # Planification de trajet (Dijkstra)
â â âââ voice_node.py # Pipeline vocal STTâLLMâTTS
â â âââ webbridge_node.py # Flask HTTPS + interface web + LLM + SSE
â â âââ led_node.py # Matrice LED RGB
â â âââ maps.py # Carte : marqueurs, stations, graphe waypoints
â âââ package.xml / setup.py # MĂ©tadonnĂ©es et points d'entrĂ©e ROS 2
â
âââ controlMoteur/ # Firmware Arduino Mega
â âââ controlMoteur.ino # Boucle principale (sĂ©rie, PID, capteurs)
â âââ fonctions.ino # Moteurs, ultrasons, suivi de ligne, tĂ©lĂ©commande
â âââ header.h # Pins, constantes, objets globaux
â
âââ vision/ # Briques vision autonomes (hors ROS)
â âââ calibrate_camera.py # Calibration de la camĂ©ra (Ă©chiquier)
â âââ camera_calibration.npz # Matrice intrinsĂšque + distorsion
â âââ camera_service.py # Service camĂ©ra HTTPS
â âââ localization.py # Localisation ArUco + odomĂ©trie (prototype)
â âââ navigation_goto.py # Go-to-goal (prototype)
â âââ navigation_service.py # Service navigation
â
âââ assistantVocale/ # Pipeline vocal autonome (importĂ© par voice_node)
â âââ voiceAssistant.py # STT (Google) â Ollama â edge-tts
â âââ modelfile.txt # Prompt systĂšme / contrainte JSON du LLM
â âââ requirements.txt
â
âââ matrixLed/ # Pilotage de la matrice LED RGB 64Ă32
â âââ eye_manager.py # Animations + clignement thread-safe
â âââ gif_viewer.py # Lecteur GIF (test standalone)
â âââ SplitEyes.py # GĂ©nĂ©ration des GIFs depuis une vidĂ©o
â âââ style1/ style2/ style3/ # Sets d'expressions (GIF)
â
âââ web/ # Interface web (servie par webbridge_node)
â âââ server.py # Ancien serveur Flask monolithique (hĂ©ritĂ©)
â âââ index.html / style.css / app.js
â âââ cert.pem / key.pem # Certificat SSL auto-signĂ© (Ă gĂ©nĂ©rer)
â
âââ assets/3d-models/ # Fichiers STL + STEP (Onshape)
âââ LICENSE
âââ README.md
- Raspberry Pi 4 (Raspberry Pi OS 64 bits recommandé)
- ROS 2 Jazzy installé
- Arduino Mega 2560 + IDE Arduino
- Python 3.9 ou supérieur
- Daemon Ollama installé et connecté (
ollama signin) â le modĂšle cloud est relayĂ© par le serveur local, aucune clĂ© API Ă gĂ©rer ffmpeg,mpg123,sox,alsa-utils,portaudio19-dev
- Ouvrir
controlMoteur/controlMoteur.inodans l'IDE Arduino. - Installer via le gestionnaire de bibliothĂšques :
FastAccelStepperIRremoteNewPingSparkFun BNO08x Arduino LibraryPID_v1(Brett Beauregard)
- Vérifier le brochage dans
header.h. - Compiler et téléverser sur l'Arduino Mega.
# Cloner le dépÎt dans un workspace ROS 2
git clone https://github.com/SALLAH-JP/MARC.git
cd MARC
# Dépendances Python du pipeline vocal et de la vision
pip install -r assistantVocale/requirements.txt
pip install opencv-contrib-python pyserial speechrecognition edge-tts pydub pillow flask
# Dépendances systÚme
sudo apt install ffmpeg mpg123 sox alsa-utils portaudio19-dev
# BibliothĂšque matrice LED (compilation native)
git clone https://github.com/hzeller/rpi-rgb-led-matrix
cd rpi-rgb-led-matrix && make build-python PYTHON=$(which python3) && cd ..
# AccĂšs GPIO sans sudo pour la matrice LED
sudo setcap 'cap_sys_rawio+ep' $(readlink -f $(which python3))
# Certificat SSL auto-signé (HTTPS requis pour le micro cÎté navigateur)
cd web
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
cd ..
# Authentification Ollama (le modÚle cloud est relayé par le daemon local,
# aucune clé API à exporter)
ollama signin
# Compilation du package ROS 2
source /opt/ros/jazzy/setup.bash
colcon build --packages-select marc_nodes
source install/setup.bashTout le systÚme démarre en une seule commande :
ros2 launch marc_nodes marc.launch.pyArguments optionnels :
| Argument | Défaut | Effet |
|---|---|---|
port:=/dev/ttyACM1 |
/dev/ttyACM0 |
Port série de l'Arduino |
style:=1 |
2 |
Style de départ des yeux LED |
use_voice:=false |
true |
Désactive le pipeline vocal |
use_led:=false |
true |
Désactive la matrice LED |
use_vision:=false |
true |
Désactive la chaßne vision (caméra + localisation + navigation) |
Exemple â sans voix ni vision, pour tester les moteurs seuls :
ros2 launch marc_nodes marc.launch.py use_voice:=false use_vision:=false- Dire le mot de réveil.
- Ănoncer la commande, par exemple :
- « Va voir Pepper » â navigation autonome jusqu'Ă la station
- « PrĂ©sente-moi NAO » â MARC s'y rend et donne une prĂ©sentation
- « Reviens Ă la base » â retour Ă l'origine
- MARC interprĂšte la requĂȘte, confirme oralement et exĂ©cute.
Accessible sur https://<ip-du-pi>:5000 depuis n'importe quel appareil du réseau local (accepter l'avertissement de certificat auto-signé) :
- Envoyer le robot vers une station
- Push-To-Talk pour enregistrer une commande vocale depuis le navigateur
- Suivre le journal des événements en temps réel (SSE)
# Envoyer MARC Ă une station
ros2 topic pub --once /mission_station std_msgs/String "{data: 'baxter'}"
# Envoyer vers un point brut (x, y)
ros2 topic pub --once /mission_point geometry_msgs/Point "{x: 1.0, y: 2.0, z: 0.0}"
# Suivre la pose estimée
ros2 topic echo /poseLe rapport complet de Projet de Fin d'Ătudes dĂ©taille l'analyse des besoins, les choix d'architecture, le passage du suivi de ligne Ă la navigation par vision, l'analyse du conflit PID-Ă©quilibre vs suivi de ligne, les tests de modĂšles LLM sur Raspberry Pi 4, la modĂ©lisation 3D sur Onshape et les rĂ©sultats expĂ©rimentaux.
đ Le rapport complet (PDF) est disponible sur demande.
SALLAH Assiongbon ThĂ©odore Jean-Paul Ătudiant en 3Ăšme annĂ©e â Informatique AppliquĂ©e đ UniversitĂ© des Mascareignes · UniversitĂ© de Limoges
Encadrant pédagogique : M. Khadimoullah Ramoth
Ce projet doit beaucoup à plusieurs contributions extérieures :
- Le projet Local-Voice de M15.ai, dont l'architecture a inspiré le pipeline vocal
- La plateforme Ollama et le modĂšle Ministral
- La bibliothĂšque FastAccelStepper de J. Kerschbaumer
- La bibliothĂšque rpi-rgb-led-matrix de H. Zeller
- NewPing, edge-tts, Flask, SpeechRecognition, OpenCV
- Les fournisseurs locaux Advanced Electronique et Transcom (Maurice)
Ce projet est distribuĂ© sous licence MIT â voir le fichier LICENSE.
Le code des bibliothÚques tierces utilisées reste sous leurs licences respectives.
Si ce projet vous a plu, n'hĂ©sitez pas Ă laisser une â !

