GPS 静态定位测量
标签:卫星导航
, 定位技术
, GPS
, 地理信息系统
一句话总结:本文讨论了GPS静态定位测量,以及相关的精度指标如 RMS, 2DRMS, CEP和大地坐标与导航坐标的变换,通过示例,文章展示了如何进行GPS计算和坐标转换,以及如何应用这些技术于实际的地理信息系统中。
Github仓库:GPS静态定位测量
1 GPS信号的解释和定位测量 (Interpretation of GPS Signals and Positioning Measurements)
1.1 静态定位测量 (Static Positioning Measurements)
- GPS静态位置误差可以用正态分布表示。
- 标准差是衡量一组数自身离散程度的指标。
- 约50%的数值分布在距离真实点平均值有0.68个标准差之内的范围。
- 约68.3%的数值分布在距离真实点平均值有1个标准差之内的范围。
- 约95.4%的数值分布在距离真实点平均值有2个标准差之内的范围。
- 约99%的数值分布在距离真实点平均值有3个标准差之内的范围。
1.2 动态定位测量 (Dynamic Positioning Measurements)
- 动态定位测量适用于移动中的物体,如车辆或无人机。
- 动态定位的精度受到多种因素的影响,包括接收器的质量、信号干扰和环境条件。
- 动态定位通常需要更复杂的算法和实时数据处理。
1.3 精度指标 (Accuracy Indicators)
-
RMS (Root Mean Square): 表示包含至少68% GPS读数的圆的半径。
-
2DRMS/2SD: 表示包含至少95% GPS读数的圆的半径。
-
CEP (Circular Error Probable): 表示包含50% GPS读数的圆的半径。
2 大地坐标与导航坐标的变换 (Transformation between Geodetic and Navigation Coordinates)
2.1 空间大地坐标系 (Geodetic Coordinate System)
- 使用大地经度、纬度和高度来描述空间位置。
- 坐标系原点位于参考椭球的中心,Z轴指向北极,X轴指向赤道上的本初子午线。
2.2 地心地固坐标系 (Earth-Centered Earth-Fixed Coordinate System)
- 转换过程首先将数据从大地坐标系转换为地心地固坐标系。
- 地心地固坐标系是一个与地球固连的直角坐标系。
2.3 局部相切平面坐标 (Local Tangent Plane Coordinates)
- 数据从地心地固坐标系转换到导航系统参照的局部相切平面坐标。
- 局部相切平面坐标系通常用于显示在地图上的数据信息。
2.4 坐标转换公式 (Coordinate Transformation Formulas)
- 转换公式涉及复杂的三角函数和椭球体参数。
- 转换需要考虑地球的扁率和参考椭球的几何特性。
如果两个点很近(通常纬度和经度相距在1’内),那么
x − x0 = Kx(Lon − Lon0) y − y0 = Ky(Lat − Lat0) Where x-x0 = displacement in east-west direction, m y-y0 = displacement in north-south direction, m Lat = latitude, expressed in radians Lon = longitude, expressed in radians Variables with subscript 0 refer to a reference position Ky = a(1 − e^2)[1 − e^2 sin^2(Lat0)]^1.5 Kx = a cos(Lat0)[1 − e^2 sin^2(Lat0)]^0.5 Where a = equatorial radius = 6378135 m b = polar radius = 6356750.5 m e = √(1 − (b^2/a^2))
Code explanation
我用python实现了上述公式,通过给定benchmark point和一系列test point的经纬度得到了每组test point和benchmark point之间的distance以及所有distance的RMS、2SD、CEP等误差指标 。
import math
from typing import List
import numpy as np
def dms_to_rad(dms:List[str]):
degree, minute, second = dms
degree = float(degree)
minute = float(minute) / 60
second = float(second) / 3600
total_degree = degree + minute + second
radian = math.radians(total_degree)
return radian
def CoordinateTransformation(benchmark, testpoint):
# benchmark: [['degree', 'min', 'second'], ['degree', 'min', 'second']]
# testpoint: [['degree', 'min', 'second'], ['degree', 'min', 'second']]
# return: distance
a = 6378135
b = 6356750.5
e = math.sqrt(1 - (b/a)**2)
benchmark_lon_rad, benchmark_lat_rad = dms_to_rad(benchmark[0]), dms_to_rad(benchmark[1])
print('benchmark longitude radian:', benchmark_lon_rad, '\t', 'benchmark latitude radian:', benchmark_lat_rad)
testpoint_lon_rad, testpoint_lat_rad = dms_to_rad(testpoint[0]), dms_to_rad(testpoint[1])
print('testpoint longitude radian:', testpoint_lon_rad, '\t', 'testpoint latitude radian:', testpoint_lat_rad)
Kx = a * math.cos(benchmark_lat_rad) / (math.sqrt(1 - e**2 * math.sin(benchmark_lat_rad)**2))
Ky = a * (1 - e**2) / (1 - e**2 * math.sin(benchmark_lat_rad)**2)**(3/2)
detx = Kx * (testpoint_lon_rad - benchmark_lon_rad)
dety = Ky * (testpoint_lat_rad - benchmark_lat_rad)
distance = math.sqrt(detx**2 + dety**2)
print('detx:', detx, '\t', 'dety:', dety, '\t', 'distance:', distance)
return distance
def calculate_mean_std(distances):
mean = np.mean(distances)
std = np.std(distances)
print('mean:', mean, 'std:', std)
return mean, std
def cal_error(mean: float, std: float):
RMS = mean + std
SD = mean + 2 * std
CEP = mean + 0.68 * std
return round(RMS, 3), round(SD, 3), round(CEP, 3)
if __name__ == '__main__':
# input('Please input the benchmark point: ')
benchmark = []
benchmark.append(input('Please input the benchmark point longitude: ').split())
benchmark.append(input('Please input the benchmark point latitude: ').split())
distances = []
while True:
print('if you want to end this program, please input "yes", otherwise, please input the test point')
if input() == 'yes':
mean, std = calculate_mean_std(distances)
RMS, SD, CEP = cal_error(mean, std)
print('The RMS is: ', RMS)
print('The 2SD is: ', SD)
print('The CEP is: ', CEP)
break
# input('Please input the test point: ')
testpoint = []
testpoint.append(input('Please input the test point longitude: ').split())
testpoint.append(input('Please input the test point latitude: ').split())
distance = CoordinateTransformation(benchmark, testpoint)
distances.append(distance)
为了使用,请先在命令行中进入本仓库所在目录,然后执行python GPS_Static _Positioning_Measurement.py
,在命令行中输入经纬度时请注意:经纬度的度分秒之间要用空格隔开,比如说,88°5’11’'请输入88 5 11
。