前言

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

本文章部分代码借鉴于@学测绘的小杨【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.将链接粘贴在路径上运行

4.任选一个文件夹打开

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

解读广播星历文件的格式

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

卫星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)

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

计算步骤与算法如下:

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

需要注意的是:

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

代码如下

import csv
import math as m
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as pltwith 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 rxdef Rz(fai):rz = np.mat([[m.cos(fai), m.sin(fai), 0], [-m.sin(fai), m.cos(fai), 0], [0, 0, 1]])return rzfor i in range(len(nfile_lines)):                                     #获取开始行if nfile_lines[i].find('C01') != -1:start_num = i + 1breakfor i in range(len(nfile_lines)):                                     #获取终止行if nfile_lines[i].find('J01') != -1:end_num = ibreakx_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转为floatdata_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 计算卫星运行的平均角速度nGM = 398600441800000n0 = m.sqrt(GM) / m.pow(sqrtA, 3)n = n0 + delta_n#1.2 计算归化时间tkif month <= 2:year -= 1month += 12JD = 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秒为BDTtp = 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 - toeif tk > 302400:tk -= 604800if tk < -302400:tk += 604800  #1.3 观测时刻卫星平近点角Mk的计算Mk = M0 + n * tk#1.4 计算偏近点角count = 0E0 = M0Ek = Mk + e * m.sin(E0)while abs(Ek - E0) > 1e-10:count += 1E0 = EkEk = 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和轨道倾角ikuk = Fai_k + sigema_urk = m.pow(sqrtA, 2) * (1 - e * m.cos(Ek)) + sigema_rik = 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-5if 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 * tkfive = -5 * m.pi / 180temp = np.mat([[XGk], [YGk], [ZGk]])temp = Rz(fi) * Rx(five) * tempXk = 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()

结果

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

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

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

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

  1. python 利用Scipy计算person 和spearman相关系数

    python 利用Scipy计算person 和spearman相关系数 觉得有用的话,欢迎一起讨论相互学习~ 学习以下两位大佬的讲解 (Pearson)皮尔逊相关系数和spearman相关系数(附p ...

  2. python利用近似公式计算π_python如何利用公式计算π

    python利用公式计算π的方法:首先导入数学模块及时间模块:然后计算Pi精确到小数点后几位数,代码为[print('n{:=^70}'.format('计算开始'))]:最后完成计算,代码为[pri ...

  3. 利用广播星历计算卫星在ECEF下的坐标

    #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <ma ...

  4. python利用列表计算斐波那契数列前30项_python斐波那契数列的计算方法

    题目: 计算斐波那契数列.具体什么是斐波那契数列,那就是0,1,1,2,3,5,8,13,21,34,55,89,144,233. 要求: 时间复杂度尽可能少 分析: 给出了三种方法: 方法1:递归的 ...

  5. python利用公式计算_从零开始用Python构造决策树(附公式、代码)

    来源:Python中文社区 作者:weapon 本文长度为700字,建议阅读5分钟 本文介绍如何不利用第三方库,仅用python自带的标准库来构造一个决策树. 起步 熵的计算: 根据计算公式: 对应的 ...

  6. python利用公式计算_Python利用openpyxl处理Excel文件(公式实例)

    前面我们学习了Python使用openpyxl模块处理Excel文件的大部分内容,今天,我们通过一个例子来学习Python使用Excel公式的方法,引出今天的主题利用openpyxl处理Excel公式 ...

  7. python利用列表计算斐波那契数列前30项并输出_python分享斐波那契数列示例分享 Python 分享斐波那契数列前20项和...

    分享助python大神.斐波那契数列,编写程序,利用列具体内容 拜托拜托有时候,最痛苦的其实不是失去,而是你得到以后其实不快乐. ##缩进格式看图 l=[1,1] for i in range(28) ...

  8. python利用近似公式计算π_Excel函数公式大全之利用SUMSQ函数快速计算多个数据的平方和...

    各位Excel天天学的小伙伴们大家好,欢迎收看Excel天天学出品的excel2019函数公式大全课程.今天我们要学习的函数是数学函数中的SUMSQ函数,SUMSQ函数的功能是快速计算多个数据的平方和 ...

  9. python利用列表计算斐波那契数列前30项并输出_python 题目:斐波那契数列计算;题目:站队顺序输出;题目:合法括号组合的生成;题目:用户登录(三次机会)...

    斐波那契数列计算 B 描述 斐波那契数列如下: F(0) = 0, F(1) = 1 F(n) = F(n-1) + F(n-2) 编写一个计算斐波那契数列的函数,采用递归方式,输出不超过n的所有斐波 ...

最新文章

  1. C#复制图片_并重命名
  2. 算法--------数组------反转字符串中的元音字母
  3. python跟unicode一样吗_PYTHON编码处理-str与Unicode的区别
  4. 30行代码如何写一封七夕密书?
  5. Facebook已经过时,蜂巢新网络崛起
  6. SpaceX载人龙飞船意外爆炸,据称几乎被完全摧毁
  7. 每天多采一半油!中东联手中国阿里云的研究有望降低国际油价
  8. 计算机操作员(高级)理论知识考试卷,计算机操作员高级试题
  9. idea中 Application Server not specified
  10. linux系统源码文档,Linux操作系统源代码详细分析
  11. 计算机科学与技术导论 网站,计算机科学与技术导论
  12. 【Urule源码解析1】开源可视化规则引擎
  13. 如何学习计算机思维,刘康平:为什么我们每个人都应该学习计算思维?
  14. 一些方便的LaTex在线编辑工具
  15. mysql5.7导出数据提示–secure-file-priv选项问题的解决方法
  16. POI使用详解 java 复杂excel导出(笔记)
  17. 基于OpenCV的图像透视变换详解(从理论到实现再到实践)
  18. 写给女朋友的java_Java会说情话的女朋友
  19. 深度搜索算法C语言实现--以走迷宫为例
  20. Android开发-WebView中实现Android调用JS JS调用Android 【三】

热门文章

  1. 一个小点阵图像JPG图片做吗?
  2. 一、Vue.js 概述
  3. java怎么调用支付接口测试_微信支付中微信红包的接口测试,Java版本
  4. 盛大网络硬盘邀请码-免费10G
  5. [渝粤教育] 西南科技大学 经济法学 在线考试复习资料
  6. Access 2003之控件使用
  7. Palm Web OS 简介
  8. 【python】练习:长度转换
  9. 金蟾论金:黄金多头迎非农,最新黄金走势分析实时策略布局
  10. 跟我一起学Python之十一:字典方法