2013-10-17 15 views
17

私はドイツのFurtwangen大学の学生です。BLE(iBeacons)Trilateration

私は私の最終的な任期にあり、今私の論文を書いています。私は非常にiBeaconsとその背後にある技術に興味があります。私の現在のプロジェクトは、ビーコン技術をGPS、ワイヤレスロケーション、GSM、NFCなどの他のテクノロジーと比較することです。私の論文では、さまざまなユースケースを作成し、結果を比較します。

最後の数日間、私は部屋の中で自分の位置を特定しようとしました。私は3つのビーコンからの相対距離(精度)を使用し、すべてのビーコンを私の部屋の固定位置にしました。 私は3つの円を取得し、6つの交差点を計算します。 ラジアン(精度)が低すぎる場合は、この値を人為的に増加させます。次に、私は6点(交差点)のどれが最も近いかを見ます。 (最も近い3つの点) これらの点で私は三角形を得、これで中点を計算します。

私の問題は、結果が本当に最高ではないということです。

私はここで、より良い解決策を見つけた:

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

が、私はトラブルのObjective Cでこれを実装したいてきた しかし、私は解決策を理解しています。どのようにしてObjective Cでインポートしたり取得したりすることができますか? libs(C、C++)が見つかりましたが、これらのlibsのどれがベストであるかわかりません。

私にとって最良の解決策は、これらの点(x1、x2、x3、 - 、y1、y2、y3、---、r1、r2、r3)で計算できるObjectice C数学ライブラリです。

Graphic of my calculation now

+0

あなたはこれに運があったことがありますか? –

+0

私は一種のツアーガイドアプリケーションの可能性を少し試してみたいので、最初の解決策にも興味があります。正確さは私にとって最も重要ではありません。とにかく論理を共有できますか、あるいは計算コードの一部を共有することはできますか? –

+0

投稿したグラフィックでiPadアプリをどのように達成したか分かりますか?私は、wikipedia Trilaterationの記事(http://en.m.wikipedia)に基づいたアルゴリズムを思いついた。org/wiki/Trilateration)、私は現在、iOSで自分の座標をマップする最良の方法を見つけようとしています。 – Yazid

答えて

19

私は同じ問題に苦しんでいたし、私はPythonで書かれ、このsolutionを見つけました。コードをobjective-cに移植し、同じケースをテストに使用してみましたが、結果は正確です。私は2次元ベクトルを受け入れることができるようにコードを修正しました。

テストケースだった:

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)を得ます。

は、その後、私はデータを使用して第2の試験を行った:

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