레이블이 beacon인 게시물을 표시합니다. 모든 게시물 표시
레이블이 beacon인 게시물을 표시합니다. 모든 게시물 표시

2016년 8월 16일 화요일

라즈베리 파이를 에디스톤 URL 비콘으로 사용하기 (Use Raspberry Pi as an Eddystone URL beacon)

이전 포스트인 라즈베리 파이를 비콘으로 사용하기를 먼저 보기를 권한다.

Eddystone beacon


Eddystone은 구글이 만든 프로토콜로 BLE 디바이스가 URL을 메시지로 브로드캐스트 할 수 있게 해 준다. Eddystone에 관한 자세한 내용은 github를 보면 된다. 현재 스펙은 3가지 타입(UID, URL, telemetry)의 브로드캐스트 메시지를 정의하고 있다.

Eddystone 비콘의 마법은 스마트폰 쪽에서 이 브로드캐스트 메시지를 기다리고 있다가 메시지를 받으면경고 메시지를 표시하거나 특정 동작을 수행할 수 있다.

이 튜토리어에서는 라즈베리 파이를 eddystone beacon으로 사용하는 방법을 보여준다.

Setting up the Pi


$ hciconfig
$ sudo hciconfig hci0 up
$ sudo hciconfig hci0 leadv 3
$ sudo hcitool -i hci0 cmd 0x08 0x0008 17 02 01 06 03 03 aa fe 0f 16 aa fe 10 00 02 77 65 62 67 61 7a 65 72 08 00 00 00 00 00 00 00 00

 바로 위의 명령 payload를 상세히 보면 다음과 같다.

0x08 - OGF (Operaton Group Field) -> Bluetooth Command Group (0x08)
0x0008 - OCF (Operation Command Field) -> HCI_LE_Set_Advertising_Data (0x0008)
17 - Length (23 bytes)
  02 - Length
    01 - Flags Data type value
    06 - Flags Data
  03 - Length
    03 - Complete list  of 16-bit Service UUID data type value
    aa - 16-bit Eddystone UUID
    fe - 16-bit Eddystone UUID
  0f - Length
    16 - Service Data data type value
    aa - 16-bit Eddystone UUID
    fe - 16-bit Eddystone UUID
    10 - Frame type -> URL
    00 - TX Power (calibrated)
    02 - URL Scheme 02 -> http://
    77 - 'w'
    65 - 'e'
    62 - 'b'
    67 - 'g'
    61 - 'a'
    7a - 'z'
    65 - 'e'
    72 - 'r'
    08 - 08 -> '.org'
  00 - 
  00 - 
  00 - 
  00 - 
  00 - 
  00 - 
  00 - 
  00 - 

위의 명령은 URL 'http://webgazer.org' 를 브로드캐스트 한다.
만일 다른 URL을 advertise하고 싶으면 아래 박스에 원하는 URL을 입력하면 그에 해당하는 명령을 자동으로 만들어 준다.


 
위의 명령을 라즈베리 파이에 입력해 주면 이제부터 라즈베리 파이가 Eddystone URL beacon으로 동작하게 된다. 아이폰에서 PhyWeb이나 안드로이드에서 크롬을 사용해 보면 링크가 뜨는걸 확인할 수 있다.

* 모든 설정이 끝났는데 안드로이드에서 비콘이 보이지 않는 경우 원인은 거의 99.9% 이상이 URL주소가 https:// 로 시작하지 않아서이다. 어떤 이유로...아마도 man in the middle attack에 대해 방어하기 위해 안드로이드의 크롬은 URL이 secure하기를 요구한다. 그러지 않으면 비콘이 발견되어도 트리거 되지 않는다.

2016년 5월 12일 목요일

라즈베리 파이를 비콘으로 사용하기 (Using Raspberry Pi as a Beacon)

독립적으로 비콘 모듈을 사용할 수도 있지만 이미 라즈베리 파이를 가지고 있다면 별도의 비콘 모듈 없이 라즈베리 파이를 비콘으로 설정해 사용할 수 있다.


라즈베리 파이 3의 경우 무선랜/블루투스가 기본 내장되어 있어 별도의 추가 하드웨어가 필요 없어 더 경제적이다. 라즈베리 파이 1/2의 경우는 USB타입의 블루투스 동글을 추가해 주면 된다.


 비콘은 특별한 것이 아니고 BLE(Bluetooth Low Energy)의 advertising packet 안에 옵션 필드인 Manufacturer Specific Data 에 특정 값을 집어넣어 주기적으로 advertising 하는 것이다. 그러므로 이 필드에 들어갈 값을 알아야 한다.

필드의 구조는 다음과 같다.

  • ID (uint8_t) : 이 값은 항상 0x02
  • Data Len (uint8_t) : payload 나머지 부분의 길이 → 0x15 (21 bytes)
  • 128-bit UUID (uint8_t[16]) : 128-bit 식별자
  • Major (uint16_t) : Major value
  • Minor (uint16_t) : Minor value
  • TX Power (uint8_t) : RSSI 기반으로 거리를 추정하기 위해 사용됨
 예를 들어 다음은 유효한 iBeacon payload의 값이다.


블루투스 표준에 의하면 Company Identifier가 Manufacturer Specific Data 필드 앞에 와야만 한다. 여기서 사용할 Apple의 company identifier는 0x004C 이다.

라즈베리 파이가 비콘 데이터를 보내게 하려면 몇가지 툴을 설치해 줘야만 한다. 여기서 핵심은 Bluez(리눅스 블루투스 스택)이고 부가적으로 libusb와 몇개의 helper library가 필요하다.

순서대로 필요한 툴들을 설치, bluez를 다운받아 컴파일 및 설치 해 주면 된다.

pi@raspberrypi ~ $ sudo apt-get install libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-def

pi@raspberrypi ~ $ sudo mkdir bluez
pi@raspberrypi ~ $ cd bluez
pi@raspberrypi ~ $ sudo wget www.kernel.org/pub/linux/bluetooth/bluez-5.11.tar.xz
 
pi@raspberrypi ~ $ sudo unzx bluez-5.11.tar.xz 
pi@raspberrypi ~ $ sudo tar xvf bluez-5.11.tar
pi@raspberrypi ~ $ cd bluez-5.11
pi@raspberrypi ~ $ sudo ./configure --disable-systemd
pi@raspberrypi ~ $ sudo make
pi@raspberrypi ~ $ sudo make install



설치가 완료되었으면 블루투스 동글을 꼽고 재부팅 시켜주면 된다.

재부팅이 완료되면 먼저 시스템에 설치된 디바이스 목록을 확인한다.


pi@raspberrypi ~ $ hciconfig
hci0:  Type: BR/EDR    Bus: USB
       BD Address: 00:1A:7D:DA:71:12 ACL MTU: 310:10 SCO MTU: 64:8
       DOWN
       RX bytes: 495 acl:0 sco:0 events:21 errors: 0
       TX bytes: 89 acl:0 sco:0 commands: 21 errors: 0
pi@raspberrypi ~ $

만일 모든것이 정상적으로 설정되어 있으면 위와 같이 hci 디바이스가 보이게 된다. 이제 다음 명령으로 디바이스를 활성화 시켜 준다. 또한 advertising을 할 때 문제를 일으킬 수도 있으므로 device scanning은 꺼 준다.

pi@raspberrypi ~ $ sudo hciconfig hci0 up 
pi@raspberrypi ~ $ sudo hciconfig hci0 leadv3
pi@raspberrypi ~ $ sudo hciconfig hci0 noscan

이제 다시 hciconfig 명령을 수행해 보면 'DOWN' 대신 'UP  RUNNING'이 보여야 한다.

pi@raspberrypi ~ $ hciconfig
hci0:  Type: BR/EDR    Bus: USB
       BD Address: 00:1A:7D:DA:71:12 ACL MTU: 310:10 SCO MTU: 64:8
       UP RUNNING
       RX bytes: 1008 acl:0 sco:0 events:45 errors: 0
       TX bytes: 236 acl:0 sco:0 commands: 45 errors: 0
pi@raspberrypi ~ $

이제 마지막으로 해 줘야 할 일은 advertising data에 beacon 값을 넣어주는 것이다. 다음과 같이 명령을 입력해 준다. (좀 길지만 한 줄에 다 입력해 준다.)


pi@raspberrypi ~ $ sudo tools/hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A 
FF 4C 00 02 15 E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 00 00 00 00 C8 00

위의 값들 중에서 FF는 Manufacturer Specific Data의 시작을 알려 주고, 4C 00은 Apple의 Company ID(0x004C), 그리고 나머지 부분부터 C8까지가 beacon의 payload이다.

이제 라즈베리 파이는 비콘으로 동작하게 된다. 확인해 보려면 iOS7 이후 버젼을 OS를 사용하는 아이폰/아이패드/아이팟 터치 또는 안드로이드 폰에 beacon toolkit 또는 유사한 앱을 설치해 실행하면 된다.

앱을 시작해 listen 모드로 들어가면 아래와 유사한 화면을 볼 수 있을 것이다.



이제 동작하는건 확인했지만 라즈베리 파이를 부팅할 때 마다 매번 위의 명령을 입력하기 힘드니 스크립트를 사용하는것이 편하다.

pi@raspberrypi ~ $ cat /home/pi/beacon.sh

#!/bin/bash
# ref: http://www.theregister.co.uk/Print/2013/11/29/feature_diy_apple_ibeacons/
set -x
# inquiry local bluetooth device
#hcitool dev
export BLUETOOTH_DEVICE=hci0
#sudo hcitool -i hcix cmd <OGF> <OCF> <No. Significant Data Octets> <iBeacon Prefix> <UUID> <Major> <Minor> <Tx Power> <Placeholder Octets>

#OGF = Operation Group Field = Bluetooth Command Group = 0x08
#OCF = Operation Command Field = HCI_LE_Set_Advertising_Data = 0x0008
#No. Significant Data Octets (Max of 31) = 1E (Decimal 30)
#iBeacon Prefix (Always Fixed) = 02 01 1A 1A FF 4C 00 02 15

export OGF="0x08"
export OCF="0x0008"
export IBEACONPROFIX="1E 02 01 1A 1A FF 4C 00 02 15"

#uuidgen  could gerenate uuid
export UUID="4a 4e ce 60 7e b0 11 e4 b4 a9 08 00 20 0c 9a 66"

export MAJOR="00 02"
export MINOR="00 01"
export POWER="C5 00"


# initialize device
sudo hciconfig $BLUETOOTH_DEVICE up
# disable advertising
sudo hciconfig $BLUETOOTH_DEVICE noleadv
# stop the dongle looking for other Bluetooth devices
sudo hciconfig $BLUETOOTH_DEVICE noscan

sudo hciconfig $BLUETOOTH_DEVICE pscan


sudo hciconfig $BLUETOOTH_DEVICE leadv

# advertise
sudo hcitool -i $BLUETOOTH_DEVICE cmd 0x08 0x0008 $IBEACONPROFIX $UUID $MAJOR $MINOR $POWER
sudo hcitool -i $BLUETOOTH_DEVICE cmd 0x08 0x0006 A0 00 A0 00 00 00 00 00 00 00 00 00 00 07 00
sudo hcitool -i $BLUETOOTH_DEVICE cmd 0x08 0x000a 01

echo "complete"


pi@raspberrypi ~ $

/home/pi/beacon.sh 라는 파일을 만들어 위의 파란색 부분의 내용을 넣어주면 된다. 위의 스크립트 중에 hcitool cmd 0x08 0x0006 a0 00 a0 00 .. 에서 첫번째/두번째 바이트 (0xa0 0x00)은 minimum interval, 세번째/네번째 바이트(0xa0 0x00)은 maximum interval이다. 0xa0 0x00은 0x00a0 (big endian)이 되므로 10진수로는 160이 된다. BLE에서 시간 granularity는 0.625ms이므로 최소/최대 인터벌은 모두 160 * 0.625ms = 100ms가 된다. 즉 매 0.1초마다 한번씩 비콘 신호를 advertising하게 된다.

파일을 만들었으면 chmod 명령으로 실행 퍼미션을 추가해 준다.

pi@raspberrypi ~ $ chmod +x beacon.sh

이제부터는 ./beacon.sh 만 입력해 주면 라즈베리 파이가 비콘으로 동작한다.

pi@raspberrypi ~ $ ./beacon.sh
+ export BLUETOOTH_DEVICE=hci0
+ BLUETOOTH_DEVICE=hci0
+ export OGF=0x08
+ OGF=0x08
+ export OCF=0x0008
+ OCF=0x0008
+ export 'IBEACONPROFIX=1E 02 01 1A 1A FF 4C 00 02 15'
+ IBEACONPROFIX='1E 02 01 1A 1A FF 4C 00 02 15'
+ export 'UUID=4a 4e ce 60 7e b0 11 e4 b4 a9 08 00 20 0c 9a 66'
+ UUID='4a 4e ce 60 7e b0 11 e4 b4 a9 08 00 20 0c 9a 66'
+ export 'MAJOR=00 01'
+ MAJOR='00 01'
+ export 'MINOR=00 00'
+ MINOR='00 00'
+ export 'POWER=C5 00'
+ POWER='C5 00'
+ sudo hciconfig hci0 up
+ sudo hciconfig hci0 noleadv
+ sudo hciconfig hci0 noscan
+ sudo hciconfig hci0 pscan
+ sudo hciconfig hci0 leadv
+ sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 4a 4e ce 60 7e b0 11 e4 b4 a9 08 00 20 0c 9a 66 00 01 00 00 C5 00
< HCI Command: ogf 0x08, ocf 0x0008, plen 32
  1E 02 01 1A 1A FF 4C 00 02 15 4A 4E CE 60 7E B0 11 E4 B4 A9
  08 00 20 0C 9A 66 00 01 00 00 C5 00
> HCI Event: 0x0e plen 4
  01 08 20 00
+ sudo hcitool -i hci0 cmd 0x08 0x0006 A0 00 A0 00 00 00 00 00 00 00 00 00 00 07 00
< HCI Command: ogf 0x08, ocf 0x0006, plen 15
  A0 00 A0 00 00 00 00 00 00 00 00 00 00 07 00
> HCI Event: 0x0e plen 4
  01 06 20 0C
+ sudo hcitool -i hci0 cmd 0x08 0x000a 01
< HCI Command: ogf 0x08, ocf 0x000a, plen 1
  01
> HCI Event: 0x0e plen 4
  01 0A 20 0C
+ echo complete
complete 

pi@raspberrypi ~ $

이제 라즈베리 파이를 비콘으로 사용하려면 부팅될 때 마다 자동으로 위의 스크립트가 실행되도록 설정해 주면 된다.

라즈베리 파이에서 특정 프로그램이 부팅될 때 실행되게 하는 방법은 몇가지가 있지만 /etc/rc.local을 수정하는 방법 또는 cron을 사용하는 방법은 문제가 있다. 라즈베리 파이에서 블루투스가 활성화 된 이후에 위의 스크립트가 실행되어야만 하는데 두가지 방법은 스크립트가 먼저 실행되어 버리기 때문에 비콘으로 동작하지 못한다.

그러므로 systemd를 사용해 준다. 먼저 /lib/systemd/system 디렉토리에 두개의 파일을 만들어 준다. 각각 파일의 내용은 아래와 같다.

pi@raspberrypi ~ $ cat /lib/systemd/system/beacon.service
[Unit]
Description=Beacon service
After=bluetooth.target

[Service]
Type=forking
ExecStart=/home/pi/beacon.sh
ExecReload=/home/pi/beacon.sh

[Install]
WantedBy=bluetooth.target


pi@raspberrypi ~ $ cat /lib/systemd/system/beacon.target
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Beacon
Documentation=man:systemd.special(7)
StopWhenUnneeded=yes


pi@raspberrypi ~ $ sudo systemctl daemon-reload
pi@raspberrypi ~ $ sudo systemctl enable beacon.service
Synchronizing state for beacon.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d beacon defaults
Executing /usr/sbin/update-rc.d beacon enable


pi@raspberrypi ~ $

이제 시스템을 리부팅 하면 항상 자동으로 비콘이 시작된다.





아이폰에서 Beecon 앱으로 확인해 본 결과이다. 스크립트에서 설정한 UUID(4a4e......9a66) , Major(2), Minor(1) 를 확인할 수 있다.






2015년 2월 10일 화요일

Beacon의 이해



비이컨 기술의 가장 기본적인 사용법은 모바일 디바이스에서 비이컨까지의 거리를 측정하는 것이다. 하지만 비이컨으로 거리를 측정하는걸 해 본 사람들은 누구나 알고 있는 것처럼 거리 추정은 상당히 오차가 크다. 5미터 떨어진 비이컨의 경우 추정 거리는 2미터에서 10미터까지 왔다갔다 한다. 

이렇게 추정 거리가 변하는 이유와 이런 오차를 줄이기 위한 방법은 비이컨에 관해 가장 흔한 질문이다. 추정에 영향을 미치는 요인은 전파 신호의 난반사, 장애물, 휴대폰과 비이컨의 방향등 매우 다양하다. 

하지만 거리 추정에 무었보다 가장 큰 요인은 전파 노이즈이다. 백그라운드 전파 노이즈는 어디에건 존재한다. 강한 전파(즉, SNR이 큰)의 경우 약한전파보다 노이즈는 별로 문제가 되지 않는다. 이런 이유 때문에 비이컨에서 10미터 이상 떨어진 경우보다는 가까운 거리에서는 좀 더 정확한 거리 추정이 가능하다. 

Apple의 권장사항




애플이 iOS7에서 iBeacon 기술을 소개했을 때, 애플의 문서는 거리 추정치를 직접 사용하지 않는걸 권장했다. 비이컨 범위 정보를 제공하는 CLBeacon 클래스는 비이컨과의 거리 추정치를 미터 단위로 제공하는 필드를 가지고 있다. 하지만 이 속성을 distance라고 부르는 대신 애플은 accuracy라고 이름붙였다. 권장하는 사용법은 이 값을 여러 비이컨들 중에 어느것이 가장 가까운가 비교하는 용도로만 사용하는 것이다. 또한 CLBeacon 클래스는 proximity라는 속성을 제공해 거리 추정치를 “immediate”, “near”, “far”로 그룹핑 한다. 이 각 그룹의 정의는 명확하지 않지만, 실험 결과 0.5미터 이내의 거리는 “immediate”, 0.5~3m 정도는 “near”, 그 이상은 “far”로 구분한다고 볼 수 있다.



이런 내용이 비이컨을 사용해 직접적으로 거리를 측정할 수 없다는걸 의미하지는 않는다. 단지 비이컨의 동작 원리와 결과값의 품질에 어떤 한계가 있는지를 먼저 이해할 필요가 있다는걸 의미한다.

Reference Transmitter Power


비이컨 전송은 transmitter power 필드를 포함하고 있어 특정 거리에서 신호 세기가 얼마의 세기가 되어야 하는가를 나타낸다. 예를들어 iBeacon 기술을 사용할 때, 표준 측정값은 비이컨에서 1미터 떨어진 곳에서 iPhone 5S(iOS7이 발표되었을 때 최신 모델)이 측정한 것이다. 비이컨은 표준거리에서 신호레벨(RSSI)을 측정한 후 비이컨이 표준값을 송신하도록 calibrate되어야만 한다.  RSSI 값은 dBm 단위를 사용하고 1미터 거리에서 calibrate 된 비이컨의 통상 RSSI 값은 -59 dBm이다. 각 송신기와 안테나는 서로 다른 세기의 전파를 송신하기 때문에 여러 비이컨의 실제 calibration 값은 서로 다르다. Radius Network의 RadBeacon같은 일부 제품은 출력파워를 조정할 수 있다.

How distance estimates work


모바일 디바이스는 비이컨의 신호레벨을 레퍼런스 신호레벨과 비교함으로서 비이컨과의 거리를 추정할 수 있다. 비이컨이 adv한 패킷이 수신될 때 마다 블루투스 칩은 비이컨의 신호레벨 측정값을 RSSI로 제공한다. 각 비이컨 전송은 위에서 언급한 calibration 값을 포함하고 있기 때문에, 실제 시그널 레벨을 1머터에서 기대되는 시그널 레벨과 비교해서 거리를 추정할 수 있다. 예를들어 비이컨 adv 패킷이 -65 dBm 시그널 레벨로 수신되었고 송신기의 출력 calibration값은 -59 dBm이라고 해 보자. -65 dBm은 -59dBm보다 약한 신호레벨이므로, 즉 비이컨은 1미터보다 먼 거리에 있을 가능성이 크다는걸 의미한다.

거리를 추정하기 위해 이 두 숫자를 공식에 집어넣을 수 있다. 아래 공식은 Android Beacon Library에 사용한 것이다. 공식의 3개의 상수(0.89976, 7.7095, 0.111)는 여러 정해진 거리에서 넥서스4를 사용해 측정한 신호 세기에 기반해 best fit으로 계산한 값이다. 


protected static double calculateDistance(int txPower, double rssi) {
  if (rssi == 0) {
    return -1.0; // if we cannot determine distance, return -1.
  }

  double ratio = rssi*1.0/txPower;
  if (ratio < 1.0) {
    return Math.pow(ratio,10);
  }
  else {
    double accuracy =  (0.89976)*Math.pow(ratio,7.7095) + 0.111;    
    return accuracy;
  }
} 


위의 예제의 경우 txPower에 -65를, rssi에 -59를 넣으면 거리 추정치는 2미터가 된다.

Filtering for noise


신호 노이즈때문에 RSSI 측정치만으로 거리를 추정하는것은 좋은 생각이 아니다. 비이컨 패캣의 RSSI 측정값을 보면 신호 레벨은 여러 곳에서 갑자기 점프하는걸 볼 수 있다. 이 노이즈를 제거하는 가장 간단한 방법은 RSSI 측정치의 running average를 사용해서 노이즈를 부드럽게 변하도록 해 주는 것이다. 또한 데이터 셋에서 이상하게 높거나, 이상하게 낮은 값은 제외해 버리는것도 일반적이다. Android Beacon Library에서 사용한 알고리즘은 20초 샘플링 구간 측정치의 상위 및 하위 10%를 버리고 나머지를 평균한다. 

이 방법의 장점은 거리 추정이 좀 더 정확하고 안정적이라는 것이다. 단점은 모바일 디바이스가 움직이면 거리 추정치가 움직인 위치를 정확히 따라잡는데 20초의 시간이 걸린다는 것이다.

20초 샘플링 구간은 iOS에서 사용하는 방법과 유사하다. 아래 그래프는 아이폰4S가 비이컨에서부터 0.5미터 거리에서 3미터로 빠르게 이동했을 때 (빨간선)  CLBeacon 클래스의 accuracy 필드가 어떻게 변하는가를 보여준다. 그래프에서 볼 수 있는것처럼 디바이스가 이동한 후 거리 추정치(파란선)이 안정화되는데 약 20초가 걸린다.


Device Variations


아이폰 4S, 5, 5S, 6 모델들의 블루투스 회로, 안테나, 케이스 디자인은 큰 변동이 없기 때문에 비이컨 거리 추정은 대부분의 iOS 디바이스에서 일관되게 동작한다. 하지만 항상 그런것은 아니다. 아이팟 터치에서의 거리 추정치는 블루투스 신호 수신 감도를 높이기 위해 안테나를 다른 식으로 배치했기 때문에 일반적으로 좀 더 가깝게  추정된다.

디바이스간의 variation은 안드로이드에서 훨씬 더 큰 문제이다. 각 안드로이드 모델은 완전히 다른 블루투스 칩셋, 안테나, 케이스 디자인을 가질 수 있기 때문이다. 이 모든 요인이 신호 수신 레벨에 영향을 미치므로 거리 추정치에도 영향을 미치게 된다. 넥서스4, 넥서스5와 갤럭시S4 모델은 비이컨과 같은 거리에서 상당히 크게 다른 신호 레벨로 받는다. 이런 이유때문에 Radius Networks는 다양한 안드로이드 디바이스에 대해 거리 공식 DB를 구축하기 시작했다.

Setting Expectations


비이컨에서의 거리를 추정하는게 가능하지만 이 측정치는 말 그대로 ‘추정’치라는걸 잊으면 안된다. 디비아스가 비이컨에서 더 멀어질수록, 이 추정치는 점점 더 정확하지 않게 된다. 비이컨에서 20미터 떨어진 디바이스는 거리 추정치에 +-10미터의 오차를 가지게 된다. 폰이 주머니에 들어있는가 여부, 어느 방향으로 놓여있는가, 간판 뒤쪽에 있는가, 또는 많은 사람들 무리에 막혀있는가등에 따라 비이컨과의 거리 추정치는 크게 영향을 받게 된다. 

그러므로 어떤걸 할 수 없는가를 인식하는게 중요하다.

  • 비이컨이 1미터 떨어져 있는지 아니면 10미터 떨어져 있는지는 쉽게 말할 수 있어도, 10미터 떨어져 있는지 아니면 20미터 떨어져 있는지는 말할 수 있을거라고 기대하면 안된다.
  • 노이즈를 제거하기 위해 running average를 사용하기 때문에 사용자가 움직이면 움직임을 거의 리얼타임으로 추정할 수 있을거라고 생각하면 안된다.
  • 비이컨이 있는 방향을 결정할 수 있을거라고 생각하면 안된다. 비이컨은 보통 전방향 송신기이기 때문에 거리를 추정할 수는 있어도 방향은 추정할 수 없다.
  • 비이컨과의 거리를 추정할 수 있다는것이 모바일 디바이스가 방 안에 정확히 어느 위치에 있는지 결정할 수 없다는걸 이해해야 한다. 비이컨이 실내 위치 시스템에서 구성요소로 사용될 수는 있어도 비이컨 거리 추정만으로는 문제를 해결할 수 없다.
  • 몇개의 비이컨으로 삼각측량법을 사용해 간단한 실내 위치 시스템을 만들수 있을거라고 기대하면 안된다. 거리 추정의 정확도는 거리가 멀어질수록 나뻐지기 때문에 실내에서 위치를 알기 위해 삼각측량을 사용하는건 정확한 위치 추정을 할 수 없다.

하지만 비이컨 거리 추정으로 할 수 있는 유용한 어플리케이션도 많다. 예를 들자면

  • 비이컨이 매우 가까워(5미터 이내)질 때 어떤 동작을 시작
  • 수미터 이내에 있어 신호를 수신할 수 있는 여러 비이컨들중에 어느것이 가장 가까운가를 결정하기 
  • 특정 위치를 찾는 사용자에게 거리 피드백을 제공 (예: 보물찾기)

Best Practices


최대한 정확한 거리 추정치를 얻기 위해서 Radius Networks는 다음의 내용을 권장한다.

  • 비이컨에서 가능한 최대 출력의 송신 레벨을 사용한다. 강한 시그널 레벨은 높은 SNR을 의미하기 때문에 좀 더 정확한 거리 추정이 가능하다.
  • 비이컨의 송신 빈도를 최대한 높여준다. 모바일 디바이스에 advertising 패킷이 더 많이 수신될수록, 노이즈를 제거하기 위해 평균해야 하는 샘플이 많아진다. 
  • 가능한 Radius Networks의 RadBeacon USB같이 외부에서 전원을 공급받는 비이컨을 사용한다. 그래야 배터리 수명을 걱정할 필요 없이 가장 고출력과 빠른 송신 빈도로 패킷을 advertising 할 수 있다.
  • 비이컨을 제대로 보정한다.
  • 명확하게 시야에 들어오는 장소에 비이컨을 설치한다. 사람들이 붐비는 장소라면 바닥보다는 높은 곳에 설치하는게 더 좋다.
  • 특정 안드로이드 모델을 위한 앱을 계획하거나 설치하려고 하면 거리 추정 공식이 해당 모델에 최적화 되어 있는가 확인해야 한다. Radius Networks의 Android Beacon Library는 다양한 안드로이드 모델을 위해 확장 가능한 거리 추정 공식 DB를 제공한다. 

원문은 http://developer.radiusnetworks.com/2014/12/04/fundamentals-of-beacon-ranging.html