基于RSSI估计信标接近度/距离 - 蓝牙LE

问题描述 投票:19回答:4

我有一个简单的iOS应用程序,显示它使用诸如“立即”,“近”等表达式检测到的蓝牙LE信标的接近度。我需要在Android上编写类似的东西。

我已经按照Android developer的教程进行了操作,我能够列出检测到的设备,现在想要估算距离/接近度 - 这就是它成为问题的地方。据this SO thread说,这只是一些数学计算。但是,它们要求我提供txPower值。

根据this tutorial by Dave Smith(以及与此Bluetooth SIG statement的交叉引用),它应该由信标设备广播为0x0A类型的“AD结构”。所以我所做的是解析AD结构并查找与该类型匹配的有效负载。

问题:我有4个信标 - 2个estimotes和2个appflares。 estimotes根本不播放txPower,appflares将它们广播为0。

这里有什么我想念的吗? iOS应用程序似乎没有任何问题处理它,但使用iOS SDK它在幕后做,所以我不知道如何产生完全相同或类似的行为。还有其他方法可以解决我的问题吗?

如果您想查看我用于解析AD结构的代码,可以从前面提到的Dave Smith的github中找到它,并且可以找到here。我对该类所做的唯一更改是添加以下方法:

public byte[] getData() {

    return mData;
}

这就是我处理扫描回调的方法:

// 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
android bluetooth bluetooth-lowenergy android-bluetooth rssi
4个回答
21
投票

目前还不清楚您是否无法读取“txPower”或“measuredPower”校准常数是由于AdRecord类还是由于您尝试解析的广告中缺少信息。我不认为该类会解析标准的iBeacon广告。无论哪种方式,都有一个解决方案:

解决方案1:如果您的信标发送包含校准常数的标准iBeacon广告,您可以使用开源Android iBeacon Library的IBeacon类here.中的代码解析它

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

对于您可能使用的每种设备类型,您必须在应用程序中对校准常数进行硬编码。从广告到估算距离真正需要的是RSSI测量。在传输中嵌入校准常数的整点是允许具有完全不同的发射机输出功率的各种信标与相同的距离估计算法一起工作。

Apple定义的校准常数基本上表示如果您的设备距离信标一米,RSSI应该是什么。如果信号更强(RSSI负值较小),则设备距离不到一米。如果信号较弱(更负的RSSI),则设备距离超过一米。您可以使用公式来估算距离。 See here.

如果您不处理包含“txPower”或“measuredPower”校准常数的广告,则可以在应用程序中对查找表进行硬编码,以存储各种发射器的已知校准常数。您首先需要测量距离一米远的每个发射机的平均RSSI。然后,您需要某种键来查找表中的这些校准常数。 (也许你可以使用AD结构中的字符串的某些部分,或者mac地址?)所以你的表可能如下所示:

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方法中查找校准常量,如下所示:

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

30
投票

@davidgyoung提到的txPower由公式给出:

RSSI = -10 n log d + A

哪里

  • d =距离
  • A = TXPOWER
  • n =信号传播常数
  • RSSI = dBm

在自由空间n = 2,但它将根据局部几何形状而变化 - 例如,墙将通过RSSI减少~3dBm并相应地影响n

如果您希望获得尽可能高的准确度,则可能值得通过实验确定特定系统的这些值。

参考文献:请参阅Qian Dong和Waltenegus Dargie的论文Evaluation of the Reliability of RSSI for Indoor Localization,以获得更详细的推导和校准说明。


22
投票
double getDistance(int rssi, int txPower) {
    /*
     * RSSI = TxPower - 10 * n * lg(d)
     * n = 2 (in free space)
     * 
     * d = 10 ^ ((TxPower - RSSI) / (10 * n))
     */

    return Math.pow(10d, ((double) txPower - rssi) / (10 * 2));
}

-2
投票

使用库中的getAccuracy()方法,它可以为您提供信标的距离

© www.soinside.com 2019 - 2024. All rights reserved.