baldav/docs/session-logs/2026-09-07_gps-model-findings-impl.md
4aiman 2d23f3a475 Wind: "headwind in the face" label button on the recording screen
Variant 5 from the findings doc, as GROUND TRUTH for validating the
from-track wind estimate — it does NOT feed kcal/power. Chosen scope
(per user): a toggle button now, binary "in the face" only, voice later.

- rec screen button "Ветер в лицо": tap opens a headwind interval, tap
  closes it; the open state is highlighted and survives a screen re-render
- GPS.toggleWindMark()/_closeOpenWindMark(); recording.windMarks =
  [{startTs,endTs}] ms, persisted to localStorage, written to the DB on
  finish and restored on crash recovery (a dangling interval auto-closes)
- gps_sessions.wind_marks (JSON) + DB.setSessionWindMarks (separate from
  finishGpsSession so recompute paths preserve marks); parsed in getGpsSession
- rec-bottom wraps now so the third button never overflows a narrow screen

Analysis (marks vs estimate) stays in tools/track once enough km accumulate.
2026-09-07 17:10:16 +03:00

5.2 KiB
Raw Blame History

Сессия 2026-09-07: реализация находок по расчётной модели GPS

Контекст

Разобрали docs/gps-model-findings.md (вывод независимого инструмента tools/track/track.py по 156 поездкам). Пользователь принял решения по каждой находке. Плана в plan-mode не было — работали по прямым решениям пользователя, зафиксированным ниже.

Решения пользователя и что сделано

  • #1 Crr-потолок 0.008 занижен → внедряем. crrFromAccel в gps.js расширен: 7-11=0.008, 11-15=0.012 (плотный грунт), >15=0.020 (трава/колея). Мапится и медиана сессии, и per-point ptCrr.
  • #2 max(физика,MET) не складывает, подъёмы недосчитаны → только пометить. Не меняем формулу: добавлен комментарий у Math.max(physicsKcal, metNetKcal) (ИЗВЕСТНОЕ ОГРАНИЧЕНИЕ, нужна калибровка), записано в README и PROJECT_MAP.
  • #3+#7 ходьба с велосипедом как езда → внедряем. computeStats: для односкоростного (gearCount 1/пусто + звезда/трещотка/колесо) порог walkBikeMs = 30 об/мин; сегмент медленнее порога (нормальный фикс) исключается из ездовой дистанции/скорости/высоты (elevRef=null), усилие = walk-MET нетто. #7: исключается каждая точка без гейта по длительности, в отчёт «пешком» только пробеги ≥30с. Возврат: walkBikeSec/walkBikeMeters. gearCount прокинут во все вызовы (live-stop, recalculateSession, recovery, bulk, main.js старт записи + detail). Время пуша ≥30с вычитается из duration (средняя скорость остаётся чисто ездовой).
  • #4 набор высоты расходится в обе стороны → только пометить. Не код: записано в README и PROJECT_MAP (предел сырого GPS-альтиметра, реальный фикс — предзагрузка DEM по проводу).
  • #5/#6 — к сведению (пульс потерян браслет; ветер в track.py, не в приложении).

Ветер (часть 2 доки)

Пользователь: калории от неточного ветра не считать. Хочет простые отслеживаемые вещи — метки «ветер в лицо», писать данные и делать выводы после набора километража. Это вариант 5 в роли РАЗМЕТКИ, не измерения. Трубка Пито (вариант 3) — точно нет. Вариант 2 (предзагрузка прогноза) — объяснил (скачать прогноз дома по проводу как подсказку-затравку для оценки по треку; изъян тот же, что у «уточнить высоты» — надо не забыть нажать перед выездом).

Решения по UX (AskUserQuestion): кнопка-тоггл, голос потом; только «в лицо» (бинарно). Реализовано:

  • кнопка «Ветер в лицо» на экране записи (тап открыть интервал / тап закрыть, активная подсвечена);
  • GPS.toggleWindMark()/_closeOpenWindMark(); windMarks=[{startTs,endTs}] мс, персист в localStorage, запись DB.setSessionWindMarks на финише, восстановление в recovery (недозакрытый интервал закрывается);
  • колонка gps_sessions.wind_marks (JSON), парсинг в getGpsSession. На distance/kcal/power НЕ влияет.
  • Анализ (сравнение меток с оценкой ветра по треку) — позже в tools/track/track.py, после километража.

Результат

Модельные правки #1/#3/#7 внедрены, #2/#4 задокументированы. node --check чист по всем файлам. Собрано и поставлено ранее build 436 (только правки пауз/высоты); эти правки требуют новой сборки.

Следующие шаги

  • Собрать/поставить новую сборку, проверить: на грунтах ккал выше; пеший подъём на односкоростном не в ездовой статистике и не склеивается с ездовым подъёмом; кнопка «Ветер в лицо» пишет интервалы в gps_sessions.wind_marks.
  • Ветер: добавить голосовые метки (отдельным шагом); анализ меток vs оценка по треку в track.py.