我想在 python 中实现三边测量。我找不到我的功能有什么问题?
I want to implement trilateration in python. I can't t find what is wrong with my funtion?
我正在尝试实现三边测量。 Funtion 获取三个 3d cordiantes 和每个坐标与基站的距离。它必须 return 点在 3d space 三边测量中的位置。
def trilateration(P1, P2, P3, r1, r2, r3):
p1 = np.array([0, 0, 0])
p2 = np.array([P2[0] - P1[0], P2[1] - P1[1], P2[2] - P1[2]])
p3 = np.array([P3[0] - P1[0], P3[1] - P1[1], P3[2] - P1[2]])
v1 = p2 - p1
v2 = p3 - p1
Xn = (v1)/np.linalg.norm(v1)
tmp = np.cross(v1, v2)
Zn = (tmp)/np.linalg.norm(tmp)
Yn = np.cross(Xn, Zn)
i = np.dot(Xn, v2)
d = np.dot(Xn, v1)
j = np.dot(Yn, v2)
X = ((r1**2)-(r2**2)+(d**2))/(2*d)
Y = (((r1**2)-(r3**2)+(i**2)+(j**2))/(2*j))-((i/j)*(X))
Z1 = np.sqrt(r1**2-X**2-Y**2)
Z2 = np.sqrt(r1**2-X**2-Y**2)*(-1)
K1 = P1 + X*Xn + Y * Yn + Z1 * Zn
K2 = p1 + X * Xn + Y * Yn - Z2 * Zn
return K1
我有一个测试例子。使用这些坐标和距离 P1=(2,2,0), P2=(3,3,0), P3=(1,4,0)
r1=1,r2=1,r3=1.4142,应该return P=(2,3,0)。
但它是 returnig [3.33253331 1.66746669 1.33373281]
问题来自 sqrt
的表达式,由于数值不精确,该表达式略微为负。这将修复它:
Z1 = np.sqrt(max(0, r1**2-X**2-Y**2))
Z2 = -Z1
改变这些行给我正确的结果:[1.99999361 3.00000639 0.]
注意:如果该点与其他3点在同一平面上,则Z值为0,否则有两种解法。此外,如@meowgoesthedog 所述,为 r1
、r2
和 r3
提供精确值非常重要。但是,即使使用精确值,您也始终需要注意浮点数的不精确性并安全地使用 sqrt
.
我没有足够的声誉来评论,所以我必须写一个新的答案。
您的代码仍有一些错误。经过多次测试,我发现K2的计算有一些错别字。
完美的功能应该是
def trilateration(P1, P2, P3, r1, r2, r3):
p1 = np.array([0, 0, 0])
p2 = np.array([P2[0] - P1[0], P2[1] - P1[1], P2[2] - P1[2]])
p3 = np.array([P3[0] - P1[0], P3[1] - P1[1], P3[2] - P1[2]])
v1 = p2 - p1
v2 = p3 - p1
Xn = (v1)/np.linalg.norm(v1)
tmp = np.cross(v1, v2)
Zn = (tmp)/np.linalg.norm(tmp)
Yn = np.cross(Xn, Zn)
i = np.dot(Xn, v2)
d = np.dot(Xn, v1)
j = np.dot(Yn, v2)
X = ((r1**2)-(r2**2)+(d**2))/(2*d)
Y = (((r1**2)-(r3**2)+(i**2)+(j**2))/(2*j))-((i/j)*(X))
Z1 = np.sqrt(max(0, r1**2-X**2-Y**2))
Z2 = -Z2
K1 = P1 + X * Xn + Y * Yn + Z1 * Zn
K2 = P1 + X * Xn + Y * Yn + Z2 * Zn
return K1,K2
两个return数组是两个可能的位置。
此代码非常有用,因为此答案中的代码是 https://en.wikipedia.org/wiki/True-range_multilateration#Three_Cartesian_dimensions,_three_measured_slant_ranges 的 Python 形式,它是 3D 坐标中最简单的三边测量代码。
我正在尝试实现三边测量。 Funtion 获取三个 3d cordiantes 和每个坐标与基站的距离。它必须 return 点在 3d space 三边测量中的位置。
def trilateration(P1, P2, P3, r1, r2, r3):
p1 = np.array([0, 0, 0])
p2 = np.array([P2[0] - P1[0], P2[1] - P1[1], P2[2] - P1[2]])
p3 = np.array([P3[0] - P1[0], P3[1] - P1[1], P3[2] - P1[2]])
v1 = p2 - p1
v2 = p3 - p1
Xn = (v1)/np.linalg.norm(v1)
tmp = np.cross(v1, v2)
Zn = (tmp)/np.linalg.norm(tmp)
Yn = np.cross(Xn, Zn)
i = np.dot(Xn, v2)
d = np.dot(Xn, v1)
j = np.dot(Yn, v2)
X = ((r1**2)-(r2**2)+(d**2))/(2*d)
Y = (((r1**2)-(r3**2)+(i**2)+(j**2))/(2*j))-((i/j)*(X))
Z1 = np.sqrt(r1**2-X**2-Y**2)
Z2 = np.sqrt(r1**2-X**2-Y**2)*(-1)
K1 = P1 + X*Xn + Y * Yn + Z1 * Zn
K2 = p1 + X * Xn + Y * Yn - Z2 * Zn
return K1
我有一个测试例子。使用这些坐标和距离 P1=(2,2,0), P2=(3,3,0), P3=(1,4,0) r1=1,r2=1,r3=1.4142,应该return P=(2,3,0)。
但它是 returnig [3.33253331 1.66746669 1.33373281]
问题来自 sqrt
的表达式,由于数值不精确,该表达式略微为负。这将修复它:
Z1 = np.sqrt(max(0, r1**2-X**2-Y**2))
Z2 = -Z1
改变这些行给我正确的结果:[1.99999361 3.00000639 0.]
注意:如果该点与其他3点在同一平面上,则Z值为0,否则有两种解法。此外,如@meowgoesthedog 所述,为 r1
、r2
和 r3
提供精确值非常重要。但是,即使使用精确值,您也始终需要注意浮点数的不精确性并安全地使用 sqrt
.
我没有足够的声誉来评论,所以我必须写一个新的答案。
您的代码仍有一些错误。经过多次测试,我发现K2的计算有一些错别字。
完美的功能应该是
def trilateration(P1, P2, P3, r1, r2, r3):
p1 = np.array([0, 0, 0])
p2 = np.array([P2[0] - P1[0], P2[1] - P1[1], P2[2] - P1[2]])
p3 = np.array([P3[0] - P1[0], P3[1] - P1[1], P3[2] - P1[2]])
v1 = p2 - p1
v2 = p3 - p1
Xn = (v1)/np.linalg.norm(v1)
tmp = np.cross(v1, v2)
Zn = (tmp)/np.linalg.norm(tmp)
Yn = np.cross(Xn, Zn)
i = np.dot(Xn, v2)
d = np.dot(Xn, v1)
j = np.dot(Yn, v2)
X = ((r1**2)-(r2**2)+(d**2))/(2*d)
Y = (((r1**2)-(r3**2)+(i**2)+(j**2))/(2*j))-((i/j)*(X))
Z1 = np.sqrt(max(0, r1**2-X**2-Y**2))
Z2 = -Z2
K1 = P1 + X * Xn + Y * Yn + Z1 * Zn
K2 = P1 + X * Xn + Y * Yn + Z2 * Zn
return K1,K2
两个return数组是两个可能的位置。
此代码非常有用,因为此答案中的代码是 https://en.wikipedia.org/wiki/True-range_multilateration#Three_Cartesian_dimensions,_three_measured_slant_ranges 的 Python 形式,它是 3D 坐标中最简单的三边测量代码。