2013-10-17 70 views
17

我是德國Furtwangen大學的一名學生。BLE(iBeacons)三角測量

我在我的最後一期,現在正在寫論文。我對iBeacon及其背後的技術非常感興趣。我目前的項目是將信標技術與GPS,無線定位,GSM和NFC等其他技術進行比較。對於我的論文,我將創建不同的用例並比較結果。

在過去的幾天裏,我試圖確定我在一個房間裏的位置。我使用三個信標的相對距離(準確度),並將每個信標都放在我的房間中。 我得到三個圓圈並計算6個交點。 當弧度(準確度)太低時,我會人爲增加此值。然後我看看6點(交點)中哪一點最近。 (最近的三個點) 用這些點我得到一個三角形,並用此計算中間點。

我的問題是結果不是最好的。

我發現了一個更好的解決方案在這裏:

https://gis.stackexchange.com/questions/40660/trilateration-algorithm-for-n-amount-of-points

,但我有我的目的C. 實施這個麻煩,但我百思不得其解。我如何在Objective C中導入或獲取它。 我找到了一些庫(C,C++),但我不確定這些庫中的哪一個庫是最好的庫。

對我來說最好的解決方案是一個Objectice C數學庫,它可以用這些點計算(x1,x2,x3, - ,y1,y2,y3,---,r1,r2,r3)。

Graphic of my calculation now

+0

你有沒有這個運氣? –

+0

我也會對第一種解決方案感興趣,因爲我想嘗試一下導遊應用程序的可能性。準確性對我來說並不是最重要的。無論如何你可以分享邏輯,甚至是一些計算代碼? –

+0

您是否介意分享您在發佈的圖形中如何實現iPad應用程序?我設法提出了基於wikipedia Trilateration文章(http://en.m.wikipedia)的算法。org/wiki/Trilateration),但我目前正在試圖找到在iOS中映射我的座標的最佳方式。 – Yazid

回答

19

我用同樣的問題所困擾,後來我發現這個solution,Python編寫的。我嘗試將代碼移植到objective-c中,並使用相同的情況進行測試,結果是準確的。我修改了代碼,以便它可以接受二維矢量。

測試用例是:

P1 = (3,0) r1 = 6.4031 
P2 = (9,0) r2 = 4.1231 
P3 = (4,8) r3 = 5.6568 

我跑通過代碼這樣的數據:

//P1,P2,P3 is the point and 2-dimension vector 
NSMutableArray *P1 = [[NSMutableArray alloc] initWithCapacity:0]; 
[P1 addObject:[NSNumber numberWithDouble:3]]; 
[P1 addObject:[NSNumber numberWithDouble:0]]; 


NSMutableArray *P2 = [[NSMutableArray alloc] initWithCapacity:0]; 
[P2 addObject:[NSNumber numberWithDouble:9]]; 
[P2 addObject:[NSNumber numberWithDouble:0]]; 

NSMutableArray *P3 = [[NSMutableArray alloc] initWithCapacity:0]; 
[P3 addObject:[NSNumber numberWithDouble:4]]; 
[P3 addObject:[NSNumber numberWithDouble:8]]; 

//this is the distance between all the points and the unknown point 
double DistA = 6.4031; 
double DistB = 4.1231; 
double DistC = 5.6568; 

// ex = (P2 - P1)/(numpy.linalg.norm(P2 - P1)) 
NSMutableArray *ex = [[NSMutableArray alloc] initWithCapacity:0]; 
double temp = 0; 
for (int i = 0; i < [P1 count]; i++) { 
    double t1 = [[P2 objectAtIndex:i] doubleValue]; 
    double t2 = [[P1 objectAtIndex:i] doubleValue]; 
    double t = t1 - t2; 
    temp += (t*t); 
} 
for (int i = 0; i < [P1 count]; i++) { 
    double t1 = [[P2 objectAtIndex:i] doubleValue]; 
    double t2 = [[P1 objectAtIndex:i] doubleValue]; 
    double exx = (t1 - t2)/sqrt(temp); 
    [ex addObject:[NSNumber numberWithDouble:exx]]; 
} 

// i = dot(ex, P3 - P1) 
NSMutableArray *p3p1 = [[NSMutableArray alloc] initWithCapacity:0]; 
for (int i = 0; i < [P3 count]; i++) { 
    double t1 = [[P3 objectAtIndex:i] doubleValue]; 
    double t2 = [[P1 objectAtIndex:i] doubleValue]; 
    double t3 = t1 - t2; 
    [p3p1 addObject:[NSNumber numberWithDouble:t3]]; 
} 

double ival = 0; 
for (int i = 0; i < [ex count]; i++) { 
    double t1 = [[ex objectAtIndex:i] doubleValue]; 
    double t2 = [[p3p1 objectAtIndex:i] doubleValue]; 
    ival += (t1*t2); 
} 

// ey = (P3 - P1 - i*ex)/(numpy.linalg.norm(P3 - P1 - i*ex)) 
NSMutableArray *ey = [[NSMutableArray alloc] initWithCapacity:0]; 
double p3p1i = 0; 
for (int i = 0; i < [P3 count]; i++) { 
    double t1 = [[P3 objectAtIndex:i] doubleValue]; 
    double t2 = [[P1 objectAtIndex:i] doubleValue]; 
    double t3 = [[ex objectAtIndex:i] doubleValue] * ival; 
    double t = t1 - t2 -t3; 
    p3p1i += (t*t); 
} 
for (int i = 0; i < [P3 count]; i++) { 
    double t1 = [[P3 objectAtIndex:i] doubleValue]; 
    double t2 = [[P1 objectAtIndex:i] doubleValue]; 
    double t3 = [[ex objectAtIndex:i] doubleValue] * ival; 
    double eyy = (t1 - t2 - t3)/sqrt(p3p1i); 
    [ey addObject:[NSNumber numberWithDouble:eyy]]; 
} 


// ez = numpy.cross(ex,ey) 
// if 2-dimensional vector then ez = 0 
NSMutableArray *ez = [[NSMutableArray alloc] initWithCapacity:0]; 
double ezx; 
double ezy; 
double ezz; 
if ([P1 count] !=3){ 
    ezx = 0; 
    ezy = 0; 
    ezz = 0; 

}else{ 
    ezx = ([[ex objectAtIndex:1] doubleValue]*[[ey objectAtIndex:2]doubleValue]) - ([[ex objectAtIndex:2]doubleValue]*[[ey objectAtIndex:1]doubleValue]); 
    ezy = ([[ex objectAtIndex:2] doubleValue]*[[ey objectAtIndex:0]doubleValue]) - ([[ex objectAtIndex:0]doubleValue]*[[ey objectAtIndex:2]doubleValue]); 
    ezz = ([[ex objectAtIndex:0] doubleValue]*[[ey objectAtIndex:1]doubleValue]) - ([[ex objectAtIndex:1]doubleValue]*[[ey objectAtIndex:0]doubleValue]); 

} 

[ez addObject:[NSNumber numberWithDouble:ezx]]; 
[ez addObject:[NSNumber numberWithDouble:ezy]]; 
[ez addObject:[NSNumber numberWithDouble:ezz]]; 


// d = numpy.linalg.norm(P2 - P1) 
double d = sqrt(temp); 

// j = dot(ey, P3 - P1) 
double jval = 0; 
for (int i = 0; i < [ey count]; i++) { 
    double t1 = [[ey objectAtIndex:i] doubleValue]; 
    double t2 = [[p3p1 objectAtIndex:i] doubleValue]; 
    jval += (t1*t2); 
} 

// x = (pow(DistA,2) - pow(DistB,2) + pow(d,2))/(2*d) 
double xval = (pow(DistA,2) - pow(DistB,2) + pow(d,2))/(2*d); 

// y = ((pow(DistA,2) - pow(DistC,2) + pow(i,2) + pow(j,2))/(2*j)) - ((i/j)*x) 
double yval = ((pow(DistA,2) - pow(DistC,2) + pow(ival,2) + pow(jval,2))/(2*jval)) - ((ival/jval)*xval); 

// z = sqrt(pow(DistA,2) - pow(x,2) - pow(y,2)) 
// if 2-dimensional vector then z = 0 
double zval; 
if ([P1 count] !=3){ 
    zval = 0; 
}else{ 
    zval = sqrt(pow(DistA,2) - pow(xval,2) - pow(yval,2)); 
} 

// triPt = P1 + x*ex + y*ey + z*ez 
NSMutableArray *triPt = [[NSMutableArray alloc] initWithCapacity:0]; 
for (int i = 0; i < [P1 count]; i++) { 
    double t1 = [[P1 objectAtIndex:i] doubleValue]; 
    double t2 = [[ex objectAtIndex:i] doubleValue] * xval; 
    double t3 = [[ey objectAtIndex:i] doubleValue] * yval; 
    double t4 = [[ez objectAtIndex:i] doubleValue] * zval; 
    double triptx = t1+t2+t3+t4; 
    [triPt addObject:[NSNumber numberWithDouble:triptx]]; 
} 

NSLog(@"ex %@",ex); 
NSLog(@"i %f",ival); 
NSLog(@"ey %@",ey); 
NSLog(@"d %f",d); 
NSLog(@"j %f",jval); 
NSLog(@"x %f",xval); 
NSLog(@"y %f",yval); 
NSLog(@"y %f",yval); 
NSLog(@"final result %@",triPt); 

我測試通過使用上述的測試案例數據笛卡爾圖上繪製,並得到了導致未知點位於(8,4)處,然後使用上面的代碼進行測試並得到結果(7.999978,4.000021710625001)。

然後我做第二測試用數據:

P1 = (2,0) r1 = 5.831 
P2 = (8,0) r2 = 5.831 
P3 = (8,10) r3 = 5.831 

手動結果是(5,5),以及使用該代碼的結果是(5,5)。 所以,我相信代碼是正確的。

+0

工程就像一個魅力!非常感謝! – Mathijs

+0

不錯的解決方案,但它僅適用於3分不再。這不是OP要求的。 – luxcem

+1

這是2D的,不準確。您需要使用3D座標並找到3個或更多球體的攔截來計算您在建築物中的位置。這樣做需要非常複雜的數學運算。如果位於人體高度之上,iBeacons的效果最好。 3D考慮非常重要。 – coolcool1994