사용자가 리포트 영상을 보고 "카메라가 벽 밖으로 튀어나가서 exo cam에서는 뭘 하는지 안 보이는 부분이 있다"고 지적(260908). exo는 학습·평가의 주 관측 카메라라 이 구간은 데이터로 못 쓴다. 먼저 얼마나 자주 발생하는지, 어떤 실패 모드인지부터 재야 했다.
tmp/cam_wall_probe.py)h5의 실제 카메라 자세(obs/sensor_param/<cam>/cam2world_gl)로 광선을 쏴 embedded(시선 첫 히트 <0.25m = 기하 안) / occluded(카메라→작업지점 사이 벽) 두 모드를 가른다.
-Z로 잡았는데 이 파이프라인은 +Z가 전방(routine_visibility 픽셀 로그로 검증된 규약과 동일). ② 목표점을 obs/extra/tcp_pose(베이스 상대 좌표)로 삼아 월드에서 집 반대편을 가리켜 "가림 99%"라는 거짓 결과가 나왔다. robot_base_pose(월드) + 전방 0.5m·z 0.9로 교정. 교훈: 좌표계 규약(전방 축·베이스 상대)은 영상 프레임으로 교차 검증하고 넘어갈 것.cam_wall_cull.py 신규 + SegmentedPolicy 훅)매 스텝 data.cam_xpos로 exo 카메라 위치가 벽 geom 내부(로컬 좌표 |p| ≤ half + 0.10m)인지 검사, 내부면 그 벽과 붙은 문·창·액자의 시각 geom만 group=5로 숨긴다(빠져나오면 25스텝 뒤 복구 — 즉시 복구 시 벽이 깜빡임). 충돌 geom(group≥3)은 그대로라 물리·주행·판정 불변. 기본 꺼짐(SCENEMEM_WALL_CULL=1일 때만) — type1/type2 재현을 안 건드린다.
실패 시도: 첫 시도(job 113066)는 모델 카메라 목록이 비어([wall-cull] 벽 36장 · 카메라 [] 감시) 아무것도 못 감시했다. exo는 MuJoCo 모델 안에 없고, RobotMountedCameraConfig가 fr3_link0에 오프셋을 얹어 파이프라인 바깥에서 자세를 만드는 구조라서다 → xpos[mount] + xmat[mount] @ offset으로 카메라 자세를 직접 계산하도록 수정.
tools/cam_wall_audit.py)사용자가 "쌍둥이 편(__5401) 마지막 부분도 벽만 보인다"고 재지적 → 리포트에 쓰인 편 전부를 stride 25로 전수 감사. 한 편(5400)만 보고 "0~19%"라 정리한 게 틀렸다 — 같은 집·같은 무대라도 동선이 달라 다른 벽에 걸린다(5400은 66% 지점, 5401은 100% 지점).
렌더 컬링은 "카메라가 벽 안"만 덮는다. 벽 밖에서 바짝 붙어 화면이 벽면으로 가득한 경우, 가구·가전 기하 안, 컬링의 부작용(벽 자리로 실외가 비쳐 보임)은 못 덮는다. 실측(tmp/cam_pose_cost.py, tmp/cam_where.py): 문제 프레임은 서 있는 자리 몇 곳에 몰림(5455 113표본 중 85개가 통 도킹 자세 1곳). 로봇이 벽에서 0.37~0.43m에 서면 뒤 0.47m 카메라 반경이 반드시 벽을 넘지만, 36방향 중 9~17방향만 해당 — 못 박힌 상면 도킹은 이미 0개 손해(train_5455 3개 중 0개, train_1652 67개 중 0개가 카메라 벽 안).
base_candidates 한 곳에 넣어 파지·놓기·통 도킹·응시가 모두 혜택을 받는다(호출처 11곳). 정렬은 거리 1순위·카메라 2순위 유지(카메라를 1순위로 두면 먼 standoff가 뽑힘).
| 편 | 벽 안 비율 (수정 전) | 조치 | 벽 안 비율 (최종) | 유닛 | 비고 |
|---|---|---|---|---|---|
train_5455__5400 | 19% (84/440) | 컬링 → 위치 예방(job 113066→113078→113400→113502) | 0% (0/309) | 4/4 ✅ | sim 439s → 308s, 통 자리 (13.76,5.55)→(10.21,9.90) |
train_5455__5401 (쌍둥이) | 11% (37/327), 편의 100% 지점 | 재실행(job 113313→113426) | 0% (1/502, exo2 표본 1건) | 4/4 ✅ | 컬링 1,087→164스텝, 짝과 통 자리 일치 |
train_1652__2001 (쇼케이스 A′) | 1% (5/802), 편의 73% 지점 차단 | 재실행(job 113319) | 미기록(감사 0%, 4/819) | 4/6 (원본과 동일 사유로 2 실패) | 컬링 1,770스텝, 정본 교체 + 쇼케이스 미디어 재생성(13:21→13:38) |
train_1652__3002·_tv | 각 1% | 보류(D② 노출 분석용 클립) | – | – | 재생성 시 컬링 켬 |
| 나머지 5편 | 0% | 조치 없음 | 0% | – | – |
| 방식 | 통 자리 | 카메라 벽 안 (5400/5401) | 컬링 발동 | 유닛 |
|---|---|---|---|---|
| 공격적(깨끗한 방향 많은 순) | (13.76,5.55) → (10.21,9.90) | 0% / 0% | 102 / 164스텝 | 4/4 · 4/4 |
| 보수적(min_clear 미만만 demote) | 원래 자리 유지 | 19% / 11% | 2,348 / 1,087스텝 | 3/4(폐기) · 4/4 |
렌더 컬링은 안전망(남은 102~164스텝, 약 4초의 주행 통과분만 덮음)이고, 위치 기반 선호가 근본이다 — 로봇이 애초에 그 자리에 안 서면 감사 수치 자체가 0%가 된다. 둘을 겹치면 긴 정지 구간은 애초에 안 생기고 남는 것은 몇 프레임짜리 통과뿐이다. 성능 손해가 없다는 점(4/4 유지, 오히려 편이 짧아짐)도 확인해 이 방식을 데이터 생성 파이프라인 기본값으로 채택할 근거가 됐다.
이동 중 프레임(5455 13/113·1652 38/70)은 도킹 자세 필터로 못 막는다 — 주행격자를 카메라 봉투만큼 부풀리면 막을 수 있지만 문 통과(폭 1.02~1.14m)가 깨진다. 벽 밖에서 바짝 붙어 보는 경우도 위치 기반·컬링 둘 다 못 잡는다.
routine_batch.py finish에 편별 "카메라가 벽 안 N%(컬링 O/X·발동 스텝)" 지표를 자동으로 찍어 물량 단계에서 걸러지도록 함 — 구현 완료.train_1652__3002·_tv)은 D② 노출 분석용이라 재생성 시점에 컬링을 켜서 처리.