LeRobot documentation

Simulación: local o servida

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.7.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Simulación: local o servida

Un entorno simulado puede controlarse de dos maneras:

  • como un entorno por lotes (--env.*): muchos entornos para una misma tarea, avanzados juntos en cada llamada a step(). lerobot-eval y la evaluación durante el entrenamiento lo utilizan.
  • como un sim robot (--robot.type=sim): un entorno detrás de la interfaz Robot, intercambiable con hardware real. lerobot-rollout, lerobot-record, lerobot-teleoperate y lerobot-replay lo utilizan.

Se ejecuta localmente, a través de la API de entorno, o servido por lerobot-env-server, normalmente en su propia imagen de Docker, para que las dependencias del simulador nunca se crucen con las de la política. Establecer un endpoint selecciona la ejecución servida; ambas rutas exponen las mismas observaciones canónicas (imágenes HWC uint8, estado float32 plano), los finales de episodio y las convenciones de control.

El código mantiene separadas tres capas:

  • Un env (lerobot.envs, --env.type) es lo que ejecuta un comando de LeRobot, configurado mediante un EnvConfig. No todos los env son simuladores: gym_manipulator controla un robot real.
  • Un sim (lerobot.sim) es el simulador detrás de un entorno simulado: un SimConfig que nombra su integración, ejecutado por LocalVectorEnv, sin torch.
  • el env server (lerobot.env_server) sirve una simulación; RemoteVectorEnv la controla con la misma API que LocalVectorEnv.

Evaluar un punto de control

Localmente, con el simulador instalado junto a LeRobot (ver LIBERO):

lerobot-eval \
  --policy.path=lerobot/smolvla_libero \
  --policy.pretrained_revision=a24f1f380461b665158d52acd140152c79e8b36d \
  --policy.device=cuda \
  --env.type=libero --env.task=libero_spatial --env.task_ids='[0]' \
  --rename_map='{"observation.images.image": "observation.images.camera1", "observation.images.image2": "observation.images.camera2"}' \
  --eval.n_episodes=1 --eval.batch_size=1 \
  --output_dir=outputs/eval_libero

Servido: inicia el servidor con el mismo entorno (consulta Servir un entorno) y añade su punto de acceso:

lerobot-env-server --config_path=docker/sim/configs/libero.yaml --docker=true
lerobot-eval ... --env.server.endpoint=tcp/127.0.0.1:7448

Todas las opciones del servidor están bajo --env.server.* y ninguna se aplica a una ejecución local. El cliente solicita el despliegue con el nombre que indica --env.type, tal como lo nombran las configuraciones del servidor; para otro, pasa --env.server.deployment. Un endpoint o despliegue incorrecto falla dentro de --env.server.handshake_timeout_s (10 s) e indica qué sirve el endpoint. Contra un servidor protegido con TLS, pasa su archivo Zenoh JSON5 con --env.server.zenoh_config_path, como para la inferencia remota. El servidor debe ejecutar el entorno que describe el comando: el mismo tipo, tarea, convenciones de control y cuerpo simulado (robot_type), o la evaluación se niega a iniciar y lista las diferencias. Otras opciones que difieren (resolución, longitud del episodio) se registran como advertencias.

Los nombres de las observaciones provienen del entorno (observation.images.<camera>, observation.state). Cuando un punto de control se entrenó con otros nombres de cámara, mapee los nombres con --rename_map, como para cualquier robot, y preserve la identidad de cada cámara incluso cuando varias tengan la misma forma. Las cámaras de marcador de posición (empty_cameras) son una configuración de la política guardada con el punto de control; sobrescríbala con --policy.empty_cameras solo cuando sea necesario.

Antes del primer paso, cada entrada de punto de control debe existir en el entorno después del cambio de nombre, con dimensiones de estado y acción coincidentes y el mismo número de canales RGB. La altura y el ancho de la imagen pueden diferir: el preprocesamiento de la política se encarga del redimensionado. No se verifican las convenciones del controlador (acciones delta frente a absolutas, formato de rotación); utilice un punto de control entrenado con la convención del entorno.

Cada step() avanza una vez cada entorno no finalizado del lote. Un entorno que termina conserva su observación terminal hasta el siguiente reinicio; avanzar los demás nunca lo reinicia. Con --eval.use_async_envs=true (el valor predeterminado), cada entorno se ejecuta en su propio proceso de trabajo, localmente o en el servidor, y el lote avanza en paralelo. Un servidor admite hasta max_envs entornos por lote (32 por defecto). --env.server.encoding=jpeg (o --robot.env.server.encoding=jpeg, con --env.server.jpeg_quality, 90 por defecto) envía los fotogramas de cámara servidos como JPEG: respuestas más pequeñas para un servidor remoto y lotes más grandes, a costa del tiempo de codificación y de fotogramas con pérdida. En localhost, los fotogramas sin procesar son más rápidos. Una respuesta lleva los fotogramas de todos los entornos del lote y debe caber en max_payload_bytes (32 MiB por defecto) en ambos extremos, o el servidor rechaza el lote al abrirlo. Para lotes grandes o cámaras de alta resolución, aumente este valor en el servidor (max_payload_bytes en la sección zenoh del YAML, junto a listen_endpoints) y en el cliente (--env.server.max_payload_bytes, o --robot.env.server.max_payload_bytes).

Ejecutar un robot simulado

El mismo entorno que un entorno por lotes y como un robot de simulación:

lerobot-eval    --env.type=libero --env.task=libero_spatial --env.task_ids='[0]' ...
lerobot-rollout --robot.type=sim --robot.env.type=libero --robot.env.task=libero_spatial --robot.task_id=0 ...

Por ejemplo:

lerobot-rollout \
  --robot.type=sim --robot.env.type=libero --robot.env.task=libero_spatial --robot.task_id=0 \
  --task="pick up the black bowl between the plate and the ramekin and place it on the plate" \
  --policy.path=lerobot/smolvla_libero \
  --policy.pretrained_revision=a24f1f380461b665158d52acd140152c79e8b36d \
  --rename_map='{"observation.images.image": "observation.images.camera1", "observation.images.image2": "observation.images.camera2"}' \
  --device=cuda --fps=20 --inference.type=sync \
  --display_data=true --display_mode=rerun \
  --return_to_initial_position=false --play_sounds=false
  • --robot.env.* acepta las mismas opciones que --env.* en la evaluación. --robot.task_id selecciona la única tarea que ejecuta el robot, mientras que la evaluación ejecuta todas las tareas del conjunto o las especificadas en --env.task_ids. Los entornos de EnvHub son --robot.env.type=envhub --robot.env.hub_path=<user/repo> --robot.env.trust_remote_code=true.
  • Algunas políticas requieren los procesadores del entorno (XVLA y Cosmos3 en LIBERO, Isaac Lab Arena). lerobot-eval los aplica, al igual que un robot de simulación con --inference.type=sync. La inferencia remota no los aplica, por lo que rechaza dicho punto de control al inicio.
  • --robot.env.server.endpoint=tcp/... controla el entorno en un servidor de entornos, de la misma manera que --env.server.endpoint lo hace para un entorno por lotes. El robot comprueba que el servidor ejecute ese entorno.
  • Cada send_action() avanza el entorno exactamente una vez. Las lecturas de observación, la inferencia de la política y la espera no avanzan la simulación; el bucle de control existente gestiona el ritmo en tiempo real.
  • --fps debe ser igual a la tasa de control del entorno, dividida por --interpolation_multiplier al interpolar, ya que cada comando avanza el entorno una vez. Al grabar, --dataset.fps debe ser igual a --fps. De lo contrario, el rollout se niega a comenzar.

Un robot de simulación es un robot: sustituya --robot.type=sim --robot.env.* por --robot.* del seguidor real, y todo lo demás permanece igual. Un teleoperador lo controla de la misma manera que controla al seguidor real (--teleop.type=so101_leader para un gemelo SO-101), cuando el entorno declara los nombres y unidades de las acciones del seguidor; una incompatibilidad se informa en la primera acción. lerobot-record almacena el cuerpo que el entorno declara como robot_type del conjunto de datos (panda para LIBERO), o sim_robot cuando no declara ninguno.

Los episodios grabados siguen los del entorno. lerobot-record y la estrategia de despliegue episódico reinician el entorno simulado al inicio de cada episodio y lo finalizan cuando el episodio del entorno termina (éxito, terminación o su límite de pasos) o cuando se agota su duración, lo que ocurra primero. Por lo tanto, cada episodio grabado es un episodio simulado, desde su estado inicial. No es necesario hacer ningún reinicio manual, así que omita la fase de reinicio entre episodios con --dataset.reset_time_s=0, y con la estrategia de despliegue episódico también pase --strategy.reset_to_initial_position=false. Cuando un episodio termina, el robot se detiene: ignora las acciones y mantiene su estado final, y latest conserva la recompensa final, la terminación y el éxito. La teleoperación y la estrategia de despliegue base inician entonces un nuevo episodio (la estrategia también reinicia la política), y la reproducción se detiene. Las estrategias sentry, highlight y DAgger aún no admiten robots simulados, ya que graban por tiempo o bajo demanda en lugar de por episodio; use la estrategia episódica para grabar. Los robots reales no se ven afectados: sus episodios son cronometrados y su escena se reinicia manualmente. Para las tasas de éxito, evalúe con lerobot-eval y un entorno por lotes.

Las funciones de la cámara del robot utilizan los mismos nombres observation.images.<camera> que la grabación con hardware real. Una cámara sin nombre es observation.images.image. La evaluación por lotes conserva las propias claves del entorno, como observation.image para una sola cámara; al desplegar un punto de control con ese nombre a través de SimRobot, use --rename_map='{"observation.images.image": "observation.image"}'.

Para la inferencia remota, mantenga las mismas opciones --robot.* y reemplace las opciones de inferencia y política locales con:

--inference.type=remote \
--inference.endpoint=tcp/127.0.0.1:7447 \
--inference.deployment=libero \
--inference.semantics=libero-delta-v1

Inicie el servidor de política por separado usando remote inference setup. Su esquema debe coincidir con las observaciones del robot después de --rename_map. Omita --policy.path del comando de rollout porque el servidor de política carga el checkpoint. Para RTC local, use --inference.type=rtc con la configuración de RTC de la política.

Cuando la política se retrasa, mantener un robot simulado no avanza la física. Las fallas del simulador se propagan al cierre del despliegue.

Servir un entorno

Desde un checkout de la fuente de LeRobot (la imagen se construye a partir de él), ejecute desde la raíz del repositorio:

lerobot-env-server --config_path=docker/sim/configs/libero.yaml --docker=true

--docker=true utiliza docker/sim/compose.server.yaml, selecciona la imagen desde sim.type, monta el YAML efectivo y ejecuta el contenedor en la red del host, de modo que el servidor escucha en localhost:7448 a menos que --zenoh.listen_endpoints indique lo contrario. Cambia el YAML para seleccionar otro simulador. La tasa de control, la convención de acciones, los nombres de los componentes y el tipo de robot de cada simulador provienen de conventions() de su integración, por lo que un YAML solo nombra la tarea y las opciones del simulador.

En cuanto a lerobot-policy-server, cada campo YAML acepta una anulación anidada desde la línea de comandos, y el archivo permanece sin cambios. Un valor de diccionario como sim.kwargs se fusiona con el del YAML:

lerobot-env-server --config_path=docker/sim/configs/libero.yaml --docker=true \
  --sim.task=libero_goal \
  --sim.kwargs='{gym_kwargs: {observation_height: 256, observation_width: 256}}'

La configuración efectiva se guarda en $HF_LEROBOT_HOME/sim, por lo que un contenedor reiniciado la encuentra. Cambiar la configuración recrea el servidor y termina las sesiones activas. La imagen se construye si falta; añade --build=true para reconstruirla después de cambiar el simulador o el código fuente de LeRobot, o --stop=true para detener el servidor. El contenedor requiere acceso a GPU de Docker para el renderizado con EGL. Los repositorios de EnvHub se sirven con --envhub=<user/repo>; consulta EnvHub y el servidor del simulador.

Si un simulador que renderiza con Vulkan (Isaac Sim, o ManiSkill/SAPIEN como en RoboMME, cuya imagen incluye su propio archivo de Vulkan) falla en el contenedor con vkCreateInstance failed o ERROR_INCOMPATIBLE_DRIVER mientras funciona fuera de Docker, el contenedor tiene las bibliotecas del controlador de NVIDIA pero no los archivos de cargador que apuntan a ellas (/usr/share/vulkan/icd.d/nvidia_icd.json, /usr/share/glvnd/egl_vendor.d/10_nvidia.json). El modo predeterminado del NVIDIA Container Toolkit, utilizado por gpus: all, puede no montarlas; su modo CDI sí lo hace. Solicita la GPU a través de CDI (--device nvidia.com/gpu=all para docker run, devices: [nvidia.com/gpu=all] en lugar de gpus: all en docker/sim/compose.server.yaml), o añade los dos archivos a la imagen.

Sin --docker=true, el mismo comando ejecuta el servidor en el entorno actual: instala las dependencias nativas del simulador en un entorno aislado, instala LeRobot con --no-deps e instala docker/sim/requirements.txt. En cualquier caso, escucha en localhost; para aceptar otras máquinas, pasa la dirección de la interfaz de red a la que pueden acceder, como en --zenoh.listen_endpoints='[tcp/192.168.1.20:7448]', y añade TLS y control de acceso con un zenoh.config_file en el YAML.

Las imágenes de tiempo de ejecución de LIBERO utilizan archivos de estado inicial de NumPy convertidos. La compilación de la imagen convierte los activos de confianza de origen con scripts/ci/convert_libero_init_states.py; el servidor rechaza los archivos convertidos que faltan. RoboTwin y RoboMME requieren su propio torch para el planificador nativo y ManiSkill, respectivamente; sus instalaciones de torch están aisladas del entorno de la política.

Las solicitudes al servidor nunca se reintentan. Después de un tiempo de espera ambiguo, el cliente falla; ciérralo y abre una nueva sesión.

Agregar un benchmark

Consulte Adding a benchmark para los módulos del simulador, las convenciones, las imágenes y la integración con CI.

Update on GitHub