← Index
2026-10-19 — Engineering

Ego2Robot: Sharpa Wave 다지 손 변환 + 물리 검증

ego2robot | branch dexhand (미커밋) | configs/h2o_ur5e_sharpa.yaml | DESIGN.md §19

TL;DR

57/829
physics baseline
45/829
lock v1
183/829
contact + force
147→18
not_held
18→2.9mm
fingertip err

1 배경 / 목적

기존 파이프라인은 사람 손을 평행 그리퍼(pose + gap 1개)로만 변환함. Sharpa나 XHand 같은 다지 손으로도 같은 H2O 데이터를 만들 수 있는지 확인하는 작업임. 방법은 그리퍼와 같은 MuJoCo physics replay로 실제 물체 조작이 되는지 검증하는 것.

범위: Sharpa Wave는 menagerie에 MJCF가 있음. XHand는 없어서 URDF→MJCF 변환이 필요함(미착수).

2 Phase 1 — kinematic 변환

robots.py ur5e_sharpa: UR5e flange + Sharpa(좌우 mirror), palm site, 21 landmark retarget.py palm frame 궤적 (기존 fill/smoothing 재사용) dexhand.py 손가락 retarget (손가락별 길이 비율), 테이블 lift (손 / 팔 링크) ik.py 손가락 joint를 매 프레임 기록, guard bisect, 좌우 ArmIK placement.py 카메라 근접 페널티 (팔꿈치가 카메라 0.17 → 0.35 m) export joint 56-D, verify_dataset 지원 / gripper config hash 불변

사람 / UR5e+2F-85 / UR5e+Sharpa composite 비교

subject1/h1/0 (cappuccino)
subject3/o1/2 (book)
subject2/k1/1 (milk)

3 물리 검증 (184 seq, 933 episode)

기존 physics replay(§17)를 손가락 22개 position actuator로 확장함. grasp 판정은 엄지와 (다른 손가락 또는 손바닥)이 함께 닿는 것. 그리퍼 경로의 연산은 그대로임.

설정moved 성공 /829static undisturbed /104주요 실패
UR5e + 2F-85 무보정61—
UR5e + 2F-85 grasp 보정 (production)317—
null baseline (물체 고정)128102
UR5e + Sharpa baseline5783ik_fail 274, dropped 151, not_held 147, slipped 39
UR5e + Sharpa dex grasp v14560ik_fail 493, not_held 110, dropped 71, slipped 20

영상 패널: 원본 | (데이터셋 이미지) | physics replay. 초록 = GT 물체, 빨강 = 로봇 없이 둔 물체.

Baseline 성공

subject2/k1/1 82-136 grab (milk): 성공
subject3/o1/2 38-148 place (book): 성공

Baseline 실패 (dropped)

subject2/k1/1 287-432 pour: 사람 궤적만 따라가서 들어 올리다 놓침(sim lift 88 mm vs GT 118 mm)

4 Lift 버그 수정

테이블 접촉 판정에 base와 shoulder 링크(원래 테이블 위 3 mm)가 포함돼 있었음. 그래서 도달 불가 프레임까지 "테이블 접촉"으로 처리돼 palm을 최대 392 mm 들어 올림(26개 시퀀스에서 100 mm 초과).

움직이는 링크만 보도록 고치고 dex.max_lift 80 mm 상한을 둠. 3개 시퀀스 재실행에서 최대 80 mm 확인.

5 Phase 2 — 물체 기준 dex grasp (진행 중)

dexgrasp.py 1. grasp 구간 검출 (그리퍼용 detect_grasps 재사용) 2. palm을 물체 좌표계에 고정 (구간 평균 pose) 3. 손바닥이 물체와 겹치면 손등 쪽으로 back-off 4. 손가락별로 접촉까지 닫고 + squeeze 0.25 rad (position servo가 힘을 냄) 5. 구간 앞뒤 10 frame 블렌드, squeeze는 6 frame에 걸쳐 증가

dex grasp 성공

subject1/h1/0 64-127 grab (cappuccino): 성공. baseline에서는 ik_fail로 실패했던 episode
subject2/k1/1 0-61 place (milk): 성공. baseline에서는 dropped였던 episode

dex grasp: 잡았지만 IK로 실패 판정

subject1/h1/0 133-255 take out: grasp_frac 0.99로 계속 쥐고 있지만, 팔이 고정 자세를 못 따라가 tracking 오차(p95 15 mm)와 lift 부족(47 vs 61 mm)이 생김

6 Phase 2b — EgoCPT식 contact-aware IK + 힘 배분

EgoCPT(arXiv 2610.17572, 같은 Sharpa 손)의 "접촉 샘플링 → 관통 없는 자세 refine → 힘 배분"을 적용함. 다만 손목을 공중에 띄우지 않고 UR5e 팔 6관절 + 손가락 22관절을 직접 최적화해서, 결과 자세가 그 base에서 도달 가능하도록 보장함.

dexcontact.py — grasp 구간(+블렌드)의 프레임마다 damped Gauss-Newton: 손끝 ↔ 접촉점(물체 표면 + pad 6 mm) 손–물체 관통 / 팔·손–테이블 관통 페널티 사람 palm 자세, retarget 손가락, 이전 프레임 근접 힘 배분: 손가락별 접촉점 150세트 샘플(반경 2 cm) → friction cone(μ 0.8) grasp matrix로 m(a−g) NNLS → 잔차 최소 세트를 구간 접촉점으로 고정 squeeze = 법선력 × lever / kp × 2 (0.05~0.25 rad)
버전 (184 seq)moved 성공 /829null보다 나은 성공static undisturbed /104
Sharpa baseline574383
lock v1454060
contact IK + 힘 배분183 (22%)15264
참고: 2F-85 grasp 보정 / ALOHA 보정317 / 174

실패 원인 변화: not_held 147→18, slipped 39→23, ik_fail 274→270, dropped 151→185(현재 최대 병목). 3 seq 개발 단계에서 접촉만 쓴 버전은 1/12로 오히려 악화됐고, 힘 배분을 넣으니 4/12. 힘 배분이 핵심이라는 EgoCPT ablation과 같은 경향임.

같은 episode 비교 — baseline vs contact

subject2/h1/1 298-444 pour (milk), baseline: 사람 궤적만 따라감
같은 episode, contact IK + 힘 배분: 성공 (ADD-S 5 mm, sim lift 72 mm)

성공 사례 (baseline에서는 실패)

subject1/h1/4 59-118 grab (chips)
subject1/k2/0 182-282 take out (cappuccino)
subject1/h1/3 156-241 open (lotion)
subject1/o1/2 239-464 read (book, 양손)
subject1/k2/4 106-180 spray

남은 실패

subject1/h1/1 304-442 pour (milk): 들어 올린 뒤 놓침(dropped, sim lift 14 mm vs GT 56 mm). 원위 관절 kp(0.9)가 낮아 힘이 부족한 것으로 의심
subject1/h2/3 438-741 apply (lotion, static): 들지 않는 grasp에서도 squeeze가 물체를 밀어 교란. apply static 11/31만 undisturbed

7 피드백 반영 — 가리키기 vs 잡기, 팔 튐

문제 1: 가리키는 손이 책을 움켜쥠. subject1/o1/2 read에서 사람은 왼손으로 책을 받치고 오른손 검지로 페이지를 가리킴. 그런데 오른손의 다른 손가락도 표지에서 2.5 cm 안에 있어 접촉 손가락으로 잡혔고, squeeze까지 걸려 쥐는 모양이 됐음.

수정: grasp = 엄지와 다른 손가락이 마주 보는 면에 닿을 때만 (중간 접촉점의 바깥 법선 내적 < -0.3) 그 외(가리키기, 손바닥 얹기) = touch 1.2 cm 안에 닿는 손가락만 표면에 붙임, squeeze / 힘 배분 없음, 나머지는 사람 posture

문제 2: 안 쓰는 손이 위로 튐. 원인은 lift가 아니라 양팔 IK의 branch transition임. 추종이 막히면 recovery가 먼 팔 자세를 찾아 관절 공간으로 옮겨가는데, 그 경로에서 손이 공중으로 휨(오른손 높이 120 → 761 mm).

수정: ik.max_transition_detour = 0.1 m (dex config만, 그리퍼 config hash 불변) 옮겨가는 경로에서 손이 직선 경로보다 10 cm 이상 벗어나면 그 branch로 가지 않고 오차를 안고 추종
subject1/o1/2수정 전수정 후
오른손 86-458 판정grasp (5손가락 squeeze)touch
55~90 프레임 오른손 최고 높이761 mm172 mm
프레임당 15 mm 넘게 움직인 프레임799
오른팔 transition 비율18.7%0.6%
read episode성공성공 (왼손이 지지)
트레이드오프: 먼 branch로 회복하던 프레임이 이제 오차를 안은 채 남음. subject2/k1/1 IK 실패율 0.07 → 0.30. 이 프레임들은 curation에서 bad로 걸러짐. 개발용 3 seq physics 성공은 4/12로 같음. 전체 184 seq 재측정은 아직임.
수정 후 read: 오른손은 touch(가리키기), 왼손이 책을 지지 → 성공
수정 전 80-177: 오른팔이 branch transition으로 화면 밖으로 휘어 나감
수정 후 80-177: 오른손이 사람처럼 책 오른쪽 모서리에 머묾

8 Floating hand + TACO

Floating hand (가상 6-DoF 손목, 팔 없음, EgoCPT와 같은 설정)로 팔 도달성 손실을 분리 측정함. 184 seq에서 moved 230/829 (28%). UR5e+Sharpa 최신판(손–손 회피 포함) 182 대비 +48이고, ik_fail은 158 → 46.

H2O 184 seqmoved 성공ik_faildroppedstatic undisturbed
UR5e + Sharpa (contact+힘 배분+touch+손–손 회피)18215821769
Floating Sharpa230 (28%)4624775
Floating Sharpa 개선판 (접촉 상태로 시작 + 도달 가능한 접촉 후보 선택)322 (39%)3418776
참고: UR5e + 2F-85 grasp 보정 (production)317

TACO (CVPR 2024, 도구 사용 양손 조작): MANO 손(numpy FK), 물체 pose, 1인칭 카메라를 로더로 붙임. 테이블은 z = 0.548 m로 일정해서 depth가 필요 없음. 도구는 자유 물체로 판정하고, 대상 물체는 GT 궤적을 따라가는 kinematic 물체로 두되 도구와만 충돌.

TACO 232 seq 샘플moved 성공주요 실패
Floating, 보정 끔 (사람 궤적 그대로)1 / 230못 쥠 54, 미끄러짐 46, 쳐서 넘어뜨림 44, IK 실패 42
Floating, 보정 켬 (contact IK + 힘 배분)0 / 226못 쥠 65, 쳐서 넘어뜨림 45, IK 실패 41, 미끄러짐 34
UR5e + Sharpa, 보정 켬0 / 230IK 실패 117, 못 쥠 43, 쳐서 넘어뜨림 27, 미끄러짐 27
Floating, 개선판0 / 230못 쥠 74, 쳐서 넘어뜨림 46, IK 39, 미끄러짐 32, 시작 관통 24
결과 (232 seq 샘플, floating + 보정 켬): moved 0/226. 실패 유형: 못 쥠 65, 쳐서 넘어뜨림 45, IK 실패 41, 미끄러짐 34, 시작부터 손이 박힘 20. 좌표 정합은 정상(쥔 손의 손끝–도구 거리 중앙값 −2~−4 mm).
kinematic 변환(retarget, IK 실패 0.4~1.4%)은 TACO에서도 정상임. 실패하는 건 physics 검증임. 이유는 세 가지: (1) 도구를 처음부터 쥔 채 시작하는데 시뮬은 손을 편 상태에서 닫음, (2) 얇고 긴 손잡이(망치 338×131×32 mm)를 1.3~1.6배 큰 손가락으로 감싸는 접촉점을 가장 가까운 표면점 방식으로는 못 맞춤(계획 손끝 오차 p95 24~52 mm), (3) 긴 도구는 회전 오차가 ADD-S에 크게 반영됨. 보정 유무, 팔 유무와 관계없이 0~1개라서, 지금 보정 방식이 TACO 상황(처음부터 쥔 도구, 얇은 손잡이)을 다루지 못한다는 뜻임.
hit/hammer/box: 사람은 처음부터 망치를 쥐고 있으나, 로봇 손은 편 채로 남고 망치(주황)가 떨어져 나감(tracking)
dust/brush/teapot: 손가락이 브러시 손잡이를 감싸지 못함(no_grasp_contact)
dust/brush/cup: 잡았지만 미끄러짐(slipped)
pour_in_some/bowl/plate: 접근 중 그릇을 침(knocked)
empty/box/plate: 시작 자세에서 손이 상자를 관통(start_collision)
scrape_off/knife/plate: IK 실패
pour_in_some/cup/kettle: 컵을 들어 따르기 직전까지 재현(ADD-S 15 mm)했으나 판정 기준 미달(other). 보라색 = 대상 kettle

9 Takeaway

기존 파이프라인 구조를 대부분 재사용할 수 있음. segment·inpaint·render·composite·curate·physics 판정은 공용임.
다지 손의 실제 병목은 retarget이 아니라 로봇이 사람보다 크다는 점과 접촉력이었음. 손목을 고정하면 팔이 닿지 못하고(lock v1), 접촉점만 맞추면 물체를 밀어냄. 팔 관절까지 포함한 contact IK와 힘 배분을 함께 써야 효과가 나옴(57→183). 다음 병목은 "잡은 뒤 놓침"과 static 교란임.

10 Next