Index
2026-04-25 — Analysis

RoboCasa Depth Camera Convention 5-Mode 검증

VGGRPO / LGM Phase 2 | PnPCounterToMicrowave demo_0 frame 0

TL;DR

9.58 cm
stored_noinject NN
1.41 cm
stored NN (채택)
0.59 cm
render NN (ref)
5
검증 모드 수

1 배경 / 목적

VGGRPO의 LGM(Latent Geometry Model)은 multi-view depth GT supervision으로 학습한다. RoboCasa v0.1 시뮬 데이터(/home/nas_main/taewoongkang/Dataset/robocasa/v0.1_216x384_depth/, 216×384 RGB+depth, 3 cam)를 dataloader에 붙이기 전, depth/camera pose convention이 어긋나면 cm급 mis-registration이 학습 신호에 그대로 유입된다.

핵심 의심 사항: RoboCasa 데이터 수집 시 randomize_cameras=True를 사용했기 때문에 cam pose가 default가 아닌 per-demo 랜덤화됨. 이 pose를 잘못 복원하면 10cm급 mis-alignment 발생 (robocasa_depth 가이드 명시). depth는 OpenGL z-buffer (0~1 normalized), pose는 cam_configs parent_body local frame, intrinsic은 fovy 기반.

Cross-camera nearest-neighbor 거리를 정량 지표로 사용해 5가지 pose 복원 경로를 비교하고, dataloader 구현에 사용할 경로를 결정했다.

2 작업 내용

scripts/viz_robocasa_alignment.py를 작성하여 동일 demo/frame에서 5가지 pose 복원 경로를 비교했다. 각 모드에서 3 cam unproject → world point cloud → agentview_left → agentview_right median NN 거리를 측정.

ModeRGB/depth 소스cam pose 복원 방법
renderenv.reset_to 후 재렌더sim 기본 (default, cam 위치 미주입)
render_patchedenv.reset_to 후 재렌더set_cameras monkey-patch + edit_model_xml
storedHDF5 저장값 그대로sim.model.cam_pos/quat 직접 write + sim.forward()
stored_patchedHDF5 저장값 그대로set_cameras monkey-patch + edit_model_xml
stored_noinjectHDF5 저장값 그대로sim 기본 (pose 주입 없음, 오류 케이스)
디버깅 이슈: robocasa_depth 측 답변에 메서드 이름이 _setup_camera로 적혀있었으나, 실제 메서드명은 set_cameras (s 있음). dir(env.env)로 확인 후 정정.
검증 스크립트: scripts/viz_robocasa_alignment.py 테스트 데모: PnPCounterToMicrowave/mg/.../demo_216x384_depth.hdf5, demo_0, frame 0 정합 지표: agentview_left → agentview_right median NN 거리 (world space, cm) 보조 지표: frac < 2cm (픽셀 비율)

3 결과 (PnPCounterToMicrowave demo_0 frame 0)

ModeMedian NN 거리frac < 2cm해석
render0.59 cm60.4%재렌더링, default pose — 이상적 하한 (참고용)
render_patched1.41 cm52.4%결정적 케이스 — pixel+pose self-consistent 재렌더인데도 1.41cm
stored1.41 cm52.4%채택 경로 — 결과 동일
stored_patched1.39 cm52.6%monkey-patch 추가해도 무의미 (거의 동일)
stored_noinject9.58 cm6.2%pose 주입 없음 → cam 위치 완전 틀림 (가설 기각용)
핵심 발견 1: stored_noinject 9.58cm → stored RGB/depth가 default cam에서 만들어진 게 아님 확인. HDF5에 저장된 cam_configs 주입이 필수임을 수치로 검증.
핵심 발견 2: render_patched 1.41cm — 픽셀과 pose가 완전히 self-consistent한 재렌더링인데도 1.41cm 잔차 발생. 이는 코드 문제가 아니라, randomize_cameras=True로 두 cam의 baseline이 비평행이어서 발생하는 pixel-grid sampling noise임을 확정.
핵심 발견 3: stored ≈ stored_patched (1.41 vs 1.39cm). monkey-patch 방식의 부수효과(body rename)가 잔차 원인이라는 가설 기각. 두 경로 모두 동일 cam world pose 산출 → 더 단순한 stored 경로 채택.

K 행렬 검증 (분석식 대조):

agentview (fovy=60°, H=216): fy = 0.5×216/tan(30°) = 187.06 → 코드 출력 187.06 ✓ eye_in_hand (fovy=75°, H=216): fy = 0.5×216/tan(37.5°) = 140.75 → 코드 출력 140.75 ✓ agentview cam_pos (demo_0): [1.3218, -1.9076, 1.82] — viz stored mode와 mm 단위 일치 ✓

4 Takeaway

1.41cm는 허용 가능한 inherent noise

각 카메라의 depth/pointcloud는 mm급 정확하다 (sim z-buffer + 정확한 K/T). 1.41cm residual은 cross-camera nearest-pixel 거리이며, 두 cam이 서로 다른 각도에서 같은 표면을 다른 픽셀 grid로 찍어서 발생하는 것이다. 즉 "같은 점을 잘못 찍은 게 아니라 다른 점을 각자 정확히 찍은" 결과다.

LGM supervision 관점에서: 1m 거리 물체 기준 1.4% relative error, 216×384 해상도에서 약 1.5 pixel. DROID RealSense GT(홀/노이즈 있음) 대비 훨씬 깨끗한 신호다.

이 검증 결과는 robocasa를 사용하는 다른 프로젝트(DreamData, robotics 일반)에도 그대로 재사용 가능하다.

선택적 개선점: randomize_cameras=False로 재수집하면 render 수준(0.59cm)의 정합 달성 가능. 그러나 현재 1.41cm로도 LGM 학습 가능 수준이므로 필수는 아님.

5 Next Steps

채택된 dataloader 경로

stored 경로: sim.model.cam_pos/quatep_meta.cam_configs 직접 write + sim.forward(). monkey-patch 불필요. src/data/robocasa_dataset.py에 구현 완료 (별도 카드 참조).

randomize_cameras=False 재수집 협의 (선택)

robocasa_depth 팀과 협의 중. 재수집 시 cross-camera NN 0.59cm 수준 달성 가능. 현재 학습 진행 결과 보고 필요시 결정.

LGM 학습 후 depth 정합성 확인

step 100 viz로 LGM pred depth vs Any4D target depth 비교. 1.41cm noise가 학습에 실질적 영향을 미치는지 실험적 확인 필요.