RTKLIB源码解析(三)、Rinex文件读取(rinex.c)——2

RTKLIB源码解析(三)、Rinex⽂件读取(rinex.c)——2⽬录
readrnxobsb()函数
static int readrnxobsb(FILE *fp, const char *opt, double ver,
char tobs[][MAXOBSTYPE][4], int *flag, obsd_t *data)
函数功能:读取o⽂件中的观测值记录(除了⽂件头剩下的部分)的函数了。严格地说,这个函数只是读取⼀个观测历元的观测数据
/* set signal index */
set_index(ver,SYS_GPS,opt,tobs[0],index  );
set_index(ver,SYS_GLO,opt,tobs[1],index+1);
set_index(ver,SYS_GAL,opt,tobs[2],index+2);
set_index(ver,SYS_QZS,opt,tobs[3],index+3);
set_index(ver,SYS_SBS,opt,tobs[4],index+4);
set_index(ver,SYS_CMP,opt,tobs[5],index+5);
⾸先,按照上⾯的⽅式建⽴索引。将三维观测值类型数组退化成⼆维数组,建⽴⼀个索引数组。然后剩下的所有代码就是读取这个历元中的数据了。在读取的过程中,读取历元头,然后读取观测数据。
步骤:
海城黑社会1、先利⽤fgets()函数缓存⼀⾏数据。
2、判断本⾏是否是历元数据第⼀⾏,如果是,则调⽤decode_obsepoch()函数解码⾸⾏数据(包括历元时刻、卫星数、卫星编号、
历元状态等信息),并将信息保存;如果不是则调⽤decode_obsdata()函数对该⾏观测数据进⾏数据解码,具体为调⽤str2num函数,从指定位置⼀次读取16个字符(每⼀个卫星的观测数据),并转换为double类型,存⼊数组。函数声明如下:
double str2num(const char s, int i, int n);
即从i处开始读取,读取n个字符,转换为double类型,存⼊字符数组中,并⽤指针s指向数组地址。
3、最后将时间转换为gps时保存,周跳信息保存。O⽂件读取完毕。
readrnxobs()函数
static int readrnxobs(FILE *fp, gtime_t ts, gtime_t te, double tint,
const char *opt, int rcv, double ver, int tsys,
char tobs[][MAXOBSTYPE][4], obs_t *obs)
函数功能:读取o⽂件中整个观测值数据了,也就是除了⽂件头之外的所有部分。readrnxobsb函数 只读取⼀个历元的观测值,因此在readrnxobs函数中,添加了内存分配语句之后,便是重复调⽤readrnxobsb函数,直到所有的观测值全被读完,或者是出现了某个历元没有卫星的情况为⽌。
注意:在观测值⽂件中,所记录的载波相位数据的单位为周,伪距数据的单位为m。观测值所对应的时标(即观测时刻)是依据接收机钟的读数所⽣成的,⽽不是标准的GPS时,因⽽在该时标中含有接收机的钟差。
decode_eph()函数
static int decode_eph(double ver, int sat, gtime_t toc, const double *data,eph_t *eph)
在rtklib.h⽂件中定义的关于卫星星历的结构体eph_t
typedef struct {        /* GPS/QZS/GAL broadcast ephemeris type */
int sat;            /* satellite number */
int iode,iodc;      /* IODE,IODC */
int sva;            /* SV accuracy (URA index) */
int svh;            /* SV health (0:ok) */
int week;          /* GPS/QZS: gps week, GAL: galileo week */
int code;          /* GPS/QZS: code on L2, GAL/CMP: data sources */
int flag;          /* GPS/QZS: L2 P data flag, CMP: nav type */
gtime_t toe,toc,ttr; /* Toe,Toc,T_trans */
/* SV orbit parameters */
double A,e,i0,OMG0,omg,M0,deln,OMGd,idot;
double crc,crs,cuc,cus,cic,cis;
double toes;        /* Toe (s) in week */
double fit;        /* fit interval (h) */
double f0,f1,f2;    /* SV clock parameters (af0,af1,af2) */
double tgd[4];      /* group delay parameters */
/* GPS/QZS:tgd[0]=TGD */
chinesefeeder
/* GAL    :tgd[0]=BGD E5a/E1,tgd[1]=BGD E5b/E1 */
/* CMP    :tgd[0]=BGD1,tgd[1]=BGD2 */
} eph_t;
函数功能:eph_t中存储了卫星星历中的卫星参数,也就是说把星历按照实际意义存储在了结构体中。readrnxnavb()函数
static int readrnxnavb(FILE *fp, const char *opt, double ver, int sys,
int *type, eph_t *eph, geph_t *geph, seph_t *seph)
先说明⼀下⽤到的⼏个⼦函数
(1)satid2no函数
之前已经说过了,就是将卫星的id号转换为唯⼀的⼀个整数类型号码,作为卫星的唯⼀标识
(2)str2time函数
这个函数也是定义在rtkcnm.h中的⼀个函数。代码如下:
extern int str2time(const char *s, int i, int n, gtime_t *t)
{
double ep[6];
char str[256],*p=str;
if (i<0||(int)strlen(s)<i||(int)sizeof(str)-1<i) return -1;
for (s+=i;*s&&--n>=0;) *p++=*s++; *p='\0';
if (sscanf(str,"%lf %lf %lf %lf %lf %lf",ep,ep+1,ep+2,ep+3,ep+4,ep+5)<6)
return -1;
if (ep[0]<100.0) ep[0]+=ep[0]<80.0?2000.0:1900.0;
*t=epoch2time(ep);
return 0;
}
国家护理质量数据平台函数功能:利⽤了sscanf函数格式化读取字符串中的内容,并且将读取到的数组转化成gtime_t类型的结构体输出
(3) str2num函数
这个函数之前也说过,之所以把它单独列出来就是因为这个函数⽐较重要,建议记住。
双馈风力发电机组
主函数实际上⽤⼀次就读取⼀个卫星的星历,是利⽤i来控制是否读完了⼀个历元的数据。设计的思想很巧妙,由于GLONASS和GALILEO 的卫星星历⽐较特殊,所以要控制单独判断。这个函数就是先读取卫星星历数据到data中,然后再对data进⾏解码。
add_eph(),add_geph(),add_seph()函数
函数功能:前⾯添加观测值的函数类似,都是判断结构体的⼤⼩是否够⽤,然后将新⼀个卫星的星历添加到原有的观测值结构体中。readrnxnav()函数
static int readrnxnav(FILE *fp, const char *opt, double ver, int sys,nav_t *nav)
函数功能:就是将之前所有的读取星历⽂件的函数整理⼀下,根据⽂件头的标识符判断⽂件是哪⼀种卫星系统的星历⽂件,利⽤相应的函数读取并添加星历。但是⼀定要注意,这个函数并⾮是读取整个星历⽂件,它只能读取星历⽂件的数据记录,不能读取⽂件头,读取⽂件头的函数在之前已经介绍过了
readrnxfp()函数
static int readrnxfp(FILE *fp, gtime_t ts, gtime_t te, double tint,
const char *opt, int flag, int index, char *type,
用人单位职业健康监护监督管理办法obs_t *obs, nav_t *nav, sta_t *sta)
函数功能:真正能够读取真个RINEX⽂件的函数,它能读取包括o⽂件,n⽂件等等的⼀系列⽂件,也就是之前函数的整合 ;这个函数就是增加了⼀个解压的功能,然后再进⾏读取
init_rnxctr()函数
extern int init_rnxctr(rnxctr_t *rnx)
有参数的先看参数的意义,然后再看有没有⼦函数,最后看函数本体。出现了⼀个以前没有见过的结构体。
typedef struct {        /* rinex control struct type */
gtime_t time;      /* message time */
double ver;        /* rinex version */
char  type;        /* rinex file type ('O','N',...) */
int    sys;        /* navigation system */
int    tsys;        /* time system */
char  tobs[6][MAXOBSTYPE][4]; /* rinex obs types */
obs_t  obs;        /* observation data */
nav_t  nav;        /* navigation data */
sta_t  sta;        /* station info */
int    ephsat;      /* ephemeris satellite number */
char  opt[256];    /* rinex dependent options */
} rnxctr_t;
观察结构体定义可以看出,这个结构体就是将之前的导航电⽂结构体和观测值结构体进⾏了组合,从⽽形成了⼀个能够概括所有RINEX格式⽂件的结构体。
函数功能:发现函数其实就是将上述的结构体进⾏初始化,即将指针指向新开辟的内存空间,将其中的各个参数置零 。
free_rnxctr()函数
extern void free_rnxctr(rnxctr_t *rnx)
{
trace(3,"free_rnxctr:\n");
章开沅
free(rnx->obs.data); rnx->obs.data=NULL; rnx->obs.n =0;
free(rnx->nav.eph ); rnx->nav.eph =NULL; rnx->nav.n =0;
free(rnx-&ph); rnx-&ph=NULL; rnx-&=0;
free(rnx->nav.seph); rnx->nav.seph=NULL; rnx->nav.ns=0;
}
理解:使⽤完指针和新开辟的内存之后,应该先释放内存,也就是进⾏free操作,然后将指针指向NULL。这样应该可以避免很多内存泄漏的问题。
open_rnxctr()函数
extern int open_rnxctr(rnxctr_t *rnx, FILE *fp)
函数功能:它是将RINEX⽂件头中的信息读⼊rnx参数中。注意,只是⽂件头的信息。
input_rnxctr()函数
extern int input_rnxctr(rnxctr_t *rnx, FILE *fp)
函数功能:这个函数是⽤来将RINEX⽂件体的信息读⼊rnx中。从下⾯的函数体中可以看出,rnx的类型是已知的,那么我们可以推测在调⽤这个函数的时候应该先调⽤open_rnxctr函数,解析头⽂件,然后再使⽤这个函数。
后⾯的内容不再仔细介绍,主要是输出函数:
/*------------------------------------------------------------------------------
* output rinex functions
*-----------------------------------------------------------------------------*/

本文发布于:2024-09-22 06:59:40,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/374450.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   读取   数据   观测   历元   结构   功能
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议