Saltar al contenido principal

Etapa 3 · Capítulo 13 · Práctica

13. Configuración de Cámara y Recopilación de Datos con LeRobot

Capítulo 13 del Curso de Introducción a la IA Física de Seeed — configuración con una o dos cámaras, búsqueda de nombres de dispositivos de cámara, sincronización de imagen/acción, creación de un dataset, grabación y regrabación, visualización y ampliación o eliminación de datos.

13.1 Configuración con una sola cámara vs. con dos cámaras​

Configuración

13.1 Configuración con una sola cámara vs. con dos cámaras

  • Configuración con una sola cámara: solo la cámara cenital conectada. Adecuada para una primera ejecución del pipeline y verificación del entorno: una cámara menos significa una variable menos al depurar.
  • Configuración con dos cámaras (ruta principal del curso, para recopilación formal): cenital + muñeca; el modelo ACT también usa por defecto dos flujos de entrada. También puedes elegir cenital + vista lateral.

También se pueden usar tres o cuatro cámaras para entrenamiento y recopilación. ACT en sí no tiene un límite estricto en el número de cámaras: cada flujo de imágenes pasa por una misma backbone ResNet18 para producir una secuencia de tokens de características, que se concatena en el codificador Transformer. El artículo original de ACT (ALOHA de doble brazo) utilizó 4 cámaras (2 cenitales + 2 en la muñeca).

  • Coste: cada cámara adicional incrementa aproximadamente de forma lineal la VRAM y el cómputo, y también aumenta los requisitos de datos (más puntos de vista implican más que aprender); cada flujo debe mantener sincronización y posición fija.

13.2 Cámaras Cenital y de Muñeca​

Cámaras

13.2 Cámaras Cenital y de Muñeca

  • Cámara cenital (frontal): fijada en un soporte que mira todo el espacio de trabajo; le indica al modelo "dónde está el objetivo y el estado general del brazo".
  • Cámara de muñeca (muñeca): montada en el extremo del brazo, sigue al efector final; le indica al modelo "la posición relativa entre el efector y el objetivo, y si debe cerrarse".
Cámaras cenital y de muñeca

13.3 Búsqueda de Nombres de Dispositivos de Cámara​

Dispositivos

13.3 Búsqueda de Nombres de Dispositivos de Cámara

Para comprobar los índices de las cámaras, primero ejecuta:

lerobot-find-cameras opencv

Verás Id: 0, donde 0 es el índice de la cámara.

--- Detected Cameras ---
Camera #0:
Name: OpenCV Camera @ 0
Type: OpenCV
Id: 0
Backend api: AVFOUNDATION
Default stream profile:
Format: 16.0
Width: 1920
Height: 1080
Fps: 15.0
--------------------
(more cameras ...)

Muestra el nombre, ID y resolución predeterminada de cada cámara. Puedes ir a ~/rebot_lerobot/outputs/captured_images/ en el directorio para ver las imágenes capturadas por cada cámara y verificar si la posición de la cámara es correcta y adecuada.

Ten en cuenta también: si usas un portátil, se escaneará la cámara integrada; tendrás que desconectar y volver a conectar para encontrar los índices correctos de las cámaras cenital y de muñeca. La cámara integrada del portátil suele ser el índice 0.

  • El orden de conexión cambia los índices. Hoy la cenital es 0; mañana, tras volver a conectar, puede cambiar. Dedica 10 segundos a volver a ejecutar lerobot-find-cameras antes de cada sesión de grabación para confirmarlo.
  • Las cámaras USB deben conectarse directamente al ordenador, no a través de una base. La contención de ancho de banda en hubs pasivos se manifiesta directamente como imágenes ilegibles o fotogramas perdidos; idealmente, las dos cámaras deberían conectarse a diferentes controladores USB.

13.4 Sincronización de Imagen y Acción​

Sync

13.4 Sincronización de Imagen y Acción

Una sola cámara​

Versión RS:

lerobot-teleoperate \
--robot.type=seeed_b601_rs_follower \
--robot.port=can0 \
--robot.id=follower1 \
--robot.can_adapter=socketcan \
--robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30, fourcc: "MJPG"}}" \
--teleop.type=rebot_arm_102_leader \
--teleop.port=/dev/ttyUSB0 \
--teleop.id=rebot_arm_102_leader \
--display_data=true

Versión DM:

lerobot-teleoperate \
--robot.type=seeed_b601_dm_follower \
--robot.port=/dev/ttyACM0 \
--robot.id=follower1 \
--robot.can_adapter=damiao \
--robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30, fourcc: "MJPG"}}" \
--teleop.type=rebot_arm_102_leader \
--teleop.port=/dev/ttyUSB0 \
--teleop.id=rebot_arm_102_leader \
--display_data=true

Si tienes más cámaras, puedes añadirlas cambiando el parámetro --robot.cameras. Ten en cuenta el formato index_or_path, que viene determinado por el último dígito del ID de la cámara que muestra el comando python -m lerobot.find_cameras opencv.

Dos cámaras​

Versión RS:

lerobot-teleoperate \
--robot.type=seeed_b601_rs_follower \
--robot.port=can0 \
--robot.id=follower1 \
--robot.can_adapter=socketcan \
--robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30, fourcc: "MJPG"}, side: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30, fourcc: "MJPG"}}" \
--teleop.type=rebot_arm_102_leader \
--teleop.port=/dev/ttyUSB0 \
--teleop.id=rebot_arm_102_leader \
--display_data=true

Versión DM:

lerobot-teleoperate \
--robot.type=seeed_b601_dm_follower \
--robot.port=/dev/ttyACM0 \
--robot.id=follower1 \
--robot.can_adapter=damiao \
--robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30, fourcc: "MJPG"}, side: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30, fourcc: "MJPG"}}" \
--teleop.type=rebot_arm_102_leader \
--teleop.port=/dev/ttyUSB0 \
--teleop.id=rebot_arm_102_leader \
--display_data=true

Puedes ver que esta es la imagen desde el interior de la caja de recopilación de datos:

Flujo de cámara desde el interior de la caja de recopilación

Parámetros recomendados: 640 × 480 @ 30 fps, fourcc: "MJPG". Cada uno de los tres parámetros es importante:

  • Resolución 640×480: equilibrio entre nitidez y rendimiento en tiempo real. Duplicar la resolución cuadruplica el ancho de banda USB y el coste de almacenamiento, mientras que la entrada del modelo ya redimensiona las imágenes de todos modos — el beneficio es limitado.
  • FPS 30: coincide con los FPS de recopilación. Si los FPS de la cámara son menores, la grabación reutilizará repetidamente fotogramas antiguos.
  • fourcc: "MJPG": la imagen se comprime antes de la transmisión, reduciendo la presión sobre el ancho de banda USB en un orden de magnitud. Por supuesto, puedes probar imágenes en formato YUYV, pero esto reducirá la resolución y los FPS, provocando tirones en el movimiento del brazo. Actualmente el formato MJPG admite 3 cámaras a resolución 1920×1080 manteniendo 30 FPS.

13.5 Crear Dataset de LeRobot​

Dataset

13.5 Crear Dataset de LeRobot

Crear dataset de LeRobot

Antes de ejecutar el siguiente comando, prepárate para grabar datos; habrá una señal de audio al entrar en la fase de grabación. Si no la oyes, comprueba en el terminal si ha comenzado.

Versión RS:

lerobot-record \
--robot.type=seeed_b601_rs_follower \
--robot.port=can0 \
--robot.id=follower1 \
--robot.can_adapter=socketcan \
--robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30, fourcc: "MJPG"}, side: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30, fourcc: "MJPG"}}" \
--teleop.type=rebot_arm_102_leader \
--teleop.port=/dev/ttyUSB0 \
--teleop.id=rebot_arm_102_leader \
--display_data=true \
--dataset.repo_id=seeed_rebot_b601_rs/test \
--dataset.num_episodes=5 \
--dataset.single_task="Grab the crayfish into the box" \
--dataset.push_to_hub=false \
--dataset.episode_time_s=30 \
--dataset.reset_time_s=20

Versión DM:

lerobot-record \
--robot.type=seeed_b601_dm_follower \
--robot.port=/dev/ttyACM0 \
--robot.id=follower1 \
--robot.can_adapter=damiao \
--robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30, fourcc: "MJPG"}, side: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30, fourcc: "MJPG"}}" \
--teleop.type=rebot_arm_102_leader \
--teleop.port=/dev/ttyUSB0 \
--teleop.id=rebot_arm_102_leader \
--display_data=true \
--dataset.repo_id=seeed_rebot_b601_dm/test \
--dataset.num_episodes=5 \
--dataset.single_task="Grab the crayfish into the box" \
--dataset.push_to_hub=false \
--dataset.episode_time_s=30 \
--dataset.reset_time_s=20

Hay varios parámetros relacionados con el propio dataset:

ParámetroSignificadoRecomendación
--dataset.repo_idNombre del dataset (también el nombre de la carpeta local)Nombres separados para conjuntos de prueba y formales, por ejemplo, rebot_b601/grab_cube_test / rebot_b601/grab_cube_v1
--dataset.single_taskDescripción de la tarea (se guarda en el dataset)En inglés, coincidiendo con la descripción de la tarea
--dataset.num_episodesCuántos Episodios grabarPrueba: 5; formal: 50 (el valor predeterminado es 50)
--dataset.push_to_hubSi se sube al Hub después de grabarfalse = no subir
--dataset.episode_time_s=30Tiempo de grabación por EpisodioAjustar según la complejidad de la tarea
--dataset.reset_time_s=20Tiempo para reiniciar la escena para la siguiente grabaciónAjustar según el tiempo de reinicio de la escena
--display_data=trueMostrar el flujo de la cámara en tiempo real-

Después, el conjunto de datos se guardará en el directorio home bajo ~/.cache/huggingface/lerobot. La carpeta anterior se creará bajo seeed_rebot_b601_rs/test.

13.6 Grabación, pausa y regrabación de episodios​

Grabación

13.6 Grabación, pausa y regrabación de episodios

Grabación​

Controles del teclado durante la grabación:

TeclaAcción
→ (Flecha derecha)Terminar el episodio actual antes de tiempo, continuar con el reinicio/siguiente
← (Flecha izquierda)Descartar el episodio actual, volver a grabar este
ESCFinalizar toda la sesión de recopilación: codificar vídeos, calcular estadísticas, guardar el conjunto de datos
aviso

Si las teclas no responden, es un problema de versión de pynput; haz un downgrade: pip install pynput==1.6.8.

Regrabación​

Después de grabar 5 episodios y verificar la reproducción, para la recopilación formal: cambia repo_id al nombre formal, num_episodes=50 al valor formal, y sigue el método del lápiz de cinco puntos del Capítulo 12: 1 episodio por punto, 5 puntos por ronda, 10 rondas en total.

Pausar la grabación​

peligro

No pulses Ctrl+C para pausar la grabación: pulsa Esc, de lo contrario saldrá de forma anómala.

13.7 Visualización y reproducción de un conjunto de datos​

Reproducción

13.7 Visualización y reproducción de un conjunto de datos

Visualizar un conjunto de datos​

Si subiste datos, también puedes visualizarlos localmente con:

echo ${HF_USER}/rebot_test
lerobot-dataset-viz \
--repo-id ${HF_USER}/rebot_test \
--episode-index 0 \
--display-compressed-images=false

Si usaste --dataset.push_to_hub=false y no subiste datos, también puedes visualizarlos localmente con:

Versión RS:

lerobot-dataset-viz \
--repo-id seeed_rebot_b601_rs/test \
--episode-index 0 \
--display-compressed-images=false

Versión DM:

lerobot-dataset-viz \
--repo-id seeed_rebot_b601_dm/test \
--episode-index 0 \
--display-compressed-images=false

Aquí, seeed_rebot_b601_rs/test es el nombre de conjunto de datos personalizado de la recopilación (repo_id).

Reproducir un conjunto de datos​

Ahora, intenta reproducir el primer conjunto de datos en tu robot: --dataset.episode=0 significa reproducir el primer conjunto de datos recopilado, y así sucesivamente.

Versión RS:

lerobot-replay \
--robot.type=seeed_b601_rs_follower \
--robot.port=can0 \
--robot.can_adapter=socketcan \
--robot.id=follower1 \
--dataset.repo_id=seeed_rebot_b601_rs/test \
--dataset.episode=0

Versión DM:

lerobot-replay \
--robot.type=seeed_b601_dm_follower \
--robot.port=/dev/ttyACM0 \
--robot.can_adapter=damiao \
--robot.id=follower1 \
--dataset.repo_id=seeed_rebot_b601_dm/test \
--dataset.episode=0

El robot ahora debería realizar las mismas acciones que grabaste durante la teleoperación.

13.8 Ampliar y eliminar datos​

Edición

13.8 Ampliar y eliminar datos

  • Los checkpoints se crean automáticamente durante la grabación.
  • Añade --resume=true al comando original para seguir ampliando los datos.
  • Al reanudar, establece --dataset.num_episodes en el número de episodios adicionales que se van a grabar (no el total objetivo en el conjunto de datos).
  • Para empezar de cero, elimina manualmente el directorio del conjunto de datos.

Utiliza el siguiente comando para eliminar episodios: --operation.episode_indices "[0]" elimina el primer episodio, y así sucesivamente. Ten paciencia durante la eliminación y modifica el nombre del conjunto de datos en consecuencia.

lerobot-edit-dataset \
--repo_id rebot_b601/grab_cube_v1 \
--operation.type delete_episodes \
--operation.episode_indices "[0]"
Loading Comments...