Closed WallyHale closed 9 years ago
@WallyHale, you are correct in your observations. The current formula used by the library is imperfect and has real problems on underestimating distance for weaker transmitters.
We have been experimenting with a different formula in this branch here: https://github.com/AltBeacon/android-beacon-library/tree/path-loss-distance-calculations. We are trying to use this formula under the theory that we can simply calculate a single dB difference between the receiver sensitivity of various device models and apply that device-specific correction constant before calculating distance. If this works, it should give better distance estimates for different beacon transmitter power levels.
However, we are still having trouble because we are finding that the RSSI returned by some Android devices at larger distances is inconsistent with what would be expected. Doing tests with the Samsung Galaxy S6 vs. the iPhone, we found that the delta in the RSSI between the devices seeing the same beacon at various distances did not stay consistent:
The RSSI offset between the iPhone and the Galaxy S6 Edge + does not stay consistent with changes in distance. For this technique to work, we need the delta RSSI in dB to be consistent for a device even as the distance increases. Unfortunately, we saw RSSI numbers like this:
Rad Beacon Dot Beacon @ 1m
iPhone Galaxy S6 Delta
-48.1 -50.8 -2.7
Rad Beacon Dot Beacon @ 5m
iPhone Galaxy S6 Delta
-70.0 -81.1 -11.1
I'd appreciate help from folks with any expertise in this area to figure out a solution.
The RSSI offset between the iPhone and the Galaxy S6 Edge + does not stay consistent with changes in distance.
While I understand that it is VERY difficult to have a one solution fits all (especially with the variety of Android devices), that doesn't explain the distance calculations with similar, and consistent RSSI values.
If similar RSSI readings to that of an iOS device, the formula should be able to be tweaked so the distance calculation in relation to the RSSI should be somewhat accurate, or at least a lot more accurate than what we are currently seeing? ie. a -90 RSSI with a Tx of -63, should never equal 4 metres?
I too am seeing massive differences with the RSSI reading, when comparing a Nexus 5X to a Nexus 5, but difference in receivers and devices aside, the formula should be accurate for whatever RSSI / Tx values it's being fed.
If, in the end, the device has a stronger receiver, so the beacon appears closer than it actually is, this shouldn't matter, the important thing is a sound calculation when the RSSI's DO match
I just realised that the figures and explanation may be misleading.
The distance and RSSI quoted above is the calculated distance (beacon.getDistance()) value, NOT the actual physical distance of the device from the beacon.
So, the Android and iOS devices are side by side, moving away from beacon and taking readings, and the RSSI values are similar on both devices, but the calculated distance is wildly incorrect on Android compared to 1) the iOS distance reading 2) the actual physical distance the device is from the beacon
So this is not to do with the Bluetooth receiver picking up weaker signals, it's the calculation of the RSSI.
The beacons were physically ~25m from the devices, the RSSI are similar (-90), the Android device says the beacon is 4m away, while iOS more on the money.
I hope this clears any confusion!
Understood. As I mentioned before, the current formula in the library has a significant flaw. It works well with higher powered transmitters but exhibits the results you see on lower power transmitters. This is why we proposed switching to a different formula that works better in the referenced pull request: https://github.com/AltBeacon/android-beacon-library/tree/path-loss-distance-calculations It will help the problem you see.
The trouble is that we have not gotten far enough with this formula to merge it into the release. I'd welcome any help you could give in testing with the branch associated with that pull request to see how well it predicts the distances on the devices you have.
Thanks @davidgyoung - I've built the path-loss-distance-calculation branch and included it in my project (removing the 2.6 build references to be certain), but I'm still seeing much shorter calculated distances when RSSI is -90 to -100 .. beacon.getDistance returns 5 metres or so away, when it's physically ~17 metres.
We'll keep investigating!
Two things you can experiment with, @WallyHale:
I have been working at tuning this off and on for months, and would love to get this to the point where it gives consistently better results than the current built-in formula.
We have come up with a linear approximation algorithm that meets our needs, and importantly, giving similar and consistent readings to iOS on various devices tested.
Wally, that sounds very promising. Do you plan to submit a pull request to incorporate this into the library?
David Helms Chief Product Officer Radius Networks dhelms@radiusnetworks.com 703.582.1576
On Nov 20, 2015, at 7:34 AM, WallyHale notifications@github.com wrote:
We have come up with a linear approximation algorithm that meets our needs, and importantly, giving similar and consistent readings to iOS on various devices tested.
— Reply to this email directly or view it on GitHub https://github.com/AltBeacon/spec/issues/30#issuecomment-158386127.
I'd love to see what you have come up with if you can share.
It probably won't suit all uses, but maybe you can work with / refine it further. The calculations were done from our testing at loudest beacon setting (-63), but it also works when changing beacon loudness to lower (weaker) values too without modifying the code.
public double calculateDistance(int tx, double rssi) {
//define reference points based on iOS test
//point 1
double x_1 = (double) -35 / -63;
double y_1 = 0;
//point 2
double x_2 = (double) -63 / -63;
double y_2 = 1;
//point 3
double x_3 = (double) -70 / -63;
double y_3 = 2;
//point 4
double x_4 = (double) -75 / -63;
double y_4 = 4.5;
//point 5
double x_5 = (double) -80 / -63;
double y_5 = 10;
//point 6
double x_6 = (double) -90 / -63;
double y_6 = 25;
//calculate relative signal strength the distance depends on
double x = rssi / tx;
//calculate distance
double distance = 0.0;
double x_startpoint = 0;
double y_startpoint = 0;
double x_endpoint = 0;
double y_endpoint = 0;
//check if x less than x_1 first, set distance to 0 in this case
if (x < x_1)
distance = 0.0;
else // check if x is larger then x_6 set distance to unknown in this case
if (x > x_6) distance = 0.0;
else
// find 2 points to use for approximation
if (x >= x_5) {
// x is between 5 and 6
x_startpoint = x_5;
y_startpoint = y_5;
x_endpoint = x_6;
y_endpoint = y_6;
} else if (x >= x_4) {
// x is between 4 and 5
x_startpoint = x_4;
y_startpoint = y_4;
x_endpoint = x_5;
y_endpoint = y_5;
} else if (x >= x_3) {
// x is between 3 and 4
x_startpoint = x_3;
y_startpoint = y_3;
x_endpoint = x_4;
y_endpoint = y_4;
} else if (x >= x_2) {
// x is between 2 and 3
x_startpoint = x_2;
y_startpoint = y_2;
x_endpoint = x_3;
y_endpoint = y_3;
} else if (x >= x_1) {
// x is between 1 and 2
x_startpoint = x_1;
y_startpoint = y_1;
x_endpoint = x_2;
y_endpoint = y_2;
}
Log.i("CalculateDistance", "x_startpoint= " + x_startpoint);
Log.i("CalculateDistance", "y_startpoint= " + y_startpoint);
Log.i("CalculateDistance", "x_endpoint= " + x_endpoint);
Log.i("CalculateDistance", "y_endpoint= " + y_endpoint);
// if we found 2 points use linear approximation formula below
if (x_startpoint > 0 && x_endpoint > 0)
distance = ((y_endpoint - y_startpoint) / (x_endpoint - x_startpoint)) * (x - x_startpoint) + y_startpoint;
// display distance
Log.i("CalculateDistance", "distance= " + distance);
return distance;
}
I have created an issue to track this here: https://github.com/AltBeacon/android-beacon-library/issues/318 as it is more appropriate to be in the repo for the Android Beacon Library.
Testing Android and iOS devices side by side, using 7 beacons on their "loudest" setting (-63 Tx), we find that -
Distance, iOS (RSSI) 0m (-35), 1m (-63 = Tx), 2m (-70), 4.5m (-75), 10m (-80), 25 (-90)
Distance, Android (RSSI) 0m (-35), 1m (-63 = Tx), 1.2m (-70), 1.6m (-75), 2.7m (-80), 4 (-90)
Is it possible to either find a way to adjust parameter in the formula to mach iOS calculations closer or use liner approximation based on the experimental data above