iBeacon. Міфи і реальність


(зображення з сайту 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 вщух. Але завдання нікуди не поділися. Як і раніше потрібно навігація всередині приміщень. Раніше, потрібна можливість повідомити відвідувачам магазину про нові товари. І робити це зараз можна не тільки рекламними банерами, але і от такими маячками.

Звичайно ж, реальне їх використання не настільки прямолінійно, і потрібно вирішувати безліч завдань, щоб все запрацювало, як потрібно. Головний висновок більше, ніж року роботи з технологією — вона, з певними застереженнями, життєздатна. А далі вже треба дивитися, чи підходить вона для конкретної застосування чи ні. На жаль, срібної кулі поки не вийшло.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.