GPS坐标的多点定位

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GPS坐标的多点定位相关的知识,希望对你有一定的参考价值。

我有N GPS坐标与N距离给我一个未知的位置,我想确定。

我的第一种方法是使用三点和三边测量,正如here所描述的那样。这种方法已经非常准确(最佳误差~5km),但我想改进这一点并增加鲁棒性。因为给定距离开始时不是很准确,所以我考虑使用多个测量和多点定位。然而,事实证明这种方法准确性不太准确(最佳误差~100km)虽然我提供超过3点/距离(最多6次测试),现在我问,如果有人知道我可以拥有什么做错了。

简而言之,我的多点定位方法如下:

  1. 将所有坐标转换为ECEF
  2. 如qqxswpoi中的等式7所述构建矩阵
  3. 使用SVD查找最小化器
  4. 由于解决方案仅达到规模,我使用根寻找方法来确定归一化,以便转换回LLA的坐标导致高度为0(我的初始假设是所有坐标都在零高度)
  5. 转换回LLA

LLA / ECEF转换经过双重检查并且正确无误。第2步和第3步我用欧氏坐标(和精确距离)检查并显示正确。我自己想出了第4步,我不知道这是否是一个很好的方法,所以欢迎提出建议。

+++ UPDATE

我已经在python中汇总了示例代码,以说明一些基本事实的问题。三角测量接近400米,而多重定位在这里10-130公里。因为长度,我把它放在wikipedia

答案

最终,我自己弄清楚了 - 或者至少显着提高了准确性。

维基百科(方程式7)中描述的方法显然不太适合这个应用程序,但在这种情况下它已经容易多了。

考虑方程式来自维基百科的6,我们可以简化它:ideone可以猜测为地球半径,因为ECEF坐标的原点位于地球的中心。因此,没有必要移动所有东西使一个点成为原点,我们可以使用所有R_0方程。

在python中,N是一个ECEF坐标数组,P指向这些点的距离,这一切都归结为

dists

通过这种方法,我不再需要我所描述的步骤4。事实上,它甚至使解决方案变得更糟。

现在,精度范围在2km到275m之间 - 在大多数情况下比“最佳”三边测量更好,误差为464m。

另一答案

一些评论:

1)您已经针对确切的答案检查了一些步骤。我建议您创建玩具问题,并在观察中添加已知量的随机噪声。由于您在这种情况下知道正确答案,因此您可以看到错误传播会发生什么。如果你的方法在这里工作得很好但对真实数据很糟糕,你可能想要考虑现实生活中的可怕行为,例如一个或几个距离严重错误。

2)我不知道为什么你的解决方案只是达到规模,因为底层数据被正确缩放 - 如果我去那里用绳索切割长度并将它们绑定到固定点,就没有歧义。当您使用SVD求解方程式(7)时,您是否正在执行类似www.cse.unr.edu/~bebis/MathMethods/SVD/lecture.pdf的操作以获得最小二乘解?这应该给你x,y和z没有歧义。

3)我完全不确定观察错误是如何起作用的(7)。一方面,我不喜欢所有的分歧。对于未知位置给定x,y,z的测量距离和计算距离之间的差异的平方和,可能值得写下等式,然后将其最小化为x,y,z。维基百科的文章由于其成本而放弃了这种方法,但它可能会给你一个更准确的答案,即使你不能在实践中使用这种方法,计算和比较这个答案也可能会告诉你一些事情。

另一答案

我按照上面显示的@ zerm代码进行了相当好的工作(黄色是从3个塔点计算出来的)。结果显示在Folium片段中。 R = 6378137 # Earth radius in meters A = [] for m in range(0,len(P)): x = P[m][0] y = P[m][1] z = P[m][2] Am = -2*x Bm = -2*y Cm = -2*z Dm = R*R + (pow(x,2)+pow(y,2)+pow(z,2)) - pow(dists[m],2) A += [[Am,Bm,Cm,Dm]] # Solve using SVD A = numpy.array(A) (_,_,v) = numpy.linalg.svd(A) # Get the minimizer w = v[3,:] w /= w[3] # Resulting position in ECEF

但是,当我使用@mcdowella建议(#2)使用MxN系统解决方案的最小二乘法进行相同的算法时,结果要好得多。 Multilateration using linalg.SVD

这是修改后的代码:

Multilateration using Least Squares MxN

我还在探索其他多点定位方法,但这篇文章真的让我理解了N点MLAT的基础知识。谢谢!

另一答案

为了改善A = [] b = [] for m in range(0,len(P)): x = P[m][0] y = P[m][1] z = P[m][2] Am = 2*x Bm = 2*y Cm = 2*z Dm = R*R + (pow(x,2)+pow(y,2)+pow(z,2)) - pow(dists[m],2) A += [[Am,Bm,Cm]] b += [[Dm]] # Solve using Least Squares of an MxN System # A*x = b --> x = (ATA)_inv.AT.b = A+.b A = np.array(A) b = np.array(b) AT = A.T ATA = np.matmul(AT,A) ATA_inv = np.linalg.inv(ATA) Aplus = np.matmul(ATA_inv,AT) x = np.matmul(Aplus,b) # convert back to lat/long from ECEF # convert to degrees lat = math.degrees(math.asin(x[2] / R)) lon = math.degrees(math.atan2(x[1],x[0])) ,改善SVD解决方案的一种方法是根据纬度考虑地球半径的变化;这特别影响海拔估计,但它对纬度和经度也有一些连锁反应。 “简单”的解决方案是使用the accepted answer的平均值,根据维基百科,它是6371008.8米而不是6378137米。

更准确的估计是调整纬度的R

R

然后根据其中一个初始点的纬度设置def EarthRadiusAtLatitude(lat): rlat = np.deg2rad(lat) a = np.float64(6378137.0) b = np.float64(6356752.3) rad = np.sqrt(((a*a*np.cos(rlat))**2 + (b*b*np.sin(rlat))**2) / ((a*np.cos(rlat))**2 + (b*np.sin(rlat))**2)) return rad 。或者,如果您的纬度变化很大,您可以根据R的估计值计算SVD,并使用初步解决方案的纬度来使用更接近的R估算来求解。

在进行此调整之后,在我使用构建的示例和基于LTE eNodeB时序提前值的“真实世界”数据的实验中,SVD解决方案通常在纬度和经度的一秒内,除了在一些退化情况下,这与a相当基于迭代优化的解决方案(即最小化距离残差)。

以上是关于GPS坐标的多点定位的主要内容,如果未能解决你的问题,请参考以下文章

GPS定位的偏移校正(WGS84与火星坐标互转)

html5 如何调用安卓手机获取gps坐标

Android实现gps定位的坐标转换成地址

JavaScript 地理定位:检查距 2 gps 坐标的距离

使用科尔多瓦地理定位插件没有互联网的 GPS 坐标

什么叫GPS单点定位