Eventually, I figured it out myself - or at least improve the accuracy significantly.
The approach described at wikipedia (Eq.7) is apparently not very suited for this application, but in this case it is already a lot easier.
Considering Eq. 6 from wikipedia, we can simplify it a lot: R_0
can be guessed as the earth radius, as the origin of ECEF coordinates lies in the center of earth. Therefore, there is no need to shift everything to make one Point the origin and we can use all N
equations.
In python, with P
an array of ECEF coordinates and dists
the distances to these points, it all boils down to
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
With this approach, what I described as Step 4 is no longer necessary. In fact, it even makes the solution worse.
Now, accuracy ranges between 2km and 275m -- in most cases better than the "optimal" trilateration with an error of 464m.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…