VEU.WathBody/1-docs/4-modules/m11-voice-input/module_reqs.md

12 KiB
Raw Permalink Blame History

Требования к модулю: m11-voice-input

Модуль — VoiceInput телефона Phone.WatchBody (архитектура разд. 1.2): офлайн-STT Vosk + грамматика команд Ф-1.2 + TTS-подтверждения

  • интеграция в экран «Тренировка» (m10) поверх ядра m09. Самодостаточная копия требований (d-dev-6). Источники: Ф-1, Ф-3.3 (таймер), Ф-13.3 («РПЭ N»), открытый вопрос 2 (закрыт шагом 5: Vosk, малая ru-модель, TTS — системный Android), tech-req 4.1/5 (VoiceInput, модель ~50 МБ, постобработка чисел), 7 п. 3 (прототип точности), ui-ux разд. 3.

1. Назначение и границы

Голосовой офлайн-учёт подходов: атлет на экране активной тренировки включает микрофон и говорит команды; команды разбираются офлайн, применяются к текущей тренировке и журналируются (🛡 Ф-1.5).

В границах модуля:

  • грамматика команд Ф-1.2 (разбор — чистая функция):
    • «Подход W на R» → подход: вес W кг × R повторений (вес — целые кг либо «…с половиной» → +0,5 кг; W — 0–500, R — 1–100; решение владельца О-2-Б);
    • «Вес W» → рабочий вес W кг для следующих подходов;
    • «Отдых S (секунд)» → таймер отдыха S секунд (5–600);
    • «РПЭ N» → RPE последнего подхода, N — 1–10 (Ф-13.3);
    • числа — словами («сто двадцать») и цифрами («120»); слова «секунд» после S — необязательны; постобработка «сто двадцать» → 120 — tech-req 5;
    • команда вне грамматики или число вне диапазона — отклоняется: короткий сигнал ошибки, состояние не меняется, в журнал пишется распознанный текст с accepted=false (Ф-1.3);
  • STT-движок: Vosk (com.alphacephei:vosk-android), малая русская модель (vosk-model-small-ru-0.22, ~45 МБ); распознавание только офлайн — сеть не используется (Ф-1.1, ОВ-2); ограничение словаря грамматикой Vosk (setGrammar, JSON-словарь: «подход», «вес», «отдых», «на», «секунд», «с половиной», числительные 0–999) — применяется, если модель поддерживает; обязательна строгая постобработка финальной гипотезы парсером (малые модели Vosk не гарантируют поддержку грамматики — деградация до свободного распознавания, лишнее отклоняет парсер по Ф-1.3);
  • доставка модели: модель НЕ входит в APK и в репозиторий; загружается zip-архивом по https в папку приложения при первом включении микрофона (или из «Настроек»), распаковывается в filesDir; URL — настройка Voice.ModelUrl (умолчание — официальный хост alphacephei.com); статус модели и кнопка «Загрузить» — в «Настройках» (решение гейта 1.3);
  • применение команд (исполнитель): «Подход» → WorkoutCore.logSet (source=voice, текущее упражнение экрана); «Вес» → рабочий вес текущего упражнения (состояние экрана, умолчание формы); «Отдых» → старт таймера отдыха (переиспользуется таймер m10); «РПЭ» → RPE последнего подхода тренировки (WorkoutCore.setLastSetRpe — расширение m09, как renameExercise в m10);
  • журнал команд 🛡 (Ф-1.5): каждая команда — принятая и отклонённая — через WorkoutCore.logCommand (текст, семантика, t_offset_s от начала тренировки, accepted); журнал не редактируется; уходит sync command_log (контракт m09 spec 04);
  • подтверждения (Ф-1.4): принятая команда — короткий «щелчок» (ToneGenerator) + голосовое TTS-подтверждение офлайн («Принято, подход 120 на 8» / «…вес 100» / «…отдых 90 секунд» / «…РПЭ 8»); TTS — системный Android TTS (ru-RU, tech-req 4.1); при отсутствии TTS-движка/русского голоса — деградация: щелчок/сигнал + текст подтверждения на экране, работа не блокируется;
  • активация (Ф-1.1): кнопка микрофона на экране «Тренировка»; повторное нажатие выключает прослушивание; прослушивание активно, пока открыт экран активной тренировки и микрофон включён — выход с экрана останавливает; разрешение RECORD_AUDIO запрашивается при первом включении (runtime);
  • текущее упражнение: голос пишет подходы в «текущее упражнение» экрана «Тренировка» — выбор тапом в блоке плана (подсветка), умолчание — первый пункт плана сессии дня, иначе последнее введённое вручную; голосовой выбор упражнения по имени в v1 отсутствует (имена произвольные — распознавание ненадёжно; решение гейта 1.3);
  • экран «Тренировка»: индикатор «слушаю/выключено» (иконка + текст 🛡), строка последней команды (принято/отклонено — текстом, не только цветом), «Вес W» меняет отображаемый рабочий вес;
  • «Настройки» (расширение m10): блок «Распознавание речи» — статус модели (не загружена / загружена, размер), кнопка «Загрузить» (по Voice.ModelUrl, прогресс/ошибка текстом), «Проверить TTS» — наличие ru-голоса;
  • unit-тесты (pure JVM): парсер (4 команды, числа словами 0–999 и цифрами, «с половиной», границы диапазонов, мусор, регистр), семантика журнала, NumberRu; исполнитель — на фейках ядра.

Вне границ модуля: wake-word (опросник 4.5 — v2), голосовой выбор упражнения по имени (v1 нет — решение гейта), распознавание на часах, запись аудио (только живой поток в движок, хранения нет), шумовой профиль зала, метрики точности в БД (КУ-1 фиксируется вручную владельцем), m12 канал часов, m13 поле данных.

2. Решения интерфейса (ui-ux разд. 3, tech-req 6)

  • Кнопка микрофона — нижняя треть экрана, цель ≥ 48 dp, состояние дублируется текстом («Слушаю…» / «Голос выключен»);
  • строка последней команды — текстом: «Принято: подход 120 на 8» / «Не распознано» (цвет — только дублирование);
  • сигнал ошибки — короткий, не пугающий; формулировки спокойные;
  • TTS-подтверждения короткие (≤ 3–4 слов + числа).

3. Инварианты (🛡 — нарушать запрещено)

  1. Офлайн-first (Ф-1.1, КУ-3): распознавание и применение команд работают без сети; сеть — только доставка модели (один раз) и SyncQueue как обычно.
  2. Журнал команд полон и неизменяем (Ф-1.5): каждая распознанная фраза (принятая и отклонённая) фиксируется с исходным текстом, семантикой и t_offset_s; удаление/правка журнала невозможны.
  3. Голос не обходит ядро: применение команд — только через WorkoutCore (единственный писатель LocalDb, инвариант m09); VoiceInput не пишет в БД напрямую.
  4. Допуск Safety не снимается голосом: команды работают только в уже начатой (допущенной) тренировке; блокировки допуска — контур m09/m10.
  5. Тайны: Voice.ModelUrl может содержать URL сервера владельца — ключи/пароли в неё не попадают; API-ключ не логируется (З-6).

4. Критерии приёмки модуля

  1. assembleDebug собирается; unit-тесты парсера/исполнителя зелёные.
  2. Ручной смок на устройстве владельца (модель загружена): включить микрофон → «Подход 60 на 10» → щелчок + «Принято, подход 60 на 10» → подход записан (источник «голос», метка плана); «Вес 62 с половиной» → рабочий вес 62,5; «Отдых 90» → таймер; «РПЭ 7» → RPE у последнего подхода; фраза вне грамматики → сигнал ошибки, состояние не изменилось, в журнале accepted=false.
  3. Смок синхронизации (живой docker-сервер): журнал команд уходит command_log-пакетом, строка в src.command_log содержит текст и семантику.
  4. КУ-1 (контрольная тренировка ≥ 4 упражнений, ≥ 16 подходов, ≥ 90 % команд с первого раза) — ручная приёмка владельца в зале (tech-req 7 п. 3); автоматизации не подлежит, фиксируется в журнале приёмки.