Constructeur d'Environnements Simulés (Sim Env Builder)

Construit un environnement 3D simulé (scènes de robotique, RL, autonomie – rues de voitures autonomes, bras robotisés, drones, robots quadrupèdes, entrepôts, maisons, fermes, environnements marins, spatiaux, sportifs, multi-agents) dans MuJoCo ou NVIDIA Isaac Sim à partir d'une description. Choisit le backend, confirme le cahier des charges avec l'utilisateur, récupère des modèles 3D depuis Poly Pizza (via le MCP Polypizza) avec des solutions de repli procédurales, construit une scène testée + un environnement de type Gymnasium, et effectue des tests de rendu, de visuels et de physique. À utiliser à chaque fois que l'utilisateur demande de créer, générer, construire ou configurer un environnement de simulation, une scène simulée, un monde virtuel, un environnement RL/robotique ou un jumeau numérique.

Qu'est-ce que Constructeur d'Environnements Simulés (Sim Env Builder) ?

Ce skill permet à un agent IA (comme Claude Code, Cursor, Codex ou similaire) de construire automatiquement un environnement de simulation 3D complet à partir d'une simple description textuelle. Il est particulièrement utile pour les développeurs en robotique, en apprentissage par renforcement (RL) ou en conception autonome qui ont besoin d'un environnement physique précis et visuellement cohérent avec un minimum d'interactions. Le skill fonctionne en plusieurs phases : (1) configuration de l'environnement Python avec MuJoCo, trimesh, etc. ; (2) sélection du backend (MuJoCo pour un usage général et rapide, ou NVIDIA Isaac Sim pour le rendu photoréaliste RTX et les grands datasets synthétiques, nécessitant un GPU NVIDIA) ; (3) confirmation du cahier des charges avec l'utilisateur via un brief court listant les actifs, le robot, le contrôleur, les contraintes physiques et les livrables ; (4) recherche d'actifs 3D sur Poly Pizza (via le MCP Polypizza) avec téléchargement et validation visuelle, et utilisation de modèles procéduraux en cas d'échec ; (5) construction de la scène MuJoCo (fichier scene.xml), d'un environnement Gymnasium (env.py), d'un contrôleur de démonstration (controller.py), de vérifications de tâche (task_checks.py) et éventuellement d'un module world.py pour la dynamique monde ; (6) exécution complète des trois séries de tests de fumée (rendu, examinateur physique et vérification visuelle humaine via les captures d'écran) ; et (7) livraison des fichiers avec README.md, REPORT.md et toutes les métriques. Le skill insiste sur l'importance de la confirmation préalable, de la qualité visuelle (l'agent doit regarder les rendus), de l'échelle réaliste, de la robustesse des vérifications et de la traçabilité des décisions.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/YangLiu68/sim-env-builder/tree/HEAD/plugin/skills/sim-env-builder

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait Constructeur d'Environnements Simulés (Sim Env Builder) ?

Objectif : à partir d'une description, livrer un environnement simulé fonctionnel, physiquement cohérent et visuellement satisfaisant en aussi peu d'interactions que possible (idéalement : demande -> une confirmation -> terminé). Barre de qualité : chaque test de fumée passe, vous avez REGARDÉ les rendus et ils correspondent à la demande.

SKILL_DIR ci-dessous = le répertoire de ce fichier. Les helpers Python se trouvent dans SKILL_DIR/scripts/simkit.

Phase 0 – Configuration (1 minute)

PY=$(bash SKILL_DIR/scripts/setup_env.sh)       # python avec mujoco, trimesh, usd-core, gymnasium
$PY SKILL_DIR/scripts/check_platform.py           # OS, GPU, disponibilité d'Isaac

Choisissez le dossier de l'environnement : ./<nom_court_en_snake_case>/ dans le répertoire courant, sauf si l'utilisateur en a nommé un.

Phase 1 – Choisir le backend (lire reference/backend_choice.md)

Isaac Sim nécessite un GPU NVIDIA RTX sous Linux/Windows. MuJoCo fonctionne partout.

  • MuJoCo : par défaut. Manipulation avec contact et locomotion, itération rapide, CPU/laptop/macOS, scènes petites à moyennes, contrôle basé sur des modèles, recherche reproductible, MJX/Warp pour le RL GPU.
  • Isaac Sim : rendu photoréaliste RTX ou données synthétiques (Replicator), réalisme des capteurs lidar/caméra RTX, milliers d'environnements parallèles dans Isaac Lab, grandes scènes USD/Omniverse, utilisateur déjà sur Isaac.
  • Si Isaac est le meilleur choix mais isaac_runnable_here est false, dites-le dans la confirmation et proposez : construire + tester entièrement dans MuJoCo ici ET exporter une scène USD + un script de test Isaac pour la machine GPU (reference/isaac.md). Ne prétendez jamais avoir des résultats Isaac que vous n'avez pas exécutés.

Phase 2 – Confirmer avec l'utilisateur AVANT de construire (reference/confirmation.md)

  1. Commencez par un scan rapide des actifs pour que le brief soit concret : un appel find_assets (MCP Polypizza) listant chaque rôle d'objet, 1 à 3 requêtes chacun.
  2. Envoyez UN brief court (modèle dans reference/confirmation.md) : backend + pourquoi, ce qui sera dans la scène, le robot/agent et son interface de contrôle, quels actifs viennent de Poly Pizza vs procédural, physique clé (gravité, frottement, pas de temps), livrables, et 2 à 4 questions qui portent chacune votre recommandation par défaut.
  3. Posez la question avec AskUserQuestion si cet outil existe. Sinon, terminez votre tour avec le brief comme message et attendez. Ne construisez pas avant que l'utilisateur réponde. Exception : l'utilisateur a dit de ne pas demander / « construis-le » -> écrivez les hypothèses dans SPEC.md, continuez.
  4. Enregistrez les décisions confirmées dans <env>/SPEC.md (modèle dans reference/confirmation.md).

Phase 3 – Actifs : Poly Pizza d'abord, repli procédural (reference/assets.md)

Pour chaque rôle d'objet :

  1. find_assets / search_models -> lisez le verdict (trouvé / faible / non trouvé).
  2. trouvé ou faible -> preview_models([...ids]) et REGARDEZ : bon objet ? style cohérent ? rejetez les jouets, les dessins animés dans les scènes réalistes, les lots multi-objets, les classes d'échelle erronées.
  3. Accepté -> download_model(id, "<chemin_absolu_env>/assets/polypizza", "<rôle>") (les crédits sont enregistrés automatiquement dans assets/polypizza/CREDITS.md).
  4. non trouvé, rejeté ou erreur de téléchargement -> procédural : recettes simkit.procedural (arbres, bâtiments, meubles, accessoires de rue, portails, vaisselle, terrain...) ou composez les vôtres à partir de primitives / lathe / extrude / rock. Ne laissez jamais un objet demandé de côté.
  5. Écrivez <env>/assets/ASSETS.md : rôle | source (ID Poly Pizza + titre + licence, ou recette procédurale) | taille réelle | pourquoi. Si le titre d'un modèle diffère du rôle (« Banc de Parc » utilisé comme table de pique-nique), dites-le et expliquez pourquoi il convient toujours – ou cherchez à nouveau / passez au procédural. Listez aussi les candidats REJETÉS (id + raison : « style cartoon », « lot de 12 objets ») pour que la recherche soit traçable même si tout finit en procédural. Les modèles Poly Pizza sont des maillages statiques : les robots articulés et les véhicules proviennent de simkit.robots (vous pouvez les habiller avec un maillage Poly Pizza comme géométries visuelles).

Phase 4 – Construction (reference/robots.md, templates/)

mkdir -p <env> && cp -r SKILL_DIR/scripts/simkit <env>/simkit       # encapsulé : l'environnement est autonome
cp SKILL_DIR/templates/build_env.py SKILL_DIR/templates/env.py SKILL_DIR/templates/view.py <env>/   # éditez les deux premiers
  • build_env.py regénère tout de manière déterministe (avec graine) -> scene.xml. Utilisez simkit.scene.Scene (ciel, sol, lumières, caméras de visée, sections pour MJCF brut), simkit.assets.glb_to_mujoco(glb, env, name, target={"height": m}, yaw_deg=..) pour les modèles Poly Pizza (taille réelle, Z vers le haut, pièces par couleur, collision boîte/enveloppe/pièces), simkit.procedural pour les replis et le terrain, simkit.robots pour les robots testés (quadrotor, voiture, diff_drive, bras
    • pince, quadrupède) et leurs contrôleurs.
  • L'échelle réelle est obligatoire (tableau de tailles dans reference/assets.md). Les objets reposent sur leur support.
  • Chaque classe d'objet nommée par l'utilisateur doit être clairement visible à une taille lisible dans la vue d'ensemble (un « sentier rocheux » a besoin de rochers visibles, pas de grains de 7 cm ; un « terrain accidenté » a besoin de bosses visibles à l'échelle du robot). Le test de fumée liste les petits grains sous hints.
  • Au moins 2 caméras nommées : une vue d'ensemble et une cadrée sur le sujet (le robot/l'objet de la tâche remplit environ 30 à 50 % du cadre ; montée sur le robot le cas échéant). Les caméras de capteur fixes ne doivent pas être obstruées par la pose de repos du robot (le fumée signale > 15 % de couverture).
  • world.py (quand la scène a sa propre dynamique) : make_world(model) -> world(model, data), appelé AVANT chaque pas de physique par le fumée, l'examinateur, la vitrine, env.py, view.py et le tableau de bord. La flottabilité/la traînée, le vent, les convoyeurs, les cycles de feux de circulation, les piétons scriptés et les NPC automobiles vivent ici, jamais dans controller.py (un test passif ou une politique RL exécuterait sinon un monde où les bateaux coulent et les feux ne changent jamais). Les vérifications de tâche qui font avancer la simulation doivent aussi l'appeler.
  • controller.py : une politique de démonstration scriptée (make_controller(model) -> ctrl(model, data)) qui montre l'environnement en action (le drone vole les portes, la voiture suit l'itinéraire, le bras atteint l'objet...). Définissez DEMO_SECONDS = <durée de la démo complète> au niveau du module : le test de fumée filme alors et vérifie la démo ENTIÈRE (prendre, soulever, placer / chaque porte), pas seulement les 4 premières secondes.
  • task_checks.py : fonctions check_<nom>(model, data) -> {"status", "value", "expect", "details"} pour la physique au niveau de la tâche. Un check par critère de succès que l'utilisateur a énoncé ou confirmé (nommez-le d'après ses mots : « pieds en contact » -> check_feet_in_contact), plus la vérification de cohérence du spawn (le robot commence sur son support). Au moins 2. Écrivez les seuils ET la définition exacte de chaque métrique (point de référence, unités : « centre de la base du rover au centre de l'atterrisseur, mètres ») dans SPEC.md AVANT la première exécution et conservez-les : un échec de justesse signifie corriger le contrôleur/la scène, jamais assouplir le check (tout changement de seuil doit apparaître sous « Modifications par rapport au plan confirmé »). Un check passant à moins de 15 % de sa limite est signalé avec sa marge (« inclinaison 25,8 degrés vs limite 30 degrés »). Tout comportement que vous revendiquez (ralentissement dû à un obstacle, cycle de feux de circulation, flottabilité, maintien de la pince) nécessite un check qui l'exerce, par ex. placez un obstacle sur le chemin et affirmez que le robot s'arrête. Chaque propriété physique clé de la scène obtient un check mesuré avec une cible physique : la décélération de roulement d'une balle, la ligne de flottaison d'un bateau, la montée de pente d'un rover, le temps de chute en faible gravité, la force de maintien de la pince. Un capteur requis obtient aussi un check : rendez la caméra du robot pendant la démo et affirmez une image non vide qui montre la tâche (par exemple des rangées d'arbres devant) ; pour le lidar, affirmez des portées sensées. Exécutez chaque check de tâche sur le déroulement scripté ET 2-3 déroulements perturbés (autre graine, pose de départ, vitesse initiale, phase de lumière) – un check qui ne tient que pour un seul déroulement précis ne prouve pas grand-chose. Les checks de préhension nécessitent un contact entre LES DEUX coussinets de doigts et l'objet pendant le levage et le transport (lisez data.contact), pas seulement « l'objet est monté ».
  • Colliders : simples et honnêtes. Arbres : collider de tronc, canopée visuelle uniquement sauf si l'utilisateur veut des impacts de canopée. Multirotors : capsules de bras ou une enveloppe, pas une boîte qui avale les hélices. Accessoires non convexes (microscope, chaise, arche, étagère) obtiennent collision="parts" ou quelques primitives ; une enveloppe convexe autour d'eux bloque un espace visiblement vide (vérifiez collision_sheet.png).
  • env.py : reset/step/render de style Gymnasium avec observation de la tâche, récompense factice, terminaison. Son auto-test __main__ pilote l'environnement À TRAVERS l'API env avec le contrôleur de démonstration (ou une politique de référence) et affiche si l'objectif de la tâche est atteint – preuve que l'objectif est accessible.
  • Corps et marqueurs de débogage/rigging de caméra : groupe de géométries 4-5 (jamais rendu), pas dans les caméras de données.
  • Choses suspendues (lumières de plafond, panneaux suspendus, étagères murales) : nommez-les mounted_* ou hanging_* pour que le check d'objet flottant les ignore.
  • Éclairage : blanc neutre (pas de lumières teintées) ; au maximum 2-3 lumières supplémentaires ; vérifiez qu'un mur blanc reste blanc-gris dans les rendus.
  • Pas d'habillage non demandé au-delà de ce qui rend la scène correcte ; listez les extras optionnels dans le brief pour que l'utilisateur puisse les choisir.
  • Limite de temps : notez l'heure quand vous commencez à construire (date). Les éléments bonus/étirés (« plier est un bonus ») viennent seulement après que tous les indispensables passent, et sont supprimés en premier. Environ 60 minutes après le début de la construction, arrêtez de régler ce qui reste : finalisez REPORT.md et les résultats README et rapportez (éléments supprimés listés). Une construction qui ne rapporte jamais est pire qu'une construction avec un écart connu.
  • Budget : une fois que tous les indispensables existent et que tous les checks passent, arrêtez d'ajouter des extras – terminez le check visuel, le README et le rapport. Les extras vont dans le README comme idées.
  • Exécutez $PY build_env.py après chaque changement ; les erreurs de compilation portent des numéros de ligne.

Phase 5 – Tests de fumée (reference/smoke_tests.md). Tous les trois sont obligatoires.

cd <env> && $PY -m simkit.smoke scene.xml --out smoke --controller controller.py --task-checks task_checks.py
  1. Test de rendu – chaque caméra nommée + vues automatiques rendent des images non vides, éclairées, détaillées ; la segmentation montre quels objets sont visibles (les objets invisibles sont signalés).
  2. Examinateur physique – sondes solveur/contacts/frottement/gravité avec les propres paramètres de la scène, stabilité du déroulement, pénétration, chute à travers, stabilisation, réponses aux pas d'actionneurs, déterminisme, sensibilité au pas de temps, facteur temps réel, disposition (accessoires flottants / enfoncés / en interpénétration), plus vos checks de tâche.
  3. Vérification visuelle – VOUS devez ouvrir et regarder smoke/contact_sheet.png, smoke/filmstrip.png, smoke/collision_sheet.png et les gros plans dans smoke/renders/ (outil Lire), puis remplissez la liste de contrôle dans smoke/visual_check.md avec des observations concrètes. Corrigez chaque ÉCHEC. Enquêtez sur chaque AVERTISSEMENT (corrigez-le, ou expliquez dans le README pourquoi c'est attendu). Reconstruisez et relancez jusqu'à ce que le verdict soit PASS / PASS_WITH_WARNINGS-expliqué ET que la vérification visuelle soit honnêtement entièrement « oui ». Attendez-vous à 2-3 itérations ; le premier rendu est rarement correct. Exécutez aussi $PY env.py (actions aléatoires, observations finies).

Phase 6 – Livrable Isaac Sim (uniquement si Isaac a été choisi ; reference/isaac.md)

$PY -m simkit.usd_export scene.xml isaac/scene.usda (exportation + validation locale), copiez SKILL_DIR/templates/isaac_smoke.py dans isaac/, documentez comment l'exécuter sur la machine GPU. Indiquez clairement ce qui a été et n'a pas été exécuté.

Phase 7 – Livraison

<env>/README.md : ce qu'il y a dans la scène, comment exécuter (construction, fumée, environnement, visualiseur : $PY view.py, qui exécute le contrôleur de démonstration en direct ; mujoco.viewer simple montre seulement la physique passive), caméras, actionneurs, contrôleur, checks de tâche, crédits des actifs, limitations connues. Message final à l'utilisateur : ligne de verdict, ce qui a été construit, quels actifs proviennent de Poly Pizza vs procédural, résultats de fumée, chemins vers smoke/showcase.mp4 (la vidéo que les gens regardent), planche contact et filmstrip, tout ce qui n'est pas fait ou non vérifié, et une liste « Modifications par rapport au plan confirmé » (actifs ou licences échangés, tailles/comptes modifiés, extras supprimés) – vide si aucun, mais toujours présent. Copiez chaque nombre (checks réussis, scores, erreurs) depuis smoke/smoke_report.json et physics_report.json ; collez son summary_line textuellement ("Smoke PASS: examinateur 19 pass / 0 warn / 0 fail ; task checks 9/9 pass ; rendu ok") et n'écrivez jamais de comptes de mémoire. Commencez <env>/REPORT.md dès que la première exécution de fumée est terminée et mettez-le à jour après chaque correction, pour qu'une session interrompue laisse quand même un rapport ; le message final est sa dernière version.

Structure du livrable (conservez exactement ; les outils et tableaux de bord en dépendent)

<env>/
  SPEC.md  README.md  REPORT.md  build_env.py  scene.xml  env.py  view.py  controller.py  task_checks.py
  world.py                      (uniquement si la scène a sa propre dynamique)
  simkit/                       helpers encapsulés
  assets/polypizza/*.glb  assets/polypizza/CREDITS.md  assets/polypizza/polypizza_assets.json
  assets/meshes/  assets/procedural/  assets/ASSETS.md
  smoke/  (showcase.mp4 contact_sheet.png filmstrip.png collision_sheet.png renders/ rollout.mp4
           physics_report.json render_report.json smoke_report.json env_manifest.json
           SMOKE.md visual_check.md)
  isaac/  (uniquement pour Isaac : scene.usda, isaac_smoke.py, section README)

Règles durement acquises (chacune a déjà fait échouer une vraie construction)

  • Restez dans le périmètre confirmé. La démo montre ce sur quoi l'utilisateur s'est mis d'accord (par ex. « rester debout suffit » signifie une position stable, pas un nouveau contrôleur de locomotion). Consacrez le temps à la scène, aux actifs, aux checks et à la revue visuelle ; listez les idées d'extension dans le README.

  • Paramètres <visual> : sc.set_visual("map", znear=.., zfar=..) etc. Chaque élément peut apparaître une fois.

  • Ne calculez jamais manuellement les xyaxes de caméra : utilisez Scene.camera(nom, position, cible) / simkit.scene.lookat.

  • N'écrivez jamais manuellement des listes de qpos d'images clés : définissez scene.home[articulation] = valeur (les robots le font pour vous) ; Scene.write construit l'image clé home par nom d'articulation et définit le ctrl de l'actionneur de position pour correspondre.

  • Les maillages plats/fins nécessitent inertia="shell" (glb_to_mujoco le fait). Géométries visuelles : contype=0 conaffinity=0 group=2 mass=0 ; proxies de collision dans le groupe 3.

  • Un robot soudé au monde entre en collision avec sa propre base : ajoutez <exclude> pour la base/le premier maillon.

  • Posit…

Skills associés