# 로드맵 각 단계는 **검증 가능한 산출물** 로 끝난다. "됐다" 를 눈으로 확인할 수 없으면 그 단계는 끝난 게 아니다. --- ## 0단계 — 개발 환경 · 데이터 계층 ✅ 완료 | | | |---|---| | 산출물 | `vkgs-doctor` 가 전부 초록, `nusim scene show` 가 씬을 출력 | | 상태 | **완료.** Docker 대신 로컬 micromamba 환경 (`scripts/local_setup.sh`) | - [x] 씬 인덱스 — 383 싱가포르 씬 / 532,157 장 / 피크 0.5 GB - [x] 인덱스 v2 — LIDAR_TOP 키프레임 추가 (씬당 약 40장) - [x] 스트리밍 JSON 파서 — 1.35 GB 를 피크 30 MB 로 순회 - [x] 카메라 리그 수학 — 6캠 배치를 실측으로 확인. Vulkan 투영행렬 y/주점 부호 버그 수정 - [x] 로컬 환경 (CUDA 12.1 + PyTorch 2.4.1 + gsplat 1.4.0 + Vulkan 1.4 로더, sudo 불필요) - [x] `vkgs-doctor` 전항목 통과 - [x] `vkgs_probe` 를 실제 GPU 에서 실행 — 컴퓨트 디스패치 검증 통과 --- ## 1단계 — 3DGS 재구성 🚧 진행 중 | | | |---|---| | 산출물 | 씬 하나의 `.ply` + 원본 대비 PSNR/SSIM 리포트 | | 기준선 | 정적 씬(주차장 등)에서 hold-out 뷰 PSNR ≥ 25 dB | - [x] `recon/init.py` — LIDAR_TOP 누적 → 초기 가우시안. 자차 점/반사 허상 제거, 씬 원점 이동(float32 정밀도), 하늘 구, 카메라 투영으로 색 초기화. **COLMAP 없음.** - [x] `recon/dataset.py` — 800×450, 씬 전체 RAM 적재(1.4 GB, 5초), 카메라별 hold-out 1/8. - [x] `recon/train.py` — gsplat + DefaultStrategy, 가우시안 상한, 카메라별 아핀 + 프레임별 게인 색 보정. - [x] `io/ply.py` — 표준 3DGS ply (원점은 헤더 comment 에 float64). - [x] 인덱스 v3 — 3D 박스 어노테이션 (싱가포르 364,833개) - [x] `recon/dynamic.py` — 움직이는 객체 판정(사람 전부 + 끝점 변위 > 2 m + moving 속성 과반), 키프레임 간 박스 보간, 근평면 클리핑 투영 마스크. 라이다 초기화와 학습 손실에서 제외. - [x] 색 굽기 — 평균 카메라 색 변환을 SH 에 구워 ply 만으로 nuScenes 색이 나오게. - [x] 정적 PSNR 25 dB 달성 — 60k 스텝 25.26 dB - [x] 카메라별 외부 파라미터 보정 (camera_adjust.json) - [x] 색 보정 중심화 (SH 굽기 대체) + 외부 파라미터 보정 L2 사전분포 - [x] 씬 3개로 검증 — 아래 표. **주간·황혼은 통과, 야간+우천은 실패** (싱가포르 우천 씬은 전부 야간) - [ ] 야간+우천 재구성 — 정적 3DGS 가정이 깨지는 조건이라 별도 접근 필요 (아래 참고) - [ ] 차량별 고정 캘리브 — 주간 씬 여럿의 외부 파라미터 보정을 평균내 n015 등 차량별로 고정 **씬 3개 검증 (60k 스텝, 최종 코드, 2026-10-01):** | 씬 | 조건 | 평균 밝기 | 정적 PSNR | SSIM | ply 그대로 | 가우시안 | 시간 | 판정 | |---|---|---:|---:|---:|---:|---:|---:|---| | scene-0003 | 주간 주차장 | 0.41 | **25.62** | 0.804 | 19.5 | 200만 | 64분 | 통과 | | scene-0992 | 황혼 ("Night") | 0.14 | **25.64** | 0.582 | 24.0 | 27만 | 20분 | 통과 (나무가 흐림) | | scene-1060 | 야간 + 우천 | 0.05 | 29.29 | 0.646 | 27.8 | 5.6만 | 15분 | **실패** — 수치만 높다 | **어두운 씬에서 PSNR 은 믿을 수 없다.** scene-1060 은 이미지가 거의 검어서(평균 0.05) 뭉개진 렌더도 29 dB 가 나온다. 실제 렌더는 가로등·차선·헤드라이트만 흐릿하게 남는다. 야간 판정은 SSIM 과 육안으로 한다. (LPIPS 를 지표에 넣는 것도 고려.) 야간+우천이 어려운 이유: 센서 노이즈, 젖은 노면의 시점 의존 반사, 헤드라이트 글레어, 렌즈의 빗방울 — 전부 '정적 장면 + 시점 무관 색' 가정을 깬다. 손실을 밝기로 정규화해 densify 를 살려 봤지만(가우시안 5.6만→48만) 노이즈를 따라가는 줄무늬만 늘었다 (PSNR 24.9, SSIM 0.50). 기본은 끄고 `max_loss_scale` 옵션으로만 남겼다. **scene-0003 (주차장 출구) 실험 이력:** | 버전 | 스텝 | 정적 PSNR | 전체 PSNR | ply 그대로 | 비고 | |---|---:|---:|---:|---:|---| | v1 기본 | 30k | 24.54 | 23.98 | 18.05 | 움직이는 차가 흐린 잔상으로 구워짐 | | v2 동적 마스킹 + 색 굽기 | 30k | 24.63 | 22.84 | 19.07 | 잔상 제거 | | v2 + 가우시안 상한 350만 | 30k | 24.64 | 22.86 | — | 상한이 병목 아님 (자연 증가 213만에서 멈춤) | | v2 + absgrad | 30k | 24.36 | 22.73 | — | 오히려 나쁨 (가우시안 119만) | | v2 + 카메라 외부 파라미터 보정 | 30k | 24.72 | 23.01 | — | 캠마다 0.3~0.44° / 2~8 cm 보정됨 | | v2 | **60k** | **25.26** | 23.33 | — | **덜 학습이 주원인.** 기준선 통과 | | **최종** v2 + 외부 파라미터 보정 | 60k | **25.42** | 23.49 | — | SSIM 0.803. 보정값이 반복 실행에서 재현됨 (0.29~0.44°) | '정적 PSNR' 은 동적 마스크 밖 픽셀만 (배경 모델의 품질, 1단계 기준선). '전체' 가 v2 에서 내려간 것은 의도된 것이다 — 움직이는 차 자리에 이제 배경을 그린다. 진단에서 알게 된 것: - 학습 뷰 PSNR 도 25.2 에서 멈춰 있었다 → 과적합이 아니라 **미적합**. 씬당 뷰 1,200장에 3만 스텝은 뷰당 25회뿐이다 (원본 3DGS 는 200장 × 3만 = 150회). - 평가 뷰 노출 게인을 이웃 프레임에서 빌리는 손실은 0.13 dB 뿐 (oracle 비교). - 하늘 구만 보이는 픽셀은 오차의 2%. 밝은 픽셀(나뭇잎 사이 하늘)이 픽셀 9% 로 오차 29%. - 외부 파라미터 보정의 view 행렬 gradient 는 gsplat 이 4x4 하나로 atomic 합산해 스텝이 2.2배 느려진다. 4스텝에 한 번, 3만 스텝까지만 켠다 (`camera_every`, `camera_until`). - 색 굽기가 약 0.1 dB 잃는다 — gsplat 이 SH 색에 `clamp_min(0)` 을 걸어 완전한 선형이 아니다. **주의할 점.** 노출/화이트밸런스가 카메라마다 다르다. 보정 없이 학습하면 카메라 경계에 이음매가 생긴다. 카메라별 색 보정 파라미터를 같이 최적화한다. --- ### 1단계 보강 — 새 시점 품질 (카메라-라이다 융합, Difix) · 2026-10-01 closed-loop 에서 차선을 바꾸면(원래 경로에서 옆으로 1.5~3 m) 노면이 파편처럼 뭉개졌다. 원인은 색이 아니라 기하 — 기본 모델의 렌더 깊이가 라이다와 20% 어긋나 있었다. | 모델 (scene-0003) | 원래 궤적 정적 PSNR | 깊이 오차 (라이다 대비) | 차선 변경 시점 | |---|---:|---:|---| | 기본 (라이다는 초기화만) | **25.62** | 22.0% | 노면 뭉개짐 | | + Difix 의사 정답 미세조정 | 24.80 | 23.8% | 매끈하지만 흐림 | | **+ 라이다 깊이 감독** (`--depth-lambda 0.1`) | 24.83 | 2.3% | **연석·차선·노면 표시 유지** ← 시뮬레이터 기본 | | 깊이 감독 + Difix | 24.18 | 2.4% | 3 m 에서 약간 더 깨끗, 대신 −0.65 dB | | 깊이 감독 + sweep 융합 (20 Hz 라이다 384장) | 24.69 | **2.0%** | 깊이 감독과 비슷, 하늘에 줄무늬 | - 라이다 깊이 감독 = 정적 라이다 누적점(동적 객체 제거)을 뷰마다 z-buffer 깊이 지도로 만들어 렌더 기대 깊이와 상대 L1 (`nusim/recon/depth.py`). 기하 오차가 10배 준다. - sweep 은 깊이 지도를 촘촘하게 하지만(1/2 해상도 채움 51% → 79%) 결과 차이는 작았다. 라이다 수직 시야 위(하늘)는 여전히 구속이 없어 floater 가 남는다. - Difix(NVIDIA, SD-Turbo 단일 스텝 확산, 연구용 라이선스)는 렌더 후처리로는 가장 좋지만 장당 1초라 closed-loop 에 못 쓰고, 참조 사진의 움직이는 차를 되살리는 환각이 있다. OneFixer(arXiv 2609.32175) 는 코드 미공개, NVIDIA Fixer 는 cosmos 컨테이너 스택이 필요해 보류. - 남은 한계: 원래 카메라가 한 번도 못 본 면(차단기·콘의 옆면)은 3 m 이동에서 여전히 깨진다. ### 환경 전용 재구성 (2026-10-02 결정) 렌더링은 **주행 맵(환경)만** 구성한다. 차량·사람 같은 교통 참가자는 3단계에서 시뮬레이터가 따로 넣는다. - `nusim recon train --objects agents`: 움직이는 객체뿐 아니라 **주차 차량·서 있는 사람·자전거까지** 학습 마스크와 라이다 누적에서 뺀다 (`nusim.recon.dynamic.masked_instances`). 콘·방호벽(movable_object)은 맵으로 남긴다. scene-0003: 기본 24개 → 54개 (승용차 35, 보행자 15, 자전거 4). - 차가 서 있던 노면은 다른 시각·다른 카메라에서 본 픽셀과 라이다 깊이 감독으로 채운다. - 결과는 `outputs/gs/_env`. `render view` 는 이 모델이 있으면 기본으로 쓴다. 다른 차량(glTF)은 기본으로 그리지 않고 `--agents` 로만 켠다. 자차는 계속 표시한다. ## 2단계 — Vulkan 렌더러 🚧 2a 완료 | | | |---|---| | 산출물 | 같은 카메라 자세에서 학습기 렌더와 Vulkan 렌더의 픽셀 차이 < 2% | ### 2a. 빌보드 경로 ✅ (2026-10-01) - [x] `.ply` 로더, 가우시안 SSBO 업로드 (3D 공분산은 CPU 에서 미리, 240 B/가우시안) - [x] 깊이 정렬 (GPU bitonic → 2026-10-05 보이는 것만 GPU radix, 엔진 경량화 참고) - [x] 화면정렬 쿼드 + 알파 블렌딩 (RGBA32F 누적, gsplat 과 같은 수식·상수) - [x] GLFW 창, 자유 카메라 / 6캠 추종 / 궤적 재생 / BEV(높이 클립) → **화면에 뜬다** - [x] nuScenes map expansion 오버레이 (주행가능영역, 차선 중심선, 구분선, 정지선, 보도, 자차 궤적·박스) - [x] `nusim render compare` — **Vulkan vs gsplat PSNR 55.95 dB, 평균 차이 0.10%** (기준 < 2%, 합격) - [x] `nusim render video` — 6캠 + BEV 재생 영상 성능 (scene-0003, 가우시안 200만 / 보이는 33만, 800x450): 전처리 0.5 + 정렬 10.8 + 래스터 5.0 = **16.3 ms/장**. 정렬이 2/3 — bitonic 231 패스. 6캠 × 1600x900 을 100 ms 안에 넣으려면 2b 의 radix 정렬·타일 래스터가 필요하다. BEV 의 한계: 학습 카메라가 1.5 m 높이에서 수평으로만 봐서, 위에서 보면 나무 캐노피가 지면을 덮고 지면 가우시안이 바늘처럼 보인다. 높이 클립(기본 지면 +2.5 m)으로 캐노피는 걷어 내지만 바늘은 남는다 — 3DGS 의 본질적 한계이고 BEV 는 맵·궤적 확인용으로 본다. ### 2a+. IBL 환경 조명 ✅ (2026-10-02) - [x] 6캠 파노라마 (색 보정 역적용, 3DGS 알파 합성 + 외삽 채움) - [x] HDR 근사 → 큐브맵 → prefiltered specular (GGX) / irradiance (SH9) / BRDF LUT - [x] BC6H 압축 + KTX2 (Khronos `ktx validate` 통과) - [x] Vulkan: KTX2 로더, 환경 배경, PBR 구 검증, 메시–스플랫 깊이 합성 - [x] glTF 차량 로더 + PBR (IBL 조명, clearcoat, 유리 근사, texture_transform) — nuScenes 의 움직이는 승용차 박스 궤적마다 CarConcept(CC-BY 4.0)를 놓는다. 재생·운전·6캠 관측 모두에 나온다 (운전 중엔 로그 시계로, 아직 반응 없음) - [x] 차량 접지 그림자 — 차체 폭(모델 폭 ×0.85)·길이의 부드러운 둥근 사각형, 차체 깊이에 가려진다 - [x] 자차도 glTF 메시 (`assets/gltf/ego_car.glb` → 지금은 CarConcept, Renault Zoe 길이 4.1 m 로). nuScenes 주차 차량 3DGS 에셋은 뒷면이 흐려 대체. 자차 카메라 시점·관측에서는 숨긴다 - [ ] 움직이던 차가 지워진 자리의 3DGS 품질 (학습 때 가려져 흰 안개처럼 남는다) - [ ] 자차 위치에 따른 환경맵 갱신 (여러 지점 굽기, 보간) ### 2b. 컴퓨트 타일 경로 - [x] GPU radix 정렬 (보이는 것만, 2026-10-05 — 엔진 경량화 참고) - [ ] 가우시안 투영 + 화면공간 공분산 (컴퓨트) - [ ] 16×16 타일 binning, 타일별 키 생성 - [ ] 타일별 정렬 + 전후 블렌딩 - [ ] 빌보드 경로와 수치 비교 ### 2c. 멀티뷰 - [ ] 6개 카메라 동시 렌더링 (뷰별 뷰포트, 큐 오버랩) - [ ] 오프스크린 → PNG/JPEG 덤프 - [ ] `nusim render` — ego 궤적 입력 → nuScenes 디렉터리 포맷 출력 **성능 목표.** 6 × 1600×900 = 8.6 Mpixel/프레임. closed-loop 10 Hz 를 위해 프레임당 100 ms 안에 들어와야 한다. --- ## 화질 개선 다음 단계 — 조사 결과 (docs/research_gs_2026-10.md) 1. MCMCStrategy + opacity/scale 정규화 2. 하늘 분리 (큐브맵 + 하늘 마스크) 3. antialiased 모드 4. 바늘 억제 정규화 + 단안 법선 5. gsplat 업그레이드 6. PPISP 색 보정 ## 전체 맵 + 합성 날씨 (2026-10-02 결정) - 싱가포르 **주간 씬만**(383씬 중 야간 약 99·우천 약 16 제외)으로 전체 맵을 재구성한다. 야간·우천 재구성은 품질이 낮다 (scene-1060 실패). - 날씨·조도는 시뮬레이터가 **합성**한다: 흐림, 비(빗줄기·젖은 노면·렌즈 물방울), 안개, 어두움(저녁·밤, 전조등). 뷰어 안 **슬라이더 UI** 로 실시간 조절하고, 같은 값을 명령줄·스크립트로도 줘서 VLA 시험을 재현 가능하게 한다. 6캠 관측에도 같은 날씨가 들어간다. - 순서: 일괄 학습 전 버그 수정 → 주간 씬 일괄 학습(GPU) → 그동안 날씨 렌더링·UI 개발 → 맵 단위 로더. ### 구현 (2026-10-05) - **일괄 재구성** `nusim recon batch` → `outputs/gs_day/` (씬마다 별도 프로세스, `batch_status.json` 으로 이어 하기). 주간 씬 284개(설명에 night/rain 낱말이 없는 씬 — 싱가포르 우천 씬은 전부 야간), 지역 순. 설정: 15k 스텝, MCMC, 라이다 깊이 0.1, 환경 전용, **하늘 분리**. 하늘을 분리하지 않으면 하늘 일부가 가까운 불투명 가우시안으로 구워져(scene-0003: 9 m 거리의 밝은 덩어리) 합성 날씨에서 하늘을 바꿀 수 없다. - **합성 날씨** `shaders/weather.comp` — 렌더 패스에 거리 누적 첨부(지금은 RG32F (Σzα, Σα), docs/architecture.md)를 더하고, 색 + 거리로 후처리: 시간대(노출·색온도·밤하늘), 구름(채도·대비·회색 하늘), 전조등(자차 앞 원뿔, 반사율 = 낮 색), 비(젖은 노면 어둡게 + 화면 공간 반사 + 빗줄기 + 물안개), 안개(거리 지수 감쇠). 끄면 입력을 그대로 복사 — 이전 렌더와 비트 단위로 같다. `--weather night` 같은 프리셋 또는 `daylight=,cloud=,rain=,fog=,wet=,headlights=`. - **슬라이더 UI** Dear ImGui 1.91.9 (MIT, third_party/imgui) — 창 왼쪽 위 패널(F1 숨기기), 프리셋 8개, 슬라이더 5개, 전조등 자동/끔/켬. 패널은 화면에만 그리고, 6캠 관측·PNG 에는 날씨만 들어간다. - 한계: 3DGS 색은 낮의 조명이 구워진 색이라 밤·전조등은 그 색을 반사율 대신 쓴다. 구워진 그림자는 흐림에서도 남는다. 젖은 노면 반사는 화면 공간이라 화면 밖·가려진 것은 비치지 않는다. 가로등 같은 밤 광원은 아직 없다. ### 시범 씬 실패 원인: 빠른 주행 (2026-10-05) | 씬 | 평균 속도 | 경로 | 15k PSNR | |---|---|---|---| | scene-0003 | 1.5 m/s | 29 m | 23.66 | | scene-0184 | 5.6 m/s | 108 m | 17.54 | | scene-0402 | 11.9 m/s | 235 m | 16.23 | scene-0402 를 `--time-window` 로 잘라 2k 스텝 학습: 2.5초 21.75 dB, 5초 20.88 dB (default 전략 20.45), 전체 20초는 15.5~16.3 dB. 전략(MCMC/default)·깊이 감독·카메라 보정은 원인이 아니고, 장면 길이가 원인이다. 학습 손실부터 높으니(L1 0.135 vs 0.05) 일반화가 아니라 적합 실패다. **대응: 빠른 씬은 시간 구간(약 5초, 60 m)별로 나눠 재구성한다.** 맵 단위 로더가 구간을 이어 붙인다. 일괄 학습(`recon batch`)에 구간 분할을 넣은 뒤 본 배치를 돌린다. ### 차량 동시 학습 + 장면 객체 에셋 (2026-10-06) 방향 전환: 차량을 지우지 않고 **객체 가우시안으로 배경과 함께 학습**한다 (`nusim recon train --objects vehicles`, `nusim/recon/objects.py`). 차량 instance 마다 박스 로컬 가우시안, 뷰 시각의 박스 자세(주차 = 대표 자세, 움직임 = 키프레임 보간)로 옮겨 배경과 한 번에 래스터화. 가우시안의 객체 번호는 학습률 0 파라미터라 gsplat 전략(복제·분할·재배치)이 같이 옮긴다. 사람·자전거는 아직 가린다. 차량 픽셀은 깊이 손실에서 뺀다 (정적 라이다 깊이는 차 뒤 배경). | scene-0003, 15k, MCMC + 깊이 | 전체 영상 PSNR | 정적 PSNR | SSIM | |---|---|---|---| | 환경 전용 (차량 지움) | 21.82 | 23.66 (차량 가림) | 0.764 | | **차량 동시 학습** | **23.51** | 23.62 (차량 포함, 사람만 가림) | 0.763 | 60k (`_env` 와 같은 레시피, `outputs/gs/scene-0003_veh60`, 93분): 전체 영상 **24.78** / 정적 24.97 / SSIM 0.789 — `_env` 60k 는 전체 22.81 / 정적(차량 가림) 25.03. 차량을 넣고도 배경 품질은 같고 전체 영상은 +2.0 dB. (`recon eval` 이 배경 ply 만 그려 21.99 로 나오던 버그를 고침 — `recon.objects.load_objects` 로 에셋을 다시 붙인다.) 단, 이 60k 모델은 차량 35대 중 17대만 남았다 — MCMC 재배치가 불투명도 ≤ 0.005 인 가우시안을 다른 자리로 옮기며 객체 번호도 같이 옮겨, 잠깐 보인 차가 가우시안을 다 잃었다. 객체 가우시안을 전부 지키면(v2, `_veh60p`) 반대로 차량이 200만 중 178만 개 (대부분 α<0.01)를 빨아들이고 배경이 22만 개로 줄었다 — 버린다. 그래서 (1) 살아 있는 수가 최소치(초기의 절반, 최소 200) 아래인 차량만 재배치에서 지키고, (2) 객체 가우시안을 박스(+0.15 m) 안에 묶는다 (MCMC 잡음·재배치 뒤). 3k 점검: 35대, 합계 4.5만, 박스 밖 최대 0.15 m. 재학습 `nusim run veh_60k_v3` → `outputs/gs/scene-0003_veh60c`. 자차 ↔ 장면 객체 충돌: `drive.hpp` `vehicle_contact(..., others)` — 객체 박스의 바닥 사각형(`Footprint`)을 차체 샘플로 본다 (장애물 지도는 차량을 지운 배경이라 따로). 기록 궤적을 재생하는 차는 프레임마다 자리를 갱신. 지운 객체는 빠진다. 아직 상대 차는 반응하지 않는다 (자차가 멈출 뿐, 밀거나 피하지 않음). 차량 영역도 배경만큼 학습된다 (정적 PSNR 이 차량을 포함해도 같다). 결과: 배경 `point_cloud.ply` + `objects/_<종류>.ply` (박스 로컬, 바닥 중앙 원점) + `objects/objects.json` (범주·크기·궤적) — 31대. 뷰어 `--objects DIR`: 객체 가우시안은 배경과 다른 버퍼, 객체 표(SSBO)로 프레임마다 자세 — 추가·삭제 때 배경을 다시 올리지 않는다 (`src/vkgs/src/scene_objects.hpp`). **K** 객체 창 → 편집 모드: 클릭 선택(노란 박스), 드래그 이동, 휠 회전, Delete 삭제, 라이브러리 에셋 추가(클릭한 지면), 저장(`objects.json`, 원본은 `objects.orig.json`). `render view`·`aug rig` 는 모델에 `objects/` 가 있으면 자동으로 넘긴다. 시점 증강(`outputs/aug/rig_veh`)에 차량이 제자리에 나온다. 남은 것: 자차와 객체 박스 충돌, 객체를 차선 따라 움직이기(지금은 기록 궤적·고정), 사람(비강체), 객체 포즈 보정 학습. ### 멀티 주행 타일 (2026-10-06) 같은 곳을 여러 날 여러 차선으로 지나간 주행을 한 모델로 학습한다 (`nusim recon train --tile <이름>`, `nusim/recon/tile.py`, 타일 정의 `configs/tiles/*.json`). 자차가 80 m 정사각형 안에 있던 시간 구간만 쓰고, 원점은 anchor 씬 것이라 단일 씬 모델과 같은 좌표다. 기하는 공유, 색 보정·외부 파라미터 보정은 주행별 (cam_id = 주행 × 6 + 카메라; `camera_adjust.pt` 는 기준 주행 6대만 — 뷰어 호환, 전체는 `camera_adjust_tile.pt`). 다른 날의 주차 차량이 달라 `--objects agents` 만 지원한다. 평가 `nusim recon tile-eval <타일> --dir A --dir B`: 학습에서 통째로 뺀 주행의 실제 사진 = 실제 차선 변경 시점의 정답. 외관(날·시각)이 다르므로 이미지마다 3×4 색 아핀을 맞춘 뒤 PSNR·SSIM (사람·차량 가림, 30% 미만만 남은 뷰는 제외 — 옆 2~4 m 의 주차 승합차가 측면 카메라를 다 가린다). 학습 카메라에서의 거리별로도 나눈다. scene-0003 타일 (`onenorth_0003`): 낮 주행 17개가 지나간다. 학습 6개(0003·0120·0045·0134·0968·0133, 6,551뷰), 평가 2개 (0127 3.9 m 옆, 0969 4.1 m 옆). 점검(2주행 300스텝, 0127): 타일 16.79 dB vs 단일 씬 `_env` 60k 15.95 dB — 코드 점검일 뿐. 본 실험 `nusim run tile_0003` (150k). **결과 (2026-10-07): 실패, 원인 미확정 — 보류.** 150k 타일 모델은 자기 주행 평가 뷰에서도 16.9 dB (색 보정 없이 6.9 dB — 색 보정이 기하 대신 맞추고 있었다), 차선 변경 시점 376뷰에서 15.86 dB 로 단일 씬(`_env` 16.46, `_veh60c` 16.52)보다 낮다. 렌더는 단색 막이나 심한 번짐. 확인한 것: - 기준 씬 0003 자세가 다른 주행 대비 yaw 1.3°·roll 1° 어긋남 → 주행별 라이다 ICP 정합(`align.json`, 17–27 cm → 9–12 cm)으로 고침. 결과는 그대로. - 주행 1개 타일 = 일반 학습 (3k: 19.8 vs 19.6), 주행 2개 정상 (18.2/18.9). 6개면 3k 스텝 이후 계속 무너진다. - 10 m 넘는 거대 가우시안이 하늘을 흡수 → 하늘 분리를 타일에 연결. 여전히 무너짐. - 정규화 벌점을 모든 가우시안에 걸면 넓은 타일에서 63% 가 죽는다 → 보이는 것만 벌점 (2k 19.2 dB 로 개선). 그래도 3k 이후 하락. - 장면 크기·SH 차수·카메라 보정·깊이 재투영은 원인 아님. 남은 의심: 색 보정의 뷰별 밝기 항, 깊이 감독. ### 맵 전체 시점 변형 증강 (2026-10-08) 방향: 타일을 보류하고 낮 284씬 전체를 시점 변형으로 증강해 싱가포르 낮 맵 전체를 덮는다. `nusim run day_map`: 1. `recon batch` — 이동 거리 60 m 넘는 씬은 같은 길이 구간(겹침 10 m)으로 나눠 `--time-window` 학습 (`plan_segments`, 결과 `outputs/gs_day//seg/` + `segment.json`). 284씬 → 696 학습 단위. init.ply 는 학습 뒤 지운다. 2. 씬의 구간이 다 끝나면 `aug map ` — CAM_FRONT 프레임마다 그 시각을 '맡는' 구간(겹침 가운데에서 자른, 겹치지 않는 구간)의 모델로 렌더. 날씨 없는 변형 9종, 키프레임 2 Hz, 지운 차량은 glTF 로 다시 (IBL 없으면 굽는다) → `outputs/aug/map///`. 변형 1개 = 약 6.8만 장, 9종 약 135 GB. scene-0003 변형 하나 20초. - 시범 scene-0402 (11.9 m/s, 235 m → 5구간): 정적 PSNR 23.78 / 22.76 / 23.04 / 23.02 / 22.70 dB (씬 통째 16.23), 구간당 약 20분. 증강 left_1m 의 구간 경계 프레임 4쌍에 색·기하 이음매가 보이지 않는다. 구간 모델의 IBL 은 그 학습 구간으로 자른 씬으로 굽는다 (색 보정 크기가 구간 뷰 수). - 2026-10-09 23:19 순서를 도로 커버리지 우선으로 바꿔 다시 시작 (`--order coverage`, `coverage_order`): 그때까지 학습 단위 83/696, 도로 10 m 칸 2,432개 중 17%. 남은 씬을 새 도로를 많이 덮는 순으로 하면 학습 단위 약 317개(약 5일)에 90%, 470개(약 7.5일)에 100%. 라이다·레이더 합성은 사용자 결정으로 보류 (카메라만 유지). - 2026-10-10 18:44 부터 약 40분 데이터셋 NAS 가 Input/output error — 단위마다 13초 만에 실패하고 다음으로 넘어가 178 단위(약 55씬)가 실패로 남았다 (scene-0378 seg0 은 학습은 됐는데 평가가 nan). `recon batch` 를 고쳤다: 단위 시작 전 데이터셋이 읽히는지 보고 안 읽히면 기다리고, I/O 오류로 실패한 단위는 기다렸다 최대 3번, 평가가 빈 단위는 평가만 다시, 한 바퀴 뒤 실패가 남으면 그것만 다시 돈다. - 본 배치 시작 2026-10-08 15:12 (`setsid nohup nusim run day_map`, 로그 `outputs/gs_day/batch.log`). - **본 배치 완료 2026-10-27 02:44** (재개분 포함 242시간): 낮 284씬 전부 · 구간 696개 실패 0 · 도로 커버리지 100% (10 m 칸 2446/2446) · 정적 PSNR 평균 25.0 dB, 22 dB 미만 43구간. ArtiFixer 증강 284씬 (창 뷰어가 VRAM 을 잡은 동안 13씬이 메모리 부족 → 배치 뒤 재실행). 산출물 `outputs/gs_day` 333 GB · `outputs/aug` 132 GB. 그림 `outputs/coverage/map_coverage_20261029.png` (`scripts/map_coverage.py`). - **구간 이어 달리기 (맵 로더 1차, 2026-10-09):** `nusim render view ` 이 구간으로 나뉜 씬(`outputs/gs_day//seg*`)을 알아보고 `/` 에 공통 원점(구간 0) 기준 리그·맵 선·주행가능영역·장애물 지도와 `segments.txt`(구간별 원점 차이·맡는 궤적 점)를 쓴다 (`nusim/render/segmap.py`). 뷰어 `--segments` (`src/vkgs/src/segment_map.hpp`, viewer.cpp `SegmentStreamer`)는 자차 위치에서 가장 가까운 구간 하나를 그리고(3 m 히스테리시스), 이웃 구간 ply 를 백그라운드 스레드가 미리 읽어 두었다가 경계에서 GPU 버퍼 내용만 바꾼다 (버퍼는 가장 큰 구간 크기로 한 번 잡음). 두 구간을 같이 그리지 않는다 — 10 m 겹침이 경계 양쪽을 덮는다. scene-0402 전체 238프레임 오프스크린: 구간 4번 바뀜, 경계 앞뒤 프레임 이음매 없음. 바꿀 때 0.19초 멈칫 (480 MB 업로드 + 장치 대기), ply 읽기 약 2.7초 (12 m/s 로 한 구간 약 4초라 미리 읽기가 따라간다). 오프스크린 리그 렌더도 프레임마다 그 구간으로 그린다. 다음: 두 버퍼로 멈칫 없애기, 씬 사이(다른 주행) 잇기 — 여러 씬을 같은 방식의 목록 하나로. - **지역 맵 (맵 로더 2차, 2026-10-10):** `nusim render map ` (`nusim/render/regionmap.py`) — 그 지역에서 학습된 모든 씬의 구간을 공통 원점(출발 씬 첫 구간) 기준 segments.txt 하나로 잇는다. 뷰어는 가까운 구간 3개를 위치로 미리 읽는다 (목록 순서가 길 위의 이웃이 아니므로). 맵 선은 지역 전체 + 씬마다 자차 궤적(= 맵이 있는 곳). 첫 실행: one-north 38씬 · 99구간. 장애물 지도 · 복셀 월드는 아직 지역 단위가 아니라 연석 충돌만, 센서 없음. - 이전 시범 모델(구간 분할 없음, 하늘 분리 없음)은 `outputs/gs_day_pilot_2026-10-05/` 로 옮겼다. - 한계: glTF 차량은 모두 같은 모델(CarConcept). 옆 1 m 변형은 노면 번짐이 있다 (사이클 벤치로 품질 표시 예정). ### 데이터셋 다양성 증강 (2026-10-05) **B. 6캠 시점 변경** — `nusim aug rig [--only a,b] [--agents]`. 변형은 `configs/aug/rig_variants.json` 에 있다 (옆 이동·높이·피치·요, 날씨 조합). 씬 인덱스의 cam→ego 캘리브만 바꾼 사본으로 `write_rig` → 오프스크린 렌더 → `outputs/aug/rig////<원본 파일명>.jpg` + `meta.json`(바뀐 calibrated_sensor, 장마다 원본 파일·시각·자차 포즈). scene-0003: 변형당 1,356장, 약 75초. 아래로 3° 는 깨끗하다. 옆 1 m·높이 +0.4 m 는 노면 번짐과 floater 가 생긴다 (새 시점 품질 한계 — Difix 점진 증류로 개선할 것). 환경 전용 모델은 차량이 없으니 `--agents` 로 glTF 차량을 넣는다. **A. 밤·비 → 낮 변환** — `nusim aug translate` (CycleGAN-Turbo, BDD100K 사전학습 night_to_day·rainy_to_clear, `cache/models/img2img-turbo/fetch.sh`). 8 GB GPU 에서 학습과 같이 돌게 모델을 CPU 에서 만들어 fp16 으로 올리고, 한 번에 하나만 쓴다. 768×432 에서 장당 0.8초. **scene-1060 에서 실패했다**: nuScenes 싱가포르 밤 영상은 BDD 보다 훨씬 어두워서, 모델이 센서 잡음을 증폭해 파란 점박이 영상을 만든다. 비→맑음은 밤 영상을 더 어둡게만 한다. 재구성 입력으로 쓸 수 없다. `recon train --image-root` 는 변환 영상으로 학습하는 경로로 남겨 둔다. 밤 경로가 낮 경로와 겹치는 정도 (15 m 안): 밤 99씬 중 90% 이상 겹침 32, 50% 미만 60. one-north 는 밤 0, queenstown 33, holland village 66 (낮은 19뿐). 따라서 낮 맵만으로는 홀랜드 빌리지 대부분이 빠진다. ### 날씨 v2 (2026-10-05) - **월드 공간 강수 입자** (`shaders/precip.vert/frag`, 렌더 그래프 `precip` 패스): 화면 공간 무늬를 대신한다. 입자는 상태 없이 (번호, 시각) 해시로 위치가 정해지고, 씬 좌표에 고정된 상자를 카메라 주변에서 감아 돌린다. 그래서 6캠이 같은 빗방울을 보고, 시차가 생긴다. 빗줄기는 노출 동안의 (낙하 + 바람 − 자차 속도) 상대 이동이라 달리면 기운다. 가까운 입자는 초점이 흐리다. 거리 버퍼로 장면에 가려지고, 전조등·하늘빛을 받고, 안개로 감쇠한다. 비 8만·눈 12만 개에 0.05 ms. - **젖은 노면**: 어두워짐과 채도 상승(Lekner–Dorf 근사), 값 잡음 물웅덩이(거울 반사), 빗방울 파문(법선 교란), 전조등 정반사 꼬리. - **높이 안개**(해석적 광학 깊이) + 해 쪽 전방 산란(HG) + **볼류메트릭 전조등**(시선 12걸음 적분). - **렌즈 물방울**: 뒤집힌 상을 굴절해 보여 주고, 밝기는 주변에 맞춘다. - 조정값은 `configs/sim.json` `weather.fx` 에 있다. 대조표는 `cache/weather_sheet.sh <모델> ` 로 만든다. - 남은 것: 하늘을 분리하지 않은 모델(`_depth`)은 하늘이 3DGS 흰 덩어리라 밤에도 밝다. 하늘 분리 모델 (`day_map` 프리셋)이면 시뮬 하늘로 바뀐다. 눈 쌓임은 3DGS 깊이 잡음 때문에 노면에 얼룩이 생긴다. 가로등 같은 밤 광원은 아직 없다. ### 엔진 경량화 (2026-10-05) 패스별 GPU 시간(`--offscreen` 끝에 출력, F2 창)을 재 보니 bitonic 정렬이 프레임의 58% 였다. | | 전 | 후 | |---|---|---| | 정렬 | bitonic, 가우시안 전체 2^21, 231 디스패치 — 31~35 ms | 보이는 것만 압축 + GPU radix (8비트 × 4패스, subgroup ballot 안정 scatter) — 2.7 ms | | 래스터 | RGBA32F 블렌딩 21.6 ms | RGBA16F 15.9 ms (32비트 대비 PSNR 64 dB). 거리 누적은 r32f 유지 (r16f 는 젖은 노면 반사에서 최대 80/255 차이) | | AA | 없음 | FXAA 컴퓨트 0.08 ms + 복사 0.06 ms (메시·선 가장자리). MSAA 는 스플랫 블렌딩을 샘플 수배로 늘려 쓰지 않는다 | (GPU 를 학습과 나눠 쓴 상태의 측정이라 절대값은 크다.) Deferred shading 은 도입하지 않았다. 조명 패스(날씨, 깊이 버퍼 기반 화면 공간 조명 — 사실상 deferred)가 0.1~0.5 ms 라 성능 이득이 없다. 광원이 많아지면(가로등·다른 차 전조등) G-버퍼 법선(메시)과 클러스터 조명으로 확장한다. ### 사이클 렌더 벤치마크 (OneFixer 부록 A.1 방식) `nusim recon cycle `: 모델 B 를 학습 시점에서 옆으로 1 m 옮겨 렌더 → 그 렌더로 모델 C 학습 → C 를 원래 기록 시점에서 렌더하면 '1 m 벗어난 새 시점' 이고 그 자리 실제 사진이 정답이다. `bench/` 에 렌더·정답·누적 불투명도·가린 객체 마스크·이웃 프레임 참조 사진. `nusim recon bench` 로 PSNR·SSIM·LPIPS·DISTS (가린 객체 영역은 정답으로 채운 뒤). `--run-difix` 는 Difix 전체 보정과 신뢰도 마스크(누적 불투명도) 블렌딩을 비교한다. **수정 (2026-10-06 검토):** 첫 벤치(scene-0003)에서 +Difix 가 LPIPS 0.391 → 0.162 로 실제 사진 학습 모델(0.338)보다도 좋게 나왔다. 원인은 참조 사진이 '같은 카메라에서 시간이 가장 가까운 학습 프레임' 이었기 때문이다. 느린 씬에서는 정답 위치에서 0.13 m 떨어진, 정답과 거의 같은 사진이라 Difix 가 정답을 베꼈다 — **그 수치는 무효**. 이제 참조는 이동 거리(1 m) 이상 떨어진 학습 프레임 가운데 시간이 가장 가까운 것이다 (실제 사용: 차선을 옮긴 시점에서 참조는 1 m 떨어진 기록 사진). 다시 잴 것. ### 레이캐스트 센서 — 라이다·레이더 (2026-10-09) 사용자 요청: 센서 데이터를 '렌더링' 하는 게 아니라 카메라처럼 시뮬레이터에 센서를 붙인다 (CARLA ray-cast 센서 방식). - 설정 `configs/sim.json` `sensors`: LIDAR_TOP (HDL-32E 근사: 32채널, −30.67~10.67°, 0.33°, 70 m) + RADAR_* 5대 (ARS 408 근사: 120°×10°, 1°, 120 m, 최대 125점, 노면 반사 버림, 도플러 vr·자차 운동 보정 속도). 장착 위치는 nuScenes 배치 근사. - 기하 = **복셀 월드** `world.vox` (`nusim/sim/voxels.py`): 정적 라이다 누적, 지면은 0.5 m 높이 지도(첫 빽빽한 층, 이중 선형 교차), 지면 위 것은 0.2 m 복셀. **빈 공간 깎기**(`src/vkgs/src/voxcarve.cpp`, 빔이 지나간 횟수 대비 부딪힌 비율 < 0.2 인 칸 제거) — 지운 차량의 어긋난 조각이 차선을 따라 지면 위 0.3~1 m 에 쌓여 있었다. + 장면 객체 상자 (차량, 속도). - 자차를 노면에 앉혀(z·pitch·roll, 네 바퀴 자리 지면 높이) 쏜다. - 실제 nuScenes 라이다와 같은 방향(고도 0.67°·방위 0.5° 칸)의 거리 비교 (6 sweep): | | 실측 센서 자세 | 시뮬 자세 (노면에 앉힘) | |---|---|---| | scene-0402, 처음 (복셀 지면, 깎기 없음) | −1.24 m, 24% | — | | scene-0402, 높이 지도 + 깎기 0.2 | −0.12 m, 5.9% | −0.18 m, 5.9% | | scene-0003 | −0.07 m, 3.6% | +0.02 m, 3.9% | (거리 차 중앙값, 상대 오차 중앙값.) 남은 오차: 나무 같은 성긴 물체, 0.2 m 복셀 면, 라이다 세기는 없다(거리로 근사). - 뷰어: `--voxels` (render view 가 자동), 창의 '센서' 패널에서 라이다(높이 색)·레이더(빨강 다가옴·파랑 멀어짐·노랑 정지) 보기, O(6캠 관측 저장)에 `LIDAR_TOP.bin` (nuScenes .pcd.bin 형식, 센서 좌표 x 앞·y 왼쪽·z 위) + `RADAR_*.txt`. 라이다 한 바퀴 약 4 ms. - 다음: 장면 객체의 실제 높이·속도 (지금 1.6 m·정지), 장애물 지도에도 빈 공간 깎기 적용 (보이지 않는 장애물의 같은 원인). ### 3인칭 노이즈 → 자차 높이 복원 · ArtiFixer 되먹임 · EMA (2026-11-05) 사용자 보고: 뷰어에서 도로·건물이 가우시안 노이즈처럼 보인다. 원인 셋. 1. **nuScenes ego_pose 의 z 는 항상 0** (피치·롤은 있다). 오르막에서 차가 기운 채 같은 높이에 머무는 셈이라 프레임끼리 기하가 어긋난다. `SceneIndex.with_ego_heights` (`nusim/data/rig.py ego_heights` — 앞 방향 기울기 dz/ds 를 수평 이동으로 적분, 카메라·라이다·박스를 같은 시각 높이만큼 올림). 학습 옵션 `--ego-z pitch` (report `ego_z`, `_model_data` 가 따른다). - 낮 맵 628구간: 구간 높이 변화 0–1 m 평균 25.40 dB, 2–4 m 22.34 dB, 4 m+ 21.28 dB (상관 −0.59). 22 dB 미만 42개 중 26개가 2 m+. - 라이다 지면 일관성 (1 m 칸 높이의 프레임 간 표준편차 중앙값): scene-0416 0.446 → 0.050 m, scene-0042 0.264 → 0.046 m, scene-0049 0.230 → 0.070 m — 평평해 보이는 구간도 좋아진다. - 재학습 (day_map 프리셋 15k 그대로): scene-0042 seg1 **21.52 → 26.71 dB** (SSIM 0.653 → 0.821), scene-0416 seg1 17.96 → 18.99 dB (나무 터널 좁은 길 — 여전히 어렵다). `outputs/gs_day_v2/`. - 뷰어는 운전 중 자차 z 를 출발 높이로 고정하고 피치가 없다 — 높이 복원 모델을 지역 맵에 넣으려면 segments.txt 궤적 점에 z, 자차 높이·피치 따라가기, 씬 사이 높이 맞춤이 필요하다 (아직). 2. **3인칭 카메라가 학습 시점 밖** (차 뒤 6.5 m · 높이 1.9 m). sim.json chase_camera 5.5 m · 1.7 m 로, 출발은 기록 궤적을 `drive.start_offset_m` (8 m) 들어간 프레임에서 (0 번 프레임이면 카메라가 아무 카메라도 지나가지 않은 곳에 있다). 3. **학습 시점 밖 화질** — `nusim recon augfix <씬> --seg <구간>` (`nusim/recon/augfix.py`, `configs/train/augfix.json`): ArtiFixer 증강(리그 변형 9종, 이미 284씬)을 그 변형 자세의 의사 정답으로 구간 모델 6k 미세조정 + 가우시안 EMA 0.999 (`TrainConfig.ema_decay`). 의사 뷰의 하늘 픽셀(원 모델 α < 0.5)은 손실에서 빼고 하늘 큐브맵은 실제 사진으로만 — 안 그러면 ArtiFixer 의 바랜 하늘을 배워 구름이 사라졌다. scene-0042 seg0 (하늘 제외 평가): | | 원래 경로 PSNR / LPIPS | 빼 둔 증강 18장 PSNR / LPIPS | |---|---|---| | 원 모델 | 24.73 / 0.321 | 25.60 / 0.152 | | augfix + EMA | **24.91 / 0.310** | **26.57 / 0.135** | | augfix, EMA 없이 | 24.66 / 0.310 | 26.35 / 0.139 | EMA 는 수렴한 모델의 미세조정에서 +0.2 dB. 처음부터 학습(15k)에서는 마지막 3k 동안 PSNR 이 빠르게 오르는 중이라 EMA 가 뒤처져 −0.5 dB (scene-0416) — 처음부터 학습에는 쓰지 않는다. ## 3단계 — closed-loop 환경 | | | |---|---| | 산출물 | VLA 모델이 씬 하나를 완주하고 경로 이탈/충돌 지표가 나옴 | - [ ] `maps/graph.py` — map expansion → 차선 방향그래프 - [ ] `sim/ego.py` — 자전거 모델 (조향각·가속 → 다음 상태) - [x] 충돌 (2026-10-02) — 정적 라이다 장애물 지도(`nusim/sim/obstacles.py`, 지면 +0.25~2.5 m, 0.2 m 칸)와 주행가능영역 경계(연석)에 차체가 닿으면 직전 자세로 되돌리고 정지, 충돌 횟수·종류를 `drive_log.csv` 에 기록. 노면(주행가능영역 안쪽 0.3 m 부터)과 원래 차체가 지나간 자리는 비운다 — 노면 위 물체(차단기 막대·콘 등)는 대부분 잠깐 있던 것이고 나중에 시뮬레이터 객체로 넣는다. scene-0003 차단기 막대 두 개가 벽으로 남아 차선을 막았었다. 충돌 판정은 차체 둘레를 0.1 m 줄여서 본다 (칸 양자화·포즈 잡음으로 물체가 부풀어 보임). 후진도 고쳤다 (예전엔 5초 눌러 0.35 m). **2026-10-09 (OBSTACLES_VERSION 4):** 긴 씬(scene-0402)에서 원래 경로 0.2~0.4 m 옆 노면에서 '건물·구조물' 충돌로 멈췄다. ① 지면 = 낮은 5 백분위였는데 먼 sweep 의 노면 점이 아래로 0.1~0.45 m 번져 지면이 0.3 m 낮게 잡혀 노면 자체가 장애물이 됐다 → 지면 = 아래에서 처음 나오는 빽빽한 10 cm 층(그 칸 최대 층의 절반 이상). ② 노면 안에서 남기는 '솟은 구조물' 을 칸의 최고점 > 3 m 로 봤더니 가로수 수관(5~18 m) 아래 노면 칸 11,091개가 남았다 → 지면 위 2~3 m 에 점이 5개 이상인 칸만 (기둥·줄기·벽). 노면에서 남는 칸 11,091 → 83, 충돌 지점 1 m 안 장애물 0. scene-0003 은 21,808 → 20,724칸. 같은 날 두 번째 시험: 원래 경로 1.6 m 왼쪽에서 화단 가장자리의 한 칸 돌출(0.2 m)에 차체 옆이 걸려 앞뒤로 못 움직였다 — 닿은 샘플 수가 1 만 늘어도 막았기 때문. 이제 `collision.graze_samples`(2) 이하는 스침으로 보고(`ContactInfo::depth`), 깊이가 늘어도 같은 방향으로 0.3 m 더 가 본 자세가 지금보다 깊지 않으면 빠져나가는 중으로 허용 (`escaping`). 벽·기둥은 차체 한 줄(약 13점)이 바로 닿아 여전히 막힌다. 운전은 정지 상태로 시작한다 (예전엔 로그 속도로 시작해 저절로 달렸다). 아직 없는 것: 충격·튕김 같은 동역학, 경사·요철, 다른 차량과의 충돌. - [ ] `sim/env.py` — gym 스타일 `reset()` / `step(action) → 6장 관측` - [ ] `sim/metrics.py` — 경로 이탈, 주행가능영역 위반, 충돌, 완주율 - [ ] `sim/bridge.py` — gRPC (그리고 필요하면 ROS2) 로 외부 모델 연동 - [ ] 교통 참가자 삽입 — 환경 전용 맵 위에 차량·사람(glTF 또는 객체별 3DGS)을 시뮬레이터가 배치 **핵심 난점.** ego 가 원본 궤적을 벗어나면 그 시점에서 본 적 없는 각도가 된다. 3DGS 는 외삽에 약해서 경로를 크게 벗어나면 화질이 급격히 무너진다. 현실적인 완화책: - 벗어남 정도를 지표로 기록해 "신뢰 구간" 을 명시 - 원본 궤적 주변 ±2 m 정도를 유효 범위로 두고 평가 - 여러 씬의 재구성을 맵 좌표계에서 합쳐 커버리지를 넓히는 것은 그 다음 문제 --- ## 다루지 않기로 한 것 - **boston-seaport (467 씬)** — 싱가포르로 한정한다. 범위를 좁혀야 끝이 난다. - ~~**LiDAR/RADAR 합성**~~ — 처음엔 카메라만이었으나 2026-10-09 사용자 요청으로 **시뮬레이터 레이캐스트 센서**로 넣었다 ('레이캐스트 센서' 절). 3DGS 로 센서 영상을 그리는 방식은 하지 않는다. - ~~**날씨/시간대 변환**~~ — 처음엔 다루지 않기로 했으나 2026-10-02 결정으로 시뮬레이터가 합성한다 ('전체 맵 + 합성 날씨', '날씨 v2'). 영상 자체의 밤 → 낮 변환은 '데이터셋 다양성 증강' 참고. - **직접 학습기 처음부터 구현** — gsplat 을 백엔드로 쓴다. 래스터라이저를 다시 쓰는 데 시간을 쓸 이유가 없다.