Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any tool to calculate the coefficient A,B and C for formula 'd=A*(r/t)^B+C'? #47

Closed
RichardFans opened this issue Oct 29, 2014 · 17 comments

Comments

@RichardFans
Copy link

we just have done RSSI measurements on Xiaomi3/2s/4, and want to know how to calculate the coefficient, so that we can add the results to model-distance-calculations.json.

@RichardFans
Copy link
Author

0.25 43
0.5 53
1 57
2 67
3 61
4 62
5 63
6 66
7 69
8 71
9 72
10 75
12 78
14 80
16 81
18 80
20 85
25 87
30 87

4.4.4
KTU84P
MI 3
XiaoMi

@davidgyoung
Copy link
Member

We imported out data into R (the free statistical computing software) and used the nls function (non-linear least squares) to fit the data with a power curve. Here is the power curve equation we used: function(x, b0, b1, b2) {b0 + b1*(x^b2)}

The nls function solves for the coefficients b0, b1, and b2 which are used in our formula for A, B, and C.

Here's a tutorial on curve fitting in R for more information http://www.walkingrandomly.com/?p=5254

@RichardFans, if you can use the procedure above to get the coefficients, I will add them to the project for the device you mention.

@RichardFans
Copy link
Author

please wait for us to do more test. in addition, we use this beacon for the test above:
http://item.taobao.com/item.htm?spm=a1z09.2.9.10.NGB4Gr&id=39098735081&_u=ulb6fc2830d

@jessolo
Copy link

jessolo commented Nov 14, 2014

Is there a way to disable ModelSpecificDistance calculations. We are not using the distance feature of the beacon. We need to only identify a beacon and don't need to know how far the beacon is from the mobile device. If it is not possible ti disable, is there already a list for popular android devices. We may not be able to do the above mentioned tests as done by RichardFans.

@davidgyoung
Copy link
Member

@jessolo, there is no need to disable these calculations. By default, if the Android device model using the library is not in the built-in list, then the library will fall back to using the calculations for the Nexus 5. The consequence of the fallback is less accurate distance estimates. But if you don't use the distance estimates, then it doesn't matter to you.

@jessolo
Copy link

jessolo commented Nov 19, 2014

Actually it is detecting the default model. But it throws a Runtime
exception during beacon service start. This is crashing the application. I
am not handling the runtime exception.

On Fri, Nov 14, 2014 at 3:51 PM, David G. Young notifications@github.com
wrote:

@jessolo https://github.com/jessolo, there is no need to disable these
calculations. By default, if the Android device model using the library is
not in the built-in list, then the library will fall back to using the
calculations for the Nexus 5. The consequence of the fallback is less
accurate distance estimates. But if you don't use the distance estimates,
then it doesn't matter to you.


Reply to this email directly or view it on GitHub
#47 (comment)
.

@davidgyoung
Copy link
Member

This is certainly not expected behavior. Can you please attach a stack trace of the exception?

@jessolo
Copy link

jessolo commented Nov 19, 2014

Pls find attached the screen shot of the stack trace...
screen shot 2014-11-19 at 2 24 20 pm

@jessolo
Copy link

jessolo commented Nov 19, 2014

InputStream stream = ModelSpecificDistanceCalculator.class.getResourceAsStream("/"+path);
if (stream == null) {
this.getClass().getClassLoader().getResourceAsStream("/"+path);
}
if (stream == null) {
throw new RuntimeException("Cannot load resource at "+path);
}
Pls refer to the code snippet from ModelSpecificDistanceCalculator. It could be a probable miss here. The stream is not assigned when stream is from class loader.Even if the file is readable from classloader stream, it will still throw a RuntimeException.

But the above exception is definitely not because of this. It is possible to load from the web and the file is getting saved. But unable to read from the file.

@davidgyoung
Copy link
Member

@jessolo, I have moved your issue above to #58 so as not to hijack issue #47

@vchukhonkin
Copy link

Hi, David. I've tried to get A, B and C coefficients for ASUS Zenfone 4 using procedure that you've posted for RichardFans. But I've got some errors while trying to do that. I use a vector of RSSI values as xdata, vector of measured distance values as ydata and function that you've posted above. I set initial value of b0 to 0.1, b1 = 1, b2 = 0.1. Unfortunately, I have no experience with R software, so I may do mistakes in script. Could you please help me to fix them, if they appeared. So, here is my example script for several measured values:

xdata = c(-41,-47,-49,-52,-57)
ydata = c(0.5,0.8,1.0,1.3,1.5)

plot(xdata,ydata)

b0 = 0.1
b1 = 1
b2 = 0.1

fit = nls(ydata ~ b0 + b1*(b2^xdata), start=list(b0=b0,b1=b1,b2=b2))

summary(fit)

new = data.frame(xdata = seq(min(xdata),max(xdata),len=200))
lines(new$xdata,predict(fit,newdata=new))

sum(resid(fit)^2)

confint(fit)

Thank you in advance.

@jnebeker
Copy link
Contributor

One issue with your approach is the use of raw RSSI values instead of the ratio of measured RSSI over RSSI at 1 meter. This is what we plot against distance to solve for the formula coefficients. I also recommend that you capture more data for the best results (with distances up to ~20 meters at least).

I’m also not an R expert so I’m not sure if your method is wrong, I can just say that it’s a little different than what we did. Instead of having xdata and ydata be separate, we imported them from a csv as a data table which can then be fed into the nls function. We also defined the power function separately before feeding it into nls. Below is the Rscript we use to get formula coefficients and a sample csv file with our Nexus 5 measurements.

powerfit.r:

#!/usr/bin/env Rscript

args <- commandArgs(trailingOnly = TRUE)
print("Imported Data")
dat <- read.table(args[1], header=TRUE, sep=",")
dat

powerfunction <- function(x, b0, b1, b2) {b0 + b1*(x^b2)}
sink("/dev/null")
power.fit <- nls(Distance ~ powerfunction(Ratio, intercept, multiplier, power), data = dat, start = list(intercept=0,multiplier=1,power=2), trace = T)
sink()
print("Power Curve Coefficients")
coef(power.fit)

Nexus5.csv:

Ratio,Distance
0.7435897436,0.25
0.9230769231,0.5
1,1
1.153846154,2
1.384615385,3
1.512820513,4
1.41025641,5
1.58974359,6
1.692307692,7
1.512820513,8
1.58974359,9
1.461538462,10
1.641025641,12
1.58974359,14
1.641025641,16
1.58974359,18
1.58974359,20
1.846153846,25
1.846153846,30
1.846153846,40

You can get the coefficients from these with the following command:

$ Rscript powerfit.r Nexus5.csv
[1] "Imported Data"
       Ratio Distance
1  0.7435897     0.25
2  0.9230769     0.50
3  1.0000000     1.00
4  1.1538462     2.00
5  1.3846154     3.00
6  1.5128205     4.00
7  1.4102564     5.00
8  1.5897436     6.00
9  1.6923077     7.00
10 1.5128205     8.00
11 1.5897436     9.00
12 1.4615385    10.00
13 1.6410256    12.00
14 1.5897436    14.00
15 1.6410256    16.00
16 1.5897436    18.00
17 1.5897436    20.00
18 1.8461538    25.00
19 1.8461538    30.00
20 1.8461538    40.00
[1] "Power Curve Coefficients"
 intercept multiplier      power
 0.7141178  0.3912203  7.0927688

@vchukhonkin
Copy link

Ok, thanks a lot. I captured some values just for test and I'll do more measurements for getting coefficients. The main problem was using raw RSSI values, I think. Because in this case I've got an model error or infinite loop error while running the script.

@Fiodora
Copy link

Fiodora commented Dec 13, 2014

Hi i tried to calculate the coefficients as well, for the test i used jnebeker values and i'm getting the same Power Curve Coefficients as him. Are these allready the Coefficients that need to be defined in the model-distance-calculations.json? I tried to do this with the values that were used to get the Nexus5 in the .json but im getting completly different Coefficients.
I'm using jnebekers approach for the algorithm:
powerfit.r

#!/usr/bin/env Rscript

args <- commandArgs(trailingOnly = TRUE)
print("Imported Data")
dat <- read.table(args[1], header=TRUE, sep=";")
dat

powerfunction <- function(x, b0, b1, b2) {b0 + b1*(x^b2)}
power.fit <- nls(Distance ~ powerfunction(Ratio, intercept, multiplier, power), data = dat, start = list(intercept=0,multiplier=1,power=2), trace = T)
print("Power Curve Coefficients")
coef(power.fit)

I used these http://altbeacon.github.io/android-beacon-library/distance-calcs/nexus5.html
and changed them to
Nexus5.csv

Ratio;Distance
0.803921569;0.25
0.843137255;0.5
0.960784314;1
1.274509804;2
1.137254902;3
1.117647059;4
1.31372549;5
1.31372549;6
1.509803922;7
1.37254902;8
1.352941176;9
1.470588235;10
1.411764706;12
1.411764706;14
1.529411765;16
1.62745098;18
1.588235294;20
1.588235294;25
1.470588235;30
1.62745098;40

This is what im getting:

[1] "Imported Data"
       Ratio Distance
1  0.8039216     0.25
2  0.8431373     0.50
3  0.9607843     1.00
4  1.2745098     2.00
5  1.1372549     3.00
6  1.1176471     4.00
7  1.3137255     5.00
8  1.3137255     6.00
9  1.5098039     7.00
10 1.3725490     8.00
11 1.3529412     9.00
12 1.4705882    10.00
13 1.4117647    12.00
14 1.4117647    14.00
15 1.5294118    16.00
16 1.6274510    18.00
17 1.5882353    20.00
18 1.5882353    25.00
19 1.4705882    30.00
20 1.6274510    40.00

[1] "Power Curve Coefficients"
 intercept multiplier      power
  0.182060   1.073929   6.652519

How do i get to these coefficients?

"coefficient1": 0.42093,
"coefficient2": 6.9476,
"coefficient3": 0.54992

Thank you in advance.

@jnebeker
Copy link
Contributor

@Fiodora, your method is correct. One reason for the difference in coefficients is that these coefficients:

"coefficient1": 0.42093,
"coefficient2": 6.9476,
"coefficient3": 0.54992

were calculated using a different data set, so you should be getting different values. The steps you're following to get the coefficients for the data on this page are correct, but the ratio values you calculated appear to be slightly off. Instead of dividing by the iPhone 5S average RSSI at 1 meter when calculating the ratio, divide by the Nexus 5 RSSI at 1 meter. In the distance formula we want the RSSI ratio to be of measurements from the same device. The reason we have the separate iPhone 5S value is to provide an absolute reference for a known device, which we can use to account for the slight differences in power for different beacons. Here are the ratio values and corresponding coefficients that I calculated for this data:

[1] "Imported Data"
       Ratio Distance
1  0.8367347     0.25
2  0.8775510     0.50
3  1.0000000     1.00
4  1.3265306     2.00
5  1.1836735     3.00
6  1.1632653     4.00
7  1.3673469     5.00
8  1.3673469     6.00
9  1.5714286     7.00
10 1.4285714     8.00
11 1.4081633     9.00
12 1.5306122    10.00
13 1.4693878    12.00
14 1.4693878    14.00
15 1.5918367    16.00
16 1.6938776    18.00
17 1.6530612    20.00
18 1.6530612    25.00
19 1.5306122    30.00
20 1.6938776    40.00
[1] "Power Curve Coefficients"
 intercept multiplier      power
 0.1820634  0.8229884  6.6525179

I will update the Nexus 5 example measurements page to reflect these coefficients to prevent any further confusion.

@Ancy1
Copy link

Ancy1 commented Oct 15, 2015

can sone one help how to do coeffient values for Samsung Galaxy, Samsung Note, LG to find the distance for ibeacons in android.appreciate your help?

@pierre-oord
Copy link

@RichardFans do you still have the original data of the phones you tested, including the iPhone 5s reference value at 1 meter? It would be great if you could send this to me, we are working on putting together a database.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants