Acted on docs/gps-model-findings.md (independent analysis of 156 rides). Implemented: - crrFromAccel extended past the old 0.008 ceiling: 7-11 -> 0.008, 11-15 -> 0.012 (packed dirt), >15 -> 0.020 (grass/rut/gravel). Rough surfaces were undercounted ~3x. Applied to session median and per-point Crr. - Auto walk-the-bike detection (single-speed only, gear_count 1/unset): a normal-fix segment slower than the 30-rpm-cadence speed is the rider pushing, not riding. Excluded from ride distance/speed/elevation (elevRef reset so a pushed climb doesn't merge with the ridden one); effort counted as walking, not bike physics. Every sub-threshold point excluded regardless of duration; only runs >=30s reported as walked (walkBikeSec/walkBikeMeters). gearCount threaded through every computeStats/finish caller. Documented as known limitations (left as-is by decision, need calibration/DEM): - kcal max(physics, MET) never sums the biological overhead, so climbs are slightly undercounted (comment + README + PROJECT_MAP). - absolute elevation gain is bounded by the raw GPS altimeter (tens of percent; needs a terrain model / wired DEM preload).
4.3 KiB
Сессия 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: для односкоростного
(
gearCount1/пусто + звезда/трещотка/колесо) порог 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 доки)
Пользователь: калории от неточного ветра не считать. Хочет простые отслеживаемые вещи — голосовые метки («ветер в лицо») и/или кнопки в UI (нажал когда дует в лицо, отжал когда перестал), писать данные и делать выводы после набора километража. Это вариант 5 в роли РАЗМЕТКИ, не измерения. Трубка Пито (вариант 3) — точно нет. Вариант 2 (предзагрузка прогноза) — пользователь не понял, нужно объяснить. Реализация ветер-фичи — отдельным шагом (нужны решения по UX: триггер-слова, место кнопки, схема хранения событий).
Результат
Модельные правки #1/#3/#7 внедрены, #2/#4 задокументированы. node --check чист по всем файлам.
Собрано и поставлено ранее build 436 (только правки пауз/высоты); эти правки требуют новой сборки.
Следующие шаги
- Собрать/поставить новую сборку, проверить: на грунтах ккал выше; пеший подъём на односкоростном не в ездовой статистике и не склеивается с ездовым подъёмом.
- Ветер: спроектировать и внедрить разметку событий (голос/кнопки).