0

Как я сделал лыжный тренер на датчиках и вайб-кодинге - вместо подписки на готовый

tvv2000 Лента автора пн. 28 Сентября 2026 (16:21) Просмотров: 14 0

Как я сделал лыжный тренер на датчиках и вайб-кодинге - вместо подписки на готовый

1. Почему вообще начал

На рынке есть готовые продукты: пара датчиков на ботинки, приложение считает технику катания, подсказывает, что тренировать. Работает неплохо. Но по подписке - и недёшево: например, у Carv безлимитный сезонный доступ стоит $249 / £199 в год. И вот тут возникает вопрос: насколько эта подписка вообще оправдана? Датчик - это акселерометр с гироскопом за пару долларов и Bluetooth-модуль, приложение - по сути обработка сигнала и немного статистики. Разовая покупка железа плюс разработка - понятные, конечные затраты. А подписка - плата за то, что уже посчитано один раз и с тех пор просто работает. Есть ощущение, что здесь платишь не за вычисления, а за то, что вход на рынок для конкурентов высокий: откалибровать алгоритмы, написать мобильное приложение, а потом ещё поддерживать серверы, пользователей и производство железа - дорого и долго. Подписка отбивает эти инвестиции. Но большая часть этого барьера - стоимость разработки, а она за последние пару лет резко упала: с ИИ-инструментами то, что раньше требовало команды, становится посильным для одного человека. Продукт для рынка так не сделать - там нужна калибровка на тысячах лыжников, поддержка и сертификация. А вот любительский инструмент - вполне.

Второй мотив - практический: проверить на реальном, не игрушечном проекте, что сейчас умеют ИИ-инструменты в разработке. Не автодополнение строк, а весь путь: от идеи и архитектуры до калибровки алгоритмов на реальных данных с настоящего железа. Ниже, в разделе 9, - про то, как это было на практике, а не в презентациях.

2. Как писал алгоритмы

Начал не с чистого листа: на рынке уже есть продукты, которые решают ту же задачу, и по ним видно, что вообще нужно измерять у лыжника, чтобы оценить технику - какой список характеристик поворота в принципе имеет смысл считать. Это ценный ориентир на уровне постановки задачи. А вот сами формулы, веса и пороги в готовых продуктах - чёрный ящик, недоступный и не особо интересный: даже если бы получилось их скопировать, это были бы чужие калибровочные числа на чужих данных и чужом железе, без понимания, откуда они взялись.

Пошёл другим путём. Физика резаного поворота на лыжах достаточно хорошо описана в биомеханической литературе - есть модели геометрии карвинга (угол закантовки, радиус дуги, боковой вырез лыжи), есть работы про анализ техники горнолыжников по IMU-данным (акселерометр + гироскоп на ботинке или лыже). Я отталкивался от этого класса моделей и от собственных записей, а не от подгонки под чей-то вывод.

Итоговый список - около десятка метрик на поворот: угол закантовки, ускорение в повороте (g-force, отсюда и название программы - G-Force Skiing), форма дуги поворота, симметрия между левой и правой ногой, темп поворотов, насколько поворот «закрыт» к концу дуги, и ещё несколько. Из них считается один сводный показатель - GF Score: каждая метрика нормализуется в диапазон «типичный худший - типичный лучший результат» и суммируется с весом, который зависит от выбранной манеры катания (карвинг, короткие повороты, параллельные лыжи - для каждой свой набор весов, потому что важность одной и той же метрики для разных техник разная).

Дисциплины сознательно ограничены тремя. У Carv, например, есть ещё могул и фрирайд, но по этим техникам у меня нет нужной личной экспертизы, чтобы понимать, что в них вообще значит «технически правильно» - а калибровать метрики вслепую, не понимая физики движения, бессмысленно. Решил остановиться на том наборе, в котором могу сам оценить результат.

Детектор самого поворота - отдельная небольшая задача, на которую ушло на удивление много времени. По потоку ориентации ботинка (кватернион, 100 раз в секунду) нужно понять, где начался и закончился один поворот. Интуитивно казалось, что это должен быть переход угла закантовки через ноль - но решил, что это слишком просто, и попробовал более сложный алгоритм из статьи Martínez et al., Automatic Turn Detection Algorithm, Sensors 2019, 19(4):902. На практике он не прижился - давал нестабильные границы на реальных записях. В итоге вернулся к первоначальной интуиции и не прогадал: граница поворота - это переход сглаженного угла закантовки через ноль, а чтобы не ловить дребезг на почти прямом участке, поворот засчитывается только после того, как угол прошёл пик и откатился от него на пороговую величину (гистерезис). Порог подбирается автоматически по записи, обычно это несколько градусов. Для этого нужен один калибровочный спуск в каждой манере катания: приложение запоминает его данные, по ним находит порог и задним числом считает метрики этого же спуска, так что спуск не пропадает. Дальше порог берётся из сохранённой калибровки.

3. Тестирование на коньках

Лыжного сезона под рукой не было, а проверять алгоритмы на синтетических данных - значит проверять только код, а не физику. Решение - коньки: каток доступен круглый год, склон - только в сезон. Кантование конька на льду (езда на внешнем или внутреннем ребре) физически похоже на кантование горнолыжной лыжи на снегу: тот же наклон корпуса, та же перекантовка с ноги на ногу, та же дуга.

  • Перетяжки (серия связанных поворотов на одной ноге кант в кант, без отталкивания, пример на видео) - физический аналог карвинга: длинная стабильная дуга, постоянная закантовка.
  • Змейка - короткие частые повороты влево-вправо - аналог коротких поворотов (short turns): высокий темп, быстрая перекантовка.

Два навыка так проверить не вышло: плуг и проскальзывание. Точнее, конёк технически тоже может скользить боком - но физика этого скольжения на льду не похожа на то, как скользит лыжа по снегу под острым углом закантовки, так что как полноценный аналог это не годится. Эти метрики и пороги для них пока откалиброваны только по физической модели и разумным предположениям, без живых данных - честно об этом ниже, в разделе про ограничения.

4. Основные сценарии использования

Стартовый экран приложения

  • Свободное катание - приложение само отличает спуск от подъёмника по GPS, пишет метрики в фоне, считает GF Score на каждом спуске. Ничего нажимать по ходу не нужно. Отдельно можно включить видео: если рядом едет и снимает на телефон другой человек, датчики передают в приложение все данные заезда, и на повторе видео можно увидеть GF Score по каждому повороту в виде графика поверх записи.
  • Тренировка навыка - выбираете конкретную деталь техники (например, раннюю закантовку), приложение следит только за её метриками и даёт обратную связь сразу, поворот за поворотом: короткий звуковой сигнал на каждом засчитанном повороте - один из двух разных звуков, в зависимости от того, насколько хорошо выполнен именно этот поворот. Уровень навыка растёт, когда нужное число поворотов подряд (обычно 8) прошли порог полностью - не «в среднем за день», а именно подряд, без провалов.
  • Без датчиков - просто GPS-трек: маршрут, скорость, потраченные калории, набор высоты, чтобы поделиться треком с друзьями, если датчиков с собой нет.

5. Как строить обучение

Дисциплины и навыки

Навыки сгруппированы в три дисциплины по манере катания (параллельные лыжи, карвинг, короткий радиус), внутри каждой - навыки по возрастанию сложности, это и есть встроенная программа обучения. У каждого навыка уровень 0-30, порог «освоено» зависит от заявленного уровня лыжника (7 / 17 / 27 из 30 для новичка / среднего / эксперта) - чем опытнее лыжник, тем выше планка, после которой навык считается закрытым.

Уровень навыка не поднимается за один удачный спуск: система смотрит на стабильность - берёт подтверждённый результат по нескольким последним засчитанным спускам, а не лучший или последний. Один эффектный заезд не завышает прогресс; нужно показать результат несколько раз подряд, чтобы он засчитался.

6. Как работают рекомендации

Главный экран с рекомендациями

После каждого спуска на главном экране - две карточки: «Освоено» и «Поработать над этим». Логика простая и без ML: навыки внутри дисциплины уже идут по порядку сложности, и приложение находит первый навык, который ещё не набрал нужный порог. Он и следующий за ним - то, что предлагается тренировать. «Освоено» - самый сложный навык, который уже перевалил порог. Никакой отдельной оценки «важности» или ML-модели, которая бы решала, что показать - вся рекомендация целиком выводится из уже посчитанных уровней навыков, по порядку программы обучения.

Это осознанный выбор в сторону от ML. У Carv, например, есть встроенная ИИ-модель, которая оценивает, насколько ваш карвинг похож на экспертный, - по ощущениям, это больше маркетинговая фишка, чем действительно полезный инструмент: она может сказать что-то вроде «похоже на эксперта на 73%», но не может сказать, что конкретно нужно исправить, чтобы стать лучше. Для пользователя это чёрный ящик - никто снаружи не знает, на основании чего модель приняла решение. Здесь вместо этого всё построено на прозрачной физике и явных порогах: можно всегда объяснить, почему именно этот навык предложен следующим и что конкретно в нём не так.

7. Железо

Готовые фирменные датчики стоят прилично: пара сенсоров Carv - €129. По сути это связка недорогого IMU-модуля (акселерометр + гироскоп), BLE-чипа, батарейки и корпуса с клипсой на ботинок. Своими руками пара таких датчиков собирается примерно за 5000 ₽ - дешевле фирменной пары, и без необходимости разбираться в закрытом протоколе: BLE-протокол у датчика открытый и документированный. Прошивку самого датчика менять нельзя, но она и не нужна - вся обработка сигнала, калибровка и метрики живут в приложении, и там можно менять всё.

Комплектующие для самодельного датчика

Само железо тоже не сразу устаканилось. Изначально использовался XIAO nRF52840 Sense Plus - компактный и удобный модуль, под который прошивку писал сам: чтение IMU, фильтр ориентации, свой BLE-протокол. Но у его гироскопа оказался дикий дрейф показаний, который было не свести на нет программно. Перешёл на WT9011DCL - готовый датчик с фирменной прошивкой, который не только оказался стабильнее, но и дешевле. Своя прошивка ушла в прошлое, и, как выяснилось, без потерь.

8. Ограничения - честно

  • Ещё не было ни одного реального теста на склоне. Вся калибровка и вся проверка алгоритмов на сегодня - данные с коньков плюс физическое моделирование. Физика поведения (закантовка, g-force, форма дуги) выглядит правдоподобно и на коньках воспроизводится похоже на лыжи, но это не то же самое, что настоящий снег, настоящие лыжи и реальный радиус бокового выреза. Первый тест на склоне - ближайший приоритет.
  • Плуг и проскальзывание не проверялись на живых данных вообще - см. раздел 3.
  • Оценка условий на склоне (жёсткий наст против рыхлого снега) в GF Score сейчас не участвует. А нужна она для поправки оценки: на льду показать хорошую технику заметно сложнее, чем на свежем «вельвете», и одинаковый GF Score на разном снеге на самом деле означает разный уровень. Выяснилось, что честная оценка требует полноценного ML-классификатора по сотне с лишним признаков, это отдельная большая задача, которую пока сознательно отложил в пользу более простой эвристики по вибрации с датчика ботинка - тоже ещё не реализовано.

9. Как прошёл сам вайб-кодинг на практике

Сразу оговорюсь: в классическом понимании вайб-кодинг - это «принимаю код, не читая». У меня был вайб-кодинг с ревью. Не «опиши функцию - получи готовое приложение». Ближе к разработке с очень быстрым и очень дотошным исполнителем, которому нужно чётко объяснять, что нужно, и проверять каждый результат. Практика, которая действительно помогла:

  • Ни одна калибровочная константа не бралась «на глаз» надолго. Например, пороги «сенсор лежит неподвижно» для авто-калибровки нулевого положения датчика сначала были оценкой без данных - потом записал 70 секунд покоя/ходьбы/движения с датчиков, посчитал разброс шума и заменил оценку настоящими числами с запасом. Без такой проверки константа так и осталась бы условной.
  • Правило «на каждый найденный баг - тест». За время разработки нашлось несколько багов: например, формула одной из метрик ломалась на отрицательном диапазоне значений - без теста именно на таком диапазоне это осталось бы незамеченным до первого реального использования.
  • Спорные архитектурные решения - сначала обсуждение, потом код. Например, живой счётчик «сколько поворотов подряд прошли порог» сначала реализовал в реальном времени во время спуска - а потом решил, что это лишняя сложность: подъём уровня не обязан считаться именно во время катания, и переделал на пересчёт по уже сохранённым данным спуска, постфактум. Такие развороты - нормальная часть процесса, если задавать вопрос «а зачем именно так» на каждом значимом решении.
  • Обязательное ревью каждого куска кода. Не «сгенерировал - принял», а построчный разбор перед тем, как что-то попадает в проект. Во многих случаях именно на этом шаге код в итоге заметно упрощался - первая рабочая версия почти никогда не была самой простой. ИИ порой действует прямолинейно там, где нужно чуть больше изящества, и, наоборот, усложняет то, что можно сделать проще. Правда, по специализации я backend-разработчик, поэтому построчно ревьюил в основном бизнес-логику, а UI-код принимал почти как есть - просматривал, но без той же дотошности.

Главный вывод: результат сильно зависит не от инструмента самого по себе, а от того, насколько дотошно проверяется каждый шаг - тестами, реальными данными с датчиков, а не только тем, что код скомпилировался и не упал. Как говорится, доверяй, но проверяй.

На самом деле я немного переоценил свои возможности: изначально проект казался не особо сложным, но на втором месяце разработки превратился в чемодан без ручки - и бросить жалко, и тащить тяжело. Но в него уже было вложено немало времени и денег, так что я всё же довёл его до релиза.

10. Что дальше

  • Первый настоящий тест на склоне - калибровка по реальным данным вместо коньков и физической модели.
  • DSP-эвристика по вибрации датчика ботинка для оценки жёсткости снега.
  • Постепенное расширение программы обучения по мере накопления реальных данных с разных лыжников.
  • Не хватает обучающих видео - коротких роликов с демонстрацией техники, как в готовых продуктах вроде Carv. Сейчас они есть только для двух навыков, а для упражнений нет вовсе. Если кто-то готов снять или поделиться такими видео - буду рад помощи.

Где взять и как связаться с автором

  • Скачать: RuStore - приложение сразу приходит с демо-данными (несколько спусков, прогресс по навыкам), чтобы можно было сразу оценить, как это выглядит, не катаясь; перед реальным использованием их можно удалить одной кнопкой в «Конфигурации». К сожалению админы не торопятся проводить модерацию, поэтому самая свежая версия лежит здесь Githib
  • Документация: прямо в приложении («Конфигурация» → «Документация») - полное описание всего заявленного функционала, то же самое руководство пользователя, что использовалось при подготовке этой статьи.
  • Обсуждение и вопросы: форум ski.ru
  • Написать напрямую: gf_skiing@mail.ru, либо через экран «Сообщить о проблеме» прямо в приложении (баг, идея, что угодно).
0