本文基于本人对rtklib源码的学习进行顺序汇总,为记录个人的学习与理解,并根据个人需要对部分代码对其进行注释,如有错误或者不完善的地方烦请提出建议或改正方法。
目录
1、execses函数
2、readobsnav函数
3、readrnxt函数
4、readrnxfile函数
5、readrnxfp函数
5.1、readrnxh函数
5.1.1、decode_obsh函数
5.1.2、decode_navh函数
5.1.3、decode_gnavh和decode_hnavh函数
5.2、readrnxobs函数
5.2.1、readrnxobsb函数
5.2.2、 addobsdata
5.3、readrnxnav函数
5.3.1、readrnxnavb函数
5.3.2 、add_eph函数
5.3.3、add_geph函数
5.3.4、add_seph函数
5.4、readrnxclk函数
1、execses函数
/* execute processing session ------------------------------------------------*/
static int execses(gtime_t ts, gtime_t te, double ti, const prcopt_t *popt,
const solopt_t *sopt, const filopt_t *fopt, int flag,
char **infile, const int *index, int n, char *outfile)
{
FILE *fp,*fptm;
rtk_t *rtk_ptr = (rtk_t *)malloc(sizeof(rtk_t)); /* moved from stack to heap to avoid stack overflow warning */
prcopt_t popt_=*popt;
solopt_t tmsopt = *sopt;
char tracefile[1024],statfile[1024],path[1024],*ext,outfiletm[1024]={0};
int i,j,k;
trace(3,"execses : n=%d outfile=%s\n",n,outfile);
/* open debug trace */
if (flag&&sopt->trace>0) {
if (*outfile) {
strcpy(tracefile,outfile);
strcat(tracefile,".trace");
}
else {
strcpy(tracefile,fopt->trace);
}
traceclose();
traceopen(tracefile);
tracelevel(sopt->trace);
}
/* read ionosphere data file */
if (*fopt->iono&&(ext=strrchr(fopt->iono,'.'))) {
if (strlen(ext)==4&&(ext[3]=='i'||ext[3]=='I')) {
reppath(fopt->iono,path,ts,"","");
readtec(path,&navs,1);
}
}
/* read erp data */
if (*fopt->eop) {
free(navs.erp.data); navs.erp.data=NULL; navs.erp.n=navs.erp.nmax=0;
reppath(fopt->eop,path,ts,"","");
if (!readerp(path,&navs.erp)) {
showmsg("error : no erp data %s",path);
trace(2,"no erp data %s\n",path);
}
}
/* read obs and nav data */
if (!readobsnav(ts,te,ti,infile,index,n,&popt_,&obss,&navs,stas)) {
/* free obs and nav data */
freeobsnav(&obss, &navs);
free(rtk_ptr);
return 0;
}//通过这部分调用readobsnav来对观测文件和星历文件进行读取
/* read dcb parameters */
if (*fopt->dcb) {
reppath(fopt->dcb,path,ts,"","");
readdcb(path,&navs,stas);
} else {
for (i=0;i<3;i++) {
for (j=0;j<MAXSAT;j++) navs.cbias[j][i]=0;
for (j=0;j<MAXRCV;j++) for (k=0;k<2;k++) navs.rbias[j][k][i]=0;
}
}
/* set antenna parameters */
if (popt_.mode!=PMODE_SINGLE) {
setpcv(obss.n>0?obss.data[0].time:timeget(),&popt_,&navs,&pcvss,&pcvsr,
stas);
}
/* read ocean tide loading parameters */
if (popt_.mode>PMODE_SINGLE&&*fopt->blq) {
readotl(&popt_,fopt->blq,stas);
}
/* rover/reference fixed position */
if (popt_.mode==PMODE_FIXED) {
if (!antpos(&popt_,1,&obss,&navs,stas,fopt->stapos)) {
freeobsnav(&obss,&navs);
free(rtk_ptr);
return 0;
}
if (!antpos(&popt_,2,&obss,&navs,stas,fopt->stapos)) {
freeobsnav(&obss,&navs);
free(rtk_ptr);
return 0;
}
}
else if (PMODE_DGPS<=popt_.mode&&popt_.mode<=PMODE_STATIC_START) {
if (!antpos(&popt_,2,&obss,&navs,stas,fopt->stapos)) {
freeobsnav(&obss,&navs);
free(rtk_ptr);
return 0;
}
}
/* open solution statistics */
if (flag&&sopt->sstat>0) {
strcpy(statfile,outfile);
strcat(statfile,".stat");
rtkclosestat();
rtkopenstat(statfile,sopt->sstat);
}
/* write header to output file */
if (flag&&!outhead(outfile,infile,n,&popt_,sopt)) {
freeobsnav(&obss,&navs);
free(rtk_ptr);
return 0;
}
/* name time events file */
namefiletm(outfiletm,outfile);
/* write header to file with time marks */
outhead(outfiletm,infile,n,&popt_,&tmsopt);
iobsu=iobsr=isbs=revs=aborts=0;
if (popt_.mode==PMODE_SINGLE||popt_.soltype==0) {
if ((fp=openfile(outfile)) && (fptm=openfile(outfiletm))) {
procpos(fp,fptm,&popt_,sopt,rtk_ptr,0); /* forward */
fclose(fp);
fclose(fptm);
}
}
else if (popt_.soltype==1) {
if ((fp=openfile(outfile)) && (fptm=openfile(outfiletm))) {
revs=1; iobsu=iobsr=obss.n-1; isbs=sbss.n-1;
procpos(fp,fptm,&popt_,sopt,rtk_ptr,0); /* backward */
fclose(fp);
fclose(fptm);
}
}
else { /* combined */
solf=(sol_t *)malloc(sizeof(sol_t)*nepoch);
solb=(sol_t *)malloc(sizeof(sol_t)*nepoch);
rbf=(double *)malloc(sizeof(double)*nepoch*3);
rbb=(double *)malloc(sizeof(double)*nepoch*3);
if (solf&&solb) {
isolf=isolb=0;
procpos(NULL,NULL,&popt_,sopt,rtk_ptr,1); /* forward */
revs=1; iobsu=iobsr=obss.n-1; isbs=sbss.n-1;
procpos(NULL,NULL,&popt_,sopt,rtk_ptr,1); /* backward */
/* combine forward/backward solutions */
if (!aborts&&(fp=openfile(outfile)) && (fptm=openfile(outfiletm))) {
combres(fp,fptm,&popt_,sopt);
fclose(fp);
fclose(fptm);
}
}
else showmsg("error : memory allocation");
free(solf);
free(solb);
free(rbf);
free(rbb);
}
/* free rtk, obs and nav data */
rtkfree(rtk_ptr);
free(rtk_ptr);
freeobsnav(&obss,&navs);
return aborts?1:0;
}
execses目前只是把函数放在这里,以此来展示最初调用readobsnav函数的部分
2、readobsnav函数
/* read obs and nav data -----------------------------------------------------*/
static int readobsnav(gtime_t ts, gtime_t te, double ti, char **infile,
const int *index, int n, const prcopt_t *prcopt,
obs_t *obs, nav_t *nav, sta_t *sta)
{
int i,j,ind=0,nobs=0,rcv=1;
trace(3,"readobsnav: ts=%s n=%d\n",time_str(ts,0),n);
obs->data=NULL; obs->n =obs->nmax =0;
nav->eph =NULL; nav->n =nav->nmax =0;
nav->geph=NULL; nav->ng=nav->ngmax=0;
/* free(nav->seph); */ /* is this needed to avoid memory leak??? */
nav->seph=NULL; nav->ns=nav->nsmax=0;
nepoch=0;
//给各个指针数据赋初值为空以及0
for (i=0;i<n;i++) {
if (checkbrk("")) return 0;
if (index[i]!=ind) {
if (obs->n>nobs) rcv++;
ind=index[i]; nobs=obs->n;
}
/* read rinex obs and nav file */
if (readrnxt(infile[i],rcv,ts,te,ti,prcopt->rnxopt[rcv<=1?0:1],obs,nav,
rcv<=2?sta+rcv-1:NULL)<0) {
checkbrk("error : insufficient memory");
trace(1,"insufficient memory\n");
return 0;
}//调用readrnxt函数对观测文件进行读取
}
if (obs->n<=0) {
checkbrk("error : no obs data");
trace(1,"\n");
return 0;
}//检测观测文件是否正常
if (nav->n<=0&&nav->ng<=0&&nav->ns<=0) {
checkbrk("error : no nav data");
trace(1,"\n");
return 0;
}//检测星历文件是否正常
/* sort observation data */
nepoch=sortobs(obs);
//按照时间、接收机、卫星来分类观测信息
/* delete duplicated(重复) ephemeris */
uniqnav(nav);
/* set time span for progress display */
if (ts.time==0||te.time==0) {
for (i=0; i<obs->n;i++) if (obs->data[i].rcv==1) break;
for (j=obs->n-1;j>=0;j--) if (obs->data[j].rcv==1) break;
if (i<j) {
if (ts.time==0) ts=obs->data[i].time;
if (te.time==0) te=obs->data[j].time;
settspan(ts,te);
}
}
return 1;
}
readobsnav函数首先对所有数据指针赋0初值,然后再检验观测文件或者星历文件是否存在,并调用readrnx函数对文件进行下一步判断。
3、readrnxt函数
extern int readrnxt(const char *file, int rcv, gtime_t ts, gtime_t te,
double tint, const char *opt, obs_t *obs, nav_t *nav,
sta_t *sta)
{
int i,n,stat=0;
const char *p;
char type=' ',*files[MAXEXFILE]={0};
trace(3,"readrnxt: file=%s rcv=%d\n",file,rcv);
if (!*file) {
return readrnxfp(stdin,ts,te,tint,opt,0,1,&type,obs,nav,sta);
}
for (i=0;i<MAXEXFILE;i++) {
if (!(files[i]=(char *)malloc(1024))) {
for (i--;i>=0;i--) free(files[i]);
return -1;
}
}//为每个输入文件分配地址
/* expand wild-card */
if ((n=expath(file,files,MAXEXFILE))<=0) {
for (i=0;i<MAXEXFILE;i++) free(files[i]);
return 0;
}//扩大通配符,不清楚具体有什么用
/* read rinex files */
for (i=0;i<n&&stat>=0;i++) {
stat=readrnxfile(files[i],ts,te,tint,opt,0,rcv,&type,obs,nav,sta);
}//解压和读rinex文件
/* if station name empty, set 4-char name from file head */
if (type=='O'&&sta) {
if (!(p=strrchr(file,FILEPATHSEP))) p=file-1;
if (!*sta->name) setstr(sta->name,p+1,4);
}//如果测站名字为空,就给依据文件自动赋4个字符的名字
for (i=0;i<MAXEXFILE;i++) free(files[i]);释放文件内存
return stat;
}
/* read RINEX OBS and NAV files -----------------