[Core Bluetooth] BLEを用いた距離および近接度(Proximity)推定のTips
もう7〜8年前になるが、下記のようなBLEを用いた距離計算(RSSIとTxPowerから推定距離を算出)する方法の記事を書いた。
これはあくまで理論的な話であって、これを実装しようとすると、現実的な課題にあれこれ直面する。
このあたりについて、2年ほど前にあれこれ実験したときのメモが出てきたので、一般的な範囲でのTipsや対策を書いておく。
なお、距離計算以外の話はこちらの記事もどうぞ:
想定ユースケース
RSSIベースの距離計算なんて全然使い物にならないよねーというのはそれはそうで、本記事では遮蔽物や反射物が入らないごくごく近距離で「近くにあるか否か」だけを判定するというユースケースを想定している。
TxPowerの問題
TxPowerは、BLE端末が発する信号の強さを示している。ひとことでいえば送信電波強度。
iOS端末の場合
まずシンプルに致命的なところでいうと、iOS端末(iPhoneやiPad)において、まともなTxPower値が取れない。
ペリフェラル側iOS端末のTxPowerは、セントラル側では以下のように取得できる:
func centralManager(_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String : Any],
rssi RSSI: NSNumber)
{
let txPower = advertisementData[CBAdvertisementDataTxPowerLevelKey] as? Int
...
}
(CBAdvertisementDataTxPowerLevelKey の実際の文字列は"Transmit Power")
で、取得した値をみると、(ペリフェラル側がiPhoneの場合に)6とか8とか、デバイスによっては12といった値が得られる。
これを上述の記事に書いた実装にあてはめると、実際には2mも離れていないのに、数百メートルみたいな値になったりしてしまう。
ビーコン端末のManufacturer Dataから得られる値はどうか?
iBeaconでは、アドバタイズメントパケットのManufacturer Dataの中にTxPowerが格納されている。(という仕様になっている)
ただ、Manufacturer Data から得られる値と、アドバタイズパケットに入ってる値とは違う(と当時のメモに書いてあったので、比較する実験をしたのだと思う)。
また、iBeacon の場合は 1m 離れた地点での受信信号強度を利用するが、Eddystone の場合は 0m 地点での強度を利用する、という違いがある。
つまり、ビーコンのTxPowerも、得られた値をそのまま利用してもあまりちゃんとした計算にはならなそうである。
対策
最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/