Lên hai tay: UMI bimanual pipeline với scripts chính thức
Đây là bài 5 trong series UMI + VLA. Bài này giả sử bạn đã có working single-arm policy từ bài 4.
Mục tiêu: thu demo bimanual với 2 UMI units, dùng scripts chính thức có sẵn trong repo (demo_real_bimanual_robots.py, eval_real_bimanual_umi.py, config umi_bimanual.yaml), và train policy hai tay đầu tiên.
Bimanual khó hơn single-arm ở chỗ nào? Hai tay phải phối hợp về thời gian — tay trái cầm object, tay phải thao tác. Sai lệch timing nhỏ (>50ms) có thể khiến policy không học được coordination. Toàn bộ section về time sync trong bài này là bắt buộc.
Chuẩn bị: 2 UMI units phải giống nhau
Trước khi thu data, đảm bảo:
[ ] Cả 2 units in từ cùng STL revision, cùng print settings
[ ] Đo caliper: max gripper width của cả 2 phải giống nhau (±1mm)
[ ] Camera angle của cả 2 phải giống nhau (đặt cạnh nhau và so sánh)
[ ] ArUco tag size giống nhau
[ ] GoPro firmware version giống nhau (recommended)
Tại sao quan trọng: policy sẽ map "left UMI pose" → "left robot gripper" và "right UMI pose" → "right robot gripper". Nếu 2 units có geometry khác nhau, mapping sẽ không đúng.
Convention trái/phải: quyết định ngay từ đầu
Đặt convention ngay bây giờ và dùng nhất quán trong toàn bộ pipeline:
robot0 = right arm (UMI unit phải, camera right, tracker right)
robot1 = left arm (UMI unit trái, camera left, tracker left)
camera0 = right wrist
camera1 = left wrist
Ghi convention này vào file calib/convention.txt. Nếu bạn swap trái/phải ở bất kỳ bước nào, policy sẽ học ngược tay.
Kiểm tra bimanual scripts có sẵn trong repo
cd universal_manipulation_interface
# Scripts chính thức cho bimanual — TẤT CẢ ĐÃ VERIFY TỒN TẠI
ls scripts_real/demo_real_bimanual_robots.py # ✓
ls scripts_real/eval_real_bimanual_umi.py # ✓
ls scripts_real/replay_real_bimanual_umi.py # ✓
# Config training bimanual — TẤT CẢ ĐÃ VERIFY TỒN TẠI
ls diffusion_policy/config/task/umi_bimanual.yaml # ✓
ls diffusion_policy/config/train_diffusion_unet_umi_bimanual_workspace.yaml # ✓
ls diffusion_policy/config/train_diffusion_transformer_umi_bimanual_workspace.yaml # ✓
# Xem options
python scripts_real/demo_real_bimanual_robots.py --help
python scripts_real/eval_real_bimanual_umi.py --help
Đây là những scripts chính thức, có sẵn, không phải custom code. Đọc --help để biết cách truyền đối số đúng cho robot và camera setup của bạn.
Thiết lập bimanual workspace
Vùng làm việc
[camera_overhead nếu có]
LEFT ARM WORKSPACE RIGHT ARM
←────────────────────────────────→
↑ ↑
Left UMI Right UMI
Workspace trung tâm: cả 2 tay có thể reach
Không có vật cản giữa 2 grippers
Đủ ánh sáng từ tất cả góc
Quan trọng: chọn task mà cả 2 tay thực sự cần phối hợp. Ví dụ:
- Gấp khăn (tay phải cầm 1 góc, tay trái cầm góc còn lại)
- Lắp nắp hộp (tay trái giữ hộp, tay phải đặt nắp)
- Chuyển vật từ tay phải sang tay trái
Đừng dùng task mà 2 tay làm độc lập nhau — như vậy bạn không cần bimanual policy.
Time synchronization
Đây là điểm fail phổ biến nhất trong bimanual setup. Cả 2 camera phải record cùng clock:
# Khuyến nghị: dùng 1 host machine cho cả 2 GoPro
# Tránh dùng 2 machine riêng vì sync qua network rất phức tạp
# Nếu bắt buộc dùng 2 machine, setup NTP/chrony:
sudo apt install chrony -y
chronyc tracking
chronyc sources -v
# Clock offset phải < 10ms
Sync event: bắt đầu mỗi demo với một clap hay LED flash visible từ cả 2 camera — giúp căn chỉnh timestamps thủ công nếu cần.
Thu demo bimanual
Dùng script chính thức để thu:
python scripts_real/demo_real_bimanual_robots.py --help
Xem arguments và điền đúng theo setup của bạn (camera serials, robot connections, output path, task description).
Workflow thu demo:
- Khởi động cả 2 GoPro (đồng thời)
- Hướng cả 2 camera về calibration board ~3 giây
- Thực hiện task — cả 2 tay cùng lúc
- Tốc độ vừa phải, tránh che khuất camera của tay này bởi tay kia
- Mở/đóng gripper rõ ràng tại điểm grasp
- Kết thúc: đưa cả 2 camera về board
- Stop recording
Số demo:
| Mục đích | Số demo bimanual |
|---|---|
| Smoke test | 5 |
| Check coordination | 20 |
| Baseline hợp lý | 50 |
| Production | 100-200 |
SLAM pipeline cho bimanual data
Chạy SLAM pipeline (00-07) riêng lẻ cho từng tay trước:
# Xử lý left UMI data
python scripts_slam_pipeline/00_process_videos.py [args for left data]
# ... chạy scripts 01-07 cho left ...
# Xử lý right UMI data
python scripts_slam_pipeline/00_process_videos.py [args for right data]
# ... chạy scripts 01-07 cho right ...
Sau đó merge hai replay buffers theo convention đã chọn (robot0=right, robot1=left).
Kiểm tra time alignment:
Sau khi có 2 trajectories, verify timestamp alignment:
import numpy as np
# Load left và right timestamps
# Kiểm tra max offset < 30ms cho manipulation tasks
left_ts = ... # timestamps từ left demo
right_ts = ... # timestamps từ right demo
offset_ms = np.abs(left_ts - right_ts).max() * 1000
print(f"Max time offset: {offset_ms:.1f} ms")
assert offset_ms < 30, "Time sync cần fix trước khi train"
Train bimanual policy
Config training bimanual đã có sẵn chính thức:
# Kiểm tra task config bimanual
cat diffusion_policy/config/task/umi_bimanual.yaml
# Train với UNet
python train.py --config-name=train_diffusion_unet_umi_bimanual_workspace \
task.dataset.dataset_path=/absolute/path/to/bimanual_replay_buffer.zarr.zip \
training.seed=42
# Train với Transformer (cần VRAM nhiều hơn)
python train.py --config-name=train_diffusion_transformer_umi_bimanual_workspace \
task.dataset.dataset_path=/absolute/path/to/bimanual_replay_buffer.zarr.zip \
training.seed=42
VRAM requirements:
- Bimanual UNet (2 cameras): 1× 24–48 GB
- Bimanual Transformer: 1× 48 GB khuyến nghị
Kiểm tra action dimension trong umi_bimanual.yaml:
python -c "
import yaml
with open('diffusion_policy/config/task/umi_bimanual.yaml') as f:
cfg = yaml.safe_load(f)
print('Action dim:', cfg.get('shape_meta', {}).get('action', {}).get('shape'))
"
Bimanual action bao gồm cả 2 arms: thường là [3+6+1, 3+6+1] = [10, 10] = 20D total (xyz + rot6d + gripper mỗi arm).
Deploy và test bimanual policy
# Xem options deploy
python scripts_real/eval_real_bimanual_umi.py --help
# Replay demo trước để test robot motion
python scripts_real/replay_real_bimanual_umi.py --help
Safety checklist cho bimanual (quan trọng hơn single-arm):
[ ] E-stop kết nối, test bấm E-stop trước
[ ] Kiểm tra 2 tay không collide trong workspace
[ ] Collision detection/avoidance bật trong robot SDK
[ ] Dry-run với slow speed trước (20-30% max speed)
[ ] Người đứng cạnh, không đứng giữa 2 tay robot
[ ] Workspace box constraint cho từng arm
Test scenarios bimanual:
| Scenario | Check gì |
|---|---|
| Object ở đúng vị trí demo | Cả 2 tay đi đúng vị trí không |
| Object lệch nhẹ | Spatial generalization |
| Task bắt đầu từ trạng thái khác nhau | Coordination timing |
| Một tay bị perturbation nhỏ | Recovery |
Lỗi bimanual thường gặp
| Lỗi | Nguyên nhân | Fix |
|---|---|---|
| 2 tay không sync | Time offset lớn | Dùng single host, clap sync event |
| Policy học 1 tay, tay kia xịt | Convention trái/phải sai | Reset về đúng convention từ đầu |
| Arms collide nhau | Không có bimanual collision check | Thêm collision sphere/capsule check |
| Training không ổn định | Action dimension sai | Verify từ umi_bimanual.yaml |
| Một tay bị "frozen" | Demo có tay đó không di chuyển | Check trajectory của từng tay riêng |
Bước tiếp theo
Nếu bimanual baseline hoạt động, bạn có thể:
- Bài 6: Upgrade lên D405 — nếu muốn RGB-D gần gripper
- Fine-tune VLA — GR00T/GR00T-LeRobot cho language conditioning
- Scale lên humanoid — xem bài 7 về whole-body pipeline
Nguồn tham khảo
- real-stanford/universal_manipulation_interface
- UMI bimanual task config
- UMI paper (Chi et al., 2024)