【python】利用广播星历计算BDS卫星的位置

这篇具有很好参考价值的文章主要介绍了【python】利用广播星历计算BDS卫星的位置。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

本程序为《卫星导航定位基础》大作业之二,功能为实现对广播星历文件的读取和处理,计算出北斗卫星的位置坐标,并绘制出二维和三维的卫星位置分布图。若需要对其他类型卫星数据处理,可根据本程序修改增进。

本文章部分代码借鉴于@学测绘的小杨【python】读取卫星星历(RENIX 3.04)进行卫星位置的计算(北斗卫星专题)

获取广播星历文件

可以通过下列链接进行下载

1.ftp://igs.gnsswhu.cn/pub/gnss/mgex/daily/rinex3/2020/

2.ftp://epncb.oma.be/pub/obs/BRDC/2023/

3.ftp://pub:tarc@ftp2.csno-tarc.cn/almanac/2023

注意:如果浏览器不能访问上面的FTP地址,则需用FTP软件进行下载

这里笔者提供另一个方法下载,以第一个链接为例。

1.先复制链接

2.打开“我的电脑”

3.将链接粘贴在路径上运行

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

 4.任选一个文件夹打开

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

 5.将压缩包复制粘贴到存放数据处解压即可

解读广播星历文件的格式

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

每一行参数代表意义如下:

卫星PRN号 卫星钟时间 卫星时钟偏差(s) 卫星时钟漂移(s/s) 卫星时钟漂移率(s/s²)

数据、星历发布时间(数据期龄) 轨道半径的正弦调和改正项的振幅(m) 卫星平均运动速率与计算值之差(rad/s) 参考时间的平近点角(rad)

维度幅角的余弦调和改正项的振幅(rad) 轨道偏心率 轨道幅角的正弦调和改正项的振幅(rad) 长半轴平方根

星历的参考时刻 轨道倾角的余弦调和改正项的振幅(rad) 参考时刻的升交点赤经 维度倾角的正弦调和改正项的振幅(rad)

参考时间的轨道倾角(rad) 轨道平径的余弦调和改正项的振幅(m) 近地点角距 升交点赤经变化率(rad)

轨道倾角变化率(rad/s) L2频道C/A码标识 GPS周数(toe)L2 P数据标志

卫星精度 卫星健康状态 TGD电频机延迟改正数 IODC时钟数据有效期

电文发送时间 拟合区间(h)

从广播星历文件中读取所需的数据并进行计算

计算步骤与算法如下:

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

来源于《GPS测量原理及应用 第四版》(武汉大学出版社) 

需要注意的是:

计算BDS卫星时,取地心引力常数μ=GM=3.986004418e14,地球自转角速度w=7.292115e-5

 文章来源地址https://www.toymoban.com/news/detail-849449.html

观测时刻应该由接收机给出,因缺乏该数据,故此处直接使用了星历给出的参考时刻

 

代码如下

import csv
import math as m
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

with open('C:\\Users\\20615\\Desktop\\Statellite\\task\\two\\brdm1260.20p', 'r') as f:
    if f == 0:
        print("不能打开文件!")
    else:
        print("星历文件已打开!")
    nfile_lines = f.readlines()                                       #按行读取N文件
    print(f'文件一共{len(nfile_lines)}行')


def Rx(fai):
    rx = np.mat([[1, 0, 0], [0, m.cos(fai), m.sin(fai)], [0, -m.sin(fai), m.cos(fai)]])
    return rx


def Rz(fai):
    rz = np.mat([[m.cos(fai), m.sin(fai), 0], [-m.sin(fai), m.cos(fai), 0], [0, 0, 1]])
    return rz

for i in range(len(nfile_lines)):                                     #获取开始行
    if nfile_lines[i].find('C01') != -1:
       start_num = i + 1
       break

for i in range(len(nfile_lines)):                                     #获取终止行
    if nfile_lines[i].find('J01') != -1:
       end_num = i
       break

x_list = []     #二维X坐标
y_list = []     #二维Y坐标
X_list = []     #三维X坐标
Y_list = []     #三维Y坐标
Z_list = []     #三维Z坐标
satellite_lines = int(((end_num - start_num) + 1) / 8)                #得到总数据数
print(f'一共{satellite_lines}组数据')

#第j组 第i行
for j in range(satellite_lines):
    for i in range(8):                                                  #使用.strip('\n)以去除空格,使数据能够从str转为float
        data_content = nfile_lines[start_num + 8 * j + i - 1]           #如果直接跳过空格读取,会导致负号丢失!!!
        if i == 0:                                                      
            PRN = data_content[0:3]                                     #卫星号                                  
            year = int(data_content[4:8])                               #年
            month = int(data_content[9:11])                             #月
            day = int(data_content[12:14])                              #日
            hour = int(data_content[15:17])                             #时
            minute = int(data_content[18:20])                           #分
            second = int(data_content[21:23])                           #秒
            a0 = float((data_content.strip('\n')[23:42]))               #卫星时钟偏差(s)
            a1 = float((data_content.strip('\n')[42:61]))               #卫星时钟漂移(s/s)
            a2 = float((data_content.strip('\n')[61:80]))               #卫星时钟漂移率(s/s²)
        if i == 1:
            IODE = float((data_content.strip('\n')[4:23]))              #数据、星历发布时间(数据期龄)
            Crs = float((data_content.strip('\n')[23:42]))              #轨道半径的正弦调和改正项的振幅(m)
            delta_n = float((data_content.strip('\n')[42:61]))          #卫星平均运动速率与计算值之差(rad/s)
            M0 = float((data_content.strip('\n')[61:80]))               #参考时间的平近点角(rad)
        if i == 2:  
            Cuc = float((data_content.strip('\n')[4:23]))               #维度幅角的余弦调和改正项的振幅(rad)
            e = float((data_content.strip('\n')[23:42]))                #轨道偏心率
            Cus = float((data_content.strip('\n')[42:61]))              #轨道幅角的正弦调和改正项的振幅(rad)
            sqrtA = float((data_content.strip('\n')[61:80]))            #长半轴平方根
        if i == 3:
            toe = float((data_content.strip('\n')[4:23]))               #星历的参考时刻
            Cic = float((data_content.strip('\n')[23:42]))              #轨道倾角的余弦调和改正项的振幅(rad)
            OMEGA = float((data_content.strip('\n')[42:61]))            #参考时刻的升交点赤经
            Cis = float((data_content.strip('\n')[61:80]))              #维度倾角的正弦调和改正项的振幅(rad)
 
        if i == 4:
            i0 = float((data_content.strip('\n')[4:23]))                #参考时间的轨道倾角(rad)
            Crc = float((data_content.strip('\n')[23:42]))              #轨道平径的余弦调和改正项的振幅(m)
            omega = float((data_content.strip('\n')[42:61]))            #近地点角距
            delta_OMEGA = float((data_content.strip('\n')[61:80]))      #升交点赤经变化率(rad)
        if i == 5:
            IDOT = float((data_content.strip('\n')[4:23]))              #轨道倾角变化率(rad/s)
            L2code = float((data_content.strip('\n')[23:42]))           #L2频道C/A码标识
            week = float((data_content.strip('\n')[42:61]))             #GPS周数(toe)
            L2Pflag = float((data_content.strip('\n')[61:80]))          #L2 P数据标志
        if i == 6:
            sacc = float((data_content.strip('\n')[4:23]))              #卫星精度
            sHEA = float((data_content.strip('\n')[23:42]))             #卫星健康状态
            TGD= float((data_content.strip('\n')[42:61]))               #TGD电频机延迟改正数
            IODC = float((data_content.strip('\n')[61:80]))             #IODC时钟数据有效期
            
            #1.计算北斗卫星在轨道平面直角坐标系下的坐标
            
            #1.1 计算卫星运行的平均角速度n
            GM = 398600441800000
            n0 = m.sqrt(GM) / m.pow(sqrtA, 3)
            n = n0 + delta_n

            #1.2 计算归化时间tk
            if month <= 2:
                year -= 1
                month += 12
            JD = 365.25 * year + int(30.6001 * (month + 1)) + day + 1720981.5 + hour / 24.0 + minute / 1440 + second / 86400  #计算儒略日
            WN = int((JD - 2444244.5) / 7)                                   # WN:GPS_week number 目标时刻的GPS周
            toc = ((JD - 2444244.5) - (7.0 * WN)) * 24 * 3600.0-14           # tGPS:目标时刻的GPS秒 减去14秒为BDT
            tp = 24 * 3600 * day + 3600 * hour + 60 * minute + second        #观测时刻
            delta_t = a0 + a1 * (tp - toc) + a2 * m.pow(tp - toc, 2)
            t = tp - delta_t                                                 #观测时刻作卫星钟差改正
            tk = t - toe
            if tk > 302400:
                tk -= 604800
            if tk < -302400:
                tk += 604800  
                
            #1.3 观测时刻卫星平近点角Mk的计算
            Mk = M0 + n * tk

            #1.4 计算偏近点角
            count = 0
            E0 = M0
            Ek = Mk + e * m.sin(E0)
            while abs(Ek - E0) > 1e-10:
                count += 1
                E0 = Ek
                Ek = Mk + e * m.sin(E0)
                if count > 1e8:
                    print("计算偏近点角时未收敛")
                    break

            #1.5 真近点角Vk的计算
            Vk = m.atan2((m.sqrt(1 - e * e) * m.sin(Ek)), (m.cos(Ek)) - e)

            #1.6 升交距角Φk的计算
            Fai_k = Vk + omega

            #1.7 摄动改正项δu、δr、δi的计算
            sigema_u = Cuc * m.cos(2 * Fai_k) + Cus * m.sin(2 * Fai_k)
            sigema_r = Crc * m.cos(2 * Fai_k) + Crs * m.sin(2 * Fai_k)
            sigema_i = Cic * m.cos(2 * Fai_k) + Cis * m.sin(2 * Fai_k)

            #1.8 计算经过摄动改正的升交距角uk、卫星矢径rk和轨道倾角ik
            uk = Fai_k + sigema_u
            rk = m.pow(sqrtA, 2) * (1 - e * m.cos(Ek)) + sigema_r
            ik = i0 + sigema_i + IDOT * tk

            #1.9 计算卫星在轨道平面坐标系的坐标
            xk = rk * m.cos(uk)
            yk = rk * m.sin(uk)

            #将卫星平面坐标写入以提供二维绘图数据
            x_list.append(xk)
            y_list.append(yk)

            #2.计算卫星在CGCS2000地固坐标系中的空间直角坐标

            omega_e = 7.2921150e-5
            if PRN in ['C01','C02','C03','C04','C05','C59','C60','C61']:        #判断是否为GEO卫星
                #2.1.1 计算观测时刻升交点精度Ωk(惯性系)
                OMEGA_k = OMEGA + delta_OMEGA * tk - omega_e * toe              
                
                #2.2.1 计算GEO卫星在自定义坐标系中的空间直角坐标
                XGk = xk * m.cos(OMEGA_k) - yk * m.cos(ik) * m.sin(OMEGA_k)
                YGk = xk * m.sin(OMEGA_k) + yk * m.cos(ik) * m.cos(OMEGA_k)
                ZGk = yk * m.sin(ik)

                #2.3 计算GEO卫星在CGCS2000地固坐标系中的空间直角坐标
                fi = omega_e * tk
                five = -5 * m.pi / 180
                temp = np.mat([[XGk], [YGk], [ZGk]])
                temp = Rz(fi) * Rx(five) * temp
                Xk = temp[0,0]
                Yk = temp[1,0]
                Zk = temp[2,0]
            else:
                #2.1.2 计算观测时刻升交点精度Ωk(地固坐标系)
                OMEGA_k = OMEGA + (delta_OMEGA - omega_e) * tk - omega_e * toe  

                #2.2.2 计算MEO和IGSO卫星在CGCS2000地固坐标系中的空间直角坐标
                Xk = xk * m.cos(OMEGA_k) - yk * m.cos(ik) * m.sin(OMEGA_k)
                Yk = xk * m.sin(OMEGA_k) + yk * m.cos(ik) * m.cos(OMEGA_k)
                Zk = yk * m.sin(ik)
            
            #将卫星空间坐标写入以提供三维绘图数据
            X_list.append(Xk)
            Y_list.append(Yk)
            Z_list.append(Zk)
            #计算完毕

            print('PRN号:%s  X坐标:%-18fY坐标:%-18fZ坐标:%-18f'%(PRN, Xk, Yk, Zk))    
print("卫星坐标数据计算完毕!")

#3.根据卫星坐标绘制二维与三维图像

#3.1 绘制二维图像
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.scatter(x_list, y_list, marker = '.', color = 'red', s = 8)

#3.2 绘制三维图像
fig = plt.figure()
ax2 = fig.add_subplot(111, projection='3d')
ax2.scatter(X_list, Y_list, Z_list, color = 'blue', s = 8, alpha = 0.5)
#展示图像
print("已展示卫星位置二维与三维图像")
plt.show()

结果 

根据卫星轨道平面坐标绘制的二维图像如下:

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

根据卫星地固坐标绘制的三维图像如下:

 

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

python 广播星历 位置,卫星导航定位基础,python,开发语言,学习

中间的球壳为MEO卫星,旁边8字形半球壳为IGSO卫星,密集分布的点状为GEO卫星

 

 

到了这里,关于【python】利用广播星历计算BDS卫星的位置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • GPS卫星位置解算

    本文介绍了基于C语言的GPS卫星位置解算原理与程序设计。针对每个原理、公式、代码设计进行了详细讲解,希望能够给测绘学子们带来帮助。 参考书籍: 李征航 黄劲松:GPS测量与数据处理(第三版) 目录 基础原理 1)卫星位置解算流程 2)卫星有关参数 3)卫星位置计算过

    2024年02月03日
    浏览(41)
  • 北斗卫星导航系统:引领现代林业发展的先锋

    北斗卫星导航系统:引领现代林业发展的先锋 随着人类社会的发展,林业作为生态环境保护和经济发展的重要组成部分,也在不断向前发展。为了更好地管理和保护森林资源,我们必须寻求一种新的方式来提高林业管理的效率。而北斗技术的应用,正是为林业带来了全新的发

    2024年02月07日
    浏览(52)
  • 深度学习卫星遥感图像检测与识别 -opencv python 目标检测 计算机竞赛

    🔥 优质竞赛项目系列,今天要分享的是 🚩 **深度学习卫星遥感图像检测与识别 ** 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分 工作量:3分 创新点:5分 🧿 更多资料, 项目分享: https://gitee.com/da

    2024年02月03日
    浏览(71)
  • 计算机设计大赛 深度学习卫星遥感图像检测与识别 -opencv python 目标检测

    🔥 优质竞赛项目系列,今天要分享的是 🚩 **深度学习卫星遥感图像检测与识别 ** 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分 工作量:3分 创新点:5分 🧿 更多资料, 项目分享: https://gitee.com/da

    2024年02月22日
    浏览(80)
  • 计算机毕设 深度学习卫星遥感图像检测与识别 -opencv python 目标检测

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月14日
    浏览(66)
  • MS2660:L1 频段卫星导航射频前端低噪声放大器芯片

    MS2660 是一款具有高增益、低噪声系数的低噪声放 大器(LNA)芯片,支持 L1 频段多模式全球卫星定位,可 以应用于 GPS、北斗二代、伽利略、Glonass 等 GNSS 导航 接收机中。芯片采用先进工艺制造,封装采用 2 mm ×2 mm ×0.5 mm DFN-4L 的封装形式。 主要特点  支持北斗、GPS、GALIL

    2024年01月16日
    浏览(61)
  • python 利用word中占位符号实现按word指定位置插入图片

    from docx import Document from docx.shared import Inches from docx.oxml.ns import qn from docx.enum.text import WD_ALIGN_PARAGRAPH def center_insert_img(doc, img):     \\\"\\\"\\\"插入图片\\\"\\\"\\\"     for paragraph in doc.paragraphs:         # 根据文档中的占位符定位图片插入的位置         if \\\'img1\\\' in paragraph.text:             # 把占

    2024年02月11日
    浏览(51)
  • 2023华为OD机试真题【计算数组中心位置】【Java Python】

    给你一个整数数组nums,请计算数组的中心位置。数组的中心位置是数组的一个下标, 其左侧所有元素相乘的积等于右侧所有元素相乘的积。数组第一个元素的左侧积为1,最后一个元素的右侧积为1。 如果数组有多个中心位置,应该返回最靠近左边的那一个,如果数组不存在

    2024年02月14日
    浏览(55)
  • 微信小程序 - 实现地图标点及导航功能,在地图上标记位置及第三方软件进行导航(无需授权,点击地址后直接打开地图并在地图上高亮标记位置、展示位置名称、详细地址,“去这里“ 可拉起外部第三方地图导航软件)

    网上的代码都太乱了,各种乱七八糟的授权验证等,很多朋友不知道如何下手。 实现了微信小程序开发中,用户无需弹框授权就能打开地图高亮显示某个位置,并且支持导航和计算路程距离等, 例如,每个商家都有店铺位置,当点击地址时在地图中显示该位置并可一键导航

    2024年02月16日
    浏览(62)
  • 2023华为OD机试真题【计算数组中心位置】【Java Python C++】

    给你一个整数数组nums,请计算数组的中心位置。数组的中心位置是数组的一个下标, 其左侧所有元素相乘的积等于右侧所有元素相乘的积。数组第一个元素的左侧积为1,最后一个元素的右侧积为1。 如果数组有多个中心位置,应该返回最靠近左边的那一个,如果数组不存在

    2024年02月15日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包