我有 3 个接收器(A、B 和 C),以及一些位置未知的信号产生源(比如说声音或光)。给定 A、B 和 C 的位置,以及每个接收器“听到”信号的时间,我想确定源的方向。
我知道有一些方法可以通过 TDoA 多边/三边测量来实现,但是我在实现计算时遇到了问题。对于那些完全不熟悉该主题的人,没有很多关于此的清晰、详细的信息。外面的东西是模糊的,更理论化的,或者对我来说有点太深奥了。
SO上的一些类似帖子(但不完全是我所追求的):
TDOA multilateration to locate a sound source
Trilateration of a signal using Time Difference(TDOA)
这也很有趣,但假设我们有一些界限:
Multiliteration implementation with inaccurate distance data
@Dave 还评论了一个优秀且易于访问的资源 https://sites.tufts.edu/eeseniordesignhandbook/files/2017/05/FireBrick_OKeefe_F1.pdf ,但它没有达到足够的深度,以至于人们可能能够在代码中实际实现这一点(至少,对于没有深入了解回归知识的人来说,找到结果双曲线的交集等)。
[编辑]:我应该补充一点,我可以假设 3 个传感器和源位于地球表面,并且地球曲率的影响可以忽略不计(即我们可以在二维中工作)。
最佳答案
有趣的问题。我懒得推导出代数解的方程。相反为什么不适合结果?
因此,只需使用能够找到局部解决方案的任何拟合方法(使用某些误差值的优化/最小化)来拟合 2D(或更高)位置。当我使用我的简单时 approximation search以适应位置结果看起来不错。
算法是:
粗略的拟合并不是所有的启发式都会减少很多问题。
从测试位置到接收站的简单旅行时间。
所以从所有接收者的时间中减去最小的到达时间。实际测量时间也是如此。这确保时间不涉及相对偏移。
简单的 abs 差异就足够了。将此值用作拟合参数(优化)。
这里使用我上面链接中的近似类来执行此操作的小 C++ 示例:
//---------------------------------------------------------------------------
// TDoA Time Difference of Arrival
//---------------------------------------------------------------------------
const int n=3;
double recv[n][3]; // (x,y) [m] receiver position,[s] time of arrival of signal
double pos0[2]; // (x,y) [m] object's real position
double pos [2]; // (x,y) [m] object's estimated position
double v=340.0; // [m/s] speed of signal
double err=0.0; // [m] error between real and estimated position
//---------------------------------------------------------------------------
void compute()
{
int i;
double x,y,a,da,t0;
//---------------------------------------------------------
// init positions
da=2.0*M_PI/(n);
for (a=0.0,i=0;i<n;i++,a+=da)
{
recv[i][0]=256.0+(220.0*cos(a));
recv[i][1]=256.0+(220.0*sin(a));
}
pos0[0]=300.0;
pos0[1]=220.0;
// simulate measurement
t0=123.5; // some start time
for (i=0;i<n;i++)
{
x=recv[i][0]-pos0[0];
y=recv[i][1]-pos0[1];
a=sqrt((x*x)+(y*y)); // distance to receiver
recv[i][2]=t0+(a/v); // start time + time of travel
}
//---------------------------------------------------------
// normalize times into deltas from zero
a=recv[0][2]; for (i=1;i<n;i++) if (a>recv[i][2]) a=recv[i][2];
for (i=0;i<n;i++) recv[i][2]-=a;
// fit position
int N=6;
approx ax,ay;
double e,dt[n];
// min, max,step,recursions,&error
for (ax.init( 0.0,512.0, 32.0 ,N, &e);!ax.done;ax.step())
for (ay.init( 0.0,512.0, 32.0 ,N, &e);!ay.done;ay.step())
{
// simulate measurement -> dt[]
for (i=0;i<n;i++)
{
x=recv[i][0]-ax.a;
y=recv[i][1]-ay.a;
a=sqrt((x*x)+(y*y)); // distance to receiver
dt[i]=a/v; // time of travel
}
// normalize times dt[] into deltas from zero
a=dt[0]; for (i=1;i<n;i++) if (a>dt[i]) a=dt[i];
for (i=0;i<n;i++) dt[i]-=a;
// error
e=0.0; for (i=0;i<n;i++) e+=fabs(recv[i][2]-dt[i]);
}
pos[0]=ax.aa;
pos[1]=ay.aa;
//---------------------------------------------------------
// compute error
x=pos[0]-pos0[0];
y=pos[1]-pos0[1];
err=sqrt((x*x)+(y*y)); // [m]
}
//---------------------------------------------------------------------------
这里预览:蓝点是接收器,红点是物体的实际位置,黄叉是它的估计位置。该地区是
512x512 m
我将它与初始步骤匹配 32 m
和 6
导致错误的递归 ~0.005 m
我对结果非常满意...您可以更改接收器的数量 n
对源代码或算法没有任何真正的改变。我将接收器位置初始化为均匀分布在圆圈上,但位置可能是任何其他位置(并非全部位于粗线)
关于algorithm - 给定三个接收器的位置和它们接收信号的时间(到达时间延迟),如何定位信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63707712/