(картинка с сайта developer.apple.com)
Что это такое?
В середине 2013 года Apple на конференции для разработчиков внезапно рассказала, что они приготовили новую технологию, предназначенную для навигации внутри помещений, что они начали создавать карты музеев, торговых центров и других интересных мест и вообще, всё круто. Поверив на слово крупной компании, многие стали предлагать «решения» по навигации внутри помещений, но мало у кого получилось что-то работоспособное. Оказалось, что в реальности применять эту технологию достаточно непросто.
Я также принял активное участие в исследовании технологии. Удалось развернуть сеть биконов на мероприятиях GeekPicnic в Москве и в Санкт-Петербурге, протестировав возможности технологии. После чего я написал библиотеку, которая, используя небольшое количество маяков, достаточно хорошо позволяет определять местоположение внутри помещений.
В статье я коротко опишу, что такое iBeacon, какие задачи мне пришлось с этой технологией решать, что удалось, что не очень.
Что же такое iBeacon? Это протокол-подмножество Bluetooth Low Energy, который позволяет узнать:
- UUID, Major, Minor для маячка
- силу сигнала от маячка
Выглядит это так:
fb0b57a2-8228-44 cd-913a-94a122ba1206 Major 1 Minor 2
Использовать iBeacon'ы можно на Айфонах, начиная с 4S, Айпадах, начиная с третьего поколения, iPad Mini, iPod Touch (с пятого поколения), поддержку Андроидов нужно искать в конкретных устройствах, а версия ОС должна быть 4.3 или выше. Также можно использовать компьютеры Macintosh.
Опыт реального использования
Когда мы рассматривали возможные использования технологии, получалось очень красиво:
- навигация,
- отслеживание перемещений (товаров, сотрудников),
- контрольно-пропускные действия,
- реклама.
На практике оказалось, что всё не так просто.
Главное разочарование в том, что навигация получается крайне неточная. В следующем разделе я покажу, как можно сделать адекватную навигацию на биконах, но вообще биконы плохо предназначены для навигации.
Вообще, основной алгоритм работы с биконами — когда пользовательское устройство приближается к нему, появляется нотификация. Тут же хочется ловить все биконы подряд. Но, к сожалению, чтобы нотификацию обработать, нужно написать соответствующее приложение и занести в него параметры конкретного бикона (или конкретного типа биконов, для этого обычно используется UUID, которые у всех нужных биконов одинаковый). То есть нельзя просто так взять и повесить, например, рекламный бикон, чтобы он висел и пиликал всем проходящим. Нужно заставить поставить приложение, которое слушает только те биконы, на которые настроено (настроить на все-все-все тоже нельзя, так как startMonitoringForRegion не даст добавить бесконечное количество регионов):
NSString *uuid = @"B9407F30-F5F8-466E-AFF9-25556B57FE6D";
CLBeaconRegion *region = [[CLBeaconRegion alloc]
initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:uuid]
identifier:[NSString stringWithFormat:@"beacon_%@", uuid]];
region.notifyEntryStateOnDisplay = YES;
_locationManager startMonitoringForRegion:region];
[_locationManager startRangingBeaconsInRegion:region];
Пиликать также непросто. Скорость реакции устройства (смартфона) — от секунды до пары минут. То есть, пользователь может пройти мимо бикона, походить еще пару минут, только после этого появится уведомление.
Сами биконы — ломаются. Если закупать их много (и это более-менее необходимость для почти всех вариантов использования), то приходится экономить, следовательно, биконы выходят из строя и их нужно заменять. Нет ничего проще, но после замены нужно перепроставлять соответствие конкретному бикону данных (рекламного текста, или координат). Как следствие, в разработке нельзя обойтись только приложением и биконами. Приходится создавать сервер, который должен хранить соответствие информации биконам, а приложению требуется регулярно обновлять данные.
Возвращаясь к реальному использованию. В 2015 году проходило два мероприятия GeekPicnic, в Москве и Санкт-Петербурге. Это мероприятия на открытом воздухе, на которых собирается много различных докладчиков, интересных артефактов, машин, арт-объектов. За два дня мероприятие посещают 25000 человек.
На каждом мероприятии (которое проходит под открытым небом и в нескольких павильонах) десятки интересных объектов. Искать на карте их не очень удобно, поэтому решено было использовать биконы для их обозначения и уведомлений, когда пользователь к ним подходит. Я писал приложение для Айфона, коллеги потом повторяли его для Андроида.
Сама схема работы получилась примерно следующая:
- по всему мероприятию развешаны биконы
- мобильное приложение выступает сканером, уведомляющим посетителя о том, что он подошел к интересному месту
- данные о связи биконов и текстов интересных мест хранятся на сервере и обновляются в мобильном приложении, когда могут (посетителей очень много и связь с сервером непосредственно на мероприятии не очень)
Чтобы избежать «дребезга» и большого количества нотификаций, сохранялись данные по всем биконам вокруг и находился ближайший, причём он должен быть «существенно ближайшим», пока несколько биконов находятся примерно на одинаковом расстоянии, нотификации не проходит.
Также пришлось решить проблему энергопотребления. Чтобы навигация не включалась сразу после установки приложения, во-первых, сканирование биконов включалось только в определенные дни, а во-вторых, только в определенной области (в радиусе нескольких километров от места проведения мероприятия). Забавно было тестировать оба этих условия, пришлось покататься на машине с включенной отладкой, следя за активностью смартфона (причём, в разных состояниях, активном, режиме сна).
В результате всё получилось, а я с коллегами получил бесценный опыт реализации крупного проекта, использующего биконы.
Навигация внутри помещений
Перейдём к технике. Когда говорят про навигацию, обычно подразумевают нахождение местоположения по расстоянию до нескольких точек (так работает GPS, триангуляция местоположения по вышкам сотовой связи и это именно то, про что обычно говорят в фильмах). Алгоритм работы простой:
- мы знаем, где находятся несколько опорных маяков. Спутники это, вышки или биконы — не важно. Главное, точки должны быть определены, и достаточно точно.
- каким-то образом мы определяем расстояние до минимум трёх точек. В реальном мире трёх недостаточно, стараются использовать больше. От точности этих расстояний также зависит точность вычислений.
- по этим расстояниям вычисляется местоположение приёмника (пользователя).
Каждый, кто пробовал это проделать с биконами, быстро понимал бесполезность идеи. Местоположение биконов можно замерить точно, а вот расстояние до них измеряется по мощности сигнала маяка. Эта мощность очень зависит от давления воздуха, влажности, наличия различных препятствий (включая людей и другую живность). Очень — это значит, в несколько раз. Конечно же, софт пытается это сгладить, применяя фильтры и разные алгоритмы, но это не важно. Алгоритм в таких условиях, фактически, не работает (выдаёт крайне неточные результаты).
Подумав немного, я вспомнил, что есть другой вариант. В отличие от «обычного» алгоритма, он не выдаёт точное местоположение пользователя, а, скорее, показывает, в какой области он находится. Но для местоположения внутри помещений часто этого достаточно.
Алгоритм называется fingerprinting, отпечаток местоположения. В общем случае он выглядит так:
- расставляем биконы как-то «адекватно»,
- бегаем по помещению, запоминая, как выглядит картинка по биконам (какие сильнее, какие слабее), снимая «отпечатки» картины биконов в разных местах.
- после того, как сняты отпечатки, пользователь перемещается и смартфон сравнивает текущий отпечаток с теми, что в его памяти. Подобрав ближайший похожий, мы понимаем, в какой области находится пользователь.
Для того, чтобы алгоритм успешно работал, пришлось повозиться. Но в результате получилось очень неплохо.
Непонятный момент был, как именно сохранять отпечатки. Мощности напрямую нельзя (они плавают очень сильно). Попробовал относительные мощности, получилось сильно лучше.
Плавание мощностей заметно даже, если просто крутиться на одном месте. Стоим, поворачиваемся, и картинка меняется кардинально. Поэтому я стал снимать несколько отпечатков, стоя на одном месте. Сами отпечатки получились такие:
@property (nonatomic) NSString *uuid;
@property (nonatomic) CLBeaconMajorValue major;
@property (nonatomic) CLBeaconMajorValue minor;
@property (nonatomic) CGFloat relativeDistance; // 0-1 (normalized by the powerful)
@property (nonatomic) CGFloat relativePowerDispersion; // 0-1 (normalized by the most powerful)
Я брал эти параметры для каждого видимого бикона в данной точке, и все параметры для всех биконов — и стали отпечатком.
Также хотелось, конечно же, чтобы точка на карте не просто прыгала, а перемещалась по карте. Для этого пришлось интерполировать отпечаток, понимая, между какими областями/точками находится пользователь, и, конечно же, сильно получившийся результат фильтровать. Расстояние между текущим отпечатком и отпечатками регионов вычислялось примерно так:
for (Fingerprint *f in in _regions[regionName].fingerprints) {
CGFloat newDistance = [f normalizedDistanceToFingerprint:aBeaconsFingerprint];
CGFloat distance = (CGFloat) (result[regionName] == nil ?
FLT_MAX :
[result[regionName] doubleValue]);
distance = MIN(newDistance, distance);
result[regionName] = @(distance);
}
А, собственно, само расстояние между отпечатками, так:
- (CGFloat)normalizedDistanceToFingerprint:(NSMutableDictionary *)aBeaconsFingerprint {
// if we do not have a beacon in region fingerprint — add DISTANCE_PENALTY_FOR_ABSENT_BEACON
// if we do not have any beacons, result is "FLT_MAX"
CGFloat result = 0;
BOOL resultIsNotInfinite = NO;
NSArray *regionBeaconIds = [_beaconsFingerprint allKeys];
NSArray *testingBeaconIds = [aBeaconsFingerprint allKeys];
for (NSString *beaconId in regionBeaconIds) {
if (![testingBeaconIds containsObject:beaconId]) {
result += DISTANCE_PENALTY_FOR_ABSENT_BEACON;
} else {
result += fabs(
fabs(((Fingerprint *) _beaconsFingerprint[beaconId]).relativeDistance) -
fabs([aBeaconsFingerprint[beaconId] doubleValue]));
resultIsNotInfinite = YES;
}
}
for (NSString *testingBeaconId in testingBeaconIds) {
if (![regionBeaconIds containsObject:testingBeaconId]) {
result += DISTANCE_PENALTY_FOR_ABSENT_BEACON;
}
}
return resultIsNotInfinite ? result : FLT_MAX;
}
Получилось очень хорошо. Настоящее решение потребует продумать систему замены вышедшего из строя бикона (переснимать все отпечатки — плохое решение, это может занять много времени). А при наличии достаточного количества грамотно расставленных биконов (лучше всего их развешивать ближе к потолку, например, но это не единственная рекомендация) — и точность получается хорошая (±несколько метров).
Выводы
Сейчас шум вокруг технологии iBeacon поутих. Но задачи никуда не делись. По-прежнему требуется навигация внутри помещений. По-прежнему нужна возможность сообщить посетителям магазина о новых товарах. И делать это сейчас можно не только рекламными банерами, но и вот такими маячками.
Конечно же, реальное их использование не столь прямолинейно, и требуется решать множество задач, чтобы всё заработало, как нужно. Главный вывод более, чем года работы с технологией — она, с определёнными оговорками, жизнеспособна. А дальше уже нужно смотреть, подходит ли она для конкретного применения или нет. Увы, серебряной пули пока не получилось.
Комментарии (32)
deniskreshikhin
07.03.2016 18:59после того, как сняты отпечатки, пользователь перемещается и смартфон сравнивает текущий отпечаток с теми, что в его памяти. Подобрав ближайший похожий, мы понимаем, в какой области находится пользователь.
Для того, чтобы алгоритм успешно работал, пришлось повозиться. Но в результате получилось очень неплохо
По-моему это как раз идеальная задача для нейронной сети.bealex
07.03.2016 19:02Вполне может быть. Впрочем, нейронная сеть нужна там, где нет других, более прямых, алгоритмов. Тут они, как показал прототип, есть.
Но не исключаю, что нейронной сетью получится удобнее.deniskreshikhin
07.03.2016 19:10Ваш алгоритм кстати, тоже из смежной области. По сути это k-NN regression:
In k-NN regression, the k-NN algorithm is used for estimating continuous variables. One such algorithm uses a weighted average of the k nearest neighbors, weighted by the inverse of their distance. This algorithm works as follows:
— Compute the Euclidean or Mahalanobis distance from the query example to the labeled examples.
— Order the labeled examples by increasing distance.
— Find a heuristically optimal number k of nearest neighbors, based on RMSE. This is done using cross validation.
— Calculate an inverse distance weighted average with the k-nearest multivariate neighbors.
Mort
08.03.2016 23:46На самом деле да. Вот статья в которой описан подобный подход для навигации — https://www.dropbox.com/s/003tjf6uc42cis5/nav.pdf?dl=0
Там, правда, в качестве источника информации используются Wi-Fi точки, но маячки точно также в него вписываются.bealex
09.03.2016 00:30Нужно пробовать. Статья статьей, а в реальной жизни там все ох как плавает.
Но я верю, что это может сработать, направление крайне перспективное.
Stas911
07.03.2016 19:18Прошу прощения за нубский вопрос: а маяки что-то могут узнать про устройство или это строго в одну сторону работает?
bealex
07.03.2016 19:28В простейшем случае — только в одну. Но, в теории, если в качестве маяков умные железки, то они тоже могут что-то получить. Я таких в руках не держал, точно не скажу. 99% того, что на рынке — такого точно не умеет.
zviad
08.03.2016 00:17Из моего опыта, сами маячки ничего знать не могут, потому что они умеют только транслировать сообщения. Всё.
Данная технология, в принципе не предполагает отпарвку маячку чего либо, потому что маячок автономен и не связан с сетью.bealex
08.03.2016 00:24Это, в конце-концов, bluetooth-устройство. Думаю, можно придумать что-нибудь, чтобы поиметь информацию об окружающем мире.
zviad
08.03.2016 00:45Об окружающем мире и маячке пожалуйста. Вы и сейчас можете узнать температуру маячка, каккую то статистику, типа времени работы, количество отправленных сообщений, у некторых даже есть акселерометры и прочее. Но это его датчики.
А вот о пользователях сейчас ни один маячок не знает, это просто не нужно.
deniskreshikhin
07.03.2016 19:35+1Обычно Bluetooth LE маячок это устройство которое только посылает сигнал, т.е. работает в периферийном режиме, за счет этого тратится очень мало энергии и маячок может проработать на одной батарейке 1-2 года.
Что бы принимать сигнал, требуется больше энергозатрат, т.к. сигнал нужно непрерывно отслеживать, демодулировать и обрабатывать. Поэтому делать такие маячки не очень практично.
Однако, теоретически устройство может одновременно работать как в периферийном, так и в центральном режиме. В частности, iPhone можно перевести в любой режим работы. И допустим, если у вас где-то лежит такое устройство работающее в центральном режиме, а у пользователя установлено какое-то приложение iPhone которое переводит его в режим маячка, то вы можете отслеживать приближение или удаление пользователя.
Соответсвенно вместо iPhone может быть iPod, современный Mac, или даже Android 5/6 версии с чипом поддерживающим Bluetooth LE 4.2
alekseev_ap
07.03.2016 22:28А какие конкретно маячки использовали и какова их приблизительная стоимость?
bealex
07.03.2016 22:54Я пробовал несколько разных вариантов. Страндартные — Estimote, Kontakt. Эти две компании выпускают хорошие, умные маячки, которые долго живут и на которых хорошо тестить приложения.
Для реального использования они очень дорогие, поэтому мы просто искали предложения на рынке и покупали пробные партии, если устраивало качество — брали больше, нет — смотрели следующих. Китайцев, российских сборщиков — просто кого смогли найти.
Конкретную компанию, на которой остановились — не скажу, не я этим занимался, мне просто привезли две коробки биконов, чтобы я их сконфигурировал.ZolDoR
08.03.2016 20:08Здравствуйте. Мы планируем использовать Estimote Indoor SDK. Если вам пришлось с ним иметь дело — какое ваше мнение о точности данного решения?
bealex
08.03.2016 20:34Если я правильно понимаю, они работаю примерно также, как я описал во второй части статьи. Сами биконы у них хорошие, мощные, хоть и дорогие.
Точность будет зависеть от расстановки биконов, времени их эксплуатации, скорости передвижения. В моих опытах она была ±пара метров (чего достаточно в длинных коридорах или среднего/большого размера помещениях).
Думаю, что можно рассчитывать на точность от 3–4 до 1–2 метров, в зависимости от конфигурации.
bealex
07.03.2016 22:56Про стоимость. Маяки «для разработки» могут стоить по $10–$30 за штуку. Для реального использования нам удалось найти что-то в пределах $5–$10.
Но мы брали малыми партиями (50–100 штук), если покупать их десятками тысяч, уверен, что можно найти за несколько долларов за штуку.
Совсем дешево не получится, увы, они совсем не бесплатные. И чем качественнее нужны — тем дороже.
zviad
08.03.2016 00:42Спасибо за статью и проделанную работу!
Тут же хочется ловить все биконы подряд. Но, к сожалению, чтобы нотификацию обработать, нужно написать соответствующее приложение и занести в него параметры конкретного бикона (или конкретного типа биконов, для этого обычно используется UUID, которые у всех нужных биконов одинаковый). То есть нельзя просто так взять и повесить, например, рекламный бикон, чтобы он висел и пиликал всем проходящим. Нужно заставить поставить приложение, которое слушает только те биконы, на которые настроено (настроить на все-все-все тоже нельзя, так как startMonitoringForRegion не даст добавить бесконечное количество регионов)
По-прежнему нужна возможность сообщить посетителям магазина о новых товарах. И делать это сейчас можно не только рекламными банерами, но и вот такими маячками.
Это один из основных недостатков технологии iBeacon. Вам нужно заставить пользователя устанвоить приложение.
В случае если нет приложения для всего торгового центра, пользователю предлагается ставить приложения для магазинов, 5, 10, а то и 50. Никто не поставит 50 приложений.
Даже если есть приложение охватывающее весь торговый центр, что тогда? Ставить приложение для каждого торгового центра?
Кстати из-за органичений, не факт что получится в одном приложении охватить огромные торговые центры, но кмк, и так понятно что это безсмысленно.
Для устранения этих недостатков и были придуманы Eddystone маячки и концепция Physical Web, о чём я недавно писал в своей статье на хабре:
Physical web. Bluetooth маячки. Eddystone. Google's beacon platform
Вам бы не пришлось писать приложения для каждой платформы, а пользователям не пришлось бы их устанавливать.
Чтобы избежать «дребезга» и большого количества нотификаций
Пиликать и пушить сообщения, уведомления вообще зло и не уважение к пользователям. Только взаимодействие по требованию. Опять же, посоветую ознакомиться со статьей и концепцией Physical Web.
Сами биконы — ломаются. Если закупать их много (и это более-менее необходимость для почти всех вариантов использования), то приходится экономить, следовательно, биконы выходят из строя и их нужно заменять. Нет ничего проще, но после замены нужно перепроставлять соответствие конкретному бикону данных (рекламного текста, или координат). Как следствие, в разработке нельзя обойтись только приложением и биконами. Приходится создавать сервер, который должен хранить соответствие информации биконам, а приложению требуется регулярно обновлять данные.
Это тоже большая проблема, когда вам реально нужно развернуть и мониторить большое количество маячков. Но и для таких случаев уже есть разные решения. Одно из них Google's beacon platform, о нём я подробно писал недавно на хабре.
P.S. слово "биконы" как то режет слух, это же маячки, как по смыслу, так и при переводе.zviad
08.03.2016 00:49+2Главное разочарование в том, что навигация получается крайне неточная
И для этой проблемы уже есть решения. Об этом я расскажу в своей следующей статье.bealex
08.03.2016 01:07Я показал, как этого можно добиться, используя эту технологию. :-) Впрочем, я с удовольствием попробую другие технологии навигации внутри помещений. Разобрав iBeacon по кусочкам, хочется перейти к более совершенным вариантам.
Так что с нетерпением жду статьи.
bealex
08.03.2016 01:04+1Eddystone — отличное развитие этой идеи. Как раз развлекаюсь с ними, но хочется попробовать их в больших проектах, как и биконы.
P. S. Я использую термин биконы, а не «маячки», как это не произвольные маяки, а элементы технологии iBeacon, не более того. :-) Да и среди тех, кто использует технологию, термин вполне устоялся.
mike114
08.03.2016 11:18+1Я немного не понял (даже после прочтения вашей статьи) как Eddystone устраняет все недостатки. Если он настроен на передачу URI, то решается проблема множества приложений, так как их заменяет браузер. Если же он настроен как часть Google's beacon platform, то какая разница как он себя представляет (Eddystone, iBeacon, etc), если необходимо отдельное приложение, которое будет соединяться с облаком и вытягивать метаданные по идентификатору маячка? Кроме того, насколько я понимаю, база маячков будет создаваться опять же под конкретное приложение, соответственно, если у каждого торгового центра свое приложение, то придется ставить их все.
zviad
08.03.2016 16:14Так в большинстве случаев, даже когда маячков много, достаточно транслировать URL, ведь он не меняется, а контент или приложение вы можете менять свободно. Это случай подходит и для торгового центра, вы единожды присваиваете им URL и расставляете маячки, всё. Для таких случаев есть промышленные маячки, которые питаются от сети.
В случае с Google's beacon platform, да, нужно приложение. Но в этом случае вы не просто транслируете ID, запись в beacon registry может содержать информацию о статусе, предполагаемой стабильности, широте и долготе, уровне внутри здания, Google Places API Place ID, текстовое описание и т.д. Эти записи, например, помогают решать часть проблем связанных с навигацией. Google's beacon platform полностью решает проблемы мониторинга маячков.
Опять же, в виде вложений можно передавать ссылки на внешние приложения и контент, который вы можете изменять по необходимости.
Google's beacon platform хорошо подходит для случаев когда у вас уже есть популярное приложение и вы хотите расширить его функционал, добавить в него возможность взаимодействовать с маячками. Когда вам нужна не публичная реализация для внутреннего использования. Или когда маячков действительно много(тысячи) и разбросаны они на огромной площади, например целые районы или города.
Кстати, интересно, сколько именно маячков было задействовано в данном случае? Надеюсь автор ответит.bealex
08.03.2016 16:31Кстати, интересно, сколько именно маячков было задействовано в данном случае? Надеюсь автор ответит.
До сотни на мероприятие.
zviad
08.03.2016 02:24-2Eddystone — отличный стандарт, но для больших проектов в любом случае нужны решения на подобие Google's beacon platform.
Т.е. "биконы" это только iBeacon'ы? Почему именно элементы технологии iBeacon? Есть ведь еще AltBeacon, PayPal beacon, Estimote Stickers (nearables), Eddystone и этот список ещё можно продолжать. Пожалуй они все маячки или биконы.
По сути, всё, в том числе iBeacon, это спецификации протокола, а технология тут Bluetooth low energy.
Да и среди тех, кто использует технологию, термин вполне устоялся.
Согласен, я то Вас прекрасно понимаю =). Но статьи на хабре мы пишем не только для тех кто уже использует подобные технологии. Для многих слово бикон лишено смысла, что затрудняет понимание.
Кмк, слово маячок, не просто явлется нормальным переводом английского слова beacon, но и отражет хоть какой то смысл, по аналогии, со словом радиомячок.
VladislavBurmistrov
08.03.2016 12:27Спасибо за статью. Подскажите пожалуйста, по какому принципу Вы расставляли биконы? Около каждого "интересного места" только один бекон, или несколько рядом стоящих, чтобы улучшить fingerprinting?
Mort
Спасибо за статью. Не до конца понял как именно Вы храните отпечатки.
bealex
В обычном списке, перебирая все постоянно, при каждом перемещении. Для прототипа этого хватило, а в реальности нужно было бы строить граф ближайших и проверять только те, что «могут быть рядом», что позволило бы обрабатывать сетки произвольного размера.