2013-10-17 3 views
17

저는 독일의 Furtwangen 대학의 학생입니다.BLE (iBeacons) Trilateration

나는 나의 마지막 학기에 있으며 지금 나는 내 논문을 쓰고있다. 저는 iBeacons과 그 뒤에 숨어있는 기술에 매우 관심이 있습니다. 나의 현재 프로젝트는 비콘 기술을 GPS, 무선 위치, GSM 및 NFC와 같은 다른 기술과 비교하는 것입니다. 저의 논문에서는 다양한 유스 케이스를 만들어 결과를 비교해 보겠습니다.

지난 며칠 동안 나는 방에서 나의 위치를 ​​결정하려고 노력했습니다. 3 개의 비컨으로부터 상대 거리 (정확도)를 사용하고 모든 비콘을 내 방의 고정 된 위치에 둡니다. 세 개의 원을 얻고 6 개의 교차를 계산합니다. 라디안 (정확도)이 너무 낮 으면이 값을 인위적으로 늘립니다. 그러면 가장 가까운 6 점 (교차점)을 봅니다. (세 개의 가장 가까운 점) 그 점들을 가지고 저는 삼각형을 얻었고, 이것으로 저는 중간 점을 계산합니다.

내 문제는 결과가 실제로 최고가 아니란 점입니다.

은 여기 더 나은 해결책을 발견 :

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

하지만 문제가 목적 C. 이 구현을 겪고있다하지만이 솔루션을 이해합니다. Objective C에서 어떻게 가져 오거나 가져올 수 있습니까? 일부 libs (C, C++)를 찾았지만 이들 lib 중 가장 좋은 것이 무엇인지 모릅니다.

나를위한 가장 좋은 해결책은이 점들 (x1, x2, x3, -, y1, y2, y3, ---, r1, r2, r3)을 계산할 수있는 Objectice C 수학 라이브러리입니다.

Graphic of my calculation now

+0

행운이 있나요? –

+0

일종의 투어 가이드 응용 프로그램에 대한 가능성을 조금 실험하고 싶으므로 첫 번째 솔루션에도 관심이 있습니다. 정확성은 나를 위해 가장 중요하지 않습니다. 어쨌든 논리를 공유 할 수 있습니까? 아니면 계산 코드 중 일부를 공유 할 수 있습니까? –

+0

게시 한 그래픽에서 iPad 앱을 어떻게 구현했는지 공유 하시겠습니까? 나는 위키피디아 삼부작 (Trilateration) 기사 (http : //en.m.wikipedia.org/wiki/Trilateration)하지만 현재 iOS에서 좌표를 매핑하는 가장 좋은 방법을 찾고 있습니다. – Yazid

답변

19

저도 같은 문제로 고민 한 후 나는 파이썬으로 작성된이 solution을 발견했다. objective-c로 코드를 포팅하고 테스트를 위해 같은 케이스를 사용했는데 그 결과가 정확합니다. 2 차원 벡터도 허용 할 수 있도록 코드를 수정했습니다.

테스트 케이스였다 : 위의 테스트 케이스 데이터를 사용하여 데카르트 다이어그램에 그려

//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); 

내가 테스트 한하고있어 :

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

는 내가 코드를 통해이 데이터를 실행 그 결과 미지의 점이 (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)이다

그러면 I 번째 테스트 데이터를 사용했다. 코드가 맞다고 생각합니다.

+0

매력처럼 작동합니다! 정말 고마워! – Mathijs

+0

좋은 솔루션이지만 더 이상 3 점으로 만 작동합니다. 그것은 OP가 요구하는 것이 아닙니다. – luxcem

+1

이것은 2D이며 정확하지 않습니다. 빌딩에서의 위치가 어디인지 계산하려면 3D 좌표를 사용하고 3 개 이상의 영역 차단을 찾아야합니다. 이 방법을 사용하는 것은 매우 복잡한 수학을 필요로합니다. iBeacons는 사람 높이보다 높으면 가장 잘 작동합니다. 3D 고려는 매우 중요합니다. – coolcool1994

관련 문제