英文:
How to get accurate distance estimations using Beacons
问题
我正在尝试开发一个Android应用程序,用于计算3个Eddystone信标之间的位置。
我有3个信标:
final double BEACON_1_X = 0.50, BEACON_1_Y = 6.38;
Identifier BEACON_1_ID = Identifier.parse("0x111111111111");
final double BEACON_2_X = 5.86, BEACON_2_Y = 0.1;
Identifier BEACON_2_ID = Identifier.parse("0x222222222222");
final double BEACON_3_X = 0.05, BEACON_3_Y = 2.63;
Identifier BEACON_3_ID = Identifier.parse("0x333333333333");
我正在使用AltBeacon库来计算从扫描设备到信标的距离。
以下是我用于扫描信标并根据信标计算位置的代码:
for (Beacon beacon : beacons) {
if (!uuids.contains(beacon)) {
uuids.add(beacon);
noBeacons.setText("" + ++beaconsFound);
}
// 如果我们看到的信标使用Eddystone-UID帧
if (beacon.getServiceUuid() == 0xfeaa && beacon.getBeaconTypeCode() == 0x00) {
curr_dist = Double.parseDouble(df.format(beacon.getDistance()));
if(beacon.getId2().equals(BEACON_1_ID)){
BEACON_1_DISTANCE = curr_dist;
} else if (beacon.getId2().equals(BEACON_2_ID)) {
BEACON_2_DISTANCE = curr_dist;
} else if (beacon.getId2().equals(BEACON_3_ID)) {
BEACON_3_DISTANCE = curr_dist;
if (BEACON_1_DISTANCE != 0 && BEACON_2_DISTANCE != 0){
calculatePosition(BEACON_1_DISTANCE,BEACON_2_DISTANCE,BEACON_3_DISTANCE);
logger.append("\nUser Position ("+SCANNER_X + ", " + SCANNER_Y + ")");
}
}
// 显示其ID和距离
// String item = "id: " + beacon.getId2() + ", distance: " + curr_dist + " m.";
// logger.append("\n" + item);
}
}
现在,为了计算位置,我有这个函数:(我在互联网上找到了这个从已知距离计算位置的公式,所以我认为它是正确的)
void calculatePosition(double d1, double d2,double d3) {
double A = 2*BEACON_2_X - 2*BEACON_1_X;
double B = 2*BEACON_2_Y - 2*BEACON_1_Y;
double C = d1*d1 - d2*d2 - BEACON_1_X*BEACON_1_X + BEACON_2_X*BEACON_2_X - BEACON_1_Y*BEACON_1_Y + BEACON_2_Y*BEACON_2_Y;
double D = 2*BEACON_3_X - 2*BEACON_2_X;
double E = 2*BEACON_3_Y - 2*BEACON_3_X;
double F = d2*d2 - d3*d3 - BEACON_2_X*BEACON_2_X + BEACON_3_X*BEACON_3_X - BEACON_2_Y*BEACON_2_Y + BEACON_3_Y*BEACON_3_Y;
SCANNER_X = (C*E - F*B) / (E*A - B*D);
SCANNER_Y = (C*D - A*F) / (B*D - A*E);
}
无论如何,我的问题是curr_dist = Double.parseDouble(df.format(beacon.getDistance()));
根本不准确。
/**
* 基于RSSI的运行平均值和包含在信标广告中的传输功率校准值的计算距离的估算值。此值特定于接收传输的Android设备类型。
*
* @see #mDistance
* @return 距离
*/
public double getDistance() {
if (mDistance == null) {
double bestRssiAvailable = mRssi;
if (mRunningAverageRssi != null) {
bestRssiAvailable = mRunningAverageRssi;
}
else {
LogManager.d(TAG, "Not using running average RSSI because it is null");
}
mDistance = calculateDistance(mTxPower, bestRssiAvailable);
}
return mDistance;
}
我可以将信标放在3米处,并获得约6米左右的估计值。我可以将信标放在0.3米处,并获得2.5米的估计值。我的观点是这个函数对我来说不起作用。我不知道是我做错了什么,还是AltBeacon的问题,还是根本不可能获得正确的距离。如果您知道任何获取更准确距离估算的方法,我将不胜感激。可以是库或手动方法。在此先行致谢。
英文:
I am trying to develop an Android application that calculates the position between 3 Eddystone beacons.
I have my 3 beacons:
final double BEACON_1_X = 0.50, BEACON_1_Y = 6.38;
Identifier BEACON_1_ID = Identifier.parse("0x111111111111");
final double BEACON_2_X = 5.86, BEACON_2_Y = 0.1;
Identifier BEACON_2_ID = Identifier.parse("0x222222222222");
final double BEACON_3_X = 0.05, BEACON_3_Y = 2.63;
Identifier BEACON_3_ID = Identifier.parse("0x333333333333");
I am using the AltBeacon library in order to calculate the distance from the scanning device to the beacons.
Here is my code which I use in order to scan for the beacons and calculate the position according to the beacons.
for (Beacon beacon : beacons) {
if (!uuids.contains(beacon)) {
uuids.add(beacon);
noBeacons.setText("" + ++beaconsFound);
}
// If the beacon we see uses the Eddystone-UID frame
if (beacon.getServiceUuid() == 0xfeaa && beacon.getBeaconTypeCode() == 0x00) {
curr_dist = Double.parseDouble(df.format(beacon.getDistance()));
if(beacon.getId2().equals(BEACON_1_ID)){
BEACON_1_DISTANCE = curr_dist;
} else if (beacon.getId2().equals(BEACON_2_ID)) {
BEACON_2_DISTANCE = curr_dist;
} else if (beacon.getId2().equals(BEACON_3_ID)) {
BEACON_3_DISTANCE = curr_dist;
if (BEACON_1_DISTANCE != 0 && BEACON_2_DISTANCE != 0){
calculatePosition(BEACON_1_DISTANCE,BEACON_2_DISTANCE,BEACON_3_DISTANCE);
logger.append("\nUser Position ("+SCANNER_X + ", " + SCANNER_Y + ")");
}
}
// Show its id and distance
// String item = "id: " + beacon.getId2() + ", distance: " + curr_dist + " m.";
// logger.append("\n" + item);
}
}
Now in order to calculate the position I have this function: (I have found this formula on the internet that finds the position from 3 known distances so I suppose it's correct)
void calculatePosition(double d1, double d2,double d3) {
double A = 2*BEACON_2_X - 2*BEACON_1_X;
double B = 2*BEACON_2_Y - 2*BEACON_1_Y;
double C = d1*d1 - d2*d2 - BEACON_1_X*BEACON_1_X + BEACON_2_X*BEACON_2_X - BEACON_1_Y*BEACON_1_Y + BEACON_2_Y*BEACON_2_Y;
double D = 2*BEACON_3_X - 2*BEACON_2_X;
double E = 2*BEACON_3_Y - 2*BEACON_3_X;
double F = d2*d2 - d3*d3 - BEACON_2_X*BEACON_2_X + BEACON_3_X*BEACON_3_X - BEACON_2_Y*BEACON_2_Y + BEACON_3_Y*BEACON_3_Y;
SCANNER_X = (C*E - F*B) / (E*A - B*D);
SCANNER_Y = (C*D - A*F) / (B*D - A*E);
}
Anyway, my problem here is that the
curr_dist = Double.parseDouble(df.format(beacon.getDistance()));
is not accurate at all.
/**
* Provides a calculated estimate of the distance to the beacon based on a running average of
* the RSSI and the transmitted power calibration value included in the beacon advertisement.
* This value is specific to the type of Android device receiving the transmission.
*
* @see #mDistance
* @return distance
*/
public double getDistance() {
if (mDistance == null) {
double bestRssiAvailable = mRssi;
if (mRunningAverageRssi != null) {
bestRssiAvailable = mRunningAverageRssi;
}
else {
LogManager.d(TAG, "Not using running average RSSI because it is null");
}
mDistance = calculateDistance(mTxPower, bestRssiAvailable);
}
return mDistance;
}
I can have a beacon at 3m and get estimations that it is at 6m or so. I can have a beacon at 0.3m and get an estimation of 2.5m. My point is that this function doesn't work for me. I don't know if I am doing something wrong or is it some fault of AltBeacon or is it just impossible to get a correct distance. If you know any way to get more accurate distance estimates I would appreciate it. It can be a library or a manual way. Thank you in advance.
答案1
得分: 1
使用蓝牙距离估算时,您必须设定您的期望。"估算"这个词是有原因的,因为该值永远不会非常准确。在理想条件下,它们会给您一个距离的大致概念(例如,当您实际距离两米时,它可能估算为1-5米)。正如您所见,这并不足够准确,不能很好地用于三角定位等技术。
我写了一篇深入的文章,解释了为什么距离估算不够准确,您可以采取哪些措施来尽可能提高它们的准确性,不应该对它们做什么,以及为什么它们在某些用例中仍然非常有价值。文章链接:距离估算为什么不够准确。
英文:
You have to set your expectations when using Bluetooth distance estimates. The word estimate is used for a reason -- the value will never be highly accurate. Under ideal conditions, they will give you a general idea of distance (e.g. it estimate 1-5 meters when you are really two meters away). As you have seen, this isn't accurate enough to work well for techniques for trilateration.
I wrote a deep dive explaining why distance estimates are not more accurate, the steps you can take to make them as accurate as possible, what you shouldn't do with them, and why they are still very valuable for some use cases.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论