GPS卫星定位—python实现

  基于导航文件的GPS定位——python实现 

模型建立:

 

前几天的文章由于第一次太激动而没有完全搞定,这次提交最新版本!!

# coding:utf-8
import os
import math as m
with open('brdm0320.22p','r') as f:
    data=f.readlines()
    # print(data)
    f.close()
#文件时间不同可取消此处注释
# def o_data_line():
#     for i in range(len(data)):
#         if data[i].find('END OF HEADER') != -1:
#             o_data_line = i + 1
#     return o_data_line
# print(o_data_line())
ff=[]
ff=data[207:3359]
# print(ff)

file_write_obj = open("GPS_data.txt", 'w')   # 新文件写入GPS_data
for i in range(3359-207) :
    file_write_obj.write(ff[i])   # 逐行写入
    # file_write_obj.write('\n')
file_write_obj.close()
print("保存文件成功")

#文件读取
with open('GPS_data.txt','r') as G:

    GPS_data=G.readlines()
    f.close()
    # print(GPS_data)
data_num=int(len(GPS_data)/8)         #数据组数
# print(data_num)


PRN = []
year = []
day=[]
month=[]
hour = []
minute=[]
second=[]
S=[]
S_s=[]
S_ss=[]
IODE=[]
C_rs=[]
n=[]
mo=[]
C_uc=[]
e=[]
C_us=[]
sqrt_A=[]
TEO=[]
C_ic=[]
C_is=[]
OMEGA=[]
I_0=[]
C_rc=[]
w=[]
OMEGA_DOT=[]
IDOT=[]
L2_code = []
PS_week_num=[]
L2_P_code=[]
TGD=[]
IODC=[]
for j in range(data_num):

    for i in range(8):
        data_l = GPS_data[8 * j +i]
        if i==0:
            # 卫星PRN号

            PRN.append(data_l[0:3])

            # 历元 TIME

            TIME=data_l[4:23]

            #year = []
            year.append(int(TIME[0:4]))
            #month=[]
            month.append(int(TIME[5:7]))
            #day=[]
            day.append(int(TIME[8:10]))
            #hour = []
            hour.append(int(TIME[11:13]))
            #minute=[]
            minute.append(int(TIME[14:16]))
            #second=[]
            second.append(float(TIME[17:19]))

            # print(TIME)
            # 卫星钟偏差(s)
            #S=[]
            S.append(float(data_l[23:42]))


           #卫星钟漂(s/s)
            #S_s=[]
            S_s.append(float(data_l[42:62]))
            # print(type(S_s))
            # print(S_s)

        # 卫星钟漂移速度(s / s * s)
            #S_ss=[]
            S_ss.append(float(data_l[62:81]))

        elif i==1:
            #IODE=[]
            IODE.append(float(data_l[4:23]))
            #C_rs=[]
            C_rs.append(float(data_l[23:42]))
            #n=[]
            n.append(float(data_l[43:61]))
            #mo=[]
            mo.append(float(data_l[61:81]))
        elif i==2:
            #C_uc=[]
            C_uc.append(float(data_l[4:23]))
            # print(C_uc)
            # print(float(row[4:23]))
            #e=[]
            e.append(float(data_l[23:42]))
            #C_us=[]
            C_us.append(float(data_l[42:62]))
            #sqrt_A=[]
            sqrt_A.append(float(data_l[62:81]))
        elif i == 3:
            #TEO=[]
            TEO.append(float(data_l[4:23]))
            #C_ic=[]
            C_ic.append(float(data_l[23:42]))
            #OMEGA=[]
            OMEGA.append(float(data_l[42:61]))
            #C_is=[]
            C_is.append(float(data_l[62:81]))
        elif i== 4:
            #I_0=[]
            I_0.append(float(data_l[4:23]))
            #C_rc=[]
            C_rc.append(float(data_l[23:42]))
            #w=[]
            w.append(float(data_l[43:61]))
            #OMEGA_DOT=[]
            OMEGA_DOT.append(float(data_l[62:81]))
        elif i == 5:
            #IDOT=[]
            IDOT .append(float(data_l[4:23]))
            #L2_code=[]
            L2_code .append(float(data_l[23:42]))
            #PS_week_num=[]
            PS_week_num .append(float(data_l[42:62]))
            #L2_P_code=[]
            L2_P_code .append(float(data_l[62:81]))
        elif i == 6:
            # 卫星精度(m)=2
            # 卫星健康状态=0
            #TGD=[]
            TGD .append(float(data_l[42:62]))
            #IODC=[]
            IODC .append(float(data_l[62:81]))
            # print(IODC)
        elif i==7:
            pass
# print(PRN, S,S_s,S_ss,
#       IODE,C_rs,n,mo, C_uc,
#       e, C_us, sqrt_A,
#       TEO, C_ic, OMEGA,C_is,
#       I_0, C_rc, w, OMEGA_DOT,
#       IDOT,L2_code,PS_week_num,L2_P_code,
#       TGD,IODC)


def CulLocation(PRN, year, month, day, hour, minute, second, S, S_s, S_ss, IDOT, C_rs, n, mo, C_uc, e, C_us, sqrt_A,
                TEO, C_ic, OMEGA, C_is, I_0, C_rc, w, OMEGA_DOT,t1):


        # 1.计算卫星运行平均角速度 GM:WGS84下的引力常数 =3.986005e14,a:长半径
    GM = 398600500000000
    n_0 = m.sqrt(GM) / m.pow(sqrt_A, 3)
    n = n_0 + n

    # 2.计算归化时间t_k 计算t时刻的卫星位置  UT:世界时 此处以小时为单位
    UT = hour + (minute / 60.0) + (second / 3600);

    if month <= 2:
        year = year - 1
        month = month + 12  # 1,2月视为前一年13,14月

    # 需要将当前需计算的时刻先转换到儒略日再转换到GPS时间
    JD = (365.25 * year) + int(30.6001 * (month + 1)) + day + UT / 24 + 1720981.5;
    WN = int((JD - 2444244.5) / 7);  # WN:GPS_week number 目标时刻的GPS周
    t_oc = (JD - 2444244.5 - 7.0 * WN) * 24 * 3600.0;  # t_GPS:目标时刻的GPS秒

    # 对观测时刻t1进行钟差改正,注意:t1应是由接收机接收到的时间
    if t1 is None:
        t_k = 0
    else:
        δt = a_0 + a_1(t1 - t_oc) + a_2(t1 - t_oc) ^ 2
        t = t1 - δt
        t_k = t - TEO

    if t_k > 302400:
        t_k -= 604800
    else :
        t_k += 604800

    # 3.平近点角计算M_k = M_0+n*t_k
    # print(mo)
    M_k = mo + n * t_k  # 实际应该是乘t_k,但是没有接收机的观测时间,所以为了练手设t_k=0

    # 4.偏近点角计算 E_k  (迭代计算) E_k = M_k + e*sin(E_k)
    E = 0;
    E1 = 1;
    count = 0;
    while abs(E1 - E) > 1e-10:
        count = count + 1
        E1 = E;
        E = M_k + e * m.sin(E);
        if count > 1e8:
            print("计算偏近点角时未收敛!")
            break

            # 5.计算卫星的真近点角
    V_k = m.atan((m.sqrt(1 - e * e) * m.sin(E)) / (m.cos(E) - e));

    # 6.计算升交距角 u_0(φ_k), ω:卫星电文给出的近地点角距
    u_0 = V_k + w

    # 7.摄动改正项 δu、δr、δi :升交距角u、卫星矢径r和轨道倾角i的摄动量
    δu = C_uc * m.cos(2 * u_0) + C_us * m.sin(2 * u_0)
    δr = C_rc * m.cos(2 * u_0) + C_rs * m.sin(2 * u_0)
    δi = C_ic * m.cos(2 * u_0) + C_is * m.sin(2 * u_0)

    # 8.计算经过摄动改正的升交距角u_k、卫星矢径r_k和轨道倾角 i_k
    u = u_0 + δu
    r = m.pow(sqrt_A, 2) * (1 - e * m.cos(E)) + δr
    i = I_0 + δi + IDOT * (t_k);  # 实际乘t_k=t-t_oe

    # 9.计算卫星在轨道平面坐标系的坐标,卫星在轨道平面直角坐标系(X轴指向升交点)中的坐标为:
    x_k = r * m.cos(u)
    y_k = r * m.sin(u)

    # 10.观测时刻升交点经度Ω_k的计算,升交点经度Ω_k等于观测时刻升交点赤经Ω与格林尼治恒星时GAST之差  Ω_k=Ω_0+(ω_DOT-omega_e)*t_k-omega_e*t_oe
    omega_e = 7.292115e-5  # 地球自转角速度
    OMEGA_k = OMEGA + (OMEGA_DOT - omega_e) * t_k - omega_e * TEO;  # 星历中给出的Omega即为Omega_o=Omega_t_oe-GAST_w

    # 11.计算卫星在地固系中的直角坐标l
    X_k = x_k * m.cos(OMEGA_k) - y_k * m.cos(i) * m.sin(OMEGA_k)
    Y_k = x_k * m.sin(OMEGA_k) + y_k * m.cos(i) * m.cos(OMEGA_k)
    Z_k = y_k * m.sin(i)

    # 12.计算卫星在协议地球坐标系中的坐标,考虑级移
    # [X,Y,Z]=[[1,0,X_P],[0,1,-Y_P],[-X_p,Y_P,1]]*[X_k,Y_k,Z_k]
    # XYZ=[X,Y,Z]

    if month > 12:  # 恢复历元
        year = year + 1
        month = month - 12

    print("历元:", year, "年", month, "月", day, "日", hour, "时", minute, "分", second, "秒", "\n卫星PRN号:", PRN, "\n平均角速度:", n,
          "\n卫星平近点角:", M_k, "\n偏近点角:", E, "\n真近点角:", V_k, "\n升交距角:", u_0, "\n摄动改正项:", δu, δr, δi, "\n经摄动改正后的升交距角、卫星矢径和轨道倾角:", u, r,
          i, "\n轨道平面坐标X,Y:", x_k, y_k, "\n观测时刻升交点经度:", OMEGA_k, "\n地固直角坐标系X:", X_k, "\n地固直角坐标系Y:", Y_k, "\n地固直角坐标系Z:", Z_k,'\n地固坐标系的位置')


    with open('GPS_XYZ.txt', 'a') as P:
        P.write(str(X_k) )
        P.write('   ')
        P.write(str(Y_k) )
        P.write('   ')
        P.write(str(Z_k) )
        P.write('\n')
if __name__ == '__main__':

    with open("GPS_XYZ.txt", 'r+') as file:#清空文件
        file.truncate(0)
    for i in range(data_num-1):
            t1=None
            CulLocation(PRN[i], year[i], month[i], day[i], hour[i], minute[i], second[i], S[i], S_s[i], S_ss[i], IDOT[i], C_rs[i], n[i], mo[i], C_uc[i], e[i], C_us[i],
                    sqrt_A[i], TEO[i],
                    C_ic[i], OMEGA[i], C_is[i], I_0[i], C_rc[i], w[i], OMEGA_DOT[i],t1)




由于我近期在完成GNSS课程的一个作业,无论是专业知识还是编程语言都是初学阶段,本着提高自己的原则, 借鉴网上一些大神的资料,完成了本次作业。主要是借鉴了python读取导航电文并计算卫星位置_Small Cube的博客-CSDN博客_python卫星定位

该作者给与了很大帮助 ,经过该作者同意,上传本人第一个CSDN作品!!!

但是此次由于搞出来太激动了还未来得及完成结果准确性的检验,会在后续继续补充完善,如果有什么不妥,请各位大佬批评指正。

  • 1
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 要使用 Python 实现 GPS 定位,可以使用 PyGPS 库来读取 GPS 接收器的输出并解码它们。 首先,需要安装 PyGPS 库。可以通过以下命令在终端中安装: ``` pip install PyGPS ``` 接下来,可以使用以下代码示例来读取 GPS 数据并解码: ```python import time import serial from gps import * # 创建一个 GPS 对象 gps = gps(mode=WATCH_ENABLE) # 打开串口 ser = serial.Serial('/dev/ttyUSB0', 4800, timeout=1) while True: # 读取串口数据 data = ser.readline().decode('utf-8') # 解码 NMEA 数据 if data[0:6] == '$GPGGA': msg = pynmea2.parse(data) # 获取位置信息 lat = msg.latitude lng = msg.longitude # 获取速度信息 speed = msg.spd_over_grnd # 打印位置和速度信息 print(f'Latitude: {lat}, Longitude: {lng}, Speed: {speed} knots') # 等待 1 秒钟 time.sleep(1) ``` 上述代码假设 GPS 接收器已经通过串口连接到计算机,并且串口名称为 `/dev/ttyUSB0`,波特率为 4800。如果串口名称不同,则需要相应地更改代码中的串口名称。 ### 回答2: GPS定位是一种通过接收来自卫星的信号来确定地理位置的技术。使用Python编写GPS定位程序可以通过以下步骤实现: 1. 导入必要的模块:在Python中,可以使用`gps`模块来实现GPS定位功能。首先需要导入该模块。 2. 创建GPS对象:通过实例化`gps.GPS()`类来创建一个GPS对象,这个对象用于接收来自GPS设备的数据。 3. 连接GPS设备:使用`gpsd.connect()`函数来连接GPS设备。这个函数在设备连接成功后会返回True,表示连接成功。 4. 获取GPS数据:通过调用GPS对象的`next()`方法可以获取到最新的一组GPS数据。 5. 解析GPS数据:获取到的GPS数据是一个字典型的数据,其中包含了经度、纬度、高度、速度等信息。可以通过将字典中的对应键取出来来获取这些信息。 6. 输出GPS数据:可以使用`print()`函数将获取到的GPS信息输出到控制台,或者保存到文件中。 7. 断开GPS设备连接:在程序结束时,可以调用`gpsd.disconnect()`函数来断开与GPS设备的连接。 需要注意的是,编写GPS定位程序时需要确保GPS设备已经正常连接,并且程序运行时可以获得GPS信号。另外,由于GPS定位是一种实时的功能,因此需要保持程序的实时运行来获取最新的GPS数据。 以上就是用Python编写GPS定位程序的基本步骤,根据需要可以继续扩展和优化程序的功能。 ### 回答3: 用Python编写GPS定位可以通过使用GPS模块和相应的库来实现。以下是使用pyserial和pynmea库进行GPS定位的基本步骤: 1. 首先,确保系统上安装了pyserial和pynmea库。可以使用以下命令安装它们: ``` pip install pyserial pip install pynmea ``` 2. 连接GPS模块到计算机的串口。 3. 导入必要的库: ```python import serial from pynmea import nmea ``` 4. 打开串口并读取GPS数据: ```python ser = serial.Serial('/dev/ttyUSB0', 9600) # 根据实际情况修改串口号和波特率 while True: data = ser.readline().decode('utf-8') if 'GGA' in data: break ``` 5. 解析GPS数据并提取位置信息: ```python gga_data = nmea.GPGGA() gga_data.parse(data) latitude = gga_data.latitude longitude = gga_data.longitude ``` 6. 最后,可以将提取的经纬度信息用于后续的操作或输出: ```python print('经度:', longitude) print('纬度:', latitude) ``` 在实际使用中,还可以根据需要对获取到的GPS数据进行进一步处理,例如计算速度、海拔高度等。同时,需要注意不同GPS模块的数据格式可能会有所不同,需要根据具体模块和数据格式进行适当的调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值