# ONDEVICE — PoC-1 na Meta Quest 3 Cel buildu dla pierwszego uruchomienia na urządzeniu. Spójny z `ROADMAP.md`. ## 1. Cel PoC-1 Uruchomić na Quest 3 minimalną aplikację, która w **passthrough** wyświetla i **wypowiada** (Piper przez sherpa-onnx) polskie polecenia, oraz **zmierzyć wydajność w realu**. **Bez żywego LLM na urządzeniu** (decyzja). **Bez STT.** ## 2. Zakres W zakresie: - bank poleceń wygenerowany offline (z istniejącego `ipin_vr`), - TTS na urządzeniu (sherpa-onnx + głos polski), - minimalne UI w passthrough (panel z tekstem + trigger „następne"), - instrumentacja i pomiar wydajności. Poza zakresem PoC-1: LLM na urządzeniu, STT, ocena wykonania, dopracowane UI/MR, obiekty 3D. (To etap 2/3 wg `ROADMAP.md`.) ## 3. Runtime — decyzja **Unity** dla PoC-1. - Uzasadnienie: najszybsza droga do działającego passthrough + TTS; narzut RAM Unity (~1 GiB) jest nieistotny, bo bez LLM cały budżet spokojnie mieści się w limicie 5,75 GiB. Meta XR SDK daje passthrough „z pudełka", a sherpa-onnx ma gotowe wtyczki do Unity. - Cel docelowego produktu pozostaje **natywny OpenXR** (lżejszy, gdy dojdzie LLM). - To jedyna łatwo odwracalna decyzja architektoniczna tego dokumentu; reszta nie zależy od wyboru runtime. ## 4. Komponenty ### 4.1 Bank poleceń (offline) Rozszerzyć `ipin_vr` o podkomendę `export`, która zrzuca bank gotowych, poprawnych poleceń do JSON (reużywamy zweryfikowanego generatora — gramatyka gwarantowana u źródła). Wywołanie: ``` python -m ipin_vr export --per-level 300 --out commands.json [--seed N] ``` Format pliku: ```json { "meta": {"version": "1", "per_level": 300}, "commands": [ {"level": 1, "text": "Połóż jabłko na stole."}, {"level": 2, "text": "Umieść niebieskie jabłko na stole."}, {"level": 3, "text": "Połóż zieloną książkę na półce i umieść klucz na biurku."} ] } ``` Wymóg: deduplikacja w obrębie poziomu; `--per-level` to liczba unikatów na poziom (jeśli przestrzeń jest mniejsza, tyle ile się da). Plik trafia do assetów aplikacji. ### 4.2 TTS na urządzeniu - Biblioteka: **sherpa-onnx** przez wtyczkę Unity (np. `Ponyu-dev/Unity-Sherpa-ONNX` lub `EitanWong/com.eitan.sherpa-onnx-unity`). - Głos: **`vits-piper-pl_PL-gosia-medium`** (z releasu `tts-models` sherpa-onnx; zawiera `.onnx`, `tokens.txt`, `espeak-ng-data`). - ABI: **arm64-v8a**. - Haczyk do obsłużenia: modele w `StreamingAssets` są spakowane w APK — przed użyciem skopiować do ścieżki zapisywalnej i podać tę nową ścieżkę do sherpa-onnx (wtyczki zwykle robią to same; zweryfikować). ### 4.3 Passthrough UI - Passthrough przez **Meta XR SDK** (building block / komponent passthrough). - Jeden panel (world-space lub HUD) z tekstem polecenia, czcionka z polskimi znakami. - Trigger „następne polecenie": przycisk kontrolera albo prosty przycisk na panelu. ## 5. Podział pracy: kod vs Unity Editor Część generowalna kodem (Claude Code): - podkomenda `export` w `ipin_vr` (+ test), - skrypty C# (ładowanie `commands.json`, wybór poziomu, wyświetlanie tekstu, wywołanie TTS, obsługa triggera), - `ondevice/README.md` z instrukcją złożenia projektu. Część ręczna w Unity Editorze (nie da się w pełni wygenerować plikami): - utworzenie projektu Unity (aktualne LTS) i konfiguracja Androida/OpenXR, - instalacja Meta XR SDK i wtyczki sherpa-onnx, - włączenie passthrough, podpięcie skryptów do sceny, import głosu i `commands.json`, - build i sideload APK na Quest. Skrypty C# mają być samodzielne i podpinalne, nie zakładać konkretnej hierarchii sceny. ## 6. Przepływ aplikacji 1. Start: passthrough on, wczytaj `commands.json` z assetów. 2. Ustaw poziom (domyślnie 1; prosty przełącznik 1/2/3). 3. Pokaż losowe polecenie danego poziomu na panelu. 4. Wypowiedz je (sherpa-onnx). 5. Trigger „następne" → wróć do kroku 3. ## 7. Pomiar wydajności (właściwy cel PoC-1) Zmierzyć i zanotować: - PSS aplikacji względem limitu 5,75 GiB, - stabilność klatek przy włączonym passthrough (spadki/utracone klatki), - latencja TTS: od wywołania do pierwszego dźwięku oraz czas pełnej syntezy, - RAM zajmowany przez model głosu, - moment wejścia w throttling termiczny przy dłuższym użyciu, - zużycie baterii. Narzędzia: OVR Metrics Tool, Perfetto, `logcat` (m.in. `lowmemorykiller`). ## 8. Środowisko developerskie Najpierw **sanity check bez kodu**: wgrać prebudowane sherpa-onnx TTS APK z `pl_PL-gosia` na telefon z Androidem (lub sideload na Quest) i potwierdzić jakość polskiego głosu. Dopiero potem budować aplikację Unity. Iteracja skryptów/logiki najszybsza na telefonie Snapdragon; pomiary docelowe — na Queście. ## 9. Definition of done - Apka na Queście w passthrough pokazuje i wypowiada polskie polecenia z banku. - Trigger „następne" działa; poziomy 1–3 dostępne. - Zebrany komplet metryk z sekcji 7 (choćby zgrubnie) — to jest wynik PoC-1. ## 10. Dalej (poza PoC-1) - PoC-2: dołożyć llama.cpp na urządzeniu i zmierzyć ponownie (żywy LLM). - Etap 3: STT + ocena wykonania, sesje, statystyki. - Ewentualne przejście runtime na natywny OpenXR pod docelowy budżet RAM z LLM.