sbench_online/place.py): 레이캐스트로 수용체 최다 히트 평지를 찾아 로봇·그리퍼를 피해 물체만 정착 — 4종 수용체 스모크 4/4_last_skill stale · held=실제 lifted uid)온라인 실행 트랙의 restore 가족("bowl을 원래 자리에 놓아라")은 find와 달리 물체를 들고 목적지까지 옮긴 뒤 실제로 내려놓아야 성공 판정을 받는다. 260821 초기 구현(carry 모드)에서는 이 "내려놓기"를 VLA(π0.5)에게 pick_and_place subgoal로 그대로 맡겼는데, 반복적으로 실패했다 — 정책이 이미 든 물체를 다시 pick하려고 그리퍼를 열어 떨어뜨리거나, PickAndPlaceTask 자체가 "이미 든 상태"에서 시작되면 1~2스텝 만에 조기 종료됐다.
여기에 판정 로직도 문제였다: 기하학적 휴리스틱(objects_on_receptacle)이 "수용체 위 공중에 떠 있는 상태(=아직 든 상태)"를 놓임으로 오판하는 사례가 반복 발견됐다. "어디에 놓을지"(VLM이 결정)와 "물리적으로 어떻게 내려놓을지"(정책 능력)를 분리하지 않으면 restore 지표가 메모리 신호가 아니라 조작 정책의 한계를 재고 있는 셈이 된다.
v1(수정 전)은 30턴 동안 "복원했다"고 가정하고 떠나는 등 판정 신뢰성 자체가 낮았다. 가드·둘레 접근(대형 가구는 중심 반경 대신 AABB 둘레 후보)·판정(든 물체 제외) 수정 후 v2/v3을 재실행했으나 VLA place가 0/3, 1/3에 머물렀다.
"Pick up X and place it on Y" 프롬프트를 이미 든 상태에서 주면 정책이 pick 단계부터 다시 하려다 그리퍼를 열어 떨어뜨리는 패턴이 7회 시도 중 6회 재현됐다. 이는 프롬프트 튜닝으로 고칠 문제가 아니라고 판단, 하네스가 직접 물리적으로 내려놓는 place 프리미티브를 만들었다.
첫 버전(v4, AABB 최고 z)은 침대에서 헤드보드에 놓아 즉시 낙하했다. 레이캐스트로 실제 평지(매트리스)를 찾도록 바꿨지만, 로봇 최근접 후보가 매트리스 가장자리 경사라 미끄러지는 문제가 12/12로 재현됐다 — 로그인 재현 디버깅(tmp/place_bed_debug*.py)으로 원인을 확인하고 평지 중심 순 정렬 + 로봇 팔 스윕 회피(keep-out)로 교체해서야 안정화됐다.
동시에 판정 신호도 3차례 수정했다: v4는 성공 신호가 "안 든 GT 전부"를 요구하는 any-of 판정이라 프리미티브가 실제로 놓았는데도 실패로 기록됐고(v5에서 is_placed_on(든 물체)로 교체), 든 물체 추적이 planner 결정을 그대로 믿어 다른 물체를 잘못 이동시키는 사고(v5→v6에서 held = judge가 실제로 확인한 lifted uid로 수정)도 있었다.
v9는 "Place the X in or on the Y"라는 place 전용 프롬프트로 VLA 내려놓기를 한 번 더 시도했지만 0/3(누적 VLA place 1/12로 확정) — restore의 주 지표는 하네스 place(primitive)로 확정하고 VLA place는 병기 수치로만 남겼다. v10은 place 프리미티브 + drive 경로 없음 시 점유맵 재계산(062c3ae, 텔레포트 폴백 0/17 navigate) + 전체 영상(드롭 없음)을 결합한 최종 구성이다.
| 버전 | 변경 | bowls+remote (multi) | remote→bed | remote→toilet |
|---|---|---|---|---|
| v1 (수정 전) | carry 모드 최초 | ✗ pick_and_place 없이 "복원 가정" | ✗ bed 접근 실패 16회 | (✓ 기록됐으나 판정 오류) |
| v2/v3 | 가드·둘레접근·판정 수정 | ✗ pick_and_place 128스텝 실패 | ✗ 55스텝 닫힘→열림, 낙하 | v3 ✓ 6턴 d=0.18 |
| v4~v6 | place 프리미티브 도입·판정 신호 3차 수정 | v5 2/3 placed (held 오류) | v6 30/30 실패(경사) | v5/v6 ✓ |
| v7 | 평지 중심순 + keep-out | ✗ 1/3 (bowl#1 VLA pick 22회 실패) | ✓ d=0.71 | ✓ d=0.25 |
| v9 | VLA place 전용 프롬프트 재시도 | ✗ 낙하 | ✗ 1.56m 밖 낙하 | ✗ 0.60m |
| v10 (최종) | 프리미티브 + 맵 재계산 drive | ✗ 0/3 놓임 (VLA pick 반복 실패) | ✓ d=0.71 | ✓ d=0.13 |
VLA place 누적 성적: v2/v3/v9 합산 1/12 — π0.5 mixv2에게 "든 상태에서 내려놓기"는 프롬프트를 바꿔도 구조적으로 어려운 동작임이 확정됐다.
텔레포트 폴백 0/17 navigate(v10) — 점유맵 재계산으로 이전 런에서 실패하던 거실↔침실 장거리 경로(최장 17.5~22.6m)가 전부 주행으로 성공했다.
restore 지표를 신뢰할 수 있게 만들려면 "정책이 못 하는 물리 동작"과 "메모리가 없어서 못 하는 것"을 분리해야 한다. VLA에게 내려놓기까지 맡긴 v1~v3의 낮은 SR은 메모리 신호가 아니라 조작 ceiling에 가려진 값이었다 — 하네스 프리미티브를 넣고서야 restore SR이 메모리 전략 비교에 쓸 수 있는 신호가 됐다(v7/v10 2/3, 남은 실패도 pick으로 원인이 명확히 좁혀짐).
이 과정에서 발견한 판정 버그 3건(프로브 판정 종류 혼선, stale _last_skill로 인한 held 해제 오류, held uid가 planner 결정이 아닌 실제 판정 기준을 따르도록 수정)은 restore뿐 아니라 find 온라인 경로에도 전역 적용됐다 — 온라인 트랙 전체의 신뢰성을 올린 부수 효과.
bowls multi에서 반복되는 VLA pick 실패(22회)는 place 프리미티브로 해결되지 않는 조작 정책 자체의 한계다 — restore 확장 시 같은 물체(bowl)가 낀 질의는 계속 병목이 될 것.
v1 데이터셋 3 컨텍스트 11질의 전체(val_406__0 6 + val_733__0 2 추가)로 restore 확장 — 사용자 결정 대기. Cosmos3-Nano-Policy-DROID 저수준 정책과 place 프리미티브를 pick만 교체하는 조합(place_mode=primitive + --policy cosmos)으로 bowl pick ceiling이 개선되는지 별도 비교(관련: 260823-cosmos_vs_pi05_restore.html).