编辑:本地化总是关于x=1980.000032943933547358028590679168701171875, y=3191.99997642902735606185160577297210693359375
我编写了以下代码来解决到达时间延迟问题。也就是说,给定三个观察者的位置、某些信号的速度以及每个接收器“看到”信号的时间,我想定位源。在这里,我们假设源和观察者位于二维平面(平面欧几里得空间)中。
我的解决方案如下:
给定每个观察者看到信号的时间,我选择一个接收器作为“基线”,我认为它是 t=0。然后我从其他两个观察者的到达时间中减去那个时间。现在,我为每个观察者分配一个圆,半径由这个差异给出(“基线”观察者从 r=0 开始),我慢慢增加每个圆的半径,直到所有三个圆在某个点相交。
实际上,它们不太可能精确地相交在一个点上,因为我只能在每次迭代时将半径增加一个离散量,而且我们还假设但不知道观察者的时钟是精确同步的。
为了解决这个问题,我改编了 Paul Bourke 的代码:http://paulbourke.net/geometry/circlesphere/tvoght.c(在这里推理:http: //paulbourke.net/geometry/circlesphere/)。我的改编或多或少与这个相同:https ://stackoverflow.com/a/19724186/14073182 。
我的问题是,代码总是产生相同的本地化,在一个单位的十分之几以内。我尝试生成一些伪数据(即选择一些位置,计算预期延迟,将其输入算法并查看它是否重建正确的定位),并且该算法仍然产生大致相同的定位......即,相当接近中心由三个接收器形成的三角形。
知道我在这里做错了什么吗?我与一些人(从事 GIS、测地线、类似领域的物理学家和一位数学家)交谈过,但没有得到任何结果。
我的代码如下(考虑到所有因素,它相当简短)。要本地化某些来源,请调用localizeSource(a,b,c,&xf,&xy)
. 其中a
、b
和c
是延迟(半径), 和xf
是xy
存储定位坐标的位置。
#define EPSILON 0.0001 // Define some threshold
#define x0 3000.00
#define y0 3600.00
#define x1 2100.00
#define y1 2100.00
#define x2 0960.00
#define y2 3600.00
bool findIntersection(double r0, double r1, double r2, double *xf, double *yf){
double a, dx, dy, d, h, rx, ry;
double point2_x, point2_y;
dx = x1 - x0;
dy = y1 - y0;
d = sqrt((dy*dy) + (dx*dx));
if (d > (r0 + r1))
{
return false;
}
a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ;
point2_x = x0 + (dx * a/d);
point2_y = y0 + (dy * a/d);
h = sqrt((r0*r0) - (a*a));
rx = -dy * (h/d);
ry = dx * (h/d);
double intersectionPoint1_x = point2_x + rx;
double intersectionPoint2_x = point2_x - rx;
double intersectionPoint1_y = point2_y + ry;
double intersectionPoint2_y = point2_y - ry;
dx = intersectionPoint1_x - x2;
dy = intersectionPoint1_y - y2;
double d1 = sqrt((dy*dy) + (dx*dx));
dx = intersectionPoint2_x - x2;
dy = intersectionPoint2_y - y2;
double d2 = sqrt((dy*dy) + (dx*dx));
if(fabs(d1 - r2) < EPSILON) {
std::cout << std::setprecision(100) << intersectionPoint1_x << ", " << intersectionPoint1_y << "\n";
*xf = intersectionPoint1_x; *yf = intersectionPoint1_y;
return true;
}
else if(fabs(d2 - r2) < EPSILON) {
std::cout << std::setprecision(100) << intersectionPoint2_x << ", " << intersectionPoint2_y << "\n";
*xf = intersectionPoint2_x; *yf = intersectionPoint2_y;
return true;
}
else {
return false;
}
}
void localizeSource(double r0, double r1, double r2, double *xf, double *yf){
bool foundSource = false;
while(foundSource == false){
foundSource = findIntersection(r0, r1, r2, xf, yf);
r0 += 0.0001; r1 += 0.0001; r2 += 0.0001;
}
}
int main(){
double xf, xy;
localizeSource(1000,3000,0,&xf,&xy);
}