Szacowanie odległości/odległości w oparciu o RSSI-Bluetooth LE

Mam prostą aplikację na iOS, która wyświetla bliskość beaconów Bluetooth LE, które wykrywa za pomocą takich wyrażeń jak "immediate", "near" itp. i muszę napisać coś podobnego na Androida.

Śledziłem samouczek na Android developer i jestem w stanie wymienić wykryte urządzenia i teraz chcę oszacować odległość/bliskość - to tutaj stało się problemem. Według ten wątek to tylko garść matematycznych obliczenia. Wymagają jednak ode mnie podania wartości txPower.

[4]}zgodnie z ten samouczek Dave Smith (i odniesienie do tego oświadczenie Bluetooth SIG ), powinien być nadawany przez urządzenia beacon jako "struktura reklam" typu 0x0A. Więc to, co robię, to analizuję struktury reklam i szukam ładunku tego, który pasuje do typu.

Problem: [[20]] mam 4 beacony - 2 estymoty i 2 appflary. Szacunki nie nadają txPower w ogóle i appflares nadawać ich jako 0.

Czy coś mi umyka? Aplikacja na iOS wydaje się obsługiwać to wszystko bez żadnego problemu, ale za pomocą iOS SDK robi to za kulisami, więc nie jestem pewien, jak wytworzyć dokładnie to samo lub podobne zachowanie. Czy jest jakiś inny sposób na rozwiązanie mojego problemu?

Jeśli chcesz przyjrzeć się kodowi, którego używam do analizy struktur reklam, został on zaczerpnięty ze wspomnianego Githuba Dave ' a Smitha i można go znaleźć tutaj . Jedyną zmianą jaką dokonałem w tej klasie było dodanie następującej metody:

public byte[] getData() {

    return mData;
}

I tak sobie radzę z wywołaniem zwrotnym ze skanów:

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

A to co widzę w konsoli to:

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
Author: Community, 2014-04-01

4 answers

Nie jest jasne, czy niemożność odczytania stałej kalibracji " txpower "lub" measuredPower " jest spowodowana klasą AdRecord, czy też brakiem informacji w reklamach, które próbujesz przeanalizować. Nie wygląda mi na to, że ta klasa będzie analizować standardową reklamę iBeacon. Tak czy inaczej, jest rozwiązanie:

Rozwiązanie 1: Jeśli Twoje beacony wysyłają standardową reklamę iBeacon , która zawiera stałą kalibracji, możesz ją przeanalizować za pomocą kodu w open source Biblioteki iBeacon Androida klasy IBeacon tutaj.

Rozwiązanie 2: Jeśli Twoje beacony nie wysyłają standardowej reklamy iBeacon lub nie zawierają stałej kalibracji:

Musisz zakodować stałą kalibracji w aplikacji dla każdego typu urządzenia, którego możesz użyć. Wszystko, czego naprawdę potrzebujesz od reklamy do oszacowania odległości, to pomiar RSSI. Cały punkt osadzenia stałej kalibracyjnej w transmisji jest do pozwól szerokiej gamie beaconów o zupełnie innej mocy wyjściowej nadajnika pracować z tym samym algorytmem szacowania odległości.

Stała kalibracji, zdefiniowana przez Apple, w zasadzie mówi, czym powinien być RSSI, jeśli urządzenie znajduje się dokładnie jeden metr od nadajnika. Jeśli sygnał jest silniejszy (mniej ujemny RSSI), to urządzenie znajduje się w odległości mniejszej niż jeden metr. Jeśli sygnał jest słabszy (bardziej ujemny RSSI), to urządzenie znajduje się ponad metr dalej. Możesz użyć formuły, aby numeryczne oszacowanie odległości. zobacz tutaj.

Jeśli nie masz do czynienia z reklamami, które zawierają stałą kalibracji " txpower "lub " measuredPower", możesz na twardo zakodować tabelę wyszukiwania w aplikacji, która przechowuje znane stałe kalibracji dla różnych nadajników. Najpierw musisz zmierzyć średnie RSSI każdego nadajnika w odległości jednego metra. Następnie będziesz potrzebował jakiegoś klucza, aby sprawdzić te stałe kalibracji w tabeli. (Być może możesz użyć jakaś część ciągu znaków ze struktury reklamy, czy adres mac?) Więc twój stół może wyglądać tak:

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

Następnie po przetworzeniu reklamy możesz sprawdzić stałą kalibracji w swojej metodzie onLeScan w następujący sposób:

String macAddress = device.getAddress();
Integer txPower = txPowerLookupTable.get(macAddress);
 24
Author: davidgyoung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:50

txPower wspomniany przez @ davidgyoung jest dany wzorem:

RSSI = -10 n log d + A

Gdzie

  • d = odległość
  • A = txPower
  • n = stała propagacji sygnału
  • RSSI = dBm

W wolnej przestrzeni n = 2, ale będzie się różnić w zależności od lokalnej geometrii – na przykład ściana zmniejszy RSSI o ~3dBm i odpowiednio wpłynie na n.

Jeśli chcesz jak największej dokładności, może warto eksperymentalnie określ te wartości dla danego systemu.

Odniesienie: patrz Artykuł ocena niezawodności RSSI dla lokalizacji wewnętrznej autorstwa Qian Dong i Waltenegus Dargie, aby uzyskać bardziej szczegółowe wyjaśnienie wyprowadzenia i kalibracji.

 33
Author: tep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-20 18:04:46
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));
}
 27
Author: sergey.n,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-19 09:57:26

Użyj metody getAccuracy () w bibliotece, podaje ona odległość beacona

 -2
Author: user1423561,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-24 06:50:14