Seoul Meari
시민의 일상이 도시의 미래가 되는 MR 소셜 플랫폼
개요
기간
2025.08 ~ 2025.09
개요
팀 프로젝트
역할
유니티, 프론트엔드, 백엔드, AR/VR 활용, AWS 서버 구축
🏆
2025 서울 AI 해커톤 - 서울특별시장상(대상 - 1등)
주요 기능
공간 메아리(AR 방명록), 시간 탐험(VR 역사 체험), AI 도시 진단
사용 기술
구현 기능 및 개발 과정
공간 메아리 (AR 방명록)
GPS 영역을 격자로 나누고, 사용자 이동 시 해당 격자의 메시지를 불러옴. 진입 격자와 이탈 격자를 큐로 전달함. 생성된 오브젝트는 해시 테이블로 관리함.
시간 탐험 (장소 인식형 역사 VR)
GPS에 기반하여 특정 랜드마크의 근처에 있으면, 해당 장소의 과거 이미지/3D 오브젝트/해설을 VR 세계에 생성. 다양한 기업과 이벤트형 공간 생성 가능
관리자는 에셋 번들과 메타데이터를 각각 CDN과 서버에 업로드. 클라이언트는 패키지(예: gyeongbokgung_v1) 메타데이터 조회 → CDN 병렬 다운로드 → 로컬 캐시 → 인게임에서 매니페스트/의존성/타겟 번들 순으로 로드.
AR 도슨트
사용자가 촬영한 사진과 위치 정보를 기반으로, AI 도슨트가 주변 환경과 맥락을 설명함. 건물의 역사, 사건의 의미, 공간적 특징 등을 AR로 직관적으로 안내함.
AI 도시 진단 엔진 (팀원 담당)
사용자 촬영 데이터의 원본(익명화)을 Yolo가 포트홀/균열/기울어진 간판/녹슨 가로등 등을 태깅함. 태깅한 정보를 바탕으로 서버에 업로드하면, 비전 모델이 위험 요소를 감지·분류함. 반복 탐지/중복 보고를 클러스터링으로 통합해 신뢰도 점수와 함께 리포트를 생성함.
Presigned URL 기반 업로드 → 분석 파이프라인 → 클러스터링/중복 통합 → 대시보드 시각화(히트맵/증거 이미지/처리 상태)로 구성함.
위치 데이터 저장·조회 서버 (PostGIS)
저장 형식: AR 메시지와 VR 역사 장면 번들의 위치를 모두 PostGIS geography(PointZ, 4326) 열에 저장하고 공간 인덱스를 선언함. 좌표는 GeoJSON 순서(경도·위도·고도)로 저장하고, 응답할 때 위도·경도·고도 객체로 바꿔 반환함.
AR 메시지 조회 순서: ① 앱이 시작되면 현재 GPS 좌표를 0.0001도(약 10m) 단위 격자 좌표로 변환하고, 주변 5×5 격자를 요청 큐에 넣음. ② 큐의 격자를 동시에 최대 5건까지 GET /echo/nearby로 요청함. 이미 캐시에 있는 격자는 요청하지 않음. ③ 서버는 격자 기준점부터 격자 간격만큼의 위도·경도 범위를 ST_Y·ST_X 조건으로 조회해, 해당 격자 안의 메시지만 반환함. ④ 응답은 격자 정수 좌표를 키로 캐시에 저장하고, 주변 3×3 격자의 메시지만 화면에 스폰함. ⑤ 사용자가 다른 격자로 이동하면 새로 포함된 줄의 격자만 다시 요청함.
AR 메시지 작성 순서: ① 사진을 Presigned URL로 S3에 먼저 업로드함. ② 메시지 저장 요청이 오면 서버가 S3에 해당 이미지 키가 있는지 확인함. ③ 위도·경도·고도를 GeoJSON Point로 변환해 메시지와 함께 저장함.
VR 장면 등록 순서: ① 관리자가 레이아웃 JSON을 올리면 관리자 웹이 mainLocation의 위도·경도·고도를 입력칸에 자동으로 채움. ② 서버가 업로드 세션을 만들고 번들 파일마다 5분간 유효한 Presigned URL을 발급함. 관리자 웹은 이 URL로 번들 파일을 S3에 직접 업로드함. ③ 업로드 완료 요청이 오면 서버가 레이아웃 JSON 구조와 좌표 값을 검사함. ④ 트랜잭션 안에서 업로드 세션에 비관적 잠금을 걸어 같은 업로드가 두 번 처리되지 않게 함. 이후 위치를 Point로 변환해 번들과 함께 저장하고, 세션을 완료 상태로 바꿈.
트러블슈팅
GPS 튐으로 메시지 위치 튐
실제로 이동하지 않아도 GPS 좌표가 수 미터씩 변동함. 이에 따라 화면에 표시된 메시지가 다른 위치로 이동함.
보정 전 GPS 값을 좌표로 사용하면 측정 오차가 화면 이동에 그대로 반영됨. 값의 변동을 완화하고 이미 생성된 오브젝트를 재생성하지 않는 처리가 모두 필요함.
보정 좌표를 이전 값과 새 값 사이에서 0.1의 비율로 이동시켜 급격한 위치 변화를 줄임.
보정 좌표를 기준으로 메시지가 보이는지 판단해 스폰하며, 실제 스폰 시점은 최신 GPS로 보완함.
이미 생성된 메시지 오브젝트는 ID 및 해시 테이블을 기반으로 렌더링됨.
급격한 GPS 변화에도 렌더링된 위치를 유지함.
XR 카메라 충돌
카메라가 가상 세계를 비추지만 휴대폰을 움직여도 화면이 함께 움직이지 않음.
XR Origin과 Cesium Georeference가 각각 카메라를 요구해 충돌함. 두 카메라 중 어느 쪽이 기기 자세를 받는지 확인해야 했음.
XR Origin과 Cesium Georeference가 각각 카메라를 요구해 충돌함.
Tracked Pose Driver는 기기 자세를 카메라에 전달하는 컴포넌트임. XR Origin의 메인 카메라에 이 컴포넌트가 붙어 있었음.
Dynamic Camera를 XR Origin 아래로 옮겼으나, 메인 카메라가 실제 화면을 계속 비추고 에러도 남았음.
메인 카메라를 제거하고 Dynamic 카메라에 해당 컴포넌트를 적용해 충돌을 해결함.
Cesium 월드에서 비정상 이동
GPS 갱신 때마다 위치가 갱신되면서 가만히 있어도 위치가 튀는 문제가 발생함. 10초마다 갱신되는 것으로 보아 GPS와 관련된 문제일 것이라 추측함.
GPS의 값이 과도하게 Cesium Globe Anchor에 반영되었다고 생각하여 Anchor 값과 Transform 값을 모두 로그로 출력해 원인을 확인함
AR과 VR의 충돌이 원인으로 드러남.
초기에는 Cesium Globe Anchor에서 Detect Transform Change를 해제하여 해결함
카메라 transform 변화에도 날아다니진 않지만, Anchor의 GPS 값은 갱신되지 않음
CesiumOriginShift는 플레이어가 멀리 이동할 때 부동소수점 정밀도 문제를 막기 위해 Georeference 기준점을 주기적으로 플레이어 근처로 옮겨주는 역할을 함
하지만 이렇게 하면 Cesium Georeference가 플레이어를 따라오지 않음
따라서 GPS의 초기 위치를 Cesium Georeference 기준으로 설정함
결과
결과
Unity 2022.3 LTS 환경에서 AR/VR 통합을 시도하며 GPS, SLAM, VPS, Cesium Georeference 등 다양한 위치 맞춤 기술을 학습함.
GPS 튐 현상을 Lerp 기반 스무딩으로 보정하는 방법을 적용하고, XR Origin과 Cesium Dynamic Camera의 충돌 문제를 해결하며 카메라 시스템의 구조를 이해함.
대용량 JSON은 한 번에 읽지 않고 스트리밍으로 처리해야 함을 확인함.
라이선스
