Die Schätzung Leuchtfeuer Nähe / Distanz basierend auf RSSI - Bluetooth LE

? JakeP @ | Original: StackOverFlow
---

Ich habe eine einfache iOS App, die die Nähe der Bluetooth LE zeigt Beacons es mit Ausdrücken wie "sofort", " in der Nähe " usw. erkannt habe, und ich muss etwas Ähnliches auf Android zu schreiben.

Ich habe das Tutorial an https://developer.android.com/guide/topics/connectivity/bluetooth-le.html gefolgt und ich bin in der Lage, Liste erkannten Geräte und wollen nun den Abstand / Näherungs schätzen - hier es ist zu einem Problem geworden . Nach http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing ist es nur eine Handvoll von mathematischen Berechnungen . Sie erfordern jedoch mir, eine txPower Wert.

Nach https://thenewcircle.com/s/post/1553/bluetooth_smart_le_android_tutorial ( und Querverweise mit diesem https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile ), sollte es durch die Leuchtfeuer Geräte als " AD-Struktur " des Typs übertragen 0x0A werden. Also, was ich zu tun ist, analysieren die AD -Strukturen und suchen Sie für die Nutzlast des einen, der den Typ übereinstimmt.

Problem : - 2 estimotes und 2 appflares Ich habe 4 Baken bekam . Die estimotes nicht übertragen die txPower überhaupt und die appflares ausgestrahlt ihnen als 0 .

Gibt es etwas, ich hier fehlt? Die iOS-App scheint alles Handhabung ohne Probleme, aber mit dem iOS SDK es tut es hinter den Kulissen so bin ich nicht sicher, wie genau das gleiche oder ein ähnliches Verhalten zu produzieren. Gibt es eine andere Möglichkeit, ich könnte mein Problem lösen ?

Falls Sie möchten, einen Blick auf den Code, den ich mit den AD -Strukturen analysieren zu nehmen, ist es aus den oben genannten Dave Smith github entnommen und gefunden werden kann https://github.com/devunwired/accessory-samples/blob/master/BluetoothGatt/src/com/example/bluetoothgatt/AdRecord.java . Die einzige Änderung, die ich zu dieser Klasse tat, war die folgende Methode :

public byte[] getData() {

    return mData;
}

Und das ist, wie ich mit dem Rückruf von den 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]));
                }
            }
        }
    }
};

Und was ich in der Konsole zu sehen ist :

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

Top 5 Antwort

1davidgyoung @

Unklar ist, ob Ihre Unfähigkeit, lesen Sie die " txPower " oder " MeasuredPower " Eichkonstante ist auf die AdRecord Klasse oder wegen der Informationen nicht fehlen aus der Werbung die Sie versuchen zu analysieren sind . Sie gilt nicht für mich aus wie diese Klasse eine Standard iBeacon Werbung analysieren. Wie auch immer, es gibt eine Lösung :

LÖSUNG 1: Wenn Ihr Baken senden Standard iBeacon Anzeige, die die Eichkonstante enthält, können Sie sie analysieren, mithilfe von Code in der Open-Source- http://developer.radiusnetworks.com/ibeacon/android/ ist iBeacon Klasse https://github.com/RadiusNetworks/android-ibeacon-service/blob/master/src/main/java/com/radiusnetworks/ibeacon/IBeacon.java

LÖSUNG 2: Wenn Ihr Baken NICHT senden Standard iBeacon Werbung oder keine Eichkonstante beinhalten:

Sie müssen fest codieren eine Eichkonstante in Ihrer Anwendung für jeden Gerätetyp Sie verwenden könnten. Alles, was Sie wirklich brauchen, aus der Werbung zu schätzen, ist der Abstand der RSSI-Messung . Der springende Punkt bei der Einbettung eines Kalibrierungskonstante in dem Getriebe ist, um eine Vielzahl von Signalanlagen mit sehr unterschiedlichen Ausgangsleistung des Senders zu ermöglichen, mit dem gleichen Abstand Schätzalgorithmuszu arbeiten.

Die Kalibrierung konstant, wie die von Apple definierten, sagt im Grunde, was das RSSI sein sollte, wenn Ihr Gerät genau einen Meter von der Bake . Wenn das Signal stärker ist (weniger negativen RSSI), dann ist das Gerät weniger als einen Meter . Wenn das Signal schwächer (negativer RSSI) ist, dann ist das Gerät über einen Meter . Sie können eine Formel verwenden, um eine numerische Abschätzung der Entfernung zu machen. http://stackoverflow.com/a/20434019/1461050

Wenn Sie nicht mit Werbung, die eine " txPower " oder " MeasuredPower " Eichkonstante enthalten zu tun haben, dann können Sie hartcodieren eine Lookup-Tabelle in Ihrer Anwendung, die die bekannten Kalibrierungskonstanten für verschiedene Sender speichert . Dazu müssen Sie zuerst, um die durchschnittliche RSSI jedes Senders an einen Meter messen. Sie müssen dann eine Art von Schlüssel in der Tabelle nachschlagen diese Kalibrierungskonstanten . ( Vielleicht können Sie die einen Teil der Zeichenfolge der AD -Struktur oder die MAC-Adresse verwenden ? ) So Tisch könnte wie folgt aussehen :

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

Dann, nach der Analyse einer Anzeige können Sie in Ihrem onLeScan Verfahren wie folgt aus den Eichkonstante :

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

Die txPower von davidgyoung erwähnt wird durch die Formel:

RSSI = -10nlogd + A

d = Abstand, A = txPower, n = Signalausbreitungskonstanteund [ RSSI ] = dBm .

Im Freiraum n = 2, aber es wird auf der Basis je nach lokalen Geometrie - zum Beispiel, wird eine Wand rssi von ~ 3 dBm reduzieren und n entsprechend beeinflussen.

Wenn Sie die höchstmögliche Genauigkeit möchte, kann es sich lohnen, diese Werte experimentell zu bestimmen, für die jeweilige System sein.

Referenz: siehe http://www.rn.inf.tu-dresden.de/dargie/papers/icwcuca.pdf für eine detailliertere Erklärung der Ableitung und Kalibrierung.

3user1423561 @

verwenden Sie die getAccuracy () -Methode in der Bibliothek, es gibt Ihnen die Entfernung der Bake

4snayde @
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));
}