Communitygithub.com

johannstark/GeminiRobotics-Skills

Rend des simulations MuJoCo avec Three.js (WASM dans le navigateur, processus Python MuJoCo streamé ou logs). Utilisé pour la configuration de scène en Z-up, la conversion des geoms et maillages MuJoCo en maillages Three.js, la synchronisation des poses par image (quaternions wxyz), la capture d'instantanés de caméra et de vidéo canvas pour Gemini Robotics-ER, le mapping des points ER [y, x] 0-1000 vers la 3D par raycasting, la projection de la 3D vers les coordonnées image, et le débogage des rendus inclinés, déformés, mal dimensionnés ou vides.

Qu'est-ce que GeminiRobotics-Skills ?

Cette compétence fournit une intégration complète entre MuJoCo et Three.js pour le rendu 3D dans le navigateur, spécifiquement conçue pour fonctionner avec Gemini Robotics-ER. Elle gère automatiquement les différences critiques entre les deux systèmes : MuJoCo est en Z-up et utilise des quaternions wxyz, tandis que Three.js est en Y-up et utilise des quaternions xyzw. La compétence prend en charge trois approches : un groupe par corps (recommandé pour le picking et la flexibilité), mjv_updateScene (pour les décorations MuJoCo officielles), et un processus Python distant (pour les ponts GPU/ROS/robot réel). Elle inclut des fonctions de raycasting pour mapper les points ER [y, x] vers des coordonnées 3D et inversement, ainsi que la capture d'instantanés et de vidéos pour la perception. La documentation détaille les pièges courants comme l'orientation des caméras, la conversion des quaternions, les demi-tailles, l'alignement des cylindres, et les problèmes de mémoire. La démo de référence est l'application Franka pick-and-place, qui illustre l'utilisation de RenderSystem.ts, GeomBuilder.ts et les fonctions de projection 2D↔3D.

Compatible avec~Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/johannstark/GeminiRobotics-Skills/tree/HEAD/threejs-rendering

Demander à votre IA préférée

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

Documentation

Rendu Three.js pour MuJoCo

Construisez la géométrie statique une fois, puis mettez à jour uniquement les transformations à chaque frame. MuJoCo est Z-up, utilise des demi-tailles, des cylindres et capsules alignés sur Z, et des quaternions wxyz. Three.js utilise par défaut Y-up, des tailles pleines, des cylindres alignés sur Y et des quaternions xyzw. Presque tous les bogues de rendu proviennent de l'un de ces points.

1. Configuration de la scène (Z-up, prête pour la capture)

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';   // chemin valide sur 0.164 et 0.18x

const renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true }); // nécessaire pour toDataURL
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
renderer.shadowMap.enabled = true;
const camera = new THREE.PerspectiveCamera(45, w / h, 0.01, 100);
camera.up.set(0, 0, 1);                       // MuJoCo est Z-up. Avec cela, aucune conversion d'axe n'est nécessaire nulle part.
camera.position.set(2, -1.5, 2.5);
const controls = new OrbitControls(camera, renderer.domElement);
const grid = new THREE.GridHelper(5, 50); grid.rotation.x = Math.PI / 2;   // poser la grille sur XY

Définissez camera.up avant de créer OrbitControls, car les contrôles mettent en cache le vecteur up.

2. Choisir une approche

ApprocheCommentQuand l'utiliser
A. Un Group par corps (la démo Franka)Chaque groupe de corps contient ses geoms à leur geom_pos/geom_quat local. Copiez xpos/xquat à chaque frame.Par défaut. Picking via userData.bodyID. Fonctionne avec n'importe quelle source de pose.
B. mjv_updateScene (démo officielle)Synchronisez un maillage mutualisé par entrée scene.geomsVous voulez les décorations propres à MuJoCo (contacts, tendons, sites)
C. Python distantPython effectue les étapes et streame xpos/xquat via WebSocket. Le navigateur exécute A.Ponts GPU, ROS ou robot réel, calcul lourd

Conversion de geom : references/geom-conversion.md. Streaming Python (serveur testé) : references/remote-python.md. Instantanés, caméra de perception, vidéo et pixel↔3D : references/perception-and-video.md.

3. Synchronisation par frame (approche A)

for (let i = 0; i < model.nbody; i++) {
  bodies[i].position.set(data.xpos[3*i], data.xpos[3*i+1], data.xpos[3*i+2]);
  bodies[i].quaternion.set(data.xquat[4*i+1], data.xquat[4*i+2], data.xquat[4*i+3], data.xquat[4*i]); // wxyz -> xyzw
}
renderer.render(scene, camera);

Ordre de la boucle : entrées → mj_step (autant de fois que le budget de temps de simulation le permet) → synchronisation → rendu (voir MujocoSim.startLoop). L'alternative par geom utilise data.geom_xpos et data.geom_xmat (matrice 3×3 ligne-majeure → Matrix4.set(r00,r01,r02,0, r10,…)), avec la géométrie à la pose identité.

4. Points ER ↔ 3D

// ER [y, x] 0-1000 sur l'image capturée -> rayon depuis la MÊME caméra qui l'a capturée
const ndc = new THREE.Vector2((x / 1000) * 2 - 1, 1 - (y / 1000) * 2);
raycaster.setFromCamera(ndc, captureCamera);
const hit = raycaster.intersectObjects(simMeshes, false)[0];     // ou raycaster.ray.intersectPlane(table, out)

// 3D -> [y, x] style ER (pour dessiner les attentes ou construire des prompts)
const v = p.clone().project(captureCamera);
const yx = [(1 - v.y) * 500, (v.x + 1) * 500];

Ceci est valable pour n'importe quel rapport d'aspect tant que l'image correspond exactement à la fenêtre d'affichage complète de la caméra (pas de recadrage, pas de letterbox) et que la caméra n'a pas bougé entre la capture et le raycast. Ignorez les hits sur le robot ou le sol en remontant jusqu'à userData.bodyID. Le hit est sur la surface supérieure, abaissez-le donc à la hauteur de préhension.

5. Pièges

SymptômeCause
Le robot est couché sur le côté, l'orbite tanguécamera.up n'est pas (0,0,1), ou défini après la création d'OrbitControls
Les liaisons torduesRéordonnancement wxyz→xyzw manquant
Boîtes deux fois plus grandesOubli que les tailles sont des demi-étendues
Cylindres ou capsules orientés du mauvais côtégeometry.rotateX(Math.PI/2) manquant
Instantané vide ou noirpreserveDrawingBuffer: false, ou les pixels ont été lus dans une tâche différente de celle du rendu
Image de perception plus sombre que l'écranLes cibles de rendu produisent une couleur linéaire (vérifié dans three r186). Convertissez en sRGB (voir la référence de perception).
Marqueurs ER décalésCaméra déplacée, [y, x] échangé, image recadrée ou letterboxée, ou le canvas avec ratio de pixels d'appareil a été redimensionné différemment
Mémoire qui augmente lors du rechargementgeometry.dispose(), material.dispose(), renderTarget.dispose(), et supprimez le modèle et les données WASM
À-coups à haute vitesseTrop d'appels mj_step par frame. Limitez les étapes, ou déplacez la physique dans un Worker.

6. Dans la démo Franka

La démo Franka pick-and-place est l'application de référence à partir de laquelle ces compétences ont été construites. Les noms de fichiers ci-dessous s'y réfèrent.

  • RenderSystem.ts utilise preserveDrawingBuffer: true, une PerspectiveCamera(45) en Z-up, des OrbitControls amortis, simGroup (un groupe par corps, userData.bodyID), erGroup (marqueurs coniques oscillants), marqueurs de contact instanciés, des transitions de caméra (moveCameraTo), et getCanvasSnapshot(w, h, mime).
  • project2DTo3D(x, y, camPos, lookAt) clone la caméra principale, la positionne au point de vue de capture ((0, -0.01, 2.0) regardant l'origine), et effectue un raycast sur les maillages de simGroup.
  • rendering/GeomBuilder.ts gère la fabrique geom→maillage. Les geoms du groupe 3 sont ignorées, les plans deviennent un sol Reflector, et les geoms de maillage lisent mesh_vert/mesh_face.
  • DragStateManager.ts et SelectionManager.ts gèrent le picking à la souris et les forces de glissement via xfrc_applied.
  • L'import map de index.html épingle three 0.164.1, tandis que package.json contient ^0.181. Conservez les imports three/examples/jsm/..., qui fonctionnent dans les deux versions.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills associés