ipin-vr/docs/ONDEVICE.md
Oskar Kapala 921a85d30b Add export subcommand and Unity PoC-1 scaffold (ONDEVICE §4)
Python (ipin_vr/export.py):
- generate_bank(): levels 1–2 enumerated exhaustively (120/720 combos),
  level 3 random with dedup; all deduplicated per-level
- run_export(): CLI --per-level / --out / --seed flags per ONDEVICE §4.1
- cli.py routes "export" subcommand before session args (backward-compat)
- 14 new tests: format, dedup for all 3 levels, space caps (L1=120, L2=720),
  seed determinism, file output

Unity scaffold (ondevice/Scripts/):
- CommandBank.cs: loads commands.json from StreamingAssets (WebRequest on Android)
- TtsManager.cs: sherpa-onnx integration with [SHERPA] stubs, StreamingAssets→
  persistentDataPath copy, defensive Speak() with onDone callback
- SessionController.cs: passthrough flow §6, level switching, busy guard on Next
- ondevice/README.md: full manual Editor steps §5 (Unity setup, Meta XR SDK,
  sherpa-onnx install, scene wiring, font, build, metrics)

pytest: 37/37 passed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 16:11:53 +02:00

118 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 13 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.