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

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

问题描述

我有一个简单的 iOS 应用程序,它使用诸如立即"、接近"等表达方式来显示它检测到的蓝牙 LE 信标的接近程度,我需要在 Android 上编写类似的内容.

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.

我已按照 Android 开发人员 上的教程进行操作,并且我能够列出检测到的设备,现在想要估计距离/接近度 - 这就是问题所在.根据this SO thread,这只是一些数学计算.但是,他们要求我提供 txPower 值.

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.

根据戴夫史密斯的本教程(以及与此蓝牙 SIG 声明),它应该由信标设备作为 0x0A 类型的AD 结构".所以我要做的是解析 AD 结构并查找与类型匹配的有效负载.

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.

问题:我有 4 个信标 - 2 个估计和 2 个 appflares.estimotes 根本不广播 txPower,appflares 广播他们的为 0.

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.

这里有什么我遗漏的吗?iOS 应用程序似乎可以毫无问题地处理这一切,但是使用 iOS SDK 是在幕后进行的,所以我不确定如何产生完全相同或相似的行为.有没有其他方法可以解决我的问题?

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?

如果你想看一下我用来解析 AD 结构的代码,它取自前面提到的 Dave Smith 的 github,可以找到 此处.我对该类所做的唯一更改是添加以下方法:

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]));
                }
            }
        }
    }
};

我在控制台看到的是:

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

推荐答案

不清楚您无法读取txPower"或measuredPower"校准常数是由于 AdRecord 类还是由于到您尝试解析的广告中缺少的信息.在我看来,该类不会解析标准的 iBeacon 广告.无论哪种方式,都有一个解决方案:

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:

解决方案 1:如果您的信标发送包含校准常数的标准 iBeacon 广告,您可以使用开源Android iBeacon 库 的 IBeacon 类 这里.

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.

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

您必须在您的应用中为您可能使用的每种设备类型硬编码校准常数.您真正需要从广告中估算距离的是 RSSI 测量值.在传输中嵌入校准常数的全部意义在于允许具有完全不同的发射机输出功率的各种信标以相同的距离估计算法工作.

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.

Apple 定义的校准常数基本上表示如果您的设备距离信标正好一米,RSSI 应该是多少.如果信号更强(负 RSSI 更小),则设备距离不到一米.如果信号较弱(RSSI 更负),则设备距离超过一米.您可以使用公式对距离进行数值估计.参见此处.

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.

如果您不处理包含txPower"或measuredPower"校准常数的广告,那么您可以在应用中硬编码一个查找表,用于存储各种发射器的已知校准常数.您首先需要测量一米外每个发射器的平均 RSSI.然后,您将需要某种键来在表中查找这些校准常数.(也许您可以使用 AD 结构中字符串的某些部分,或 mac 地址?)所以您的表可能如下所示:

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));

然后在解析广告后,您可以像这样在 onLeScan 方法中查找校准常数:

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天全站免登陆