Index
2026-09-14 — Analysis

Cartesian action replay 실패 원인 분석 → 공식 source IK bridge 검증

R2S | 원본 DROID Cartesian-velocity action 재현 디버깅 체인

TL;DR

0.22mm
로컬 DLS 이동량
RMSE=0
공식 IK parity (32 rows)
2.44e-05rad
70ms bridge RMSE
0
torque clip

1 배경 / 목적

Controller/physics 카드에서 joint-target replay는 안정적으로 stack에 도달했지만, 이는 recorded joint position을 그대로 재생한 것일 뿐 DROID 원본 데이터의 실제 action space인 Cartesian velocity를 재현한 게 아니다. H5에는 action/cartesian_velocity와 action/gripper_velocity가 모두 존재하고 공식 DROID franka 컨트롤러 기본값도 Cartesian velocity이므로, 이 경로가 원본 action 재현의 기본 가설이었다. 이 경로가 실제로 물리적 lift/stack을 만들어낼 수 있는지, 만약 실패한다면 원인이 좌표계 변환 실수인지 IK 알고리즘 차이인지를 규명해야 했다.

기존 한계: worker venv에는 소스가 쓰는 dm_control/dm_robotics 제약형 Cartesian6d velocity effector가 없어, 로컬 MuJoCo Jacobian DLS로 근사할 수밖에 없는 상태였다.

2 작업 내용

DROID 공식 소스(droid-dataset/droid@33ae6a6)의 robot_ik_solver.py, franka/robot.py, transformations.py를 SHA로 고정한 뒤, 로컬 adapter는 시뮬레이션 현재 EE state에서 광고된 0.075m/0.15rad Cartesian 노름 캡을 적용하고 MuJoCo Jacobian DLS로 풀어 전체 joint delta를 0.2rad로 균일 rescale했다(job 125568). cartesian_failure_audit.md는 이 실패를 read-only로 재감사해 rollout-vs-recorded RMSE 0.14373rad(p95 0.33759), 재고정 one-step RMSE 0.00963rad, site-frame R/Rᵀ 변환 대안이 각각 0.02784/0.02811rad로 재고정 baseline보다 더 나쁨을 확인 — 단순 프레임 관례 문제가 아님을 시사했다.

이어서 두 diagnostic으로 원인을 좁혔다: (A) cartesian_free_space_diagnostic.md Stage A(job 125614)는 DLS damping 그리드(0.0001/0.01/0.1)에서 0.1을 선택(fit RMSE 0.00860811809rad, holdout 0.005358834505rad), Stage B(job 125615)는 frozen 125316 스케일 위에서 controller factor 그리드(0.5/1/2)를 fit q-response RMSE로 골라 0.5를 선택(fit 0.03699890047rad, holdout 0.06528947587rad). (B) cartesian_oracle_target_diagnostic.md(job 125624)는 B125615의 XML/factor/feedback을 그대로 고정하고 DLS qdes만 recorded joint target으로 치환 — fit/holdout RMSE가 0.008305960543/0.010193401646rad로 급격히 개선됐다. 이는 factor 튜닝이 아니라 IK 산출값 자체가 문제임을 강하게 시사했다.

가설을 검증하기 위해 DROID 공식 RobotIKSolver를 pinned 상태로 직접 실행하는 격리 환경(.venv-source-ik, DROID commit 33ae6a6, MoMa 0.5 호환 스택)을 만들었다. One-row probe(job 125733, GL/OpenCV contrib 의존성 수정 후 성공)에서 row 9 qdes가 recorded target과 bitwise 일치했고, 전체 parity table(job 125772, rows 9-40)에서 32개 row/224개 joint value 전부 RMSE=0으로 재확인됐다. 마지막으로 시뮬레이션 현재 state를 실시간으로 source IK subprocess에 전달하는 70ms causal bridge smoke를 만들었다 — job 125818은 child stdout에 non-JSON 텍스트가 섞여 실패했고(child stdout을 fd 1→2로 영구 리다이렉트해 원인 규명 후 수정), 수정된 job 125824가 7초만에 완료됐다.

3 결과 (수치 필수)

단계측정치상태
로컬 DLS 원본 action replay (job 125568)94 samples/93 commands, 블록 0.22mm 이동, lift/stack 실패FAIL
실패 감사 (rollout vs recorded)RMSE 0.14373rad, p95 0.33759rad; R/Rᵀ 대안 0.02784/0.02811rad (더 나쁨)원인=단순 프레임 아님
DLS damping 선택 (job 125614)damping 0.1: fit RMSE 0.00860811809rad, holdout 0.005358834505radCOMPLETE, 미채택
Controller factor 선택 (job 125615)factor 0.5: fit RMSE 0.03699890047rad, holdout 0.06528947587radCOMPLETE, 미채택
Recorded-target 오라클 (job 125624)fit 0.008305960543rad / holdout 0.010193401646rad (B125615 대비 4-6배 개선)IK가 원인임을 특정
공식 IK teacher-forced parity (job 125772)rows 9-40, 224 joint value 전부 recorded target과 bitwise 일치, RMSE=0PASS (teacher-forced)
70ms causal bridge smoke (job 125824)row-10 q RMSE 2.443532601650518e-05rad, torque clip 0, 7초 완료PASS (causal, 짧은 구간)
핵심 발견: "로컬 근사 IK가 부정확하다"는 가설이 정량적으로 확정됐다 — factor를 아무리 튜닝해도(0.5→0.03699890047rad) recorded target 자체를 쓰는 것(0.008305960543rad)에 못 미친다. 공식 IK를 그대로 bridge하면 teacher-forced/짧은 causal 구간 모두에서 사실상 완벽하게 일치한다.
범위 제한: parity(job 125772)는 teacher-forced(같은 row의 raw state로 매번 재고정)이고, bridge smoke(job 125824)는 단 70ms/1회 control뿐이다. rows 9-40 전체(2170 step)를 causal하게 통합했을 때도 이 정확도가 유지되는지는 아직 미실행.

4 Takeaway

의미

이 디버깅 체인의 가치는 "실패했다"가 아니라 "왜 실패했는지 좌표계/알고리즘 수준까지 특정했다"는 데 있다. Recorded-target 오라클(카드1의 controller fit과는 독립적인 실험)이 로컬 DLS보다 4-6배 낮은 오차를 보인 순간, 문제는 controller gain이 아니라 IK 알고리즘 자체(DROID의 constrained/nullspace solver vs 단순 DLS)로 좁혀졌다. 공식 소스를 그대로 가져와 bridge하는 우회로가 성공했다는 것은, 로컬 근사를 정교화하는 대신 "공식 알고리즘을 그대로 이식"하는 방향이 훨씬 효율적임을 보여준다.

5 Next Steps

미해결 한계

bridge smoke는 70ms/1-control 스모크일 뿐이라, 원래 목표였던 rows 9-40 전체 causal 통합(2170 step)에서도 오차가 누적 없이 유지되는지는 검증되지 않았다. 매 control마다 fresh solver를 새로 생성하는 방식이 "operationally causal"하긴 하지만, 2023년 원본 시스템이 solver state를 유지했는지는 별개 문제로 남는다.

다음 실험

사전등록된 source_ik_causal_diagnostic(rows 9-40, 32 read/31 control, 2170 step)을 실행해 causal 통합 환경에서도 parity가 유지되는지 확인한다. 성공하면 cartesian_action_adapter의 로컬 DLS를 이 source IK bridge로 교체하고, job 125568의 lift/stack 실패가 실제로 해소되는지 카드1의 controller/physics gate와 함께 재평가한다.