Dongubak 2f570681eb Fix rail rendering under the Android status bar
targetSdk 36 (Android 15+) forces edge-to-edge, so the fixed-position
top rail was drawing behind the status bar clock/battery icons on a
real device (title and DARK/LIGHT toggle both obscured) — invisible on
desktop since there's no inset there. Add env(safe-area-inset-top) via
a --rail-h variable used everywhere the rail's height was hardcoded as
42px, plus viewport-fit=cover so the inset actually gets populated.

Verified on a physical Galaxy Z Fold over adb.
2026-08-23 15:11:05 +09:00
2026-08-23 15:03:20 +09:00

PCD Viewer — 네이티브 빌드 (macOS / Android)

FAST-LIVO2용 포인트 클라우드 뷰어(pcd_viewer.html, Three.js)를 Tauri 2로 감싼 macOS 앱. 빌드 없는 단일 HTML이 웹의 단일 소스이고, src-tauri/가 그걸 그대로 실어 네이티브 창으로 띄운다.

준비물

  • Rust 툴체인 (rustup 권장, src-tauri/Cargo.tomlrust-version 확인)
  • Xcode Command Line Tools (xcode-select --install)
  • cargo tauri(tauri-cli)는 필요 없음 — 아래는 raw cargo build만으로 진행하는 절차

빌드

git clone <this-repo> && cd duru_pcd_viewer
sh src-tauri/stage-web.sh          # pcd_viewer.html + vendor/ 를 src-tauri/web/ 로 스테이징
cd src-tauri
cargo build --release              # target/release/pcd-viewer (원시 실행 파일)

.app 번들(target/release/bundle/macos/PCD Viewer.app)이 이미 존재한다면(첫 빌드가 아니라면), cargo build --release만으로는 그 안의 바이너리가 갱신되지 않는다 — cargo tauri build(번들러)가 만드는 별개 산출물이기 때문. 재빌드할 때마다 아래로 동기화한다.

cp target/release/pcd-viewer \
  "target/release/bundle/macos/PCD Viewer.app/Contents/MacOS/pcd-viewer"

tauri-cli(cargo install tauri-cli --version "^2")가 있다면 cargo tauri build로 번들·서명까지 한 번에 처리할 수 있다(위 수동 동기화 불필요).

실행

open "target/release/bundle/macos/PCD Viewer.app"

.pcd 파일은 앱에 번들되어 있지 않다 — 창에 드래그해서 불러오는 구조가 의도된 설계다 (DEFAULT_URL이 404 나는 게 정상이며, 그때 드래그 안내로 자연스럽게 떨어진다).

코드를 고쳤다면

web/은 빌드 시점에 바이너리로 임베드되므로, pcd_viewer.html만 고쳐서는 네이티브 앱에 반영되지 않는다. 위 빌드 절차(stage-web.shcargo build --release → 바이너리 동기화)를 다시 밟아야 한다.

Android 빌드

같은 pcd_viewer.html을 Android WebView로 감싼다(React Native/Expo 대신 — WebView도 진짜 하드웨어 가속 WebGL을 쓰므로 렌더링 경로 자체는 동일하고, 코드베이스를 두 벌로 안 나눠도 된다). src-tauri/gen/android/cargo tauri android init이 생성한 Android Studio 프로젝트다.

준비물

  • Rust는 rustup으로 설치되어 있어야 함 — Homebrew의 rust 패키지(고정 타깃 하나만 빌드)로는 aarch64-linux-android 같은 크로스 타깃을 추가할 수 없다. brew install rustup(또는 공식 설치 스크립트) 후:
    rustup target add aarch64-linux-android armv7-linux-androideabi \
      i686-linux-android x86_64-linux-android
    
  • Android SDK + NDK (sdkmanager로 platform-tools, platform, NDK 설치, 라이선스 동의까지)
  • JDK 17+ (Temurin 21 확인됨)
  • cargo install tauri-cli --version "^2" --locked

macOS에 Homebrew rust와 rustup이 공존하면 cargo/rustc가 PATH상 Homebrew 쪽으로 잡힐 수 있다 (데스크톱 빌드는 그대로 Homebrew rust를 쓰도록 건드리지 않았다) — Android 명령은 rustup 툴체인의 cargo를 명시적으로 가리켜서 실행한다:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home
export ANDROID_HOME=~/Library/Android/sdk
export NDK_HOME=~/Library/Android/sdk/ndk/<설치된 버전>
export PATH="$HOME/.rustup/toolchains/stable-aarch64-apple-darwin/bin:$HOME/.cargo/bin:$PATH"

빌드

cd src-tauri
sh stage-web.sh
cargo tauri android build --debug --target aarch64   # 갤럭시 대부분은 arm64-v8a

산출물:

  • APK: gen/android/app/build/outputs/apk/universal/debug/app-universal-debug.apk
  • AAB: gen/android/app/build/outputs/bundle/universalDebug/app-universal-debug.aab

기기에 설치

adb install "gen/android/app/build/outputs/apk/universal/debug/app-universal-debug.apk"

(갤럭시에서 설정 → 휴대전화 정보 → 빌드 번호 7번 탭으로 개발자 옵션 열고, USB 디버깅 켠 뒤 USB로 연결 — adb devices에 기기가 떠야 설치된다.) USB 없이는 APK 파일을 기기로 옮겨 직접 설치(출처를 알 수 없는 앱 허용 필요)해도 된다.

알아둘 점

  • usesCleartextTraffic이 디버그 빌드에선 자동으로 켜지지만 release 빌드에선 꺼진다 — rosbridge 주소가 ws://(평문)라면 release APK에서 연결이 막힌다. wss://로 옮기거나 gen/android/app/src/main/AndroidManifest.xml에서 명시적으로 허용해야 한다.
  • 아이콘은 기본 Tauri 플레이스홀더다. cargo tauri icon <source.png>로 교체 가능.
  • gen/android/는 커밋되어 있지만 build/·.gradle/·생성된 Kotlin 소스·jniLibs/*.so는 중첩 .gitignore로 제외된다 — 클론 후 첫 빌드에서 다시 만들어진다.

그 밖의 문서

  • PCD_Viewer_가이드.md — 사용법(측정/실시간 모니터링). 아직 vendoring·Tauri 반영 전 버전.
  • ROS2_이관_체크리스트.md — ROS2 이관 체크리스트.
S
Description
포인트 클라우드 맵 뷰어입니다.
Readme 1.5 MiB
Languages
HTML 89.3%
JavaScript 9.7%
Shell 0.7%
Rust 0.3%