Точное позиционирование в помещении: роль UWB и его возможности
Мы интегрируем UWB (Ultra-Wideband) для точного позиционирования в мобильных приложениях. GPS в помещении не работает — это известно. Bluetooth Low Energy даёт точность 1-3 метра в лучшем случае. Wi-Fi RSSI triangulation — 2-5 метров с высокой нестабильностью. UWB — технология с точностью 10-30 сантиметров, основанная на измерении времени прохождения радиосигнала (Time of Flight / Two-Way Ranging). Именно её Apple встроила в iPhone 11+ через чип U1, и именно она даёт AirTag точность «вот ваша сумка, поверните направо». Наша команда имеет 10+ лет опыта в разработке мобильных решений, и мы гарантируем качественную интеграцию UWB под ключ. Получите консультацию по выбору UWB-оборудования для вашего объекта. Ultra-Wideband — технология, которая изменила indoor-навигацию.
Почему UWB лучше BLE и Wi-Fi для indoor-навигации?
| Параметр |
UWB |
BLE |
Wi-Fi RSSI |
| Точность |
10-30 см |
1-3 м |
2-5 м |
| Стабильность |
Высокая |
Средняя |
Низкая |
| Задержка |
< 1 мс |
1-10 мс |
50-100 мс |
| Помехоустойчивость |
Высокая |
Средняя |
Низкая |
UWB обеспечивает точность в 10 раз лучше BLE, что подтверждается нашими проектами для торговых центров и складов.
Как работает UWB и что это означает для разработчика
UWB использует импульсы шириной ~500 МГц в диапазоне 6-8.5 ГГц. Время прохождения сигнала между двумя устройствами измеряется с точностью до наносекунд (TWR — Two-Way Ranging, или TDoA — Time Difference of Arrival). Из времени вычисляется расстояние: 1 нс = ~30 см.
Для сценария indoor positioning нужны якоря (anchors) — UWB-маяки с известными координатами — и мобильное устройство (tag). По измеренным расстояниям до минимум 3 якорей вычисляется позиция методом трилатерации.
Поддерживаемые устройства
iOS: Apple NearbyInteraction framework. Устройства с чипом U1/U2: iPhone 11–15, iPhone SE 3rd gen, AirTag, HomePod mini 2, Apple Watch Ultra. NISession — основной класс. Одна сессия = одна пара устройств. Для позиционирования относительно нескольких якорей — несколько параллельных NISession.
Android: UwbManager из Jetpack Core UWB (androidx.core:core-uwb). Поддерживаемые устройства: Samsung Galaxy (S21 Ultra+, S22+, S23, S24, Z Fold3+), Pixel 6 Pro+, некоторые Xiaomi. Проверка поддержки: UwbManager.isAvailable().
UWB-якоря (hardware): Для инфраструктурного позиционирования нужны сторонние якоря: Qorvo DWM3000EVB, Decawave DWM1001, Sewio RTLS, Pozyx. Они общаются по IEEE 802.15.4z и имеют SDK для конфигурации.
Сравнение платформ iOS и Android
| Параметр |
iOS (NearbyInteraction) |
Android (UwbManager) |
| Фреймворк |
NISession |
UwbManager |
| Обмен токенами |
NIDiscoveryToken |
Конфигурация через Controlee |
| Поддержка якорей |
Только Qorvo MFi |
Любые IEEE 802.15.4z |
| Фоновый режим |
Не поддерживается |
Не поддерживается |
Ограничения платформы
Apple Nearby Interaction — только peer-to-peer между двумя Apple-устройствами или с MFi-сертифицированными аксессуарами. Для инфраструктурного indoor positioning (якоря → телефон) напрямую через NISession работает только с Qorvo-совместимыми якорями через специальный NIConfiguration.
NISession требует обмена NIDiscoveryToken между устройствами заранее — обычно через Multipeer Connectivity, Bluetooth или сервер. После обмена токенами NISession.run(configuration:) начинает измерения.
Как интегрировать UWB в мобильное приложение?
Практический кейс: навигация в торговом центре (из нашей практики)
Сценарий: покупатель ищет конкретный магазин. GPS недоступен. BLE-навигация недостаточно точна для коридоров шириной 3 метра. UWB-якоря установлены на потолке каждые 10-15 метров.
Якоря Pozyx Creator (UWB, PoE, самостоятельная локализация) → центральный сервер Pozyx собирает данные позиционирования → REST API отдаёт координаты tag-устройства в системе координат здания.
Мобильное приложение: при входе в здание устройство «подключается» к системе (через BLE handshake для идентификации), далее каждые 100-200 мс получает обновление координат через WebSocket (x, y, floor).
Координаты накладываются на план здания (SVG-схема этажей). Плавное движение маркера: Kalman-фильтр для сглаживания шумных UWB-измерений. Без фильтра маркер «прыгает». Kalman-фильтр на мобиле — 20-30 строк кода, но ощутимо улучшает UX.
Навигация к точке: A* pathfinding по графу проходов (граф строится из SVG-схемы, запрещённые зоны — стены и витрины). При отклонении от маршрута на > 1м — пересчёт.
Интеграция с Apple NearbyInteraction
Для устройство-к-устройству сценариев (курьер → клиент, кладовщик → конкретный поддон):
import NearbyInteraction
class UWBSession: NSObject, NISessionDelegate {
let session = NISession()
func startSession(with peerToken: NIDiscoveryToken) {
session.delegate = self
let config = NINearbyPeerConfiguration(peerToken: peerToken)
config.isCameraAssistanceEnabled = true // iOS 16+: AR overlay
session.run(config)
}
func session(_ session: NISession, didUpdate nearbyObjects: [NINearbyObject]) {
guard let peer = nearbyObjects.first else { return }
if let distance = peer.distance {
print("Distance: \(distance) m")
}
if let direction = peer.direction {
// SIMD3<Float> - направление в 3D
print("Direction: \(direction)")
}
}
}
isCameraAssistanceEnabled включает Precision Finding — AR-стрелка поверх камеры показывает направление к объекту (как в AirTag Precision Finding). Требует ARKit и NSCameraUsageDescription.
Обмен токенами
NIDiscoveryToken нельзя создать программно — только получить из session.discoveryToken. Чтобы начать UWB-сессию, оба устройства должны обменяться токенами заранее. Типичная схема: оба устройства публикуют токен через Bluetooth Peripheral → сканируют друг друга → получают токены → стартуют NISession.
В CloudKit или через сервер — для сценариев где устройства не рядом физически при инициализации.
Типичные проблемы интеграции
- Multipath interference. UWB-сигнал отражается от металлических поверхностей (стеллажи, оборудование) — ложные измерения расстояния. Решение: NLOS (Non-Line-of-Sight) detection через анализ First Path Power vs Total Received Power. Pozyx и Decawave возвращают эти метрики в сыром пакете.
- NISession suspended. iOS приостанавливает UWB-сессию при уходе приложения в фон.
sessionWasSuspended(_ session:) — сохраняем последнее положение, при sessionSuspensionEnded — рестартуем. В фоне UWB не работает — ограничение платформы.
- Калибровка якорей. Координаты якорей в пространстве нужно измерить точно — ошибка в 5 см смещает все расчёты. Self-localization якорей (Pozyx, Sewio) автоматически определяют свои координаты при первом запуске через UWB TWR между собой.
- Точность в динамике. При быстром движении (> 2 м/с) TDoA-системы дают больше ошибок чем TWR. Для пешеходов TWR с обновлением 10 Гц достаточен.
Что входит в работу?
- Аудит инфраструктуры и сценариев использования
- Выбор UWB-платформы и оборудования
- Интеграция SDK (iOS NearbyInteraction, Android UwbManager, якори)
- Разработка Kalman-фильтра и навигационного графа
- Нагрузочное тестирование (до 100+ устройств)
- Документация, поддержка и обучение команды
Процесс проекта
- Аудит сценария использования и оборудования
- Выбор UWB-платформы (Apple NI / Qorvo / Pozyx)
- Пилот на тестовой зоне с измерением точности
- Интеграция с мобильным приложением
- Kalman-фильтрация и навигационный граф
- Нагрузочное тестирование (100+ одновременных устройств)
- Развёртывание якорей и ввод в эксплуатацию
Сроки
Пилот с Apple NearbyInteraction на двух устройствах — 1-2 недели. Полноценная indoor-навигация с инфраструктурными якорями, Kalman-фильтром и картой здания — 2-4 месяца в зависимости от масштаба объекта. Стоимость рассчитывается после оценки инфраструктуры и целевых сценариев.
Свяжитесь с нами для консультации по вашему проекту. Закажите интеграцию UWB под ключ — получите точное позиционирование в помещении.
Карты и геолокация в мобильных приложениях: Google Maps, MapKit, геофенсинг, трекинг
Мы интегрируем геолокацию и картографические сервисы в мобильные приложения — это не просто «добавить карту». Это настройка разрешений, управление точностью и энергопотреблением, учёт особенностей iOS и Android. Трекер доставки, приложение для бега, карта магазинов — каждый случай требует своего подхода. Оценим ваш проект за 2 часа — напишите нам.
Разрешения: один из самых частых источников плохих отзывов
На iOS разрешение на геолокацию — самое чувствительное после микрофона и камеры. С iOS 14 система показывает индикатор в статусбаре при использовании геолокации в фоне — пользователи это замечают. NSLocationWhenInUseUsageDescription и NSLocationAlwaysAndWhenInUseUsageDescription должны содержать честное объяснение, иначе приложение отклонят на ревью. Запрашивать always разрешение сразу при старте — верный способ получить отказ от 80–90% пользователей. Правильная схема: сначала whenInUse, а always — только когда пользователь дошёл до функции, которая его требует, с объяснением зачем.
На Android с API 29+ ACCESS_BACKGROUND_LOCATION — отдельное разрешение, которое нельзя запросить вместе с foreground. Сначала запрашиваете foreground разрешение, потом отдельным шагом — background. Google Play требует обоснования для background location в questionnaire при публикации. Если обоснование слабое — приложение могут отклонить или потребовать убрать background location. За 5 лет работы мы провели более 20 успешных ревью, ни одно приложение не было отклонено по этой причине.
Точность и энергопотребление: как не разряжать аккумулятор
Постоянный GPS на максимальной точности потребляет 100–150 мВт — аккумулятор садится за 4–6 часов. Для большинства задач это избыточно.
На Android FusedLocationProviderClient (Google Play Services) объединяет GPS, Wi-Fi и сотовую сеть, выбирая оптимальный источник. LocationRequest.Builder с приоритетами:
-
PRIORITY_HIGH_ACCURACY — GPS включён, для навигации
-
PRIORITY_BALANCED_POWER_ACCURACY — точность ~100 метров, Wi-Fi + сотовая
-
PRIORITY_LOW_POWER — точность ~10 км, только сотовая
-
PRIORITY_PASSIVE — координаты от других приложений, без активного запроса
Для трекера пробежки в активном режиме — HIGH_ACCURACY с интервалом 2–5 секунд. Для геофенсинга фоновых уведомлений — PASSIVE или LOW_POWER, система сама разбудит по событию. Википедия: GPS — авторитетный источник по точности.
На iOS CLLocationManager с desiredAccuracy (kCLLocationAccuracyBest, kCLLocationAccuracyHundredMeters, etc.) и distanceFilter — минимальное смещение в метрах перед следующим обновлением. Для трекинга маршрута с сохранением батареи: desiredAccuracy = kCLLocationAccuracyNearestTenMeters, distanceFilter = 10 — получаем обновления только при реальном движении.
Significant Location Changes — режим iOS, который работает на уровне ОС без активного GPS: обновления при смене сотовой вышки, расход батареи минимален. Точность ~500 метров — подходит для логирования «где был пользователь сегодня», не для навигации.
Как выбрать картографический SDK? Сравнительный анализ
| SDK |
Платформа |
Офлайн-карты |
Кастомный стиль |
Без Google Services |
| Google Maps SDK |
iOS/Android |
Нет (только Maps API) |
Да (Cloud-based) |
Нет |
| MapKit |
iOS |
Нет |
Ограниченно |
Да |
| Mapbox Maps |
iOS/Android |
Да |
Полностью |
Да |
| HERE Maps |
iOS/Android |
Да |
Да |
Да |
| OpenStreetMap + MapLibre |
iOS/Android/Flutter |
Да |
Полностью |
Да |
Google Maps SDK — выбор по умолчанию для большинства проектов: знакомый UI, хорошая документация, Directions API, Places Autocomplete. Ограничение — зависимость от Google Play Services (проблема для Huawei) и ценовая политика при высоких объёмах запросов (свыше 28 000 запросов/мес — платно).
Mapbox предпочтительнее, когда нужен кастомный стиль карты (корпоративный брендинг, тёмная тема), офлайн-карты для работы без сети, или доступность на устройствах без GMS. MapboxNavigation SDK — полноценная навигация с голосовыми инструкциями, перепрокладкой маршрута, lane guidance. Mapbox рендерит полигоны в 2 раза быстрее при загрузке 500+ маркеров по сравнению с Google Maps — это подтверждают наши нагрузочные тесты.
Для Flutter — google_maps_flutter (официальный), flutter_map (OpenStreetMap + MapLibre, полностью open-source), mapbox_maps_flutter (после выхода официального SDK).
Пример выбора: приложение с офлайн-картами и геозонами на 100+ точек
Клиент — сеть розничных магазинов. Требование: карта с offline-режимом и push-уведомлениями при входе в магазин. Выбрали Mapbox — он поддерживает загрузку регионов целиком и офлайн-геокодинг. Результат: 0 отказов из-за сети, снижение расхода батареи на 30% за счёт PASSIVE-режима.
Почему геофенсинг срабатывает с задержкой?
Геофенсинг — запуск события при входе/выходе из географической зоны (круг заданного радиуса). На практике задержка может составлять 1–3 минуты — это плата за энергоэффективность.
На Android — GeofencingClient из Google Location Services. Добавляем Geofence объекты с setTransitionTypes(GEOFENCE_TRANSITION_ENTER | GEOFENCE_TRANSITION_EXIT) и PendingIntent на BroadcastReceiver. Ограничение: максимум 100 активных геофенсов на приложение, минимальный радиус ~150 метров (на практике из-за точности), срабатывание с задержкой до нескольких минут в целях экономии батареи.
На iOS — CLCircularRegion + CLLocationManager.startMonitoring(for:). Лимит: 20 регионов на приложение. ОС управляет когда проверять — разработчик не контролирует задержку. Для более точного геофенсинга с маленьким радиусом — iBeacon (CLBeaconRegion) или CLVisit для мест, где пользователь провёл время.
Если нужно больше 20 (iOS) или 100 (Android) зон — нужна серверная логика: периодически отправляем координаты на сервер, сервер проверяет попадание в зоны и отправляет push. Менее точно по времени, но масштабируется на тысячи зон. Википедия: Геозона — подробнее о принципах работы.
Трекинг маршрутов и фоновая геолокация
Трекинг маршрута пробежки или маршрута курьера в фоне — технически разные задачи.
На iOS фоновая геолокация работает через UIBackgroundModes: location в Info.plist. Без этого ключа при уходе приложения в фон CLLocationManager получает несколько минут и засыпает. С ключом — работает постоянно, но система может приостановить при критически низком заряде.
Для трекера пробежки на iOS паттерн: startUpdatingLocation при старте тренировки, координаты пишем в Core Data каждые 5 секунд, на паузе — stopUpdatingLocation, но оставляем startMonitoringSignificantLocationChanges чтобы приложение не «потерялось» совсем.
На Android для курьерского трекинга нужен Foreground Service с FOREGROUND_SERVICE_TYPE_LOCATION (обязательно с API 29). Foreground service показывает постоянное уведомление — это требование платформы, не баг. Без него Android Doze убьёт обновления геолокации. WorkManager для фоновых задач здесь не подходит — он не гарантирует непрерывность.
Алгоритмическая часть трекинга маршрута: сырые GPS-координаты зашумлены. Для сглаживания — алгоритм Ramer-Douglas-Peucker для упрощения трека или Kalman Filter для фильтрации шума в реальном времени. Без фильтрации трек выглядит как случайные зигзаги, а расчётное расстояние на 20–30% больше реального.
Как мы внедряем карты и геолокацию: пошаговый процесс
-
Анализ сценариев — определяем, нужен ли foreground/background, точность, количество геозон, необходимость офлайн-режима.
-
Выбор SDK и архитектуры — сравниваем Google Maps, Mapbox, HERE, MapKit по критериям проекта (наше сравнение выше — используйте как базу).
-
Интеграция и настройка разрешений — прописываем
Info.plist / AndroidManifest.xml, тестируем ревью-чеки (App Store Review Guidelines Section 4.2/5.1, Google Play policy).
-
Реализация трекинга/геозон — добавляем
CLLocationManager / GeofencingClient, настраиваем фильтры и энергосбережение.
-
Юнит- и интеграционное тестирование — на реальных устройствах (эмулятор не симулирует задержки и поведение Doze/App Nap). Проверяем не менее 50 сценариев.
-
Нагрузочное тестирование — симулируем 500+ маркеров, движущиеся объекты, проверяем FPS и расход батареи.
-
Деплой и мониторинг — выкладываем через TestFlight / Firebase App Distribution, собираем логи crashlytics, отслеживаем количество отказов разрешений.
Сроки и что входит в работу
| Этап |
Срок |
Состав deliverables |
| Базовая интеграция карты с маркерами и поиском |
1–2 недели |
Исходный код (Swift/Kotlin/Dart), документация API, инструкция по сборке |
| Геофенсинг с push-уведомлениями |
2–3 недели |
Код геозон, настройка FCM/APNs, тестовые зоны, отчёт по задержкам |
| Полноценный трекинг маршрутов (фон, сглаживание, серверная синхр.) |
4–6 недель |
Код с Kalman фильтром, серверная часть (опционально), мониторинг батареи |
Что вы получите в любом случае:
- Исходный код с комментариями (Swift, Kotlin, Dart, TypeScript)
- Интеграцию с вашим бэкендом (REST/GraphQL/WebSocket)
- Поддержку 1 месяц после сдачи (исправление багов, помощь с ревью сторов)
- Инструкцию по публикации в App Store и Google Play (включая обоснование для background location)
- Сертификаты code signing, provisioning profiles, ключи Google Maps/Mapbox
Наши компетенции: 10+ лет опыта в мобильной разработке, 50+ проектов с геолокацией, сертифицированные разработчики Apple и Google (Google Associate Android Developer). Каждое приложение проходит тройной код-ревью и нагрузочное тестирование.
Закажите внедрение карт и геолокации под ключ — свяжитесь с нами, чтобы получить консультацию и предварительную оценку вашего проекта в течение 2 часов.