AltBeacon / android-beacon-library

Allows Android apps to interact with BLE beacons
Apache License 2.0
2.84k stars 836 forks source link

Google Pixel RSSI Values Vs Distances #498

Open ghassanghassan opened 7 years ago

ghassanghassan commented 7 years ago

Hi, I am not sure if I this is the right place to post this issue here or on StackOverflow.com. We tried to use the AltBeacon library in order to get the distances from the RSSI.

We expected to see low RSSI values (i.e., going away from the zero) as the phone is further away from the beacon.

Actually, we are seeing the reverse of that behavior. In other words, as we are further away from the beacon, we receive higher RSSI values (i.e., close to zero) and as we get close to the beacon, we receive low RSSI values (i.e., far from zero)

We kept repeating the run and it is always the same issue.

We are using Google Pixel G-2PW4100 and OS version Android 7.1 Nougat. In addition, the latest AltBeacon library is used.

Just want to know if it happened before with anybody. Any guidance is appreciated.

Thank you, Ghassan

davidgyoung commented 7 years ago

Wow. That is really surprising. Just to rule out other factors, do you have another device you can verify this on? You should always see (on average) more negative RSSI values as you get further away from a beacon.

ghassanghassan commented 7 years ago

Thank you for the fast reply. I really appreciate it! My understanding is that we did try two of these phones. However, we would need to double check if one or two were used.

Some thoughts: 1) what I am thinking is that maybe if we use Kalman filter, it may resolve the problem.

2) we found that these beacons connect for sometime and then disconnect and then reconnect again for sometime and then re-disconnect. Maybe in this case, we are not getting sufficient RSSI values.

3) I found a comment posted by you about the calibrated value that it might be incorrect

I hope I did not violate the rules regarding this forum when I mentioned my thoughts.

Thanks in advance

davidgyoung commented 7 years ago

@ghassanghassan, I think this is relevant to this forum in the sense that if what you report is confirmed, it means a Google-manufactured device is behaving in new and unexpected ways that affects the core use of this library.

I would like to see confirmation before jumping to conclusions. It would be helpful if you could get a 60 second debug log from the Pixel when ranging in the foreground with beaconManager.setDebug(true), with a beacon 1m away from the Pixel phone for the first 30 secs and ~10 meters away for the second 30 secs.

ghassanghassan commented 7 years ago

Thanks you very much. We will get back to you as soon as we follow these steps. Kindly keep this thread open since we may need some time

lakshmanpasala commented 7 years ago

I see a lot of guys asking for the Kalman Filter. Just for reference, this is how I implemented Kalman filter for RSSI values.

public class Kalman {

/* Complete calculation of Kalman Filter */
public static Double kalman (ArrayList<Double> inputValues, double initialVariance, double noise){
    return calculate(inputValues, initialVariance, noise);
}

/* Calculation of Kalman Filter using default values for wireless Access Points data acquisition */
public static Double kalman (ArrayList<Double> inputValues){
    return calculate(inputValues, 50.0, 0.008);
}

/* Calculation of arithmetic mean */
public static Double mean (ArrayList<Double> inputValues){
    return StatUtils.mean(inputValues);
}

/*This method is the responsible for calculating the value refined with Kalman Filter */
private static Double calculate(ArrayList<Double> inputValues, double initialVariance, double noise){
    Double kalmanGain;
    Double variance = initialVariance;
    Double processNoise = noise;
    Double measurementNoise = StatUtils.variance(inputValues);
    Double mean = inputValues.get(0);

    for (Double value : inputValues){
        variance = variance + processNoise;
        kalmanGain = variance/((variance+measurementNoise));
        mean = mean + kalmanGain*(value - mean);
        variance = variance - (kalmanGain*variance);
    }

    return mean;
}

} and with a StatUtils class

public class StatUtils {

static Double variance (ArrayList<Double> values){
    Double sum = 0.0;
    Double mean = mean(values);
    for(double num : values){
        sum += Math.pow(num - mean , 2);
    }
    return sum/(values.size()-1);
}

static Double mean (ArrayList<Double> values){
    return sum(values)/values.size();
}

private static Double sum (ArrayList<Double> values){
    Double sum = 0.0;
    for (Double num : values){
        sum+=num;
    }
    return sum;
}

}

ghassanghassan commented 7 years ago

Thank you lakshmanpasala. We will have a look at it. David, let us know what you think about the values in the log file Log.txt

I just forgot also to mention that we did check it for both phones.

Thank you very much

davidgyoung commented 7 years ago

Thanks, @ghassanghassan.

I was actually hoping to see a log including low-level Android logging from BluetoothAdapter. These are sent out automatically to LogCat -- you just have to capture in a way that you aren't filtering only for your application. They look like this:

D/BluetoothAdapter﹕ onScanResult() - Device=F9:57:DA:5A:67:09 RSSI=-66

Capturing these will help eliminate any higher level processing that might be affecting the readings.

That said, a quick graph of the data you sent shows the result below. You can see there is very little difference in RSSI readings over time. The bands you see are likely different signal readings on different advertising channels -- something that is common, and is an important reason to capture as many statistical samples across all channels as possible. The graph does appear to show a weak relationship where the signal is slightly stronger on average at the end of the time scale. If you have moved the beacon further away at this point, this is certainly the opposite of what you would expect to see. It's unclear what is going on there, and I'd still like to see the BluetoothAdapter logs to rule out something in higher level processing.

screen shot 2017-04-21 at 11 12 07 am
ghassanghassan commented 7 years ago

Thanks @davidgyoung for your quick reply. I will send it as soon as I have it.

Thanks again

ghassanghassan commented 7 years ago

We have it now but I am not really sure about the content of the file now. Let me know if I missing anything. Log.txt

Thanks in advance.

davidgyoung commented 7 years ago

Sorry, @ghassanghassan, it seems that Android 7.0 removed that debug line from BluetoothAdapter. I'm going to have to add a new debug line to the library to capture that. I'll send you an ad-hoc binary build to test with.

davidgyoung commented 7 years ago

The new debug line will look like this, and you will get one such line for each beacon packet detected.

04-23 20:10:55.766 5656-5676/org.altbeacon.beaconreference:BeaconService D/BeaconService: Beacon packet detected for: id1: b3048a20-868f-4470-8147-e97a84d2b641 id2: 0 id3: 0 with rssi -45

To capture this in the log you will need to use the ad-hoc library release here:

https://github.com/AltBeacon/android-beacon-library/releases/tag/2.9.2-mpb1

lakshmanpasala commented 7 years ago

@ghassanghassan , could you re-confirm the behavior

Actually, we are seeing the reverse of that behavior. In other words, as we are further away from the beacon, we receive higher RSSI values (i.e., close to zero) and as we get close to the beacon, we receive low RSSI values (i.e., far from zero)

using Nordic's nRF Connect APP?

ghassanghassan commented 7 years ago

Thanks @lakshmanpasala for the follow-up. The behavior is still the same and we are using iBKS beacons. We do not want to use for the moment the Time of Flight algorithm but maybe later on but thanks anyways.

rrjanbiah commented 7 years ago

@lakshmanpasala Thanks for the Kalman implementation. Do you have a fork? (I don't know where to hook your code in the library)

lakshmanpasala commented 7 years ago

@rrjanbiah , the implementation is fairly simple. You just need to create the above two classes Kalman and StatUtils. And where ever you have the method onBeaconServiceConnect, create a collection of beacon id and rssi. You can then recursively add all the rssi values of an unique beacon id into an ArrayList and pass it Kalman.kalman method. This would return a normalized rssi value which you can then use to calculate distance.

davidgyoung commented 7 years ago

I have opened issue #502 for tracking the Kalman filter feature request. Please use that issue for further discussion of that feature, so we don't hijack this issue which is about Google Pixel RSSI measurements. I am renaming this issue to clarify its focus.