Index
2026-10-23 — Experiment

Sharpa Wave RL tracking: TACO에서 FDR / CHORD policy 영상과 결과

ego2robot-dexhand | FlashDexRetarget job 203738 · FlashCHORD job 204649/204650 | floating bimanual Sharpa

TL;DR

87.5%
CHORD SR (1 seq)
11.9%
FDR obj SR@1.0 (210)
47 / 210
FDR ever-success
0 / 230
우리 IK 파이프라인

0 사람 영상 시점 overlay

왼쪽은 TACO egocentric 원본, 오른쪽은 원본을 어둡게 하고 그 위에 RL 시뮬레이션(Sharpa 손 + 물체)을 같은 카메라로 렌더해 합성한 것이다. 반투명 초록이 사람 demo의 물체 pose다. 시뮬레이션 물체(갈색/연두)와 초록이 겹칠수록 잘 따라간 것이다. 손은 실제 사람 팔 위에 그대로 그려진다(가림 처리 없음).

CHORD: brush / brush / bowl_20230919_036 (64-world eval SR 87.5%)

TACO 30 fps 원본 속도로 재생한다. 정책은 0.5배속으로 학습되어 control step 348개가 TACO 262 프레임에 대응하고, 각 영상 프레임에는 가장 가까운 step을 보여 준다. world 1개(env 0) rollout이다.

FDR: 성공 archive 6 clip (같은 정책 1개)

brush / brush / cup_20231026_006 · 182 frames (30 fps, 실제 속도) · 평균 물체 오차 R 1.4 cm / 24° · L 2.3 cm / 19°
cut / knife / plate_20231015_263 · 157 frames (30 fps, 실제 속도) · 평균 물체 오차 R 1.0 cm / 27° · L 1.9 cm / 23°
empty / teapot / cup_20230927_040 · 225 frames (30 fps, 실제 속도) · 평균 물체 오차 R 1.1 cm / 22° · L 1.1 cm / 12°
put_in / bowl / bowl_20231013_140 · 108 frames (30 fps, 실제 속도) · 평균 물체 오차 R 2.7 cm / 17° · L 1.5 cm / 24°
smear / soap / plate_20230927_056 · 199 frames (30 fps, 실제 속도) · 평균 물체 오차 R 1.0 cm / 22° · L 1.3 cm / 27°
stir-fry / spoon / pan_20231020_071 · 130 frames (30 fps, 실제 속도) · 평균 물체 오차 R 1.9 cm / 19° · L 1.5 cm / 23°
정렬: RL reference 물체 궤적 ↔ TACO Object_Poses를 Kabsch + 시간 offset 탐색으로 맞춤 (tmp/rl_overlay/align.py) FDR : A = Rz(180°), TACO frame = FDR frame / 2 + 1.5 (6 clip 모두 잔차 < 0.001 cm) CHORD : A ≈ I, TACO frame = 0.75 · step + 0.25 (잔차 0.12 cm, motion_speed 0.5) 카메라: TACO egocentric_intrinsic + frame별 extrinsic → MuJoCo camera (focal/principal pixel, ego2robot robots.py와 같은 규약) 렌더러: tmp/rl_overlay/render_fdr_ego.py (FDR success rollout npz) tmp/rl_overlay/chord_dump.py (view_policy 실행 중 매 step body_q 기록) → render_chord_ego.py

1 배경 / 목적

우리 kinematic + contact IK 파이프라인은 TACO에서 0/230이었다. 처음부터 쥐고 있는 얇은 도구를 floating Sharpa로 쥐는 데 실패했기 때문이다. 그래서 사람 궤적을 물리 시뮬레이터 안에서 RL로 따라가는 외부 방법 두 가지를 붙였다(FDR, FlashCHORD). 10/22 리포트에는 수치만 있었고 CHORD 영상 렌더는 실패한 상태였다.

이번 목적: policy가 실제로 어떻게 움직이는지 영상으로 확인하고, 수치(성공률)가 시각적 품질과 맞는지 본다.

2 작업 내용

CHORD 렌더 수정

job 204651은 pyglet.display.xlib.NoSuchDisplayException: Cannot connect to "None"으로 실패했다. newton ViewerGL(headless=True)가 pyglet을 import하면서 X11 shadow window를 만들려 하기 때문이다. 환경변수 PYGLET_HEADLESS=1을 주면 pyglet이 EGL로 붙는다. 카메라는 물체 위치(약 (0, 0, 0.58) m)를 보도록 지정했다. eval과 같은 checkpoint를 world 1개로 348 step 렌더했고(20 Hz, 17.4 s), 로그인 GPU에서 약 1분 걸렸다.

PYGLET_HEADLESS=1 python scripts/view_policy.py \ evaluation.checkpoint=tmp/chord/runs/204649/policy_250003456.safetensors \ viewer.backend=mp4 viewer.headless=true viewer.num_frames=348 viewer.width=1280 viewer.height=720 \ "viewer.camera_position=[0.55,-0.45,0.95]" "viewer.camera_target=[0.0,0.0,0.6]" markers.enabled=false

FDR rollout 렌더러 (신규)

FDR은 학습 중 처음으로 성공한 clip의 rollout을 checkpoints/success/rollouts/*.npz에 저장한다(joint_pos, obj_pos/quat, 60 Hz). 공식 시각화는 viser 웹 서버뿐이라, tmp/fdr/render_rollouts.py를 새로 작성했다. FDR의 assets/robot/sharpa/bimanual.xml에 qpos를 그대로 넣고, 물체 visual mesh를 mocap body로 추가해 MuJoCo EGL로 offscreen 렌더한다.

3 결과: CHORD (1 시퀀스 expert)

taco_brush__brush__bowl_20230919_036, policy 250M steps, world 1개, frame 0부터 시작, object assistance 없음. 노란 원판이 받침대이고 초록 점은 Sharpa 손끝 marker다. 양손이 bowl(왼쪽)과 brush(오른쪽)를 들어 올려 공중에서 brush질을 한 뒤 원래 자리에 내려놓는다.

지표 (64 worlds eval, 204650)값
CHORD SR0.875 (실패: object 0.125, wrist 0.016)
ManipTrans SR / SPIDER SR0.953 / 0.953
mean ADD (AUC)2.06 cm (0.884)
물체 위치 / 자세 오차1.94 cm / 5.4°
0.0cm 2.0cm 4.0cm 6.0cm 0.0s 4.0s 8.0s 12.0s 16.0s time (s) object position error, median of 64 worlds (cm) tool (brush): 0.0s → 0.9cm tool (brush): 0.4s → 1.2cm tool (brush): 0.8s → 0.9cm tool (brush): 1.2s → 0.9cm tool (brush): 1.6s → 0.9cm tool (brush): 2.0s → 0.8cm tool (brush): 2.4s → 0.8cm tool (brush): 2.8s → 5.2cm tool (brush): 3.2s → 3.2cm tool (brush): 3.6s → 2.7cm tool (brush): 4.0s → 4.0cm tool (brush): 4.4s → 1.8cm tool (brush): 4.8s → 1.9cm tool (brush): 5.2s → 2.9cm tool (brush): 5.6s → 2.1cm tool (brush): 6.0s → 1.6cm tool (brush): 6.4s → 1.6cm tool (brush): 6.8s → 1.3cm tool (brush): 7.2s → 1.4cm tool (brush): 7.6s → 1.8cm tool (brush): 8.0s → 2.3cm tool (brush): 8.4s → 2.6cm tool (brush): 8.8s → 1.2cm tool (brush): 9.2s → 1.6cm tool (brush): 9.6s → 2.1cm tool (brush): 10.0s → 1.5cm tool (brush): 10.4s → 1.6cm tool (brush): 10.8s → 1.4cm tool (brush): 11.2s → 1.1cm tool (brush): 11.6s → 1.4cm tool (brush): 12.0s → 1.9cm tool (brush): 12.4s → 1.6cm tool (brush): 12.8s → 1.0cm tool (brush): 13.2s → 1.3cm tool (brush): 13.6s → 1.5cm tool (brush): 14.0s → 0.8cm tool (brush): 14.4s → 1.5cm tool (brush): 14.8s → 0.9cm tool (brush): 15.2s → 0.9cm tool (brush): 15.6s → 1.2cm tool (brush): 16.0s → 1.2cm tool (brush): 16.4s → 1.1cm tool (brush): 16.8s → 1.1cm tool (brush): 17.2s → 1.2cm tool (brush) 1.2cm target (bowl): 0.0s → 0.2cm target (bowl): 0.4s → 0.5cm target (bowl): 0.8s → 0.6cm target (bowl): 1.2s → 0.6cm target (bowl): 1.6s → 0.6cm target (bowl): 2.0s → 0.3cm target (bowl): 2.4s → 1.1cm target (bowl): 2.8s → 3.1cm target (bowl): 3.2s → 3.4cm target (bowl): 3.6s → 2.4cm target (bowl): 4.0s → 2.9cm target (bowl): 4.4s → 1.0cm target (bowl): 4.8s → 1.6cm target (bowl): 5.2s → 1.5cm target (bowl): 5.6s → 1.3cm target (bowl): 6.0s → 0.8cm target (bowl): 6.4s → 1.0cm target (bowl): 6.8s → 1.4cm target (bowl): 7.2s → 0.9cm target (bowl): 7.6s → 0.9cm target (bowl): 8.0s → 2.6cm target (bowl): 8.4s → 0.6cm target (bowl): 8.8s → 0.9cm target (bowl): 9.2s → 1.2cm target (bowl): 9.6s → 0.7cm target (bowl): 10.0s → 0.8cm target (bowl): 10.4s → 1.6cm target (bowl): 10.8s → 0.9cm target (bowl): 11.2s → 0.7cm target (bowl): 11.6s → 1.3cm target (bowl): 12.0s → 1.5cm target (bowl): 12.4s → 1.9cm target (bowl): 12.8s → 1.3cm target (bowl): 13.2s → 1.4cm target (bowl): 13.6s → 1.6cm target (bowl): 14.0s → 1.2cm target (bowl): 14.4s → 0.8cm target (bowl): 14.8s → 0.8cm target (bowl): 15.2s → 0.7cm target (bowl): 15.6s → 0.8cm target (bowl): 16.0s → 0.8cm target (bowl): 16.4s → 0.8cm target (bowl): 16.8s → 0.9cm target (bowl): 17.2s → 0.8cm target (bowl) 0.9cm
tool (brush)target (bowl)
프레임별 물체 위치 오차, 64 worlds의 median(점에 마우스를 올리면 값이 보인다). 평균 tool 1.64 cm / target 1.24 cm, 최대 5.3 / 4.0 cm. 90th percentile 평균은 2.4 / 1.9 cm다.

4 결과: FDR (210 clips, 정책 1개)

0.0% 5.0% 10.0% 15.0% 20.0% 25.0% 0M 100M 200M 300M 400M 500M env steps success rate (210 clips) obj@2.0: 20M → 0.0% obj@2.0: 40M → 0.0% obj@2.0: 60M → 0.0% obj@2.0: 80M → 0.0% obj@2.0: 100M → 0.0% obj@2.0: 120M → 0.0% obj@2.0: 140M → 0.9% obj@2.0: 160M → 1.4% obj@2.0: 180M → 1.9% obj@2.0: 200M → 2.9% obj@2.0: 220M → 3.8% obj@2.0: 240M → 6.2% obj@2.0: 260M → 6.7% obj@2.0: 280M → 8.1% obj@2.0: 300M → 6.2% obj@2.0: 320M → 10.0% obj@2.0: 340M → 10.0% obj@2.0: 360M → 10.5% obj@2.0: 380M → 12.4% obj@2.0: 400M → 12.9% obj@2.0: 420M → 12.9% obj@2.0: 440M → 19.1% obj@2.0: 460M → 16.7% obj@2.0: 480M → 20.5% obj@2.0: 500M → 20.5% obj@2.0 20.5% obj@1.0: 20M → 0.0% obj@1.0: 40M → 0.0% obj@1.0: 60M → 0.0% obj@1.0: 80M → 0.0% obj@1.0: 100M → 0.0% obj@1.0: 120M → 0.0% obj@1.0: 140M → 0.9% obj@1.0: 160M → 0.5% obj@1.0: 180M → 0.9% obj@1.0: 200M → 0.5% obj@1.0: 220M → 0.9% obj@1.0: 240M → 2.4% obj@1.0: 260M → 1.4% obj@1.0: 280M → 2.9% obj@1.0: 300M → 1.4% obj@1.0: 320M → 2.9% obj@1.0: 340M → 2.9% obj@1.0: 360M → 3.8% obj@1.0: 380M → 5.2% obj@1.0: 400M → 7.1% obj@1.0: 420M → 7.1% obj@1.0: 440M → 8.6% obj@1.0: 460M → 8.6% obj@1.0: 480M → 11.4% obj@1.0: 500M → 11.9% obj@1.0 11.9%
obj@1.0 (10 cm / 30°)obj@2.0 (완화)
20M steps마다 210 clips 전체를 평가한 결과. 120M까지 0이었고, 이후 계속 올라 500M에서도 포화되지 않았다(obj@1.0 기준 20M당 약 +1%p).

성공 clip 영상 (archive 47개 중 작업이 다른 6개)

불투명 물체가 시뮬레이션, 반투명 파란 물체가 사람 demo reference다. 60 Hz 재생. L/R은 왼손/오른손 물체다.

brush / brush / cup_20231026_006
364 frames (6.1 s) · 처음 성공 260M steps
평균 물체 오차 R 1.4 cm / 24° · L 2.3 cm / 19°
cut / knife / plate_20231015_263
314 frames (5.2 s) · 처음 성공 340M steps
평균 물체 오차 R 1.0 cm / 27° · L 1.9 cm / 23°
empty / teapot / cup_20230927_040
450 frames (7.5 s) · 처음 성공 460M steps
평균 물체 오차 R 1.1 cm / 22° · L 1.1 cm / 12°
put_in / bowl / bowl_20231013_140
216 frames (3.6 s) · 처음 성공 420M steps
평균 물체 오차 R 2.7 cm / 17° · L 1.5 cm / 24°
smear / soap / plate_20230927_056
398 frames (6.6 s) · 처음 성공 380M steps
평균 물체 오차 R 1.0 cm / 22° · L 1.3 cm / 27°
stir-fry / spoon / pan_20231020_071
260 frames (4.3 s) · 처음 성공 480M steps
평균 물체 오차 R 1.9 cm / 19° · L 1.5 cm / 23°

작업 종류별 성공 분포 (한 번이라도 성공한 clip)

taskclips성공비율
brush391333%
dust29828%
cut23626%
scrape_off22418%
pour_in_some1600%
empty15213%
put_in14321%
skim_off14321%
put_out13323%
stir7114%
smear6233%
measure400%
stir-fry4250%
hit300%
screw100%
합계2104722.4%
pour_in_some 0/16, measure 0/4, hit 0/3: 액체를 붓거나 도구로 치는 동작처럼 물체 자세가 크게 바뀌는 작업은 하나도 성공하지 못했다. 반면 brush 33%, cut 26%, stir-fry 2/4는 비교적 잘 된다.

5 Takeaway

해석

  • RL tracking은 TACO의 "처음부터 쥔 얇은 도구"를 실제로 푼다. 영상에서 CHORD와 FDR 성공 clip 모두 도구를 쥔 채 궤적을 따라가는 것이 보인다. 우리 IK 방식(0/230)으로는 안 되던 경우다.
  • FDR 성공은 위치는 맞지만 회전이 느슨하다. 렌더한 6개의 평균 회전 오차는 12–27°로, CHORD(5.4°)보다 3–5배 크다. 데이터셋으로 쓰려면 obj@1.0보다 엄격한 기준(예: 15°)으로 다시 걸러야 할 수 있다.
  • 시퀀스당 expert(CHORD)가 품질은 압도적이다. 대신 seq당 1.4 GPU·h가 들어 230 seq에 약 320 GPU·h다. FDR은 하나의 정책이지만 아직 학습이 부족하다.
  • CHORD 시퀀스(brush/brush/bowl_036)를 FDR이 한 번도 풀지 못했다는 점에서, 같은 clip에서 multi-clip 정책과 per-seq expert의 품질 차이가 크다.
  • 단, CHORD는 반속도(motion_speed 0.5)라 과제가 더 쉽다. 실제 속도로 재학습하거나 평가해야 FDR(실제 속도)과 공정하게 비교할 수 있다. 데이터셋으로 쓸 때도 action 시간축을 2배로 늘려야 한다.
  • 사람 영상 시점 overlay가 되므로, RL rollout도 우리 파이프라인처럼 [inpaint된 사람 영상 + 로봇 합성] 데이터셋 이미지로 export할 수 있다. 카메라, 시간, 좌표 정렬은 이미 풀렸다.
주의: 지표 정의가 서로 다르다. CHORD SR, FDR obj@1.0(10 cm/30° 시간 평균), 우리 ADD-S는 직접 비교할 수 없다. 영상은 성공 clip만 보여 주므로 FDR의 대표 품질이 아니라 상위 22%의 모습이다.

6 보완점 / 다음

CHORD 영상: ego2robot-dexhand/tmp/chord/runs/204649/policy.mp4 FDR 렌더러: ego2robot-dexhand/tmp/fdr/render_rollouts.py (MUJOCO_GL=egl, FlashDexRetarget env) FDR 영상: ego2robot-dexhand/tmp/fdr/videos/fdr_m*.mp4, fdr_meta.json ego overlay: ego2robot-dexhand/tmp/rl_overlay/out/fdr_ego_m*.mp4, chord_ego_brush_bowl_036.mp4