C/C++ 项目:分别用精密星历和广播星历计算卫星坐标

29 篇文章 98 订阅
本文介绍了如何使用C++和Matlab处理一个项目,通过比较卫星的精密星历和广播星历计算结果,展示坐标差异。作者分享了代码实现、数据结构以及如何在Matlab中进行结果可视化。
摘要由CSDN通过智能技术生成

Part.I Introduction

本文将介绍一个小项目的使用方法,此项目可用精密星历和广播星历计算卫星位置,并将两者结果做差,输出至文件。
在这里插入图片描述

其实 『分别用精密星历和广播星历计算卫星坐标』 是笔者在本科阶段的一次 GNSS 编程作业,当时就把自己的代码上传的 CSDN 上面了,没想到后来受到了许多朋友的关注。但是当时本科阶段写的代码,使用起来很麻烦,近期又有朋友来请教,并且现在看当时的代码,简直是一坨…,所以花了一晚上的时间对其进行了重构,现在看起来似乎没有那么糟糕了。

整个项目的文件树如下:

.
├─data
│  ├─2019_08_28
│  └─out
├─src
│  ├─app_run
│  └─LibGNSS
│      ├─gdata
│      ├─gexport
│      └─gproc
└─_doc
    └─imgs

其中

  • data: 2019年08月28日的广播星历和精密星历,out是一个参考输出结果(输出结果格式:sec x y z time,其中sec是天内秒,单位为s;xyz是坐标单位为m;time 是钟改正,单位为 1e-6 s)结果文件有:
    • brdcxx.txt:这是用广播星历计算出来的Gxx号卫星的坐标
    • spxx.txt:这是用精密星历计算出来的Gxx号卫星的坐标
    • detxx.txt:这是两者之间的差值
  • src: 程序源码,包括一个 LibGNSS 库和一个 app
  • _doc: Eigen 包和本文档所用到的图片。

整个项目实现的功能有:读取精密星历和广播星历、计算两个卫星计算卫星坐标并将计算结果存储到 txt 文件中,戳我下载(可私我,瓶抬油茶伽,私我便宜)


下面是部分文件内容

Chap.I rinex.h

/**
* @verbatim
    History
     -1.0 hlgou     2024-04-01 created
     -1.0 xxx       20xx-xx-xx do some changes

  @endverbatim
*
* @file             rinex.h
* @brief            BRDC(broadcast ephemeris) data structure
* @author           hlgou.
* @date             2024-04-01
*/

#ifndef RINEX_H
#define RINEX_H


#include <string>

#include "gexport/ExportLibGNSS.h"
namespace dawn 
{
    struct LibGNSS_LIBRARY_EXPORT DATANODE
    {
        int PRN;//卫星的prn,
        double IODE;
        double a0, a1, a2;//钟差,钟漂
        double a_sqrt, e;//轨道参数
        double Cuc, Cus, Crc, Crs, Cic, Cis;//6个摄动参数
        double Dn, OMEGA, omega, i0, M0;
        double i_DOT, OMEGA_DOT, TGD;
        int GPS_WEEK, TOE, TIME;//GPS周,周内秒数,卫星发送时刻
        int SEC_DAY;//一天当中的多少秒
    };

    struct LibGNSS_LIBRARY_EXPORT DATALINE
    {
        int YEAR, MONTH, DAY, HOUR, MINITE, SECOND, TOC;//卫星钟的参考时刻(年月日时分秒)
        DATANODE nod[35];
    };

    struct LibGNSS_LIBRARY_EXPORT BRDC
    {   //广播星历
        DATALINE lin[30];
        double A[4], B[4], A0, A1;//电离层参数,多项式系数
        int T, W, LEAP_SEC, YEAR, MON, DAY;//UTC参考时刻,周,跳秒
    };

}

#endif

Chap.II gmain_body.h

/**
* @verbatim
    History
     -1.0 hlgou     2024-04-01 created
     -1.0 xxx       20xx-xx-xx do some changes

  @endverbatim
*
* @file             gmain_body.h
* @brief            Main process class.
* @author           hlgou.
* @date             2024-04-01
*/

#ifndef GMAIN_BODY_H
#define GMAIN_BODY_H

#include <cmath>

#include "gdata/rinex.h"
#include "gdata/sp3.h"

using namespace std;

namespace dawn
{
    class LibGNSS_LIBRARY_EXPORT t_gmain_body
    {
    public:

        void setFileNmame(string wdir, string f1, string f2, string sdir);

        //计算精密星历和广播星历的结果及其差值并保存,i 是第 i 颗星
        void processBatch();

    protected:
        int _decodeSp3();

        int _decodeBrdc();

        Point _subBrdc(int time);

        Point _brdcCaculate(int time, int j);

        double _subSp3(int time, int i, int j, int t);

        Point _sp3Caculate(int time, int j);

        int _find(string p, int num, string* prn);

        string _wdir;           // 数据所在目录
        string _sdir;           // 结果保存目录
        string _sp3_filename;
        string _brdc3_filename;
        SP3 _gsp3;      // 精密星历结构体
        BRDC _gbrdc;    // 广播星历结构体

        DATANODE _current_DN;
    };
}

#endif

Part.II 使用方法

所需软件:CMake + VS Studio
所需矩阵库:Eigen(放心,压缩包里有)

为了防止不必要的歧义,下面将项目的根目录称为『当前目录』

首先解压Eigen.zip,将其放在一个你不常动的目录中,将这个目录(或 这个目录/Eigen)称为『Eigen目录』

1、在src目录下新建build 文件夹

2、打开 CMake,源码路径设置为当前目录,build 路径设置为 src/build

3、点击 Configure,之后配置根据自己实际情况配,配好点击 Finish

在这里插入图片描述

4、会报错,不要急,把 『Eigen目录』赋给 Third_Eigen_ROOT,再次点击Configure

在这里插入图片描述

5、依次点击GenerateOpen Project,打开项目

6、将解决方案配置改为RelWithDebInfo(其实改不改无所谓,程序本身体量很小),将 app_run 设为启动项目,run.cpp 就是主程序

在这里插入图片描述

7、将 wdirsdir 分别改为你的路径(最好是绝对路径)

在这里插入图片描述

8、将 out 文件夹改名为 out1(备份),新建一个out 文件夹

9、快捷键F5运行程序,在out 文件夹下等待程序运行结果,完事!

Part.III 使用 Matlab 绘图

Chap.I 结果展示

在这里插入图片描述

Chap.II 源码

源码如下(注意改文件路径和文件名)

%% LOAD DATA
wdir='A:\aWork\scripts\mGit\cpp\GNSS0\data\out\';
f1=[wdir,'brdc01.txt'];
f2=[wdir,'sp01.txt'];
fs=[wdir,'_det01.txt'];
Data1 = load(f1);
Data2 = load(f2);
Det = Data2 - Data1;
Det(:,1)=Data1(:,1);

%% PLOT BRDC and SP3
plot(Data1(:,1),Data1(:,2));
hold on;
plot(Data2(:,1),Data2(:,2));
set(gca,'FontName','Times New Roman');
legend('BRDC','SP3');
xlabel('Time (SOD)');
ylabel('Vale (m)');

%% PLOT difference value
figure
plot(Det(:,1),Det(:,2));
hold on;
plot(Det(:,1),Det(:,3));
hold on;
plot(Det(:,1),Det(:,4));
set(gca,'FontName','Times New Roman');
legend('X','Y','Z');
xlabel('Time (SOD)');
ylabel('Diff (m)');

%% Save difference value
fid=fopen(fs,'w'); 
fprintf(fid,'%6d %20.6f %20.6f %20.6f %20.6f\r\n',Det');
fclose(fid);

扩展阅读

  • 36
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: C是一种用于计算卫星位置广播星历算法。广播星历是一种卫星导航系统中常用的技术,通过广播卫星的轨道参数来计算卫星位置。在GPS系统中,卫星通过GPS卫星发送广播信号,其中包含了卫星的轨道参数以及其他相关信息。 使用C方法计算卫星位置的过程如下: 首先,接收器通过GPS接收卫星广播信号,信号中包含了卫星卫星编号、时间标记、信号传播的时刻以及其他相关参数。 然后,接收器使用C方法中的计算公式,根据卫星的轨道参数以及信号传播的时刻,计算出每颗卫星位置坐标。 接着,接收器通过卫星位置坐标以及接收器的位置坐标计算卫星与接收器之间的距离。 最后,接收器根据接收到的多个卫星的距离以及卫星位置坐标,进行三角定位,从而计算出接收器的位置坐标。 C方法通过广播星历计算卫星位置的优势是简单易懂,计算速度快,并且能够在接收器没有实时星历数据的情况下进行定位。然而,由于广播星历是通过卫星发送的广播信号进行计算的,其精度相对较低,误差较大,通常适用于一般定位应用。对于精度要求较高的应用,通常需要使用更精确的星历数据或者其他定位算法来进行计算。 ### 回答2: 广播星历是通过GPS卫星发射的信号,包含了卫星位置、速度、时钟偏差等信息。利用广播星历计算卫星位置的过程主要分为以下几个步骤: 首先,接收器会接收到GPS卫星发射的信号,其中包含了卫星广播星历信息。 其次,接收器通过解码星历信息,得到卫星位置和速度等参数。 然后,接收器会根据接收到的广播星历信息以及卫星的时钟偏差,进行位置和速度的估计。 接着,接收器通过卫星位置和速度等参数,结合卫星时钟偏差,可以通过测量卫星信号的传播时间来计算卫星与接收器之间的距离。 最后,利用多个卫星之间的距离和卫星位置信息,可以使用三角定位或者最小二乘法等方法来计算出接收器的位置。 需要注意的是,广播星历计算卫星位置的过程中,存在一些误差因素,例如接收器的时钟误差、大气延迟等,需要通过差分定位或者其他误差补偿方法来提高计算的准确性。 总的来说,通过利用广播星历计算卫星位置,可以为导航系统提供准确的位置信息,实现精确定位。 ### 回答3: 广播星历是通过卫星发射的信号广播卫星位置和时间信息。广播星历计算卫星位置的过程如下: 首先,卫星通过GPS卫星系统发射无线信号,包含有关卫星位置、时钟偏移和其他相关数据的信息。 接下来,接收器接收到卫星发射的信号,并解码其中的星历数据。星历数据包括卫星的时间、卫星位置卫星钟差等信息。 然后,接收器将解码的星历数据与自身的观测数据进行比对和计算。观测数据包括接收时间、接收位置等。 在接收器计算中,需要使用星历数据中的卫星位置、观测数据中的接收时间和接收位置,利用相对导航原理和时差等参数进行计算卫星位置的算法。 最后,通过算法计算得到的卫星位置可以用于导航、测量和其他相关应用。这些计算过程在接收器内部进行,得到的卫星位置信息可以用于确定接收器的准确位置。 综上所述,广播星历是通过解码卫星发射的信号中的星历数据,并将其与接收器的观测数据进行比对和计算,来计算卫星位置的过程。这种方法可以在不依赖外部计算设备的情况下,通过接收卫星广播信号,获取卫星位置信息,实现精确定位和导航功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流浪猪头拯救地球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值