GPS单点定位原理与C++程序实现(一)

作为一名大二导航工程专业的学生,假期留校和老师做科研。众所周知,导航的目标是一下三个:P(positioning)V(velocity)T(timing)。其中,定位和测速有着不可分割的关系。下面就先来看看GPS定位的基本原理和程序实现。

一、单点定位原理

1.原始数据

目前,绝大多数的导航原始文件都来源于IERS(国际地球自转服务)所提供的数据。大家可以随便找一个能够下载卫星星历的网站,下载卫星星历供调试程序使用。卫星星历下载下来之后是一个压缩包,解压后的文件夹里面有好多文件。我在写单点定位的程序的时候只用了GPS卫星进行单点定位,那么就只用到其中的o文件(观测值文件)和n文件(GPS广播星历文件)。当然了,如果想要北斗,GALILEO或者是GLONASS卫星进行定位,可以采用其他的文件。目前的文件记录格式都是采用RINEX进行记录的。我采用的数据是RINEX3.01格式的,其实2.11版本的也可以,只是文件格式略有不同而已,大家在读文件的时候注意一下就好。RINEX3.01的数据记录格式说明(英文版)我已经传到资源区了。

2.基本原理

单点定位分为标准单点定位和精密单点定位。在本篇博客中,我想介绍标准单点定位的相关内容。
标准单点定位就是利用广播星历给出的卫星轨道和卫星钟差以及伪距观测值来进行的,定位精度不是很好,一般为10米级左右。观测方程如下
观测方程的一般形式

其中的参数学测绘的应该都能看懂,要是看不懂,建议参考武汉大学出版社出版的李征航老师和黄劲松老师编写的GPS测量与数据处理这本书,比较详细。
有了观测方程之后就需要线性化,然后根据最小二乘的原理进行最优估计,详细理论过程大家可以参考吴云老师的最优估计及其在GNSS中的应用这本书。由于这篇博客想要重点介绍程序是如何实现,因此在理论部分不多说了。

二、程序设计流程及部分代码

1.读取广播星历文件

在读取卫星的广播星历的文件时,首先要跳过文件头,然后读取相应的卫星星历数据。我在读取GPS卫星数据的时候,采用的是单链表的形式。其实用C++库中的vector类就可以,但是我认为这样不自由,因此我采用了数据结构中的单链表的形式。在头文件中定义了用于存储广播星历参数的数据结构。

//定义用于存储GPS星历参数的结点
typedef struct GPSeph{
 int PRN;
 int year,month,day,hour,minute;
 float second;
 long double a0,a1,a2;
 long double IODE,Crs,deltan,M0;
 long double Cuc,e,Cus,sqrtA;
 long double TOW,Cic,OMEGA,Cis;
 long double i0,Crc,omega,OMEGAdot;
 long double IDOT,L2,WN,L2P;
 long double accurancy,health,TGD,IODC;
 long double sendtime;
 struct GPSeph * nextdata;
 long double deltat;//求卫星钟差的时候要用到
}GPSeph;

有了用来存储卫星星历的数据结构,下面就是读取广播星历了。
大家通过观察广播星历的数据记录格式可以发现,数据是下面这种记录形式
广播星历
也就是说中间是用D隔开,以科学计数法的形式记录的。在读取的时候可以像下面这样读取

GPS_nexteph->a0=a*pow(10,b);
fo>>a>>g>>b;

其中g是char类型的变量,a,b都是long double 类型的变量。利用ifstream读取至文件末尾。整个的读文件的程序我在这里就不附上代码了,因为代码太长了,而且大体上都是这样。在跳过文件头的时候,有两种方法:一种是偷懒型的,就是直接getline,跳过指定的行数(哈哈哈,我就是用的这种方法);还有一种就是利用String类中的字符串匹配方法查找是否含有“End Of Header”。最后读取到文件末尾,留下头指针,广播星历文件读取完毕。

2.读取观测值文件

我下载的观测值文件是间隔为半分钟的观测值,里面虽然数据看上去很多,但是我们只需要伪距观测值就够了,其它的以后再说。
观测值文件的文件头中的一部分上面的图片是我从观测值文件头中截取的一小部分,这里面记录了各种卫星有哪些类型的观测值,里面的字母代表的意义大家可以去我上传的RINEX3.01的说明文档的附录中查看。总之,我们利用每个卫星的PRN号后面的第一个观测值就够了。观测值文件的特点是一个时间点下面有好多颗卫星,因此我也为观测值文件的读取定义了一个单链表。

typedef struct OBSERVATIONdata{
 int year,month,day,hour,minute;
 long double second;
 int flag,satellite_number;
 vector<char> satellite_system;//存储卫星所属的系统
 vector<long double> pseudorange;//存储卫星的伪距观测值
 vector<int> PRN;
 OBSERVATIONdata * nextdata;
}OBSERVATIONdata;

其实用vector类直接就可以完成数据的存储,但是我想让数据的存储格式变得灵活一些,同时便于后期想要向代码中添加新的元素,我采用了比较复杂的自己定义单链表的形式。
o文件的读取不像n文件那样复杂,没有什么想要特殊说明的。

至此,第一部分总算完成了。当时请教老师的时候,老师就说文件的读取会占用代码的很大一部分,果不其然。另外,还要特别的感谢老师,在暑假期间还为我当面为我解答一些问题。下一篇博客打算写读取文件后的计算过程,代码等我完成测速后,一起打包传到资源区。不得不说,看上去过程简单,实际上想要运行出来真正正确的结果对于初学者来说真的不容易。希望大家代码的bug少少,今年新年我的愿望一定是希望我在以后写程序的时候代码少一点啊~
另外,大家如果想要找我交流什么,可以给我留言,不足之处请大家多多指教~

伪距单点定位是一种通过接收卫星信号测量卫星与接收机间距离的方法,利用伪距观测值可以进行单点定位。C语言是一种常用的程序设计语言,可以用于实现伪距单点定位程序设计。 伪距单点定位程序设计主要包括以下几个步骤: 1. 初始化:首先,需要初始化卫星的轨道参数和接收机的位置信息。轨道参数包括卫星的轨道半径、卫星的升交点角度、卫星的半长轴等。接收机的位置信息包括接收机的经纬度、海拔等。 2. 接收卫星信号:接收卫星信号是定位的第一步。通过接收站的接收机,可以接收到卫星发送的信号。 3. 伪距观测值测量:接收到卫星信号后,可以利用伪距测量方法测量卫星与接收机间的距离。伪距是卫星信号从发射到到达接收机时所经过的时间乘以光速。 4. 伪距单点定位:利用测量得到的伪距观测值,可以进行单点定位计算。单点定位计算是根据已知的卫星位置和接收机的位置信息,通过多个卫星伪距观测值的比较,计算出接收机的位置。 伪距单点定位程序设计可以使用C语言完成。C语言具有较高的效率和灵活性,在计算复杂的伪距单点定位问题时非常有用。程序设计中,需要使用适当的数据结构和算法来处理卫星信号和伪距观测值,并进行位置计算。 总之,伪距单点定位程序设计是一个复杂而关键的任务,通过合理设计和使用C语言,可以实现高效准确的单点定位
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值