ДЛЯ ТЕХ, КОМУ ИНТЕРЕСНО УСТРОЙСТВО

Азимуты
под капотом

Как данные спутников становятся координатой, почему карта работает офлайн и что происходит между «Стартом» и GPX-файлом. Ниже — фактическая архитектура, алгоритмы и границы текущей реализации.

Срез исходников: 4 октября 2026 года · в Android-сборке указана версия 1.9 · исследовательские функции отмечены отдельно

01 / СТЕК

Нативный Android и общее вычислительное ядро

Интерфейс и доступ к датчикам находятся в Android-модуле app. Геометрия, граф маршрутов, астрономия и часть GNSS-логики вынесены в shared на Kotlin Multiplatform. Это позволяет проверять вычисления на JVM без запуска телефона.

СлойРеализацияЗадача
ПриложениеKotlin, Android SDKНативные экраны, службы, датчики и файловое хранилище
ПлатформаminSdk 26, target/compileSdk 36Android 8.0 и новее
КартаMapLibre Android 13.6.1Отрисовка карты, стилей, подписей и пользовательских слоёв
ИнтерфейсAndroid Views, Material 1.13.0, Core KTX 1.18.0Элементы управления и интеграция с Android
Общее ядроKotlin Multiplatform, Android + JVMРасчёты без зависимости от экранов
СборкаGradle, Android Gradle Plugin 9.4.1, Java 17Сборка и проверки общего кода
Подготовка данныхPython, инструменты PMTiles, OSM, Copernicus DEMРегиональные карты, дорожные графы и рельеф
Доставка регионовPython-сервис, Cloud.ru Container Apps, S3-совместимое хранилищеКаталог, права доступа и временные ссылки на файлы

Версии в таблице взяты из файлов сборки этого среза. Цели iOS в конфигурации общего модуля пока отключены; готовое приложение для iPhone здесь не заявляется.

ВХОДAndroid и файлы региона

Координаты, состояние спутников, датчики, карта и граф дорог.

ОБРАБОТКАПроверки и расчёты

SignalTrust, запись трека, NavRoute, RoadGraph и геометрия.

РЕЗУЛЬТАТЭкран и локальные файлы

Карта, предупреждения, направление, журнал и GPX.

02 / КООРДИНАТЫ И ТРЕК

Системный GNSS, фоновая служба и журнал точек

GnssMonitor и TrackService получают координаты через LocationManager.GPS_PROVIDER, запрашивая обновления с интервалом 1 секунда. Это запрос к Android, а не гарантия поступления каждой точки точно раз в секунду. Google Play Services для этого пути получения координат не требуется.

TrackService работает как foreground service типа location и показывает постоянное уведомление. Через тот же сервис поступают данные о движении и, при наличии датчика, давлении. Поддержка датчиков и политика энергосбережения зависят от устройства.

Фильтрация до сохранения

TrackRecorder учитывает профиль, паузу, оценку точности и Trust.trusted. Точки с расчётной скоростью перехода выше 90 м/с отбрасываются. Профильные пороги текущего кода:

ПрофильМинимальное перемещениеМаксимальная заявленная погрешность точки
Авто25 м25 м
Мото15 м25 м
Вело8 м25 м
Пешком4 м30 м
Грибы3 м35 м

Эти значения — правила отбора, а не измеренная точность приложения. Принятые точки добавляются в CSV-журнал. При остановке он преобразуется в GPX 1.1; при следующем запуске recoverOrphans обрабатывает оставшиеся журналы. Такое восстановление работает с уже записанными данными и не заполняет периоды отсутствия измерений.

03 / SIGNALTRUST

Объяснимые эвристики вместо единственного флага

Общий модуль SignalTrust накапливает признаки и их веса. Среди входов — Android mock-location flag, скачки позиции и времени, состав спутниковых систем, C/N₀, наличие второго диапазона, изменение AGC. Сравнение с высотой из DEM и последней сетевой координатой используется, когда такие данные доступны.

Сетевая координата берётся из уже известного Android положения с ограничением по возрасту. Ради этой проверки приложение не отправляет текущую точку на сервер. В фоне TrackService передаёт спутниковый статус без AGC, поэтому набор доступных признаков на экране и при выключенном экране может различаться.

  • От 3 баллов — подозрение, от 5 — вероятная подмена. Mock-флаг имеет вес 10.
  • Событийные признаки хранятся до 120 секунд; понижение уровня требует 60 секунд без поддержки прежней тревоги.
  • Проверка помех учитывает наличие координаты ранее. Обычный холодный старт сам по себе не считается глушением.
  • При включённой защите уровни SPOOF и JAM запрещают приём точек в трек. Уровень SUSPECT сам по себе запись не блокирует.
  • В экспериментальном разделе пользователь может отключить эту проверку.

Границы методаЭто эвристический классификатор. Порогам нужна полевая калибровка на реальных помехах и подменах. Совпадение признаков не является криптографической проверкой сигнала; отсутствие тревоги также не доказывает его подлинность.

В высотной проверке Android MSL используется при доступности. Для иных случаев в текущем коде есть приближённая поправка геоида 20 м, ориентированная на европейскую часть России. Это дополнительная причина осторожно интерпретировать высотный признак вне проверенных условий.

04 / ДОСТАВКА ДАННЫХ

Региональные файлы и проверка целостности

Картографическая основа подготовлена из OSM/Protomaps, данные упакованы в PMTiles. Дорожная сеть хранится в собственном бинарном формате RG01, отображаемый рельеф — в отдельном PMTiles с тайлами Terrarium. Шрифты и значки карты входят в APK.

RegionStore получает каталог с размерами и SHA-256, проверяет свободное место, пишет загрузку в .part и продолжает её через HTTP Range. После завершения вычисляется SHA-256 всего загруженного файла. Только после совпадения с каталогом выполняется установка файла на рабочее место.

Закрытое S3-совместимое хранилище отдаёт данные по временным подписанным ссылкам. Отдельный сервис проверяет доступ устройства и выдаёт эти ссылки. HMAC используется в механизме доступа; координаты прогулки для этого процесса не нужны. SHA-256 проверяет целостность файла относительно каталога, а не актуальность нарисованных дорог.

В бесплатной версии доступен один выбранный регион. Полный доступ открывает другие регионы и расширенные инструменты. Сравнение версий вынесено на главную страницу.

05 / ПУТЬ ПО ДОРОГАМ И ПО СЛЕДУ

Два разных графа для двух разных задач

Маршрутизация по дорожной сети

Граф строится заранее из OSM. Рёбра содержат геометрию, направления, доступность и скорости для автомобиля, велосипеда и пешехода. В телефоне RoadGraph использует A* с критерием времени; эвристика — расстояние по прямой, делённое на максимальную скорость профиля. Для поиска ближайшей подходящей дороги применяется пространственная сетка.

Авто и мото используют автомобильный профиль, «Пешком» и «Грибы» — пешеходный. От исходной точки до выбранного дорожного сегмента и от сети до цели остаются прямые соединения. Они требуют оценки по местности.

Текущая реализация не учитывает полный набор запретов поворотов и задержек на перекрёстках. Скоростные правила стартовые. Расчётное время и проходимость маршрута зависят от качества исходных данных и требуют дальнейшей проверки.

Возвращение по записанному следу

NavRoute.backtrack строит граф из соседних точек трека и соединений между близкими участками. Текущий радиус соединения — 20 м; стоимость такого перехода умножается на 1,5. Затем алгоритм Дейкстры ищет путь от последней точки к первой, позволяя сократить петли.

Близость точек не доказывает физическую проходимость промежутка. В алгоритме нет проверки канав, заборов или перепада между двумя соседними на плане участками. Это свойство важно понимать при использовании сокращённого обратного пути.

06 / РЕЛЬЕФ И КАРТОГРАФИЯ

Подготовка тяжёлых данных до поездки

В журнале проекта зафиксирована обработка 3 725 исходных тайлов Copernicus DEM GLO-30: 78,6 ГБ исходников, затем региональные файлы рельефа для 85 пакетов. Это результат конкретной сборки данных, а не обещание неизменного объёма каталога.

Для отмывки используются Terrarium-тайлы с квантованием высоты 1 м. Это шаг кодирования, а не вертикальная точность исходной модели. Copernicus GLO-30 — модель поверхности: растительность и здания могут влиять на высоты.

DemReader для численной высоты читает отдельные файлы DEM1 с диска и выполняет билинейную интерполяцию по четырём узлам. В проверенном срезе он не декодирует загруженный relief.pmtiles. Поэтому отмывка и доступность высотного профиля — разные возможности; покрытие зависит от наличия отдельных DEM-файлов.

Собственные растровые карты

SQLitedb/MBTiles перепаковываются в PMTiles. Для Ozi и JNX используются отдельные импортёры; Ozi-привязка вынесена в общее ядро. Поддержка Ozi в текущем коде ограничена WGS 84 и проекциями Mercator / Latitude–Longitude. Зашифрованные OZF3/OZFX3 не поддерживаются. Файлы исторических карт добавляет сам пользователь.

07 / ЭКСПЕРИМЕНТАЛЬНОЕ ЯДРО GNSS

Свой путь от сообщения спутника до координаты

Статус: исследовательская функцияМодули RawGnss, GnssNav и OwnFix обрабатывают сырые измерения и навигационные сообщения. Результат показывается отдельно и сравнивается с системным. Основной трек сохраняет координаты Android GPS provider.

СистемаРеализованный разборПоложение спутника
GPSLNAV, L1 C/AКеплеровы эфемериды
GalileoI/NAV, E1-BКеплеровы эфемериды
BeiDouD1, B1I, MEO/IGSOКеплеровы эфемериды
ГЛОНАССL1OF, строки 1–4Интегрирование движения методом Рунге–Кутты 4-го порядка

Решатель использует псевдодальности первой частоты каждой системы. Координата находится взвешенным методом наименьших квадратов; веса зависят от оценки неопределённости измерения и угла места. Для каждой спутниковой системы оценивается собственное смещение часов.

В расчёте присутствуют поправки часов спутника, релятивистский член, вращение Земли за время распространения сигнала, модель Клобушара при наличии коэффициентов и приближённая тропосферная поправка. Низкие спутники исключаются из геометрии при наличии начального положения.

Решатель требует избыточных измерений для оценки невязки. При больших невязках он может исключить худший сигнал и повторить расчёт. OwnFix дополнительно отбрасывает решения с RMS выше 100 м и отклонением от координаты телефона больше 5 км. Положение телефона может использоваться и как начальное приближение. Поэтому сравнение с ним нельзя считать полностью независимой проверкой.

Эфемериды кэшируются локально с ограничением по возрасту. Есть разбор RINEX NAV, запись наблюдений RINEX 3.04 и повторный прогон сырых журналов на JVM. Поддержка полей и навигационных сообщений зависит от GNSS-чипа и реализации Android на конкретном телефоне. Это ограничение описано и в документации Android о сырых GNSS-измерениях.

08 / ПРОВЕРКИ

Один вычислительный код на телефоне и в проверочном запуске

В JVM-модуле есть SelfCheck и Replay. Первый содержит контрольные сценарии для дорожных маршрутов, проекции на трек, сокращения петель, SignalTrust, привязки Ozi, астрономии и собственного координатного решения. Второй повторно обрабатывает записанные сырые данные; при необходимости подключаются навигационные данные RINEX.

Синтетический GNSS-сценарий задаёт известную координату и проверяет её восстановление. Он полезен для проверки математики, но не измеряет реальную точность на смартфоне. Контроль движения ГЛОНАСС в текущем наборе также имеет ограниченный характер; его нельзя выдавать за полную валидацию орбитального вычислителя.

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

09 / ПЕРВОИСТОЧНИКИ

Те самые 530 страниц

В репозитории сохранены следующие PDF. Число страниц посчитано по полным локальным файлам, включая титульные и служебные страницы.

Документ из проектаСтраниц
IS-GPS-200N248
Galileo OS SIS ICD, Issue 2.1128
GLONASS ICD, Edition 5.1 (2008)65
BDS-SIS-ICD-B1I, Version 3.089
Всего530

Это редакции, на которые опирается проверенный код. Например, на официальной странице Galileo уже опубликована редакция 2.2; наличие в проекте 2.1 не означает, что она самая новая.

Есть что обсудить?

Нам интересны реальные наблюдения: как ведёт себя сигнал на вашем телефоне, что получается на маршруте и где расчёт расходится с местностью.

Написать разработчику