Strands Robots transforme un simple agent IA en chef d'orchestre capable de piloter des robots physiques, des simulations et des jeux de données LeRobot. Voici comment tout s'assemble.

UNE RÉVOLUTION DANS L'IA ROBOTIQUE : TOUT DANS UN SEUL AGENT

Imaginez un monde où pour apprendre à un robot une nouvelle tâche, il ne faut plus cinq outils différents : un pour enregistrer des démonstrations, un autre pour entraîner le modèle, un troisième pour tester en simulation, un quatrième pour déployer sur du Matériel, et un cinquième pour coordonner plusieurs robots. Strands Robots, un SDK open source d'AWS sous licence Apache 2.0, change la donne en intégrant tout cela dans un seul agent IA.

Cet agent ne remplace pas les outils existants comme LeRobot : il les unifie. LeRobot gère l'enregistrement des démonstrations et le calibrage du matériel, tandis que Strands Robots s'occupe de l'orchestration globale. Résultat ? Un seul flux de travail, une seule boucle d'agent, et une compatibilité totale entre simulation et matériel réel.

« Un seul agent IA pour piloter robots physiques, simulations et jeux de données LeRobot. Plus besoin de jongler entre cinq outils séparés. »

COMMENT ÇA MARCHE ? CINQ ÉTAPES CLÉS DANS UN SEUL AGENT

Le tutoriel complet se trouve dans les fichiers examples/lerobot/hubtohardware.py et hubtohardware.ipynb du dépôt strands-labs/robots. Voici les cinq étapes que l'agent réalise en une seule boucle :

  1. Construire l'agent avec les outils LeRobot intégrés
  2. Enregistrer une démonstration en simulation au format LeRobotDataset
  3. Exécuter une politique d'IA sur le même robot
  4. Déployer le même code sur un robot physique SO-101 avec un simple changement de paramètre
  5. Diffuser des commandes à toute une flotte de robots via un réseau maillé (mesh)

Le notebook hubtohardware.ipynb est spécialement conçu pour une exécution en simulation sans matériel, sans GPU et sans même besoin de compte Hugging Face. Parfait pour tester avant de passer au matériel réel.

DEPUIS LA SIMULATION JUSQU'AU MATÉRIEL : UN SEUL CODE POUR DEUX MONDES

Le cœur de l'innovation réside dans la façon dont Strands Robots gère la transition entre simulation et matériel. Prenez ce simple extrait de code :

from strands_robots import Robot
from strands import Agent

arm = Robot("so100")  # mode="sim" par défaut (sans matériel, sans risque)
agent = Agent(tools=[arm])
agent("Pick up the red cube")

Ce code fonctionne exactement de la même manière que le robot soit en simulation ou branché sur du matériel réel. La seule différence ? Un paramètre à changer : mode="real" au lieu de mode="sim".

En mode simulation, le robot SO-100 utilise MuJoCo, un moteur de physique très réaliste, pour simuler les mouvements. En mode réel, il contrôle un bras robotique physique SO-100 ou SO-101. Les deux modes partagent la même structure de données et la même interface, ce qui rend les jeux de données interchangeables.

« Robot("so100") en mode simulation utilise MuJoCo. En mode réel, il contrôle un bras physique SO-100. Le même code fonctionne dans les deux cas. »

ENREGISTRER DES DÉMONSTRATIONS : DEPUIS LA SIMULATION JUSQU'AU HUB HUGGING FACE

Pour enregistrer une démonstration en simulation, l'agent utilise un outil intégré qui écrit directement au format LeRobotDataset, le même format utilisé par LeRobot pour les données réelles. Voici comment faire :

from strands import Agent
from strands_robots import Robot

robot = Robot("so100")  # mode="sim" par défaut
agent = Agent(tools=[robot])

agent(
    "Record a demonstration of 'pick the red cube and place it in the box' "
    "using the Mock policy provider at FPS 30. Write the dataset to "
    "myuser/cubepicking_sim and push to the Hub when done."
)

L'outil Mock policy génère des actions aléatoires pour que le flux fonctionne de bout en bout, même sans modèle entraîné. Le robot bouge de manière aléatoire, mais les données enregistrées (états des articulations, images des caméras, actions) sont structurées exactement comme un vrai jeu de données LeRobot. Vous pouvez ensuite pousser ce jeu de données sur le Hugging Face Hub pour le partager ou l'entraîner.

Pour utiliser un vrai modèle entraîné dès l'enregistrement, ajoutez simplement le paramètre --policy lerobotlocal --checkpoint allenai/MolmoAct2-SO100101. Le reste du code reste identique.

LA STRUCTURE D'UN JEU DE DONNÉES LEROBOT : UN FORMAT UNIQUE POUR TOUT

Un jeu de données LeRobot est organisé en épisodes, chaque épisode contenant des séquences d'observations et d'actions. Voici comment le lire :

from lerobot.datasets.lerobot_dataset import LeRobotDataset

dataset = LeRobotDataset("myuser/cubepicking_sim")
print(dataset.features)
# {'observation.state': Sequence(.),
#  'observation.images.front': VideoFrame(.),
#  'action': Sequence(.),
#  'episodeindex': Value(.), 'frameindex': Value(.), .}

Ce format est identique que les données viennent de la simulation ou du matériel réel. Les scripts d'entraînement de LeRobot peuvent lire les deux sans modification. Vous pouvez donc entraîner un modèle sur des données de simulation puis le déployer directement sur du matériel, sans conversion nécessaire.

ENREGISTRER DES DÉMONSTRATIONS SUR DU MATÉRIEL RÉEL : LES OUTILS DE LEROBOT

Pour enregistrer des démonstrations sur un robot physique SO-101, Strands Robots ne réinvente pas la roue. Il utilise directement les outils de calibrage et d'enregistrement de LeRobot :

lerobot-calibrate --robot.type=so101follower --robot.id=myfollower
lerobot-calibrate --robot.type=so101leader   --robot.id=myleader

lerobot-record \
  --robot.type=so101follower --robot.id=myfollower \
  --teleop.type=so101leader  --teleop.id=myleader \
  --dataset.repoid=myuser/cube_picking \
  --dataset.single_task='Pick up the red cube and place it in the box' \
  --dataset.num_episodes=25 \
  --dataset.pushtohub=true

Les fichiers de calibration doivent être placés dans ~/.cache/huggingface/lerobot/calibration/. Une fois l'enregistrement terminé, le jeu de données est poussé sur le Hub Hugging Face et peut être utilisé pour l'entraînement, exactement comme les données de simulation.

EXÉCUTER UNE POLITIQUE D'IA : DEPUIS LA SIMULATION JUSQU'AU MATÉRIEL

Une fois le jeu de données enregistré et poussé sur le Hub, l'étape suivante est d'exécuter une politique d'IA pour faire exécuter la tâche au robot. En simulation, l'agent utilise l'outil gr00t_inference pour gérer le conteneur d'inférence :

from strands import Agent
from strandsrobots import Robot, gr00tinference

robot = Robot("so100")  # mode="sim" par défaut
agent = Agent(tools=[robot, gr00t_inference])

agent(
    "Start GR00T inference on port 5555 with the cube-picking checkpoint "
    "from my_user/cube-picker. Then ask the robot to pick up the red cube."
)

Pour les développeurs qui préfèrent une inférence en local (sans conteneur Docker), il existe une alternative : LerobotLocalPolicy. Cet outil charge directement le modèle depuis le Hub Hugging Face :

from strandsrobots.policies import createpolicy
policy = createpolicy("lerobot/actalohasimtransfercubehuman")

LerobotLocalPolicy prend en charge plusieurs types de modèles : ACT, Diffusion Policy, SmolVLA, π0, et π0.5. Pour les politiques de type flow-matching comme π0 ou SmolVLA, le Real-Time Chunking s'active automatiquement pour optimiser les performances.

Attention : LerobotLocalPolicy charge les modèles Hugging Face avec trustremotecode=True. Pour activer cette option, définissez la variable d'environnement STRANDSTRUSTREMOTE_CODE=1. Ne chargez que des modèles provenant d'organisations de confiance.

PASSER DU SIMULATEUR AU ROBOT PHYSIQUE : UN SEUL PARAMÈTRE À CHANGER

Le déploiement sur du matériel physique est presque identique à l'exécution en simulation. La seule différence est dans la création du robot :

robot = Robot(
    "so100",
    mode="real",
    port="/dev/ttyACM0",
    dataconfig="so100dualcam",
    cameras={
        "front": {"type": "opencv", "indexorpath": "/dev/video0", "fps": 30},
        "wrist": {"type": "opencv", "indexorpath": "/dev/video2", "fps": 30},
    },
)
agent = Agent(tools=[robot, gr00t_inference])

agent(
    "Start GR00T inference on port 5555 with the cube-picking checkpoint "
    "from my_user/cube-picker. Then ask the robot to pick up the red cube."
)

Le port /dev/ttyACM0 correspond au port série où est branché le robot. Les caméras frontale et poignet sont configurées pour capturer des images à 30 images par seconde. Une fois le robot calibré (voir étape suivante), l'agent peut exécuter la même commande qu'en simulation pour faire saisir le cube rouge au robot physique.

CALIBRER LE ROBOT : UNE ÉTAPE INDISPENSABLE AVANT LE DÉPLOIEMENT

Avant de pouvoir utiliser un robot physique, il doit être calibré. Strands Robots utilise les outils de calibrage de LeRobot :

lerobot-calibrate --robot.type=so101follower --robot.id=myfollower
lerobot-calibrate --robot.type=so101leader --robot.id=myleader

Les fichiers de calibration générés sont stockés dans ~/.cache/huggingface/lerobot/calibration/. Tous les outils Strands qui interagissent avec le matériel lisent ces fichiers. Si un fichier de calibration est manquant, l'agent affiche une erreur provenant du pilote LeRobot.

COORDONNER PLUSIEURS ROBOTS : LE RÉSEAU MAILLÉ (MESH) DE STRANDS

Jusqu'à présent, nous avons contrôlé un seul robot à la fois. Mais que faire avec une flotte de robots ? C'est là que le réseau maillé (mesh) de Strands Robots entre en jeu. Imaginez un bras leader sur votre bureau téléopérant un bras follower dans une autre pièce, ou cinq SO-101 exécutant la même tâche en entrepôt en parallèle. Tous ces scénarios sont possibles grâce au réseau maillé.

Le réseau maillé est basé sur Zenoh, un protocole peer-to-peer open source. Pas besoin de gérer des adresses IP, d'écrire du code de découverte ou de choisir un courtier : les nouveaux robots apparaissent automatiquement sur le réseau dès qu'ils sont connectés. L'agent peut alors communiquer avec tous les robots simultanément.

Chaque instance de Robot() et de Simulation() rejoint automatiquement le réseau maillé Zenoh. L'outil robot_mesh fournit à l'agent un vocabulaire pour les opérations de flotte :

agent = Agent(tools=[robot_mesh])
agent(
    "List every robot and simulation on the mesh. "
    "Then send 'go to home pose' to each one in parallel."
)

L'agent appelle robot_mesh(action="peers") pour lister tous les robots et simulations disponibles, puis robot_mesh(action="broadcast", .) pour envoyer une commande structurée à chaque pair avec un délai d'attente. Pour étendre ce réseau au-delà du réseau local, ajoutez l'option [mesh-iot] pour router le trafic via AWS IoT Core.

Par défaut, toutes les actions physiques du réseau maillé nécessitent une approbation humaine avant exécution : diffusion de commandes à toute la flotte, arrêt d'urgence, et commandes individuelles. Vous pouvez ajuster ce comportement avec la variable d'environnement STRANDSMESHHITL_ACTIONS (valeurs possibles : all, none, ou une liste de commandes séparées par des virgules).

« Le réseau maillé Zenoh permet de contrôler une flotte de robots sans gérer d'adresses IP ni de code de découverte. Les nouveaux robots apparaissent automatiquement. »

DEVICE CONNECT : UNE COUCHE RÉSEAU POUR LES FLOTTES DE PRODUCTION

Pour les flottes de production, Strands Robots propose Device Connect, une couche réseau développée en collaboration avec Arm. Cette solution gère la découverte des appareils, leur présence, les appels de procédure à distance structurés, le routage d'événements et la sécurité. L'outil robot_mesh utilise Device Connect lorsqu'il est disponible, et revient au réseau maillé Zenoh par défaut. Le code de l'agent reste donc identique dans les deux cas.

ESSAYEZ VOUS-MÊME : LE TUTORIEL COMPLET SUR GITHUB

Pour tester tout cela par vous-même, le dépôt strands-labs/robots sur GitHub contient le tutoriel complet. Vous y trouverez :

  • Le script CLI examples/lerobot/hubtohardware.py
  • Le notebook hubtohardware.ipynb pour une exécution pas à pas en simulation
  • Tous les exemples MuJoCo et LIBERO pour explorer d'autres scénarios

Pour exécuter le tutoriel en simulation sans matériel, GPU ni compte Hugging Face, suivez ces commandes :

uv pip install "strands-robots[sim-mujoco,lerobot,mesh]"
git clone https://github.com/strands-labs/robots.git
cd robots
export STRANDSMESHLOCAL_DEV=1
python examples/lerobot/hubtohardware.py

Le notebook est particulièrement recommandé pour les débutants : ouvrez-le dans JupyterLab et exécutez les cellules de haut en bas en mode simulation.

PRÉREQUIS : CE DONT VOUS AVEZ BESOIN POUR COMMENCER

Pour exécuter le tutoriel en mode simulation par défaut (sans matériel) :

  • Python 3.12+
  • Système d'exploitation : Linux ou macOS (Apple Silicon supporté pour le backend MuJoCo)
  • Un fournisseur de modèle compatible Strands pour le raisonnement de l'agent (Amazon Bedrock, Anthropic API, OpenAI, Ollama en local)

Installez Strands Robots avec les extras nécessaires :

uv pip install "strands-robots[sim-mujoco,lerobot,mesh]"

Pour le déploiement sur du matériel réel, des politiques réelles et le push vers le Hub Hugging Face, vous aurez besoin de :

  • Un compte Hugging Face avec un token d'accès en écriture
  • Un ou plusieurs robots compatibles LeRobot (par exemple, une paire SO-101 follower et leader)
  • Les fichiers de calibration placés dans ~/.cache/huggingface/lerobot/calibration/
  • Pour l'inférence locale avec GR00T : un GPU NVIDIA avec au moins 16 Go de mémoire vidéo et Docker installé

LES DÉTAILS TECHNIQUES : COMMENT TOUT S'ASSEMBLE

Deux choix de conception rendent tout cela possible :

  1. Robot("so100") retourne une simulation par défaut (sans matériel, sans risque), et mode="real" retourne un robot physique piloté par LeRobot. Le code de l'agent est identique dans les deux modes.
  2. L'outil DatasetRecorder qui écrit un LeRobotDataset est partagé entre le chemin de simulation et l'enregistrement matériel de LeRobot. Résultat : un jeu de données capturé dans MuJoCo et un autre capturé depuis un SO-101 physique ont le même format sur disque.

Les politiques d'IA (GR00T, LerobotLocal, MolmoAct2) sont accessibles via une interface commune, ce qui permet de basculer facilement entre elles en changeant simplement un paramètre dans la commande de l'agent.

LES OUTILS DE POLITIQUE : GR00T, LEROBOTLOCAL ET MOLMOACT2

Strands Robots prend en charge plusieurs fournisseurs de politiques :

  • GR00T : un modèle d'IA développé par NVIDIA pour le contrôle de robots, accessible via un conteneur Docker
  • LerobotLocal : pour une inférence locale sans conteneur, chargeant directement les modèles depuis le Hub Hugging Face
  • MolmoAct2 : un modèle spécifique pour les robots SO-100 et SO-101, détecté automatiquement via son config.json

Tous ces outils sont accessibles via la même interface, ce qui permet de basculer entre eux sans modifier le code de l'agent. Par exemple, pour utiliser GR00T en inférence locale :

agent.tool.gr00t_inference(action="lifecycle", lifecycle="full", .)

GÉRER LE CYCLE DE VIE DES CONTENEURS : DEMARRER ET ARRÊTER GR00T

L'outil gr00t_inference permet de contrôler le cycle de vie du conteneur GR00T :

agent.tool.gr00t_inference(action="stop", port=5555)

Pour démarrer GR00T avec un checkpoint spécifique :

agent.tool.gr00t_inference(
    action="lifecycle",
    lifecycle="full",
    .
)

Le paramètre lifecycle="full" télécharge l'image Docker, récupère le checkpoint depuis le Hub, et démarre le conteneur en une seule commande.

LES VARIABLES D'ENVIRONNEMENT : PERSONNALISER LE COMPORTEMENT

Plusieurs variables d'environnement permettent de personnaliser le comportement de Strands Robots :

  • STRANDSTRUSTREMOTE_CODE=1 : active le chargement de code distant non vérifié (nécessaire pour LerobotLocalPolicy)
  • STRANDSMESHLOCAL_DEV=1 : active le développement local du réseau maillé Zenoh
  • STRANDSMESHAUTH_MODE=mtls : active l'authentification par certificats pour le réseau maillé
  • STRANDSMESHBACKEND=bridge : utilise Device Connect pour les flottes de production

LES LIMITES ET LES SÉCURITÉS : CE QU'IL FAUT SAVOIR

Par défaut, toutes les actions physiques du réseau maillé nécessitent une

Sources :
  • Hugging Face Blog

L'indépendance de CLODCO est votre garantie.

Pour que l'actualité de l'IA reste sans filtre et sans concession, votre soutien est indispensable. Votre contribution est le seul moteur de notre liberté éditoriale.

Soutenir CLODCO