Estimation de la balise de proximité/distance basée sur RSSI - Bluetooth LE
J'ai une simple application iOS qui affiche la proximité de la Bluetooth LE les balises qu'il détecte à l'aide des expressions telles que "immédiate", "près de", etc. et j'ai besoin d'écrire quelque chose de similaire sur Android.
J'ai suivi le tutoriel à Développeur Android et je suis capable de la liste des appareils détectés et souhaitez maintenant l'estimation de la distance/proximité - c'est là que c'est devenu un problème. Selon ce fil c'est juste une poignée de calculs mathématiques. Cependant, ils m'obligent à fournir un txPower valeur.
Selon ce tutoriel par Dave Smith (et en les croisant avec cette Bluetooth SIG déclaration), il doit être diffusée par la balise périphériques comme une "structure AD" de type 0x0A
. Donc ce que je fais est d'analyser l'ANNONCE de structures et de regarder pour la charge de celui qui correspond au type.
Problème: j'ai 4 balises - 2 estimotes et 2 appflares. Le estimotes à ne pas diffuser le txPower à tous et la appflares diffuser la leur en tant que 0.
Est-ce que je suis en manque ici? L'application iOS semble être la manipulation de tout sans aucun problème, mais en utilisant le SDK iOS il n'derrière les scènes, donc je ne suis pas sûr de la façon de produire exactement le même ou un comportement similaire. Est-il un autre moyen je pourrais résoudre mon problème?
Dans le cas où vous souhaitez prendre un coup d'oeil au code que j'utilise pour analyser l'ANNONCE de structures, il est pris de la même Dave Smith github et peut être trouvé ici. Le seul changement que j'ai fait pour cette classe était ajoutez la méthode suivante:
public byte[] getData() {
return mData;
}
Et c'est comment je gère le rappel de l'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]));
}
}
}
}
};
Et ce que je vois dans la console:
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
Vous devez vous connecter pour publier un commentaire.
Il est difficile de savoir si votre incapacité à lire le "txPower" ou "measuredPower" constante d'étalonnage de l'est en raison de la
AdRecord
classe ou en raison de renseignements manquants dans les publicités que vous essayez de l'analyser. Il ne me semble pas comme ça classe d'analyser un standard iBeacon publicité. De toute façon, il y a une solution:SOLUTION 1: Si vos balises envoyer un standard iBeacon annonce qui comprend la constante d'étalonnage, vous pouvez l'analyser en utilisant un code en open source Android iBeacon Bibliothèque's IBeacon classe ici.
SOLUTION 2: Si votre invisibles NE PAS envoyer un standard iBeacon annonce ou de ne pas inclure une constante d'étalonnage:
Vous devez coder en dur une constante d'étalonnage dans votre application pour chaque type de périphérique que vous pourriez utiliser. Tous vous avez vraiment besoin de la publicité pour l'estimation de la distance est le RSSI de mesure. Le point de l'ensemble de l'incorporation d'une constante d'étalonnage dans la transmission est de permettre une grande variété de balises avec tout autre émetteur puissance de sortie de travailler avec la même distance de l'estimation de l'algorithme.
La constante d'étalonnage, tel que défini par Apple, dit en substance ce que le RSSI doit être si votre appareil est exactement un mètre de distance de la balise. Si le signal est plus fort (moins négatif RSSI), l'appareil est à moins d'un mètre. Si le signal est plus faible (plus négative RSSI), puis l'appareil est supérieure à un mètre de l'appareil. Vous pouvez utiliser une formule pour faire une estimation chiffrée de la distance. Voir ici.
Si vous n'êtes pas affaire avec les annonces qui contiennent un "txPower" ou "measuredPower" constante d'étalonnage, vous pouvez coder en dur une table de recherche dans votre application qui stocke l'connu constantes d'étalonnage pour les différents émetteurs. Vous devez d'abord mesurer la moyenne RSSI de chaque émetteur à un mètre de l'appareil. Vous aurez alors besoin d'une sorte de clé à rechercher ces constantes d'étalonnage dans le tableau. (Peut-être vous pouvez utiliser la partie de la chaîne à partir de l'ANNONCE de la structure ou de l'adresse mac?) Si votre table pourrait ressembler à ceci:
Puis après l'analyse d'une annonce, vous pouvez consulter la constante d'étalonnage dans votre
onLeScan
méthode comme ceci:La
txPower
mentionné par @davidgyoung est donnée par la formule:RSSI = -10 n log d + A
où
d
= distanceA
= txPowern
= signal de la constante de propagationRSSI
= dBmDans l'espace libre
n = 2
, mais il va varier en fonction de la géométrie locale – par exemple, un mur de réduireRSSI
par~3dBm
et affecteran
en conséquence.Si vous voulez la plus grande précision possible, il peut être utile de déterminer expérimentalement ces valeurs pour votre système.
De référence: voir le papier Évaluation de la Fiabilité des RSSI pour l'Intérieur de la Localisation Qian Dong et Waltenegus Dargie pour une explication plus détaillée de la dérivation et de l'étalonnage.
utiliser le getAccuracy() la méthode dans la bibliothèque, il vous donne la distance de la balise
getAccuracy()
méthode n'est pas une méthode fiable pour calculer la distance. Utiliser seulement à identifier la différence entre les deux balises avec la même valeur RSSI.