Find a file
Oskar Kapala cc3d066854 feat(vr-poc): Phase 1 scaffold — native OpenXR passthrough + quad panel
NDK/C++ NativeActivity, arm64-v8a, Gradle 8.12 + AGP 8.7.3 + CMake 3.22.1.

Implementacja (main.cpp):
- EGL headless PBuffer context (wymagany przez OpenXR GLES binding)
- xrCreateInstance z XR_FB_passthrough + XR_KHR_opengl_es_enable
- xrCreateSession → XrGraphicsBindingOpenGLESAndroidKHR
- XR_FB_passthrough: xrCreatePassthroughFB / xrCreatePassthroughLayerFB
  (dynamiczne PFN, graceful fallback gdy extension niedostępna)
- Quad swapchain 512×256 — statyczny ciemnoniebieski panel 80×40 cm,
  1 m przed użytkownikiem (przygotowany pod stb_truetype w fazie 5)
- Pętla klatek: xrWaitFrame / xrBeginFrame / [passthrough + quad] / xrEndFrame
- environmentBlendMode = OPAQUE (passthrough przez warstwę FB_passthrough)

Brakujące pliki SDK (nie w git, lista w vr-poc/README.md):
- libs/arm64-v8a/libopenxr_loader.so   — z Meta OpenXR Mobile SDK
- ovr_sdk/OpenXR/Include/openxr/*.h    — nagłówki OpenXR

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 15:33:27 +02:00
docs docs: native OpenXR coexistence PoC spec 2026-06-10 15:18:58 +02:00
ipin_vr fix(tts): Linux audio — pw-play/paplay first, warn on nonzero exit 2026-06-10 14:01:30 +02:00
ondevice Add export subcommand and Unity PoC-1 scaffold (ONDEVICE §4) 2026-06-09 16:11:53 +02:00
tests Add export subcommand and Unity PoC-1 scaffold (ONDEVICE §4) 2026-06-09 16:11:53 +02:00
vr-poc feat(vr-poc): Phase 1 scaffold — native OpenXR passthrough + quad panel 2026-06-10 15:33:27 +02:00
.gitignore chore: gitignore models/builds 2026-06-10 15:22:07 +02:00
README.md Add export subcommand and Unity PoC-1 scaffold (ONDEVICE §4) 2026-06-09 16:11:53 +02:00
requirements.txt Implement Stage 1: command generator, CLI, TTS and LLM clients 2026-06-09 15:03:50 +02:00

ipin-vr

Generator prostych, gramatycznie poprawnych polskich poleceń do terapii afazji (np. „Połóż jabłko na stole") wraz z wypowiadaniem ich przez Piper TTS.

Docelowo narzędzie ma działać w trybie mieszanej rzeczywistości na Meta Quest 3 (offline). Etap 1 (ten kod) realizuje wyłącznie rdzeń: generowanie poleceń i ich wypowiadanie na PC. Bez rozpoznawania mowy (STT), bez VR.

Dokumentacja

Zasada naczelna

Poprawność fleksji jest nienegocjowalna. Wszystkie formy słów pochodzą wyłącznie z ręcznie zweryfikowanego leksykonu; model językowy (gdy włączony) wybiera tylko identyfikatory elementów, a nie generuje polskiego tekstu.

Szybki start (bez audio)

python -m ipin_vr --level 3 --count 6 --no-audio

Przykładowy wynik:

1. Połóż zieloną książkę na półce i umieść klucz na biurku.
2. Umieść żółtą piłkę na parapecie i połóż kubek na stole.
...

Dostępne opcje CLI:

Flaga Domyślnie Opis
--level {1,2,3} 1 poziom trudności
--count N 5 liczba poleceń
--delay S 4.0 pauza między poleceniami (s)
--voice PATH ścieżka do modelu Piper .onnx
--no-audio wyłącza TTS
--llm użyj LLM do wyboru poleceń
--llm-endpoint URL localhost:8080 endpoint llama.cpp
--llm-model NAME local nazwa modelu
--seed N deterministyczny generator

Audio (Piper TTS)

pip install piper-tts
# pobierz głos polski, np. ze https://huggingface.co/rhasspy/piper-voices
python -m ipin_vr --level 2 --count 5 --voice pl_PL-gosia-medium.onnx

LLM (llama.cpp, opcjonalny)

# uruchom lokalnie serwer llama.cpp na porcie 8080
python -m ipin_vr --level 3 --count 5 --no-audio --llm

LLM zwraca wyłącznie identyfikatory elementów; gramatykę buduje zawsze leksykon. Przy błędzie (timeout, zły JSON, nieznany identyfikator) — fallback na generator losowy.

Eksport banku poleceń (na urządzenie)

Generuje gotowe, deduplikowane polecenia do JSON — używane przez aplikację Unity na Quest 3 (PoC-1, docs/ONDEVICE.md):

python -m ipin_vr export --per-level 300 --out commands.json [--seed N]
Flaga Domyślnie Opis
--per-level N 300 liczba unikatów na poziom
--out PATH - (stdout) ścieżka pliku wyjściowego
--seed N powtarzalny wynik

Format wyjściowy:

{
  "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."}
  ]
}

Przestrzeń każdego poziomu: L1 = 120 unikatów, L2 = 720, L3 ≈ 635 000. Jeśli --per-level przekracza dostępną przestrzeń, zwracane jest tyle ile możliwe.

Testy

pytest

Status

Etap 1 zrealizowany wg docs/SPEC.md. PoC-1 (Quest 3): skrypty C# w ondevice/.