基于RSSI估计灯塔接近/距离 - 蓝牙LE [英] Estimating beacon proximity/distance based on RSSI - Bluetooth LE

查看:289
本文介绍了基于RSSI估计灯塔接近/距离 - 蓝牙LE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的iOS应用,其显示的蓝牙LE的信标附近检测到使用这种EX pressions为立即,近等,我需要写类似的东西在Android上。

我已经按照本教程在 Android开发,我能清单检测到的设备,现在要估计的距离/接近 - 这是它成为一个问题。根据这太线程这只是少数的数学计算。然而,他们要求我提供一个TXPOWER值。

根据本教程由戴维·史密斯(和交叉引用本<一个href="https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile">Bluetooth SIG声明),应当由信标设备类型的AD结构播出的0x0A 。所以,我做的是解析AD结构,并寻找一个匹配类型的有效载荷。

问题:我有4标 - 2 estimotes和2 appflares。该estimotes不广播TXPOWER在所有和appflares播出他们为0。

这有什么,我在这里丢失?在iOS应用似乎在处理这一切没有任何问题,但使用的iOS SDK它是在幕后,所以我不知道如何产生完全相同的或类似的行为。有没有我可以解决我的问题,任何其他方式?

如果你想看看在code我使用解析AD结构,它采取从上述戴维·史密斯的GitHub上,可以找到<一href="https://github.com/devunwired/accessory-samples/blob/master/BluetoothGatt/src/com/example/bluetoothgatt/AdRecord.java">here.我做了这个类,唯一的变化是添加下面的方法:

 公共字节[]的getData(){

    返回MDATA;
}
 

这是我如何处理从扫描回调:

  // prepare的回调BLE设备扫描
this.leScanCallback =新BluetoothAdapter.LeScanCallback(){

    @覆盖
    公共无效onLeScan(最终BluetoothDevice类设备,INT RSSI,byte []的scanRecord){

        如果(!deviceList.contains(设备)){

            MyService.this.deviceList.add(设备);
            Log.e(测试,设备:+ device.getName());

            名单&LT; AdRecord&GT; adRecords = AdRecord.parseScanRecord(scanRecord);

            对于(AdRecord adRecord:adRecords){

                如果(adRecord.getType()== AdRecord.TYPE_TRANSMITPOWER){

                    Log.e(测试,有效载荷的大小:+ adRecord.getData()的长度);
                    Log.e(测试,有效载荷:+ Byte.toString(adRecord.getData()[0]));
                }
            }
        }
    }
};
 

和我在控制台中看到的是:

  11月4号至一号:33:35.864:E /测试(15061):设备:estimote
11月4日至1日:33:36.304:E /测试(15061):设备:estimote
11月4日至1日:33:36.475:E /测试(15061):设备:N86
11月4日至1日:33:36.475:E /测试(15061):有效载荷的大小:1
11月4日至1日:33:36.475:E /测试(15061):有效载荷:0
11月4日至1日:33:36.525:E /测试(15061):设备:F79
11月4日至1日:33:36.525:E /测试(15061):有效载荷的大小:1
11月4日至1日:33:36.525:E /测试(15061):有效载荷:0
 

解决方案

目前还不清楚你无法是否阅读TXPOWER或measuredPower校准常数是由于 AdRecord 类或由于信息是从广告你正在试图解析缺失。它看起来并不对我来说,这个类将解析标准iBeacon广告。无论哪种方式,有一个解决方案:

解决方案1:如果你的信标发送标准iBeacon广告,其中包括校准常数,您可以用code在开源的 Android的iBeacon图书馆的IBeacon类<一href="https://github.com/RadiusNetworks/android-ibeacon-service/blob/4185a5bd0c657acaf145098a09466bb34a144557/src/main/java/com/radiusnetworks/ibeacon/IBeacon.java"相对=nofollow>这里

解决方案2:如果您的信标不发标准iBeacon广告或不包括校准常数:

您必须硬codeA校准常数在你的应用程序为您可能会使用每个设备的类型。所有你从广告确实需要估计距离为的RSSI测量。在传输中嵌入的校准常数的整点是允许各种各样的信标与完全不同的发射机输出功率的具有相同的距离估算算法来工作。

校准常数,由苹果定义,基本上说什么RSSI应该是,如果你的设备正好一米距离的灯塔。如果信号强(少负的RSSI),则该设备是小于一米的路程。如果信号较弱(更负的RSSI),则该设备是超过一米的路程。你可以用一个公式来进行距离的数值估计。 在这里看到。

如果你不处理一个包含TXPOWER或measuredPower校准常数的广告,那么你就可以在你的应用程序,存储已知的校准常数不同发射机硬codeA查找表。首先,您需要衡量每个发射器的平均RSSI在一米以外。然后,您需要某种形式的键来查找这些校准常数表。 (也许你可以使用的一些部件从公元结构的字符串,或者MAC地址?)所以你的表可能是这样的:

 的HashMap&LT;字符串,整数&GT; txPowerLookupTable =新的HashMap&LT;字符串,整数&GT;();
txPowerLookupTable.put(A5:09:37:78:C3:22,新的整数(-65));
txPowerLookupTable.put(D2:32:33:5C:87:09,新的整数(-78));
 

然后解析一个广告后,你可以看看你的 onLeScan 这样的方法校准常数:

 字符串MACADDRESS = device.getAddress();
整数TXPOWER = txPowerLookupTable.get(MACADDRESS);
 

I've got a simple iOS app which displays the proximity of the Bluetooth LE beacons it detects using such expressions as "immediate", "near" etc. and I need to write something similar on Android.

I've followed the tutorial at Android developer and I'm able to list detected devices and now want to estimate the distance/proximity - this is where it's become a problem. According to this SO thread it's just a handful of mathematical calculations. However, they require me to provide a txPower value.

According to this tutorial by Dave Smith (and cross-referencing with this Bluetooth SIG statement), it should be broadcast by the beacon devices as an "AD structure" of type 0x0A. So what I do is parse the AD structures and look for the payload of the one that matches the type.

Problem: I've got 4 beacons - 2 estimotes and 2 appflares. The estimotes don't broadcast the txPower at all and the appflares broadcast theirs as 0.

Is there anything I'm missing here? The iOS app seems to be handling it all without any problem, but using the iOS SDK it does it behind the scenes so I'm not sure how to produce the exact same or similar behaviour. Is there any other way I could solve my problem?

In case you'd like to take a look at the code I'm using to parse the AD structures, it's taken from the aforementioned Dave Smith's github and can be found here. The only change I did to that class was add the following method:

public byte[] getData() {

    return mData;
}

And this is how I handle the callback from the scans:

// Prepare the callback for BLE device scan
this.leScanCallback = new BluetoothAdapter.LeScanCallback() {

    @Override
    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {

        if (!deviceList.contains(device)) {

            MyService.this.deviceList.add(device);
            Log.e("Test", "Device: " + device.getName());

            List<AdRecord> adRecords = AdRecord.parseScanRecord(scanRecord);

            for (AdRecord adRecord : adRecords) {

                if (adRecord.getType() == AdRecord.TYPE_TRANSMITPOWER) {

                    Log.e("Test", "size of payload: " + adRecord.getData().length);
                    Log.e("Test", "payload: " + Byte.toString(adRecord.getData()[0]));
                }
            }
        }
    }
};

And what I see in the console is:

04-01 11:33:35.864: E/Test(15061): Device: estimote
04-01 11:33:36.304: E/Test(15061): Device: estimote
04-01 11:33:36.475: E/Test(15061): Device: n86
04-01 11:33:36.475: E/Test(15061): size of payload: 1
04-01 11:33:36.475: E/Test(15061): payload: 0
04-01 11:33:36.525: E/Test(15061): Device: f79
04-01 11:33:36.525: E/Test(15061): size of payload: 1
04-01 11:33:36.525: E/Test(15061): payload: 0

解决方案

It is unclear whether your inability to read the "txPower" or "measuredPower" calibration constant is due to the AdRecord class or due to the information being missing from the advertisements you are trying to parse. It doesn't look to me like that class will parse a standard iBeacon advertisement. Either way, there is a solution:

SOLUTION 1: If your beacons send a standard iBeacon advertisement that includes the calibration constant, you can parse it out using code in the open source Android iBeacon Library's IBeacon class here.

SOLUTION 2: If your beacons DO NOT send a standard iBeacon advertisement or do not include a calibration constant:

You must hard-code a calibration constant in your app for each device type you might use. All you really need from the advertisement to estimate distance is the the RSSI measurement. The whole point of embedding a calibration constant in the transmission is to allow a wide variety of beacons with quite different transmitter output power to work with the same distance estimating algorithm.

The calibration constant, as defined by Apple, basically says what the RSSI should be if your device is exactly one meter away from the beacon. If the signal is stronger (less negative RSSI), then the device is less than one meter away. If the signal is weaker (more negative RSSI), then the device is over one meter away. You can use a formula to make a numerical estimate of distance. See here.

If you aren't dealing with advertisements that contain a "txPower" or "measuredPower" calibration constant, then you can hard-code a lookup table in your app that stores the known calibration constants for various transmitters. You will first need to measure the average RSSI of each transmitter at one meter away. You'll then need some kind of key to look up these calibration constants in the table. (Perhaps you can use the some part of the string from the AD structure, or the mac address?) So your table might look like this:

HashMap<String,Integer> txPowerLookupTable = new HashMap<String,Integer>();
txPowerLookupTable.put("a5:09:37:78:c3:22", new Integer(-65));
txPowerLookupTable.put("d2:32:33:5c:87:09", new Integer(-78));

Then after parsing an advertisement, you can look up the calibration constant in your onLeScan method like this:

String macAddress = device.getAddress();
Integer txPower = txPowerLookupTable.get(macAddress);

这篇关于基于RSSI估计灯塔接近/距离 - 蓝牙LE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆