lerobot_tutorial / 3. LeRobot Manipulation.md
aailabkaist's picture
Upload 4 files
1a59c60 verified
|
Raw
History Blame Contribute Delete
6.64 kB
# 3. LeRobot Manipulation
last updated Dec/26/2025
## 3-1. Teleoperation
### ์นด๋ฉ”๋ผ index, ์ŠคํŽ™, fps ํ™•์ธ
2๊ฐœ ์ด์ƒ์˜ ์นด๋ฉ”๋ผ๋ฅผ ์—ฐ๊ฒฐํ•ด ๋ฐ์ดํ„ฐ์…‹ ๊ตฌ์ถ•/๋ชจ๋ธ ์ถ”๋ก ์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
PC์— ์—ฐ๊ฒฐ๋œ ์นด๋ฉ”๋ผ์˜ index, ํ•ด์ƒ๋„, fps ๋“ฑ ์ •๋ณด๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.
```bash
lerobot-find-cameras
```
```bash
# Example print
--- Detected Cameras ---
Camera #0:
Name: OpenCV Camera @ /dev/video0
Type: OpenCV
Id: /dev/video0
Backend api: V4L2
Default stream profile:
Format: 0.0
Fourcc: YUYV
Width: 640
Height: 480
Fps: 30.0
--------------------
Camera #1:
Name: OpenCV Camera @ /dev/video2
Type: OpenCV
Id: /dev/video2
Backend api: V4L2
Default stream profile:
Format: 0.0
Fourcc: YUYV
Width: 640
Height: 480
Fps: 30.0
--------------------
Finalizing image saving...
Image capture finished. Images saved to outputs/captured_images
```
> **TIP**: ์นด๋ฉ”๋ผ ์—ฐ๊ฒฐ ์ˆœ์„œ์— ๋”ฐ๋ผ index๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์œผ๋‹ˆ, ์‹คํ–‰ ์ „ํ›„๋กœ ํ•ญ์ƒ `lerobot-find-cameras` ๋‹ค์Œ์— `.../lerobot/outputs/captured_images`์—์„œ ์บก์ฒ˜๋œ ์‚ฌ์ง„์„ ํ†ตํ•ด ๊ฐ camera์˜ ํฌํŠธ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
### Teleoperation command
```bash
lerobot-teleoperate \
--robot.type=so101_follower \
--robot.port=/dev/so101_follower \
--robot.id=follower_new_gripper \
--robot.cameras="{
top: {type: opencv, index_or_path: "/dev/video0", width: 640, height: 480, fps: 30},
wrist: {type: opencv, index_or_path: "/dev/video2", width: 640, height: 480, fps: 30}
}" \
--teleop.type=so101_leader \
--teleop.port=/dev/so101_leader \
--teleop.id=leader \
--display_data=true
```
### ์˜ต์…˜ ์„ค๋ช…
| ์˜ต์…˜๋ช… | ์„ค๋ช… | ์˜ˆ์‹œ ๊ฐ’ |
|---|---|---|
| `--robot.type` | follower ๋กœ๋ด‡ ํƒ€์ž… | `so101_follower` |
| `--robot.port` | follower USB ํฌํŠธ | `/dev/so101_follower` |
| `--robot.id` | follower ๋กœ๋ด‡ ๊ณ ์œ  ID (calibration ๋•Œ ์„ค์ •ํ•œ ID) |
| `--robot.cameras` | ์นด๋ฉ”๋ผ ์ •๋ณด | `lerobot-find-cameras`๋กœ ํ™•์ธํ•œ ๊ฐ’ |
| `--teleop.type` | leader ๋กœ๋ด‡ ํƒ€์ž… | `so101_leader` |
| `--teleop.port` | leader USB ํฌํŠธ | `/dev/so101_leader` |
| `--teleop.id` | leader ์ด๋ฆ„ | `leader` |
---
## 3-2. Record
### HuggingFace ๊ณ„์ • ์„ค์ •
```bash
# HuggingFace CLI ํ† ํฐ ๋กœ๊ทธ์ธ
hf auth login --token ${YOUR_TOKEN_HERE} --add-to-git-credential
# ๋กœ๊ทธ์ธ ํ™•์ธ
HF_USER=$(hf auth whoami | head -n 1)
export HF_USER=$(python -c "from huggingface_hub import whoami; print(whoami().get(\"name\", \"\"))")
# (Optional) ์˜๊ตฌ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •
echo 'export HF_USER=$(python -c "from huggingface_hub import whoami; print(whoami().get(\"name\", \"\"))")' >> ~/.bashrc
source ~/.bashrc
echo ${HF_USER}
# Task Name ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •
echo export ${TASK_NAME}=TASK_NAME >> ~/.bashrc # Task ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ์„ค์ •
#-------------------------------------------------------------------
# Huggingface ๋กœ๊ทธ์ธ ํ•˜์ง€ ์•Š๊ณ  ๋กœ์ปฌ์—์„œ ์ง„ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ
echo export ${HF_USER}=YOUR_NAME >> ~/.bashrc
echo export ${TASK_NAME}=TASK_NAME >> ~/.bashrc
source ~/.bashrc
echo ${HF_USER} && echo ${TASK_NAME}
```
- HuggingFace [ํ† ํฐ ์„ค์ • ํŽ˜์ด์ง€](https://huggingface.co/settings/tokens)์—์„œ ์ƒˆ ํ† ํฐ ์ƒ์„ฑ
- ๊ถŒํ•œ: `Write` ์„ ํƒ (๋‚˜์ค‘์— pretrained model์„ ํ•™์Šต์‹œํ‚ค๋Š” ๊ฒฝ์šฐ `Read` ๊ถŒํ•œ๋„ ํ•„์š”ํ•˜๋ฏ€๋กœ `Fine-grained` ์„ ํƒ ์ถ”์ฒœ)
- ์ƒ์„ฑ๋œ ํ† ํฐ์„ ์œ„ ๋ช…๋ น์–ด์˜ `YOUR_TOKEN_HERE`์— ์ž…๋ ฅ
### Record command
```bash
lerobot-record \
--robot.type=so101_follower \
--robot.port=/dev/ttyACM0 \
--robot.id=follower_new_gripper \
--robot.cameras="{
top: {type: opencv, index_or_path: "/dev/video0", width: 640, height: 480, fps: 30},
wrist: {type: opencv, index_or_path: "/dev/video2", width: 640, height: 480, fps: 30}
}" \
--teleop.type=so101_leader \
--teleop.port=/dev/ttyACM1 \
--teleop.id=leader \
--dataset.single_task="make a cup of coffee." \
--dataset.repo_id=${HF_USER}/${TASK_NAME} \
--dataset.num_episodes=10 \
--dataset.episode_time_s=1200 \
--dataset.reset_time_s=3 \
--display_data=true \
--dataset.push_to_hub=true \
--resume=true # ์ด๋ฏธ ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ์…‹ repo์— ์ถ”๊ฐ€๋กœ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ํ•˜๋Š” ๊ฒฝ์šฐ
```
### ์ฃผ์š” Record ์˜ต์…˜
| ์˜ต์…˜ | ์„ค๋ช… |
|------|------|
| `--robot.type` | follower ๋กœ๋ด‡ ํƒ€์ž… |
| `--robot.port` | follower USB ํฌํŠธ |
| `--robot.id` | follower ๋กœ๋ด‡ ๊ณ ์œ  ID (calibration ๋•Œ ์„ค์ •ํ•œ ID) |
| `--robot.cameras` | ์นด๋ฉ”๋ผ ์ •๋ณด |
| `--teleop.type` | leader ๋กœ๋ด‡ ํƒ€์ž… |
| `--robot.port` | leader USB ํฌํŠธ |
| `--teleop.id` | leader ๋กœ๋ด‡ ๊ณ ์œ  ID (calibration ๋•Œ ์„ค์ •ํ•œ ID) |
| `--dataset.single_task` | language instruction |
| `--dataset.repo_id` | ๋ฐ์ดํ„ฐ์…‹ repo ์ด๋ฆ„ |
| `--dataset.num_episodes` | ์ˆ˜์ง‘ํ•  ์—ํ”ผ์†Œ๋“œ ์ˆ˜ |
| `--dataset.episode_time_s` | ๊ฐ ์—ํ”ผ์†Œ๋“œ ๋…นํ™” ์‹œ๊ฐ„ |
| `--dataset.reset_time_s` | ์—ํ”ผ์†Œ๋“œ ๊ฐ„ ๋ฆฌ์…‹ ์‹œ๊ฐ„ |
| `--display_data` | ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™” ์—ฌ๋ถ€ (`Rerun`) |
| `--dataset.push_to_hub` | Huggingface ์ž๋™ ์—…๋กœ๋“œ ์—ฌ๋ถ€ |
### Record ์‹œ ํ‚ค๋ณด๋“œ ๋‹จ์ถ•ํ‚ค
| ํ‚ค | ๊ธฐ๋Šฅ |
|----|------|
| โ†’ | ์—ํ”ผ์†Œ๋“œ ์กฐ๊ธฐ ์ข…๋ฃŒ |
| โ† | ์—ํ”ผ์†Œ๋“œ ์žฌ๊ธฐ๋ก |
| ESC | Command ์ข…๋ฃŒ ๋ฐ ์—…๋กœ๋“œ |
### FileExistsError
๋ฐ์ดํ„ฐ์…‹ repo๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•˜๋ฉด ๊ธฐ์กด ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋ฎ์–ด์“ฐ์ง€ ์•Š๊ณ  FileExistsError๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ๊ธฐ์กด repo๋ฅผ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ `--resume=true` ์˜ต์…˜์œผ๋กœ ๊ธฐ์กด repo์— ์ด์–ด์„œ ์ˆ˜์ง‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
```bash
FileExistsError: [Errno 17] File exists: '/home/.../so101_pickplace'
```
**ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:**
```bash
rm -rf ~/.cache/huggingface/lerobot/${HF_USER}/${TASK_NAME}
```
---
## 3-3. Replay
```bash
lerobot-replay \
--robot.type=so101_follower \
--robot.port=/dev/so101_follower \
--robot.id=follower \
--dataset.repo_id=${HF_USER}/${TASK_NAME} \
--dataset.episode=0
```
### ์ฃผ์š” ์˜ต์…˜
| ์˜ต์…˜ | ์„ค๋ช… |
|------|------|
| `--dataset.repo_id` | ์žฌ์ƒํ•  ๋ฐ์ดํ„ฐ์…‹ repo ์ด๋ฆ„ |
| `--dataset.episode` | ์žฌ์ƒํ•  ์—ํ”ผ์†Œ๋“œ ๋ฒˆํ˜ธ |
| `--dataset.fps` | ์žฌ์ƒ ์†๋„ |
---
## 3-4. Visualization (๋ฐ์ดํ„ฐ์…‹ ํ™•์ธ)
### ๋ฐฉ๋ฒ• 1: HuggingFace ์›น์—์„œ ํ™•์ธ
[LeRobot Dataset Visualizer](https://huggingface.co/spaces/lerobot/visualize_dataset) ํŽ˜์ด์ง€์—์„œ ๋ฐ์ดํ„ฐ์…‹ repo๋ฅผ ์ž…๋ ฅ ํ›„ ํ™•์ธ
### ๋ฐฉ๋ฒ• 2: ๋กœ์ปฌ ์‹œ๊ฐํ™”
```bash
lerobot-dataset-viz \
--repo-id=${HF_USER}/${TASK_NAME} \
--episode-index=0 # visualizeํ•  ์—ํ”ผ์†Œ๋“œ ๋ฒˆํ˜ธ
```
- Rerun ๋ทฐ์–ด ์ž๋™ ์‹คํ–‰
- ์นด๋ฉ”๋ผ ์˜์ƒ, ๋กœ๋ด‡ ์•ก์…˜, ์ƒํƒœ ์ •๋ณด ํ™•์ธ ๊ฐ€๋Šฅ
---