LeRobot Phase 2 Stage 1.75 — 장애물 인지형 손목 접근 전문가
초록
Stage 1.5에서 장애물 앞에 파국적으로 실패했던 손목 컨트롤러를 손가락 curl과 같은 사전-감속 패턴으로 고치려 했으나 세 번의 시행착오를 거쳤다: (1) 단순 비례 감속은 목표가 물리적으로 도달 불가능한 벽 너머일 때 점근적으로 계속 파고들어 개선 없음, (2) 손가락 자체가 장애물을 전혀 보지 않고 자기 스케줄로 계속 오므라들어 장애물을 뚫는 것을 발견해 손가락 근접도에도 장애물 거리를 포함, (3) 목표를 정확히 얼리는 하드 스톱을 추가해도 관성으로 인한 1.5mm 순간 침투가 남아, 감속 시작·정지 여유거리를 15mm/3mm에서 80mm/40mm로 크게 키워 완전히 해결했다. 최종적으로 5개 장애물 위치 전부 침투비 0.0000으로 통과(Stage 1.5는 전부 실패, 최악 49%)했고, 손이 안전거리에서 정직하게 멈추는 궤적을 확보했다. 이 궤적으로 손목+손가락 통합 12차원 행동 데이터셋(31 에피소드)을 생성해 Stage 2 착수 준비를 마쳤다.
LeRobot/ACT Phase 2 Stage 1.75 — 장애물 인지형 손목 접근 전문가, 세 번의 실패 끝에 완전 통과
저자: Moojoco (hb5u)
계기: [[2026-08-20-moojoco-lerobot-act-phase2-plan]] v3에서 신설한 Stage 1.75 착수. 사령관 지시("응 착수해줘")로 진행.
일자: 2026-08-20
분류: handshake-robot, result, moojoco, mujoco, lerobot
0. 목표
[[2026-08-20-moojoco-lerobot-stage1-5-dataset-result]] §2에서, 장애물이 접근 경로에 조금이라도 들어오면 기존 손목 컨트롤러(목표까지 그냥 밀어붙임)가 예외 없이 파국적으로 실패(침투비 최대 49%)하는 걸 확인했다. 이번 목표는 손가락 curl에 이미 있던 "상대와의 거리 기반 사전-감속" 패턴을 손목 접근에도 적용해, 장애물 근처에서 스스로 감속·정지하는 컨트롤러를 만드는 것. 성공하면 (a) 이 컨트롤러 자체가 장애물 문제의 실질적 해법이 되고, (b) 그 궤적이 Stage 2가 모방학습할 "정답 손목 행동" 데이터가 된다.
1. 세 번의 시행착오 — 이번엔 매번 원인이 달랐다
1차: 비례 감속만 추가 → 개선 없음 (0.28~0.49 그대로)
손목 접근에 손가락과 같은 방식(거리에 비례해 속도를 줄이는 slow_factor = clip(거리/기준거리, 0, 1))을 그대로 적용했는데, 결과는 Stage 1.5와 거의 그대로였다. 원인을 실측 추적해보니, 이 비례 감속 방식은 거리가 정확히 0이 되기 전까지는 항상 "0보다 큰" 증분을 계속 더해 목표를 전진시킨다 — 손가락-손가락 접촉은 CURL_TARGET 자체가 서로 거의 겹치지 않게 미리 보정된 값이라 이 점근적 접근이 문제없었지만, 장애물은 그런 보정이 없는 진짜 강체라서 애초에 목표 지점(a_end/b_end)이 벽 너머(물리적으로 도달 불가능)일 수 있다. 그러면 아무리 감속해도 결국은 벽을 계속 파고드는 방향으로 미세 전진한다. 실측으로 확인: 거리가 0.5초 만에 15mm에서 -0.2mm로 붕괴.
2차: 손가락 자체도 장애물을 안 본다는 것 발견 → 부분 개선
디버깅 중 worst-contact 쌍을 직접 찍어보니 handB_pinky_geom vs obstacle_geom이었다 — 손목이 멈춰도 손가락은 자기 스케줄대로 계속 오므라들어(반대쪽 손과의 거리만 보고, 장애물은 안 봄) 장애물을 파고들고 있었다. 손가락 근접도 계산에 장애물까지의 거리도 포함시켰다.
3차: 하드 스톱 추가 → 그래도 남는 1.5mm 관성 침투 → 여유거리를 키워 해결
"거리에 비례해 감속"을 "일정 거리 밑에서는 정확히 0으로 얼림(하드 스톱)"으로 바꿨다. 로그로 목표 자체는 완벽하게 얼리는 걸 확인했는데도(그 프레임 이후 approach_state 완전 불변), 여전히 최대 1.5mm 침투가 남았다 — 원인은 목표가 아니라 관성이었다. 정지 신호가 오기 직전까지 붙어있던 속도 때문에 손이 몇 mm를 더 미끄러져 들어간 뒤 반동으로 되돌아 나오는 "소프트 캐치"였다(실측 로그: 거리가 -1.5mm까지 갔다가 몇 프레임 뒤 다시 +2mm대로 회복). 정지 시점의 속도 자체를 낮추려면 더 일찍(장애물에서 더 멀리) 감속을 시작해야 한다는 뜻 — 하드 스톱 여유거리를 3mm→40mm, 감속 시작거리를 15mm→80mm로 크게 키우자 5개 장애물 위치 전부 침투비 0.0000으로 완전히 해결됐다.
2. 최종 결과 — Stage 1.5와 직접 비교
| 장애물 위치 | Stage 1.5 (장애물 무지) | Stage 1.75 (장애물 인지, 최종) | 손목이 멈춘 지점 (handA/handB 진행률) |
|---|---|---|---|
| 없음 | 0.000 PASS | 0.000 PASS | 1.0 / 1.0 (완전 접근) |
| y=0.06 | 0.303 FAIL | 0.000 PASS | 1.0 / 0.653 |
| y=0.045 | 0.490 FAIL | 0.000 PASS | 0.97 / 0.711 |
| y=0.03 | 0.343 FAIL | 0.000 PASS | 0.875 / 0.768 |
| y=0.015 | 0.301 FAIL | 0.000 PASS | 0.771 / 0.825 |
| y=0.0 | 0.133 FAIL | 0.000 PASS | 0.662 / 0.876 |
침투는 완전히 사라졌고, 손이 완전히 오므라들지 못한 채 "안전거리에서 멈춘" 정직한 절충(악수를 다 못 끝내지만 다치지 않는다)을 확인할 수 있다 — 장애물이 접근 경로에 깊이 들어올수록 두 손 모두 더 일찍 멈추는 것도 합리적이다(handA/handB 진행률이 장애물 위치에 따라 체계적으로 낮아짐).
좌우/상하 오프셋 서브 스윕(회귀 확인, 장애물 없음)은 Stage 1.5와 완전히 동일한 결과(18/25 통과)로, 이번 변경이 장애물 없는 케이스에 영향을 주지 않았음을 확인했다.
종합: 31개 에피소드 중 24개 통과(Stage 1.5는 19개) — 장애물 서브 스윕만 보면 1/6(Stage 1.5) → 6/6(Stage 1.75)로 완전히 뒤집혔다.
3. 데이터셋 — 행동 공간이 손목까지 확장됨
data/procedural_curl_dataset_stage1_75/ — 31 에피소드, Parquet, 268KB, GPU 미사용 4.33초.
- 관찰(15차원): Stage 1.5와 동일(변경 없음).
- 행동(12차원):
handA_approach_use_frac,handB_approach_use_frac(신규) + Stage 1의 손가락 curl 사용비율 10차원. [[2026-08-20-moojoco-lerobot-act-phase2-plan]] v3에서 결정한 "손목접근까지" 정책 범위를 실제로 반영한 첫 데이터셋이다.
4. 다음 단계
이제 세 데이터셋(Stage 1: 45, Stage 1.5: 31, Stage 1.75: 31 — 총 107 에피소드)이 모두 준비됐다. Stage 2 착수 전 정리할 점:
- Stage 1/1.5는 행동이 10차원(손가락만), Stage 1.75는 12차원(손목 포함)이라 스키마가 다르다 — Stage 2 학습에 셋을 합칠지, 12차원 스키마로 통일해 Stage 1/1.5를 재생성할지 결정 필요.
- [[2026-08-20-moojoco-lerobot-act-phase2-plan]] v2에서 정한 필터링 방침(성공 궤적만 행동으로, 실패 궤적은 관찰만) 그대로 적용 가능.
사령관 확인 후 Stage 2(LeRobot 환경 세팅 + ACT 학습)로 진행한다.
