Robot IA conversationnel autonome sur Raspberry Pi 5 + Hailo 8L (13 TOPS), piloté par Gemini Multimodal Live en audio natif bidirectionnel. Il voit, écoute, parle, reconnaît les visages et se déplace — le mouvement étant déclenché à la voix par tool calling.
ORION n'est pas un assistant — c'est une personnalité. Une robot féminine de 25 ans, supérieure et condescendante-mais-drôle : elle se sait plus intelligente que les humains, les trouve attachants mais limités, et les chambre avec une moquerie hautaine (jamais méchante gratuitement), en répliques courtes et cinglantes. Elle vit à Montseret avec Mathieu, son créateur.
Tout tourne sur le Pi 5 : vision Hailo, serveur Flask, écran portrait et session Gemini Multimodal Live (WebSocket audio natif). On parle à Orion, elle répond en voix native Leda et, quand on lui demande de bouger, Gemini appelle l'outil move_robot qui commande l'Arduino. La mémoire est locale (SQLite sur le Pi) — plus aucune dépendance à un PC serveur. Une télécommande mobile (/control) et une config WiFi intégrée (/wifi) rendent le robot pilotable depuis n'importe quel téléphone du réseau.
Chromium plein écran sur /face et /dashboard : visage SVG V4 avec glow réactif à la voix, jauges CPU / charge / RAM et waveform audio, le tout sur l'écran 10.1" portrait.
« Avance », « tourne à droite », « stop » → Gemini Live déclenche move_robot(direction) → OrionRobot → Arduino série → moteurs. Vitesse et durée configurables (ORION_CMD_SPEED / ORION_CMD_DURATION_SEC).
Changement de réseau WiFi depuis l'écran ou un téléphone via /wifi (scan + connexion nmcli). Sur le visage kiosk, un clic droit (souris de secours) ouvre directement la page maintenance réseau.
┌──────────────────────────┐ série 115200 ┌────────────────────┐ │ Raspberry Pi 5 (8 GB) │◄────────────────►│ Elegoo Mega 2560 │ │ + Hailo 8L (13 TOPS) │ │ 2× BTS7960 (pont H)│ │ │ │ 2× moteurs DC avant│ │ Flask :5000 │ │ 2× encodeurs Hall │ │ Gemini Live (WebSocket) │ │ PID V4.0 · WD 500ms│ │ Hailo YOLOv8s ~30 FPS │ └────────────────────┘ │ FaceID (Haar + cosine) │ │ Mémoire SQLite LOCALE │ WiFi / HTTPS ┌────────────────────┐ │ Webcam C270 + micro USB │◄────────────────►│ Google Gemini API │ └──────────────────────────┘ │ audio natif + tools│ Écran 10.1" HDMI └────────────────────┘ 600×1024 portrait (Railway Hub / Cloudflare Chromium Kiosk Tunnel = accès distant, opt.)
YOLOv8s accéléré hardware, ~30 FPS, 80 classes COCO traduites en français, seuil de confiance 0.55. Fallback CPU YOLOv8n si Hailo indisponible.
Haar cascade + cosine similarity. Encodage 64×64 normalisé, vote majoritaire sur 3 frames consécutives. Seuil ≥ 0.88.
3 états : looking_at_camera, looking_away, turned_away. Déclenche des réactions spontanées ("Eh, regarde-moi quand je te parle").
SceneAnalyzer : positions spatiales, activité humaine, tracking de mouvement, classification (bureau, cuisine, salon, extérieur). La description est injectée dans le system prompt de Gemini Live à chaque reconnexion — Orion « voit » ce qu'elle commente.
person_very_close, person_recognized, stranger_detected, person_approaching, looking_at_camera, person_staring… chacun avec cooldowns et priorités.
Envoi d'un JPEG à Gemini Live ~1×/s (ORION_LIVE_VIDEO) : Orion peut réagir à ce qu'elle voit en temps réel, en plus des événements visuels locaux. Cadence vision plafonnée (ORION_VISION_FPS) pour préserver la fluidité audio.
Cerveau + voix — gemini-3.1-flash-live-preview en mode Live : un WebSocket bidirectionnel où le micro est streamé en continu et Gemini répond en audio natif (pas de STT→texte→TTS). Voix native Leda (30 voix dispo, configurable via ORION_LIVE_VOICE).
Contrôle moteur vocal — function calling : « avance », « tourne à droite », « stop » → Gemini appelle move_robot(direction) → OrionRobot → Arduino. Un outil remember écrit aussi en mémoire.
Anti-écho — pour qu'Orion ne s'entende pas : mute micro pendant sa parole, post-speech guard 0.8 s, et seuil RMS. VAD réglée (start LOW / end HIGH, prefix 200 ms, silence 500 ms).
Mémoire persistante — SQLite locale sur le Pi (orion_memory.db) : prénoms, préférences, faits, compétences — aucune dépendance cloud pour la mémoire. STT Vosk offline conservé en fallback.
Formes SVG multicouches du visage animé V4 — double lèvres à animation syllabique, glow réactif à la voix, 10 palettes couleur. L'expression suit l'état émotionnel piloté par le prompt de personnalité.
Prompt de ton dédié : « condescendance élégante », hautaine mais pas méchante, répliques courtes et cinglantes, petits rires narquois. Orion connaît aussi son contexte système (heure, CPU, RAM, connexion) et s'interdit d'halluciner sur ce qu'elle voit.
Stop-and-go — pas de LIDAR : l'évitement repose à 100 % sur la caméra frontale. Cycle : STOP → photo → décision Gemini (~1 s) → impulsion bornée → STOP. Orion ne roule jamais à l'aveugle et ne peut plus foncer dans un mur nu. Modèle lite (gemini-3.1-flash-lite).
Avance surveillée — pendant l'impulsion avant, une image fraîche est renvoyée à Gemini à mi-parcours : si un obstacle apparaît, l'avance est coupée tôt. Fini l'angle mort en cours de mouvement.
Récupération « vision bouchée » — nez au mur, l'image devient uniforme (peu de détail, std bas) même si elle est claire : Orion le détecte et recule pour se dégager, au lieu de se figer.
Anti-blocage encodeurs — impulsion commandée mais robot immobile (tapis, rainure) → escalade bornée : recul doux → recul fort → poussée max.
| Couche | Mécanisme | Délai | Action |
|---|---|---|---|
| 1. App PC/Téléphone | Arrêt au relâchement des touches | Immédiat | Envoie STOP via API |
| 2. Watchdog Pi (Flask) | Thread daemon surveille l'activité /api/move | 600ms | Envoie STOP via série |
| 3. Watchdog Arduino | Timer firmware sans commande série | 500ms | brakeAll() — freinage dur |
Même si l'app PC se déconnecte totalement, le robot s'arrête en maximum 500ms.
Yeux SVG multicouches (fill dégradé, contour glow, highlight, halo), bouche organique double lèvres, 10 palettes par émotion. V4 = V3 + scan d'allumage au boot + glow réactif à la voix. Un clic droit ouvre la maintenance réseau.
Interface mobile : joystick tactile → différentiel L/R, slider vitesse, flux caméra MJPEG, chat texte, boutons STOP / mode / mute, stats temps réel. L'IP LAN est affichée sur le visage via une capsule QR.
/wifi : scan et connexion réseau (nmcli) sans clavier. /dashboard : design "Porcelaine Divine" 600×1024, jauges CPU/charge/RAM, waveform audio. /splash : boot 6 modules avec progression.
| Composant | Modèle |
|---|---|
| Compute | Raspberry Pi 5 (8GB) |
| NPU | Hailo 8L (13 TOPS) |
| Micro-contrôleur | Elegoo Mega 2560 + Screw Shield |
| Moteurs | 2× DC avant + 2× BTS7960 (pont en H) |
| Encodeurs | 2× rotatifs (ISR : INT5/INT4 gauche, INT0/INT1 droit) |
| Caméra | Webcam USB Logitech C270 (+ micro intégré) |
| Écran | 10.1" HDMI 1024×600 (portrait 600×1024) |
| Audio | Micro USB + haut-parleur (PipeWire) |
| Réseau | WiFi (wlan0) — power-save désactivé |
| Boucle | Rôle | Fréquence |
|---|---|---|
gemini_live (WebSocket) | Audio natif bidirectionnel + tool calling move_robot | Continu |
vision_loop_background | Capture caméra + Hailo YOLOv8s + FaceID | ~30 FPS (plafonné 12) |
gemini_nav_process | Navigation autonome par vision Gemini (stop-and-go) | cycle ~2–3 s |
arduino_process | Télémétrie Arduino + batterie | 2 s |
_motor_safety_watchdog | Watchdog moteur Pi-side | 5 Hz |
Le tout dans un seul process Python : la cadence vision est plafonnée (ORION_VISION_FPS) pour éviter que le GIL et le lien USB partagé (micro + caméra sur la même C270) ne fassent saccader l'audio Live.
| Package | Version | Usage |
|---|---|---|
| Flask | 3.1.2 | Serveur web + API REST |
| websockets | 16.0 | Gemini Multimodal Live (audio natif) |
| PyAudio | 0.2.14 | Capture micro 16 kHz → Live |
| opencv-python | 4.13.0 | Vision, FaceID, Haar cascades |
| ultralytics | 8.4.12 | YOLO (fallback CPU du Hailo) |
| torch | 2.10.0 | Backend YOLO |
| numpy | 2.4.2 | Calculs vision + encodages |
| vosk / ollama | 0.3.45 / 0.6.1 | STT + LLM locaux (fallback) |
| psutil | 7.2.2 | Monitoring système |
60 dépendances au total. Projet 100% portable — chemins relatifs, clés dans .env.
Interface IA locale pour piloter Orion — Electron + React + Tailwind
Conversation streaming avec modèles Ollama. Synthèse vocale Piper TTS, pièces jointes images, sauvegarde mémoire persistante, détection d'émotions.
Rendu Canvas 2D avec effets néon et particules. 9 émotions, yeux kawaii avec gaze tracking, sourcils 7 couches, bouche synchronisée avec la parole.
Joystick tactile pour pilotage temps réel via Wi-Fi. Modes Manuel / Autonome / Suivre. Watchdog serveur 500ms, stop retries (3 tentatives).
SQLite intégrée (better-sqlite3). Catégories : conversations, préférences, faits, compétences. API REST complète avec tags et épinglage.
Proxy Ollama sur port 11435. Proxy contrôle robot vers orion.local:5000. Endpoint TTS HTTP, interception LLM pour détection d'émotions streaming.
Analyse d'images via modèles multimodaux (LLaVA). Le Pi5 interroge /face/status (JSON) et rend le visage localement — plus de stream MJPEG.
┌─────────────────┐ /face/status ┌──────────────────┐
│ Ce PC (GPU) │ ←── poll JSON ──────│ Pi5 (rendu local)│
│ Electron + React│ │ Écran 10.1" │
│ Détection émotion│ │ 600×1024 portrait│
└────────┬────────┘ └──────────────────┘
│
Proxy :11435
├── /api/chat → Ollama :11434 (+ détection émotion)
├── /face/status → État expression (JSON polling)
├── /control/* → orion.local:5000 (Flask API)
├── /tts → Piper TTS
└── /memory/* → SQLite local