# HopeJR

## Prerrequisitos

- [Configuración del hardware](https://github.com/TheRobotStudio/HOPEJr)

## Instalar LeRobot

Siga las [instrucciones de instalación](https://github.com/huggingface/lerobot#installation) para instalar LeRobot.

Instale LeRobot con las dependencias de HopeJR:

```bash
pip install -e ".[hopejr]"
```

## Configuración de dispositivos

Antes de iniciar la calibración y la operación, debe identificar los puertos USB de cada componente de HopeJR. Ejecute este script para encontrar los puertos USB del brazo, la mano, el guante y el exoesqueleto:

```bash
lerobot-find-port
```

Esto mostrará los puertos USB disponibles y sus dispositivos asociados. Anote las rutas de los puertos (p. ej., `/dev/tty.usbmodem58760433331`, `/dev/tty.usbmodem11301`), ya que deberá especificarlas en los parámetros `--robot.port` y `--teleop.port` al grabar datos, reproducir episodios o ejecutar scripts de teleoperación.

## Paso 1: Calibración

Antes de realizar la teleoperación, las extremidades de HopeJR deben calibrarse. Los archivos de calibración se guardarán en `~/.cache/huggingface/lerobot/calibration`

### 1.1 Calibrar la mano robótica

```bash
lerobot-calibrate \
    --robot.type=hope_jr_hand \
    --robot.port=/dev/tty.usbmodem58760432281 \
    --robot.id=blue \
    --robot.side=right
```

Al ejecutar el script de calibración, se abrirá una GUI de calibración. Las articulaciones de los dedos se nombran de la siguiente manera:

**Miniatura**:

- **CMC**: articulación base que conecta el pulgar con la mano
- **MCP**: articulación metacarpofalángica
- **PIP**: primera articulación del dedo
- **DIP** : articulación interfalángica distal

**Dedos índice, medio, anular y meñique**:

- **Flexor radial**: Mueve la base del dedo hacia el pulgar
- **Flexor cubital**: Mueve la base del dedo hacia el meñique
- **PIP/DIP**: Flexiona la falange distal y proximal del dedo

Cada uno de estos deberá calibrarse de forma individual a través de la GUI. Tenga en cuenta que los flexores ulnares y radiales deben tener rangos del mismo tamaño (pero con desplazamientos diferentes) para obtener un movimiento simétrico.

  <img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/calibration_gui_1.png" alt="Estableciendo límites en la interfaz de calibración de mano" title="Estableciendo límites en la interfaz de calibración de mano" width="100%"
  >

Use la interfaz de calibración para establecer los límites del rango de cada articulación, como se muestra arriba.

  <img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/calibration_gui_2.png" alt="Guardando los valores de calibración" title="Guardando los valores de calibración" width="100%"
  >

Una vez que hayas establecido los límites adecuados para todas las articulaciones, haz clic en "Save" para guardar los valores de calibración en los motores.

### 1.2 Calibrar la guante de teleoperación

```bash
lerobot-calibrate \
    --teleop.type=homunculus_glove \
    --teleop.port=/dev/tty.usbmodem11201 \
    --teleop.id=red \
    --teleop.side=right
```

Mueve cada dedo a través de su rango completo de movimiento, comenzando por el pulgar.

```
Move thumb through its entire range of motion.
Recording positions. Press ENTER to stop...

-------------------------------------------
NAME      |    MIN |    POS |    MAX
thumb_cmc |   1790 |   1831 |   1853
thumb_mcp |   1497 |   1514 |   1528
thumb_pip |   1466 |   1496 |   1515
thumb_dip |   1463 |   1484 |   1514
```

Continúa con cada dedo:

```
Move middle through its entire range of motion.
Recording positions. Press ENTER to stop...

-------------------------------------------
NAME                 |    MIN |    POS |    MAX
middle_mcp_abduction |   1598 |   1718 |   1820
middle_mcp_flexion   |   1512 |   1658 |   2136
middle_dip           |   1484 |   1500 |   1547
```

Una vez completada la calibración, el sistema guardará la calibración en `/Users/your_username/.cache/huggingface/lerobot/calibration/teleoperators/homunculus_glove/red.json`

### 1.3 Calibrar el brazo robótico

```bash
lerobot-calibrate \
    --robot.type=hope_jr_arm \
    --robot.port=/dev/tty.usbserial-1110 \
    --robot.id=white
```

Esto abrirá una interfaz de calibración donde puedes establecer los límites de rango para cada motor. Los movimientos del brazo se organizan de la siguiente manera:

- **Hombro**: elevación, giro y balanceo
- **Codo**: flexión
- **Wrist**: cabeceo, alabeo y guiñada

  <img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/calibration_gui_2.png" alt="Estableciendo límites en la interfaz de calibración del brazo" title="Estableciendo límites en la interfaz de calibración del brazo" width="100%"
  >

Use la interfaz de calibración para establecer los límites de rango de cada articulación. Mueva cada articulación a través de su rango completo de movimiento y ajuste los valores mínimo y máximo en consecuencia. Una vez que haya establecido los límites apropiados para todas las articulaciones, guarde la calibración.

### 1.4 Calibrar el exoesqueleto de teleoperación

```bash
lerobot-calibrate \
    --teleop.type=homunculus_arm \
    --teleop.port=/dev/tty.usbmodem11201 \
    --teleop.id=black
```

El exoesqueleto permite controlar el brazo robótico. Durante la calibración, se le pedirá que mueva todas las articulaciones a través de su rango de movimiento completo:

```
Move all joints through their entire range of motion.
Recording positions. Press ENTER to stop...

-------------------------------------------
-------------------------------------------
NAME            |    MIN |    POS |    MAX
shoulder_pitch  |    586 |    736 |    895
shoulder_yaw    |   1257 |   1374 |   1390
shoulder_roll   |    449 |   1034 |   2564
elbow_flex      |   3023 |   3117 |   3134
wrist_roll      |   3073 |   3096 |   3147
wrist_yaw       |   2143 |   2171 |   2185
wrist_pitch     |   1975 |   1993 |   2074
Calibration saved to /Users/your_username/.cache/huggingface/lerobot/calibration/teleoperators/homunculus_arm/black.json
```

## Paso 2: Teleoperación

Debido a conflictos de variables globales en el middleware de Feetech, la teleoperación del brazo y la mano debe ejecutarse en sesiones de shell separadas:

### Mano

```bash
lerobot-teleoperate \
    --robot.type=hope_jr_hand \
    --robot.port=/dev/tty.usbmodem58760432281 \
    --robot.id=blue \
    --robot.side=right \
    --teleop.type=homunculus_glove \
    --teleop.port=/dev/tty.usbmodem11201 \
    --teleop.id=red \
    --teleop.side=right \
    --display_data=true \
    --fps=30
```

### Arm

```bash
lerobot-teleoperate \
    --robot.type=hope_jr_arm \
    --robot.port=/dev/tty.usbserial-1110 \
    --robot.id=white \
    --teleop.type=homunculus_arm \
    --teleop.port=/dev/tty.usbmodem11201 \
    --teleop.id=black \
    --display_data=true \
    --fps=30
```

## Paso 3: Grabar, reproducir, entrenar

Record, Replay and Train con Hope-JR sigue siendo experimental.

### Registro

Este paso registra el conjunto de datos, que puede verse como un ejemplo [aquí](https://huggingface.co/datasets/nepyope/hand_record_test_with_video_data).

```bash
lerobot-record \
    --robot.type=hope_jr_hand \
    --robot.port=/dev/tty.usbmodem58760432281 \
    --robot.id=right \
    --robot.side=right \
    --robot.cameras='{"main": {"type": "opencv", "index_or_path": 0, "width": 640, "height": 480, "fps": 30}}' \
    --teleop.type=homunculus_glove \
    --teleop.port=/dev/tty.usbmodem1201 \
    --teleop.id=right \
    --teleop.side=right \
    --dataset.repo_id=<USER>/hand_record_test_with_video_data \
    --dataset.single_task="Hand recording test with video data" \
    --dataset.num_episodes=1 \
    --dataset.episode_time_s=5 \
    --dataset.push_to_hub=true \
    --dataset.private=true \
    --dataset.streaming_encoding=true \
    --dataset.encoder_threads=2 \
    --display_data=true
# Optional: --dataset.rgb_encoder.vcodec=auto
```

### Repetir

```bash
lerobot-replay \
    --robot.type=hope_jr_hand \
    --robot.port=/dev/tty.usbmodem58760432281 \
    --robot.id=right \
    --robot.side=right \
    --dataset.repo_id=<USER>/hand_record_test_with_camera \
    --dataset.episode=0
```

### Entrenar

```bash
lerobot-train \
  --dataset.repo_id=<USER>/hand_record_test_with_video_data \
  --policy.type=act \
  --output_dir=outputs/train/hopejr_hand \
  --job_name=hopejr \
  --policy.device=mps \
  --trackio.enable=true \
  --policy.repo_id=<USER>/hand_test_policy
```

### Evaluar

```bash
lerobot-record \
  --robot.type=hope_jr_hand \
  --robot.port=/dev/tty.usbmodem58760432281 \
  --robot.id=right \
  --robot.side=right \
  --robot.cameras='{"main": {"type": "opencv", "index_or_path": 0, "width": 640, "height": 480, "fps": 30}}' \
  --display_data=false \
  --dataset.repo_id=<USER>/eval_hopejr \
  --dataset.single_task="Evaluate hopejr hand policy" \
  --dataset.num_episodes=10 \
  --dataset.streaming_encoding=true \
  --dataset.encoder_threads=2 \
  --policy.path=outputs/train/hopejr_hand/checkpoints/last/pretrained_model
# Optional: --dataset.rgb_encoder.vcodec=auto
```

