# YAM

[YAM](https://doc.i2rt.com/products/yam)은 [I2RT Robotics](https://i2rt.com/)의 모방 학습 및 embodied AI를 위한 6-DOF 로봇 팔입니다. LeRobot에서 `yam_follower`는 선형 DM4310 그리퍼가 장착된 표준 YAM v1 팔 하나를 구동하고, `bi_yam_follower`는 두 개를 구동합니다. `lerobot-calibrate`, `lerobot-rollout`, `lerobot-replay`와 함께 사용하세요. LeRobot에는 아직 YAM 리더 팔이 없으므로, YAM은 정책(policy)에 의해 또는 데이터셋을 재생하는 방식으로 구동됩니다.

I2RT의 가이드를 참고하여 팔을 조립하고 배선하세요. 이 페이지는 LeRobot 쪽을 다룹니다.

| 가이드                                                           | 포함 내용                                  |
| --------------------------------------------------------------- | ----------------------------------------------- |
| [YAM Arm 시리즈](https://doc.i2rt.com/products/yam)             | Unboxing, mounting, wiring, motors and grippers |
| [소프트웨어 설정](https://doc.i2rt.com/getting-started/sw-setup) | CAN 어댑터, 비트레이트 및 고정 인터페이스 이름 |
| [YAM Cell](https://doc.i2rt.com/products/yam-cell)              | 팔로우어와 리더가 두 개인 양손 조작 스테이션 |

  <img
    src="https://doc.i2rt.com/images/yam-standard/YAM-ST-GP-1.webp"
    alt="YAM follower arm with the linear gripper"
    width="48%"
  />
  <img
    src="https://doc.i2rt.com/images/yam-station/DS-ST-1.webp"
    alt="YAM Cell bimanual station"
    width="48%"
  />

_YAM 팔로워(왼쪽)와 YAM Cell 양손 작업 스테이션(오른쪽). LeRobot이 팔로워를 제어합니다. 이미지 출처: I2RT Robotics._

## 하드웨어 및 안전

각 팔에는 ID 1부터 7까지의 7개 모터가 있습니다: 1~3번 관절에는 DM4340, 4~6번 관절과 그리퍼에는 DM4310이 사용됩니다. YAM Pro, Ultra, BIG YAM 및 기타 그리퍼는 아직 지원되지 않습니다.

다음이 필요합니다:

- Linux, and one USB-to-CAN adapter per arm (SocketCAN, classic CAN at 1 Mbit/s).
- 모든 모터의 CAN 타임아웃은 최대 400 ms(`8000` 틱, I2RT의 값)로 설정해야 하며, 예를 들어 [I2RT SDK](https://github.com/i2rt-robotics/i2rt)의 `set_timeout.py --timeout`를 사용할 수 있습니다. 타임아웃은 LeRobot이 명령을 보내지 않는 경우의 마지막 안전장치이므로, 이 설정이 없으면 LeRobot은 토크를 활성화하지 않습니다.
- 처음 연결할 때 인터넷 접근이 필요합니다. 중력 보상은 [`lerobot/robot-urdfs`](https://huggingface.co/buckets/lerobot/robot-urdfs/tree/yam/v1) 버킷에서 YAM 모델을 다운로드하여 `HF_LEROBOT_HOME/robot-urdfs/yam/v1` 아래에 캐시합니다.

> [!WARNING]
> 팔을 안정적인 표면에 고정하고 작업 공간을 비워 두세요. 연결을 해제하면 토크가 비활성화되고 팔이 중력에 의해 떨어지므로, 먼저 팔을 지지해야 합니다. 구동 중 전원이 또는 CAN 어댑터가 연결 해제되면, 프로그램을 중지하고 팔을 지지한 후 다시 연결하세요.

## LeRobot 설치 🤗

[설치 가이드](./installation)를 따르고, YAM 지원을 설치합니다:

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

이 명령은 팔에 `motorbridge`와 `python-can`을, 중력 보상에 `placo`를 설치합니다.

## 하드웨어 연결

두 팔은 동일한 모터 ID를 사용하므로 각각 자체 CAN 인터페이스가 필요합니다.

```bash
lerobot-setup-can --mode=setup --interfaces=can0 --use_fd=false
```

두 팔을 사용하는 경우 `--interfaces=can0,can1`을 사용합니다. 이 명령은 `sudo ip link`를 사용하여 Linux 인터페이스를 구성하며 모터 명령을 전송하지 않습니다. 두 팔을 사용하는 경우 재부팅 후 `can0`와 `can1`이 교체될 수 있습니다. 각 인터페이스가 어떤 팔을 구동하는지 확인하거나, I2RT의 [software setup](https://doc.i2rt.com/getting-started/sw-setup)을 사용하여 `can_follower_l`과 같은 고정된 이름을 부여한 후 해당 이름을 포트 olarak 사용하세요.

## 장치 유형

| 유형              | 장치            |
| ----------------- | ----------------- |
| `yam_follower`    | 단일 팔로워   |
| `bi_yam_follower` | 양손 팔로어 |

두 개의 팔을 사용하는 경우, 각 팔의 옵션을 `--robot.left_arm_config.<option>` 및 `--robot.right_arm_config.<option>`으로 설정합니다.

## 교정

Calibration은 완전히 닫힌 상태와 완전히 열린 상태의 gripper 한계만 측정하며, 관절은 공장 출하 시 제로 값을 유지합니다. 아래에 표시된 대로 먼저 팔을 접습니다. 측정하는 동안 Torque는 꺼져 있습니다: 팔을 지지하고, gripper만 손으로 움직이며, 각 프롬프트에서 Enter를 누릅니다. 이미 calibration이 존재하는 경우, 연결 시 제어 시작됩니다: 재사용하려면 Enter를 누르거나, 다시 측정하려면 `c`를 입력합니다. 그러면 LeRobot이 Torque를 끄기 전에 팔을 지지하도록 요청합니다.

  <img
    src="https://doc.i2rt.com/images/yam-standard/YAM-ST-GP-2.webp"
    alt="YAM arm in its folded position"
    width="48%"
  />
  <img
    src="https://doc.i2rt.com/images/linear-gripper-4310/GP-4310-CTR-1.webp"
    alt="Linear DM4310 gripper"
    width="48%"
  />

_모든 관절이 0인 접힌 자세(왼쪽)와 선형 DM4310 그리퍼(오른쪽). 이미지 제공: I2RT Robotics._

```bash
lerobot-calibrate --robot.type=yam_follower --robot.port=can0 --robot.id=yam
```

왼쪽 그립퍼가 먼저 측정된 후, 오른쪽 그립퍼가 측정되어 각각 `<id>_left` 및 `<id>_right` 파일에 저장됩니다.

```bash
lerobot-calibrate --robot.type=bi_yam_follower --robot.id=bimanual_yam \
  --robot.left_arm_config.port=can0 --robot.right_arm_config.port=can1
```

이후 명령에서 동일한 `--robot.id`를 사용하여 LeRobot이 저장된 파일을 로드하도록 합니다.

## 관찰과 행동

한 팔은 관찰과 동작 모두에서 `joint_1.pos`부터 `joint_6.pos`, 그리고 `gripper.pos`를 가집니다. 관절은 도 단위 절대 각도이며, 그리퍼는 0(닫힘)에서 100(열림)까지의 값을 가집니다. `use_degrees=false`를 설정하면 I2RT 및 MolmoAct2 데이터와 동일하게 라디안과 0에서 1 범위로 전환됩니다. `use_velocity_and_torque=true`를 설정하면 `.vel` 및 `.torque` 관찰이 추가됩니다. 동작은 관절 한계 값으로 클리핑된 절대 관절 목표 값입니다.

두 팔은 `left_`와 `right_` 접두사가 붙은 동일한 이름을 사용합니다. 팔에 설정된 카메라에도 접두사가 붙지만, 최상위 `--robot.cameras`는 이름을 그대로 유지합니다.

## 정책 실행

연결하기 전에 팔을 접힌 위치에 두되, 모든 관절을 0으로 설정하세요. LeRobot은 모든 관절이 해당 위치에서 11.5° 이내인지 확인한 후, 측정된 위치에서 제어를 시작합니다. 정책이 동작을 보내기 전까지는 아무것도 움직이지 않습니다.

```bash
lerobot-rollout \
  --robot.type=yam_follower --robot.port=can0 --robot.id=yam \
  --robot.cameras='{"wrist": {"type": "opencv", "index_or_path": 0, "width": 640, "height": 480, "fps": 30}}' \
  --policy.path=<user>/<policy> \
  --task="Pick up the cube"
```

두 개의 팔을 사용하는 경우 `--robot.type=bi_yam_follower --robot.id=bimanual_yam --robot.left_arm_config.port=can0 --robot.right_arm_config.port=can1`을 사용합니다. 롤아웃을 기록하려면 `--dataset.repo_id=<user>/rollout_<name>`을 추가하고, [추론 실행 및 정책 평가](./il_robots#run-inference-and-evaluate-your-policy)를 참고하세요. `lerobot-replay`는 동일한 `--robot.*` 옵션으로 기록된 에피소드를 재생합니다.

첫 번째 동작 이전, 그리고 `command_timeout_s`(1초) 동안 동작이 도착하지 않으면 팔은 현재 위치를 유지합니다. `idle_mode=float`인 경우, 관절은 중력 보상과 약한 감쇠가 적용되어 팔을 손으로 움직일 수 있으며, 그립퍼는 현재 개방 상태를 유지합니다. 추적은 사용자가 팔을 이동시킨 위치에서 재개됩니다.

## 안전

- 모터 고장 또는 피드백 누락은 모든 명령을 중단합니다. 두 개의 팔이 있는 경우, 어느 쪽에서든 고장이 발생하면 두 팔 모두 중단됩니다. 계속하려면 연결을 해제하고 다시 연결하세요.
- `gravity_factors`는 카메라나 페이로드 없이 표준 암을 대상으로 합니다. 카메라 또는 페이로드를 추가한 후에는 float 모드에서 암이 표류하지 않는지 확인하고, 표류가 발생하면 `gravity_factors`를 조정하세요.

## 구성 옵션

| 옵션                    | 기본값                          | 설명                                                |
| ------------------------- | -------------------------------- | ---------------------------------------------------------- |
| `port`                    | 필수                         | 예를 들어 `can0`와 같은 SocketCAN 인터페이스                    |
| `use_degrees`             | `true`                           | 도(degree)와 0~100 그리퍼; `false`는 라디안과 0~1 |
| `use_velocity_and_torque` | `false`                          | `.vel` 및 `.torque` 관측값 추가                      |
| `idle_mode`               | `hold`                           | `hold`로 포지션을 유지하거나, 액션이 도착하지 않으면 `float`      |
| `command_timeout_s`       | `1.0`                            | 유휴 모드로 전환되기 전까지 동작이 없는 초             |
| `initial_position_deg`    | 모두 0                        | 필수 초기 위치; `None`은 검사를 건너뜁니다          |
| `initial_tolerance_deg`   | `11.5`                           | 초기 위치로부터 허용되는 거리                 |
| `gripper_force_limit_n`   | `50.0`                           | 그리퍼가 물체에 막힌 후의 손가락 힘      |
| `gravity_factors`         | `[1.0, 1.1, 1.1, 1.2, 1.0, 1.0]` | 중력 보상의 관절별 배율          |
| `cameras`                 | `{}`                             | 팔에 부착된 카메라                                |

## 예: MolmoAct2

[`lerobot/MolmoAct2-BimanualYAM-LeRobot`](https://huggingface.co/lerobot/MolmoAct2-BimanualYAM-LeRobot)은 `allenai/MolmoAct2-BimanualYAM`을 LeRobot 형식으로 변환한 것으로, 공개된 정규화 통계가 포함되어 있습니다. 두 개의 YAM 팔을 라디안 단위로, 그립퍼는 0–1 범위로 학습했으며, 카메라는 상단, 좌측, 우측 순서로 세 개가 사용되었습니다. [MolmoAct2](./molmoact2)를 참고하세요.

```bash
pip install -e ".[yam,molmoact2,dataset]"

lerobot-rollout \
  --robot.type=bi_yam_follower --robot.id=bimanual_yam \
  --robot.left_arm_config.port=can0 --robot.right_arm_config.port=can1 \
  --robot.left_arm_config.use_degrees=false --robot.right_arm_config.use_degrees=false \
  --robot.cameras='{
    "top": {"type": "opencv", "index_or_path": "/dev/v4l/by-id/TOP_CAMERA", "width": 640, "height": 480, "fps": 30},
    "left": {"type": "opencv", "index_or_path": "/dev/v4l/by-id/LEFT_CAMERA", "width": 640, "height": 480, "fps": 30, "fourcc": "MJPG"},
    "right": {"type": "opencv", "index_or_path": "/dev/v4l/by-id/RIGHT_CAMERA", "width": 640, "height": 480, "fps": 30, "fourcc": "MJPG"}
  }' \
  --policy.path=lerobot/MolmoAct2-BimanualYAM-LeRobot \
  --inference.type=rtc --inference.rtc.execution_horizon=20 --inference.queue_threshold=20 \
  --device=cuda --interpolation_multiplier=2 \
  --interactive=true --play_sounds=false \
  --task="Pick up the red block and place it in the green bin"
```

`/start`를 입력하여 정책을 실행하고, `/subtask <text>`를 입력하여 지시를 변경하며, `/reset`를 입력하여 초기 위치로 복귀하고, `/stop`를 입력하여 종료합니다. 복귀 동작은 고정된 시간 동안 지속되며 YAM의 속도 제한이 여전히 적용되므로, 초기 위치에서 멀리 떨어진 팔은 완전히 복귀하지 못하고 중간에 멈출 수 있습니다.

Float 모드는 정책을 임의의 위치에서 시작할 수 있게 합니다: `--robot.left_arm_config.idle_mode=float --robot.right_arm_config.idle_mode=float`를 추가하세요. 첫 번째 `/start` 실행 전과 `/reset` 완료 후 1초 동안, 팔을 원하는 위치로 수동으로 이동한 후 `/start`를 입력하여 해당 위치에서 정책을 실행하세요. 이 용도로 `/stop`를 사용하지 마세요: 세션을 종료하고 토크를 비활성화합니다.

## 문제 해결

| 문제                                         | 확인                                                                                                        |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| CAN 인터페이스가 없거나 중단되었습니다            | 어댑터의 전원과 USB 케이블을 확인하고 `ip link show`를 실행합니다. `lerobot-setup-can`을 다시 실행합니다.                  |
| `missing or stale motor feedback`               | 24 V 전원, CAN 배선 및 종단, 모터 ID 1~7, 그리고 `port`가 해당 팔의 인터페이스인지 확인하세요. |
| 잘못된 팔이 움직입니다                             | 각 인터페이스가 어떤 arm을 구동하는지 확인하거나, 인터페이스에 고정된 이름을 지정하세요.                                   |
| `unsafe motor CAN timeout`                      | I2RT SDK를 사용하여 모든 모터의 CAN 타임아웃을 최대 400 ms로 설정합니다.                                           |
| `not within initial_tolerance_deg`              | …                                                   |
| Connecting에서 다시 보정을 요청합니다          | 교정 시 사용한 `--robot.id`를 동일하게 사용하세요.                                                             |
| 팔이 float 모드에서 표류합니다                    | 팔의 카메라 또는 페이로드에 대해 `gravity_factors`를 조정합니다.                                              |
| MolmoAct2가 팔을 잘못된 위치로 이동시킵니다 | `use_degrees=false`를 두 팔 모두에 설정하세요: 모델은 라디안과 0~1 그리퍼를 사용합니다.                              |

## 참고

- [YAM Arm 시리즈](https://doc.i2rt.com/products/yam): 하드웨어, 모터 및 그립퍼
- [소프트웨어 설정](https://doc.i2rt.com/getting-started/sw-setup): CAN 비트레이트 및 고정 인터페이스 이름
- [YAM Cell](https://doc.i2rt.com/products/yam-cell): 양손 조작 스테이션
- [I2RT SDK](https://github.com/i2rt-robotics/i2rt): 모터 도구, URDF 및 MuJoCo 모델
- [YAM 제품 페이지](https://i2rt.com/products/yam-6-dof-arm)
- [MolmoAct2](./molmoact2): LeRobot에서 정책 로드

