지금까지 만지신 파라미터들은 로봇 제어 루프(arm velocity, hand fps, teleop frequency) 위주라 카메라 스트리밍 지연에는 거의 영향이 없습니다. 영상 파이프라인은 별도 라인이에요.
영상 파이프라인 구조 먼저
Isaac Sim 렌더링 (GPU)
↓ GPU→CPU readback ← ① 큰 비용
shared memory write
↓
image_server.py (cv2.imencode JPEG) ← ② CPU 인코딩
↓ ZMQ PUB
Vuer 백엔드 (WebSocket) ← ③ TCP/HoL blocking
↓ Wi-Fi
Quest 3 브라우저 디코드
↓
WebXR 텍스처 업로드 → 합성 ← ④ Quest GPU
지연이 누적되는 지점은 ①②③④인데, 사용자가 “느리게 따라옴” 정도로 느낀다면 보통 ②+③ 조합이 8할입니다.
우선순위별 개선 포인트
1순위: ZMQ 프레임 누적 차단 (효과 큼, 작업 5분)
xr_teleoperate/image_server/image_server.py(또는 동등 파일)의 PUB 소켓에 다음을 추가하세요.
socket.setsockopt(zmq.SNDHWM, 1)
socket.setsockopt(zmq.CONFLATE, 1)
CONFLATE는 큐에 미전송 프레임이 쌓이면 최신 한 장만 남기고 폐기합니다. 이게 없으면 네트워크 jitter 발생 시 오래된 프레임이 큐에 쌓여 지연이 누적되는데, 사용자가 묘사한 "한 박자 늦음"의 전형적인 원인이에요. 수신단(Vuer 쪽)에도 RCVHWM=1, CONFLATE=1 적용.
2순위: JPEG 인코딩 부하 감소 (효과 매우 큼)
image_server.py에서 cv2.imencode('.jpg', img, ...) 호출부 찾으세요. 일반적으로:
# 기본값이 95인 경우가 많음 - 너무 높음
cv2.imencode('.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 60])
품질 95→60으로 낮추면 인코딩 시간과 대역폭이 절반 이하로 떨어지고 VR 시야각에서는 화질 차이가 거의 보이지 않습니다. 50까지도 실용적입니다.
3순위: 카메라 해상도 (효과 매우 큼)
unitree_sim_isaaclab의 카메라 설정에서 해상도 확인하세요. G1 inspire hand 시연 기준으로 한쪽 눈 640×480 정도면 충분합니다. 1280×720 이상이면 readback과 인코딩 모두 비례해서 느려집니다. VR 시야에서는 어차피 작게 보여서 1080p가 의미 없어요.
4순위: 네트워크 경로 (간과되기 쉬움)
- Quest 3는 반드시 5GHz 또는 Wi-Fi 6 6GHz에 연결. 2.4GHz면 거의 확정적으로 끊김/지연
- PC와 Quest가 동일 AP, 동일 서브넷, 가능하면 PC는 유선 연결
- 같은 라우터라도 mesh hop 거치면 RTT 5~20ms씩 추가됨
- 회사망의 Multi-AP 환경이면 격리된 단독 AP 권장
지표로는 Quest 3에서 PC로 ping해서 RTT가 연속 측정 시 max 10ms 이하여야 합니다. spike가 50ms+이면 Wi-Fi 채널 간섭.
5순위: Isaac Sim GPU→CPU readback
--enable_cameras로 활성화된 카메라가 RTX rendering으로 되어 있으면 GPU→CPU 복사 비용이 큽니다. unitree_sim_isaaclab의 카메라 설정에서:
- 카메라 개수를 꼭 필요한 만큼만(보통 head 2개)
- TiledCamera 사용 시 단일 readback으로 묶이는지 확인
- 가능하면
pathtracing 대신 RaytracedLighting 또는 RasterizedLighting
사용자가 만진 항목 재평가
shared_memory_utils.py의 _min_interval_sec을 50→100Hz로 올린 건 읽기 측이 빠르지 않으면 무의미합니다. shared memory에 100Hz로 써도 image_server가 30Hz로 읽으면 70%는 버려져요. 오히려 writer 부하만 증가. 50Hz로 되돌리고, 대신 image_server의 송출 주기를 측정해보세요.
끊김(jitter) 여부 진단
"부드럽고 빠르게"를 동시에 원하시는데, 이 둘은 다른 문제입니다.
- 느리게 따라옴 (latency): 파이프라인 깊이 → 위 1~3순위로 해결
- 끊김/뚝뚝거림 (jitter): 프레임 도착 간격이 불균일 → 4순위 네트워크 + CONFLATE 옵션으로 해결
Quest 3 브라우저에서 chrome://inspect 원격 디버깅으로 Performance 탭 보시면 프레임 간격 히스토그램 나옵니다. 16.7ms(60fps)에 일정하게 몰려 있으면 jitter는 없는 거고, 30~100ms로 산포되어 있으면 네트워크 문제입니다.
가장 빠른 검증 순서
- JPEG quality 60으로 낮추기 (1줄 수정)
- ZMQ CONFLATE/HWM=1 추가 (2줄 수정)
- 카메라 해상도 절반으로 (config 1줄)
- Quest를 5GHz로 강제
이 4개만 해도 체감 지연이 절반 이하로 떨어지는 게 일반적입니다. 적용해보시고 그래도 남는 지연이 있으면 chrome://inspect의 Performance 캡처를 공유해주세요. 어느 단계가 병목인지 정확히 짚을 수 있습니다.