Jarvis

Description du projet

Jarvis est un système d’assistance intelligent conçu pour aider les personnes vivant avec une négligence spatiale à gagner en autonomie au quotidien, tout en transformant les gestes de tous les jours en opportunités de rééducation continue.

La négligence spatiale est un trouble qui pousse une personne à ignorer partiellement une zone de l’espace, souvent le côté gauche. Concrètement, cela peut vouloir dire ne pas voir un obstacle en marchant, ne pas remarquer un objet pourtant visible, ou ne manger qu’une moitié de l’assiette. Ce problème a un impact direct sur la sécurité, l’autonomie et la qualité de vie.

Notre idée est simple : au lieu de limiter la thérapie à des séances ponctuelles, nous voulons l’intégrer dans la vraie vie. Jarvis accompagne l’utilisateur pendant ses activités quotidiennes, le guide avec un feedback haptique discret, et l’aide à réentraîner son attention spatiale en continu.

Le projet a été développé dans le cadre d’un hackathon avec des ressources limitées. Nous avons donc conçu une architecture pragmatique, portable et peu coûteuse, capable de relier vision par caméra, commande vocale, logique temps réel et feedback physique via Arduino.


Ce que fait Jarvis

Jarvis intervient dans plusieurs situations du quotidien :

1. Aide à la mobilité

Quand l’utilisateur se déplace, le système surveille la présence d’obstacles du côté négligé. Si un obstacle est détecté, Jarvis envoie une vibration légère pour attirer l’attention de la personne et l’aider à réagir.

2. Recherche d’objet par la voix

Si l’utilisateur ne trouve pas un objet, il peut demander de l’aide à voix haute en utilisant le mot-clé “Jarvis”. Le système écoute la commande, identifie l’objet demandé, puis analyse le flux caméra en direct. Dès que l’objet apparaît dans le champ de vision, une vibration est déclenchée pour prévenir l’utilisateur.

3. Aide pendant les repas

Jarvis détecte lorsqu’une personne est en train de manger et surveille la manière dont l’assiette est consommée. Si l’utilisateur mange seulement d’un côté, le système déclenche une vibration pour rappeler qu’une partie de l’espace est en train d’être négligée.

4. Thérapie intégrée au quotidien

L’objectif n’est pas seulement d’assister, mais aussi de réentraîner progressivement l’attention. Chaque rappel haptique agit comme un petit signal thérapeutique intégré dans une action réelle : marcher, chercher, manger.


Architecture globale

Le système est organisé en 4 couches qui communiquent en continu :

  1. Client web mobile
  2. Backend Flask
  3. Services métier temps réel
  4. Chaîne hardware Arduino

Cette architecture nous permet de séparer clairement :

  • la capture audio/vidéo ;
  • l’orchestration en temps réel ;
  • la logique métier de vision, voix et modes ;
  • l’exécution physique côté capteurs et actionneurs.

1. Client web mobile

Le client est une application web légère basée sur index.html et app.js.

Son rôle est de :

  • ouvrir la caméra et le micro depuis le navigateur ;
  • transmettre les flux au backend avec WebRTC ;
  • piloter certaines actions via des endpoints REST ;
  • recevoir l’état du système en temps réel via SSE (Server-Sent Events).

Responsabilités principales

  • Accès aux périphériques avec WebRTC
  • Création d’une RTCPeerConnection
  • Envoi de l’offre SDP au backend
  • Réception des événements temps réel :
    • voix
    • object search
    • mode runtime
    • état Arduino

Le choix d’un client web mobile rend le prototype simple à déployer : un téléphone suffit pour fournir la caméra POV, le micro et l’interface utilisateur.


2. Backend Flask : orchestrateur temps réel

Le backend est construit avec Flask et agit comme le cerveau central du système.

Points d’entrée principaux

  • __main__.py
  • __init__.py

Blueprints montés par le backend

  • WebRTC : api.py
  • Arduino : arduino.py
  • Voix : voice.py
  • Recherche d’objet : object_search.py
  • Mode runtime : mode.py

Composition des services

Tous les services métier sont instanciés et connectés dans services.py.

Le backend reçoit les flux du téléphone, déclenche les traitements nécessaires, agrège les signaux provenant de la voix, de la vision et du hardware, puis décide des actions à envoyer à l’Arduino.

En pratique, Flask joue ici le rôle d’orchestrateur temps réel entre :

  • l’utilisateur ;
  • le flux média ;
  • les modèles IA ;
  • la logique de modes ;
  • le feedback physique.

3. Services métier

Cette couche contient la logique centrale du projet.

Gestion de session

Fichier : session_manager.py

Le SessionManager gère les sessions et distingue deux rôles :

  • sender : l’appareil principal qui envoie audio + vidéo ;
  • spectator : un client secondaire qui peut observer le flux.

Quand une session sender est créée, le backend démarre aussi :

  • le service de voix ;
  • le service de recherche d’objet ;
  • le gestionnaire de modes.

Le mode spectator n’est autorisé que si le flux vidéo du sender est déjà disponible.


Traitement WebRTC

Fichier : webrtc_session.py

Le composant WebRtcPeerSession consomme les flux audio et vidéo reçus du sender.

Côté vidéo

Les frames sont envoyées vers :

  • l’analyse visuelle ;
  • le service de recherche d’objet ;
  • le gestionnaire de modes.

Côté audio

Les chunks audio sont convertis en PCM, puis transmis au service voix pour transcription et détection du wake-word.

Pour le spectator, le système utilise MediaRelay afin de relayer le flux du sender sans dupliquer inutilement la capture.


Voix : transcription et wake-word

Fichier : voice.py

La couche voix envoie les chunks audio vers un coordinateur de transcription en temps réel :

  • Audio chunks
  • VoiceCoordinator
  • OpenAI Realtime

Le système récupère :

  • les transcriptions finales ;
  • la détection du mot-clé “jarvis”.

Ces événements sont ensuite exposés au front via :

  • /api/voice/events

Le wake-word joue un rôle central dans l’expérience : il permet de passer d’un fonctionnement passif à une interaction explicite initiée par l’utilisateur, notamment pour la recherche d’objet.


Recherche d’objet

Fichier : object_search.py

Après la détection du mot “Jarvis”, le système entre en mode object search et attend une commande vocale décrivant l’objet à trouver.

Cette étape repose sur deux sous-blocs :

1. Résolution de la commande vocale

Le texte est transformé en labels exploitables par le détecteur via :

  • OpenAI chat
  • ObjectTargetResolver

2. Détection visuelle

L’image caméra est analysée pour déterminer :

  • si l’objet est trouvé ou non ;
  • sa position horizontale dans l’image.

Cette détection est réalisée par :

  • Grounding Dino

Le système utilise aussi la position du joystick Arduino pour ajuster une ligne de référence gauche/droite, ce qui permet d’adapter plus finement la logique de signalement selon l’orientation ou les préférences du dispositif.

Les statuts sont diffusés au front via :

  • /api/object-search/events

Mode adaptatif

Fichier : mode_manager.py

Le ModeManager agrège les signaux provenant de plusieurs services pour décider du mode actif du système.

Modes principaux

  • idle
  • eating
  • writing
  • generalist
  • object_search

Rôle du mode manager

Il combine :

  • les événements voix ;
  • les résultats de recherche d’objet ;
  • les signaux visuels ;
  • les détections contextuelles comme l’alimentation ou l’écriture.

À partir de ces signaux, il détermine quel comportement doit être actif à un instant donné et peut déclencher des vibrations adaptées côté backend.

L’état du mode courant est exposé en SSE via :

  • /api/mode/events

Détection d’alimentation et d’écriture

Fichier : eating_detection.py

Ce module permet de contextualiser les actions observées dans le flux vidéo.

Par exemple, en situation de repas, le système peut :

  • vérifier qu’une assiette est bien présente ;
  • déterminer si l’utilisateur est en train de manger ;
  • détecter si seule une partie de l’assiette est consommée.

Cette logique permet de sortir d’un système purement réactif pour entrer dans une logique contextuelle, où Jarvis adapte son comportement à l’activité réelle de la personne.


4. Chaîne hardware : Python vers Arduino

La dernière couche transforme les décisions logicielles en actions physiques.

Transport

Fichier : arduino_transport.py

La communication entre le backend Python et l’Arduino passe par :

  • le port série
  • ou le Bluetooth RFCOMM

Protocole

Fichier : uart_protocol.py

Les commandes sont encodées sous forme de trames binaires avec :

  • un protocole UART custom ;
  • une validation par CRC16.

Cela garantit une communication plus fiable entre le backend et le firmware embarqué.


Firmware embarqué

Fichiers principaux

  • main.cpp
  • FirmwareApplication.cpp
  • UartProtocolEndpoint.cpp

Spécification

  • uart-protocol.md

Le firmware reçoit les commandes du backend et pilote les composants embarqués :

  • moteur de vibration ;
  • capteur de distance ;
  • joystick ;
  • accéléromètre.

Il renvoie aussi la télémétrie au backend toutes les 50 ms, notamment :

  • distance ;
  • accélération ;
  • position joystick.

Cette télémétrie remonte ensuite vers le frontend via :

  • /api/arduino/events

Communication de bout en bout

Voici comment le système fonctionne de manière complète, du téléphone jusqu’au moteur de vibration.

1. Négociation de session

Le front envoie :

  • POST /api/webrtc/offer

Le backend :

  • crée une session via SessionManager ;
  • détermine si le client est sender ou spectator ;
  • démarre les services nécessaires si le client est sender.

2. Flux média WebRTC

Le sender pousse audio + vidéo vers le backend.

Le WebRtcPeerSession :

  • distribue les frames vidéo vers les analyseurs ;
  • convertit les chunks audio et les transmet au moteur voix.

3. Traitement voix

L’audio est transcrit en temps réel. Quand “Jarvis” est détecté :

  • un événement est généré ;
  • le système peut basculer en object search.

4. Recherche d’objet

Le backend attend la commande utilisateur, la convertit en cible visuelle, puis inspecte le flux caméra pour retrouver l’objet. Quand l’objet apparaît, Jarvis déclenche une vibration.

5. Gestion des modes

Le ModeManager combine toutes les informations disponibles pour choisir le bon mode et éviter des comportements contradictoires.

6. Action sur le hardware

Le backend crée une ActuatorCommand, l’encode via le protocole UART, puis l’envoie à l’Arduino. Le firmware exécute la commande et renvoie sa télémétrie.

7. Retour temps réel vers le front

Tous les états importants sont renvoyés au navigateur via SSE :

  • état voix ;
  • état object search ;
  • mode courant ;
  • état et télémétrie Arduino.

Défis techniques

Construire Jarvis nous a confrontés à plusieurs défis :

Orchestration temps réel

Nous devions faire communiquer en continu plusieurs composants :

  • flux WebRTC ;
  • transcription vocale ;
  • détection visuelle ;
  • moteur de modes ;
  • microcontrôleur.

Fusion multimodale

Le système doit agréger plusieurs signaux :

  • ce que l’utilisateur dit ;
  • ce que la caméra voit ;
  • ce que les capteurs mesurent ;
  • le contexte d’usage actuel.

Fiabilité du feedback

Un mauvais signal peut être gênant. Il fallait donc éviter les vibrations inutiles ou contradictoires et privilégier des alertes courtes, simples et pertinentes.

Contraintes de hackathon

Nous avons dû bâtir une solution crédible avec peu de temps, peu de matériel et une architecture suffisamment légère pour rester démontrable rapidement.


Et après ?

À plus long terme, nous aimerions :

  • améliorer la robustesse de la détection d’objets et de contextes ;
  • personnaliser les vibrations selon le type d’alerte ;
  • suivre les progrès de l’utilisateur dans le temps ;
  • adapter le système à différents profils de négligence spatiale ;
  • miniaturiser davantage le dispositif.

En une phrase

Jarvis est un système temps réel mêlant voix, vision et feedback haptique pour aider les personnes atteintes de négligence spatiale à être plus autonomes, tout en transformant leurs activités quotidiennes en thérapie continue.

Built With

Share this project:

Updates