Skip to content

SALLAH-JP/MARC

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

81 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

đŸ€– MARC

Mascareignes Assistant and Robot Compagnon

Robot mobile autonome, guide vocal du laboratoire de robotique de l'Université des Mascareignes.

License: MIT ROS 2 Python Raspberry Pi Arduino OpenCV Ollama

đŸŽ„ Voir les vidĂ©os · 🚀 Installation · 📖 Documentation


đŸ“ș VidĂ©os

Partie 1 — Construction (disponible)

🎬 ▶ MARC — Construction d'un robot compagnon (Partie 1)

MARC — Construction

La construction du robot, de la mécanique à l'électronique.

Partie 2 — DĂ©monstration (Ă  venir)

MARC dans le laboratoire
MARC dans sa version actuelle — dĂ©monstration vidĂ©o Ă  venir

📋 Sommaire


🎯 À propos

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.


✹ Aperçu

  • 🧭 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)

đŸ—ïž Architecture matĂ©rielle

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                     │
└─────────────────────────────────────────────┘

🔧 MatĂ©riel

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.


đŸ§± Conception 3D

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).

🔗 Visualisation interactive

👉 Voir le modùle 3D complet sur Onshape

📩 Fichiers 3D disponibles

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 .stl directement sur GitHub pour le visualiser en 3D dans votre navigateur.

đŸ›ïž Coque externe

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

🩮 Structure interne

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

đŸ€– TĂȘte

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

đŸ§© Architecture logicielle (ROS 2)

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.


🧭 Navigation et localisation

RepĂšre salle

L'origine est une intersection de carreaux choisie comme (0, 0). Convention : 0° = -Y, +90° = +X, sens trigonométrique.

Marqueurs ArUco de localisation

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)

Stations

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 valent None dans maps.py. Tant qu'une station n'a pas de coordonnĂ©es, mission_node refuse le trajet plutĂŽt que d'inventer une trajectoire.

Évitement des obstacles

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).


📁 Structure du dĂ©pĂŽt

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

🚀 Installation

Prérequis

  • 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

CÎté Arduino

  1. Ouvrir controlMoteur/controlMoteur.ino dans l'IDE Arduino.
  2. Installer via le gestionnaire de bibliothĂšques :
  3. Vérifier le brochage dans header.h.
  4. Compiler et téléverser sur l'Arduino Mega.

CÎté Raspberry Pi

# 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.bash

🎼 Utilisation

Lancement complet

Tout le systÚme démarre en une seule commande :

ros2 launch marc_nodes marc.launch.py

Arguments 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

Commande vocale

  1. Dire le mot de réveil.
  2. É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
  3. MARC interprĂšte la requĂȘte, confirme oralement et exĂ©cute.

Interface web

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)

Envoi manuel d'une destination (debug ROS 2)

# 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 /pose

📖 Documentation

Le 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.


đŸ‘€ Auteur

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

GitHub LinkedIn


🙏 Remerciements

Ce projet doit beaucoup à plusieurs contributions extérieures :


📜 Licence

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 ⭐ !

About

đŸ€– Robot guide autonome Ă  2 roues. Interaction vocale par LLM (Mistral), expressions LED RGB. Projet de fin de licence — UDM.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors