В конце концов, я понял это сам - или, по крайней мере, значительно улучшил точность.
Подход, описанный в Википедии (уравнение 7), очевидно, не очень подходит для этого приложения, но в этом случае он уже намного проще.
Учитывая уравнение 6 из Википедии, мы можем сильно упростить это: R_0
можно угадать как радиус Земли, так как начало координат ECEF лежит в центре Земли. Следовательно, нет необходимости сдвигать все, чтобы сделать одну точку источником, и мы можем использовать все N
уравнения.
В python, с P
массивом координат ECEF и dists
расстояниями до этих точек, все сводится к
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
При таком подходе то, что я описал как Шаг 4 , больше не требуется. Фактически, это даже ухудшает решение.
Теперь точность колеблется между 2 км и 275 м - в большинстве случаев лучше, чем «оптимальная» трилатерация с ошибкой 464 м.