RTKLIB源码调试.trace文件解析.stat文件解析

article/2025/9/9 7:57:34

.trace文件是调试文件,帮助用户在程序、输入数据时,进行分析的一个很好的提示!

.trace文件的生成、trace文件内容的生成,均在execses中!

以单点定位为例,大体流程为:

  • 生成.trace文件:raceopen(tracefile); //开始对 trace文件进行写处理
  • 读取观测文件、导航文件,将调试信息放入.trace文件中;

    /* read obs and nav data */
    if (!readobsnav(ts,te,ti,infile,index,n,&popt_,&obss,&navs,stas)) return 0;

  • 生成解决方案文件/日志流:open solution status file

    /* open solution statistics */
    if (flag&&sopt->sstat>0) { /* solution statistics level (0:off,1:states,2:residuals) */
        strcpy(statfile,outfile);
        strcat(statfile,".stat");
        rtkclosestat();
        rtkopenstat(statfile,sopt->sstat);
    }

 

一、设置trace/debug 1-5

在Visual Studio中修改、调试代码时,如下设置:

sopt.trace = 5;          /* debug trace level (0:off,1-5:debug) */

单基站、移动站等数据作为输入时,.trace文件的生成是:

/* 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;prcopt_t popt_=*popt;char tracefile[1024],statfile[1024],path[1024],*ext;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"); //输出文件名,后加.trace}else {strcpy(tracefile,fopt->trace);}traceclose(); //关闭记录文件traceopen(tracefile); //开始对 trace文件进行写处理tracelevel(sopt->trace); //读取调试等级} //以上执行完后,.trace文件为空/* read ionosphere data file *///目前的输入文件中,文件输入为:filopt_t fopt = { 0 };  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)) return 0;/* read dcb parameters */if (*fopt->dcb) {reppath(fopt->dcb,path,ts,"","");readdcb(path,&navs,stas);}/* set antenna paramters 设置天线参数*/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);return 0;}}/*定位模式:PMODE_DGPS PMODE_KINEMA  PMODE_STATIC */else if (PMODE_DGPS<=popt_.mode&&popt_.mode<=PMODE_STATIC) {if (!antpos(&popt_,2,&obss,&navs,stas,fopt->stapos)) {freeobsnav(&obss,&navs);return 0;}}/* open solution statistics */if (flag&&sopt->sstat>0) { /* solution statistics level (0:off,1:states,2:residuals) */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);return 0;}iobsu=iobsr=isbs=ilex=revs=aborts=0;if (popt_.mode==PMODE_SINGLE||popt_.soltype==0) {//在kinematic模式下,如果前向处理则进行单点定位if ((fp=openfile(outfile))) {procpos(fp,&popt_,sopt,0); /* forward前向处理 */fclose(fp);}}else if (popt_.soltype==1) {if ((fp=openfile(outfile))) {revs=1; iobsu=iobsr=obss.n-1; isbs=sbss.n-1; ilex=lexs.n-1;procpos(fp,&popt_,sopt,0); /* backward */fclose(fp);}}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,&popt_,sopt,1); /* forward */revs=1; iobsu=iobsr=obss.n-1; isbs=sbss.n-1; ilex=lexs.n-1;procpos(NULL,&popt_,sopt,1); /* backward *//* combine forward/backward solutions */if (!aborts&&(fp=openfile(outfile))) {combres(fp,&popt_,sopt);fclose(fp);}}else showmsg("error : memory allocation");free(solf);free(solb);free(rbf);free(rbb);}/* free obs and nav data */freeobsnav(&obss,&navs);return aborts?1:0;
}

二、trace文件说明:位于execses函数中

以单点定位为例,即输入两个文件,分别为:观测文件、导航文件;

首先读取观测文件,在trace中相关信息如下:

1、函数readobsnav,输出第一条trace信息:

在readobsnav中,循环读取观测文件、导航文件;先读取观测文件……

1.1、函数readrnxt中,trace中显示输入观测文件路径和接收机数量

1.2、readrnxh为读取Rinex文件头的信息,进入readrnxh程序,输出信息:3 readrnxh:

其中,trace中每一行的开头都标记有函数信息,即调用时间顺序!

1.3、decode_obsh为读取Rinex文件头的信息,每次读取一行,进入decode_obsh程序,输出一行信息:

4 decode_obsh: ver=3.03

示意如下:

3 readobsnav: ts=2019/04/01 00:00:00 n=2
3 readrnxt: file=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\CUT000AUS_R_20190910000_01D_30S_MO.rnx rcv=1
3 expath  : path=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\CUT000AUS_R_20190910000_01D_30S_MO.rnx nmax=1024
3 expath  : file=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\CUT000AUS_R_20190910000_01D_30S_MO.rnx
3 readrnxfile: file=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\CUT000AUS_R_20190910000_01D_30S_MO.rnx flag=0 index=1
3 rtk_uncompress: file=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\CUT000AUS_R_20190910000_01D_30S_MO.rnx
3 rtk_uncompress: stat=0
3 readrnxfp: flag=0 index=1
3 readrnxh:
4 decode_obsh: ver=3.03
4 decode_obsh: ver=3.03
4 decode_obsh: ver=3.03
4 decode_obsh: ver=3.03
4 decode_obsh: ver=3.03
4 decode_obsh: ver=3.03
忽略重复的数据,此图仅仅是示意

1.4、读取观测文件body,

函数: readrnxobs;

然后输出:readrnxobs: rcv=1 ver=3.03 tsys=13830824

4.1 readrnxobsb

然后进入函数:readrnxobsb 中,首先实现的功能是将 读取观测文件头时保存的观测类型/OBS TYPES,从变量

tobs变为index, 在具体实现时:

1、设置了每一个系统观测类型频率的优先级;

2、每一个频率只保留优先级最高的数据;(扔掉的数据在trace中出现,如下)

readrnxobs: rcv=1 ver=3.03 tsys=13830824
4 reject obs type: sys= 1, obs=C2X
4 reject obs type: sys= 1, obs=D2X
4 reject obs type: sys= 1, obs=L2X
4 reject obs type: sys= 1, obs=S2X
4 reject obs type: sys= 4, obs=C1C
4 reject obs type: sys= 4, obs=C2C
4 reject obs type: sys= 4, obs=D1C
4 reject obs type: sys= 4, obs=D2C
4 reject obs type: sys= 4, obs=L1C
4 reject obs type: sys= 4, obs=L2C
4 reject obs type: sys= 4, obs=S1C
4 reject obs type: sys= 4, obs=S2C
4 reject obs type: sys= 8, obs=C7X
4 reject obs type: sys= 8, obs=C8X
4 reject obs type: sys= 8, obs=D7X
4 reject obs type: sys= 8, obs=D8X
4 reject obs type: sys= 8, obs=L7X
4 reject obs type: sys= 8, obs=L8X
4 reject obs type: sys= 8, obs=S7X
4 reject obs type: sys= 8, obs=S8X
4 reject obs type: sys=16, obs=C1X
4 reject obs type: sys=16, obs=C1Z
4 reject obs type: sys=16, obs=C6L
4 reject obs type: sys=16, obs=D1X
4 reject obs type: sys=16, obs=D1Z
4 reject obs type: sys=16, obs=D6L
4 reject obs type: sys=16, obs=L1X
4 reject obs type: sys=16, obs=L1Z
4 reject obs type: sys=16, obs=L6L
4 reject obs type: sys=16, obs=S1X
4 reject obs type: sys=16, obs=S1Z
4 reject obs type: sys=16, obs=S6L

附:频率优先级:

static char codepris[7][MAXFREQ][16]={  /* code priority table *//* L1/E1      L2/B1        L5/E5a/L3 E6/LEX/B3 E5b/B2    E5(a+b)  S */{"CPYWMNSL","PYWCMNDSLX","IQX"     ,""       ,""       ,""      ,""    }, /* GPS */{"PC"      ,"PC"        ,"IQX"     ,""       ,""       ,""      ,""    }, /* GLO */{"CABXZ"   ,""          ,"IQX"     ,"ABCXZ"  ,"IQX"    ,"IQX"   ,""    }, /* GAL */{"CSLXZ"   ,"SLX"       ,"IQX"     ,"SLX"    ,""       ,""      ,""    }, /* QZS */{"C"       ,""          ,"IQX"     ,""       ,""       ,""      ,""    }, /* SBS */{"IQX"     ,"IQX"       ,"IQX"     ,"IQX"    ,"IQX"    ,""      ,""    }, /* BDS */{""        ,""          ,"ABCX"    ,""       ,""       ,""      ,"ABCX"}  /* IRN */
};

RTKLIB Manual中描述:

从函数readrnxobsb中,开始循环读取每一个历元的观测数据:

 

1.5、解码decode_obsepoch

decode_obsepoch

首先 读取此历元的观测卫星数目,并在trace中输出:分别为进入函数和结束函数时的输出!

4 decode_obsepoch: ver=3.03

4 decode_obsepoch: time=2019/04/01 00:00:00.000 flag=0

然后开始对每历元中卫星相关数据进行读取:函数为decode_obsdata;读取每行时,输出信息:

4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=97 //此时的sat是各个卫星系统累加值

循环用decode_obsdata读取,以上两条信息重复显示,最终如下:

4 decode_obsepoch: ver=3.03
4 decode_obsepoch: time=2019/04/01 00:00:00.000 flag=0
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=97
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=98
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=99
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=100
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=101
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=102
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=103
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=104
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=106
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=109
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=114
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=61
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=63
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=64
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=68
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=70
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=73
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=84
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=89
4 decode_obsdata: ver=3.03
4 decode_obsdata: unsupported sat sat=E36
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=10
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=15
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=16
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=20
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=21
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=25
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=26
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=27
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=29
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=31
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=90
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=91
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=92
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=37
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=38
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=39
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=42
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=43
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=44
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=45
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=53
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=54
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=55
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=146
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=147
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=148
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=149
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=151
4 decode_obsdata: ver=3.03
4 decode_obsdata: time=2019/04/01 00:00:00 sat=156
4 reject obs type: sys= 1, obs=C2X
4 reject obs type: sys= 1, obs=D2X
4 reject obs type: sys= 1, obs=L2X
4 reject obs type: sys= 1, obs=S2X
4 reject obs type: sys= 4, obs=C1C
4 reject obs type: sys= 4, obs=C2C
4 reject obs type: sys= 4, obs=D1C
4 reject obs type: sys= 4, obs=D2C
4 reject obs type: sys= 4, obs=L1C
4 reject obs type: sys= 4, obs=L2C
4 reject obs type: sys= 4, obs=S1C
4 reject obs type: sys= 4, obs=S2C
4 reject obs type: sys= 8, obs=C7X
4 reject obs type: sys= 8, obs=C8X
4 reject obs type: sys= 8, obs=D7X
4 reject obs type: sys= 8, obs=D8X
4 reject obs type: sys= 8, obs=L7X
4 reject obs type: sys= 8, obs=L8X
4 reject obs type: sys= 8, obs=S7X
4 reject obs type: sys= 8, obs=S8X
4 reject obs type: sys=16, obs=C1X
4 reject obs type: sys=16, obs=C1Z
4 reject obs type: sys=16, obs=C6L
4 reject obs type: sys=16, obs=D1X
4 reject obs type: sys=16, obs=D1Z
4 reject obs type: sys=16, obs=D6L
4 reject obs type: sys=16, obs=L1X
4 reject obs type: sys=16, obs=L1Z
4 reject obs type: sys=16, obs=L6L
4 reject obs type: sys=16, obs=S1X
4 reject obs type: sys=16, obs=S1Z
4 reject obs type: sys=16, obs=S6L
4 decode_obsepoch: ver=3.03
4 decode_obsepoch: time=2019/04/01 00:00:30.000 flag=0

循环读取每一个历元数据,最后读取完成;

在readrnxobs函数最后,trace(4,"readrnxobs: nobs=%d stat=%d\n",obs->n,stat);

4 readrnxobs: nobs=5800 stat=1

总的观测数:即有多少个历元!

读取完之后,回到readrnxt函数中,

然后回到readobsnav函数中,进行读取下一个文件,即导航文件!

如果是相对定位,输入两个观测文件,先读移动站观测文件、接着读基准站观测文件:

紧接着读取导航电文:

2.1、函数readrnxt中,trace中显示输入导航文件路径和接收机数量

.trace文件中

开始进行导航文件读取:

2.2、再一次进入readrnxfile中:

4 readrnxobs: nobs=5800 stat=1
3 readrnxt: file=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\CUT000AUS_R_20190910000_01D_MN.rnx rcv=2
3 expath  : path=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\CUT000AUS_R_20190910000_01D_MN.rnx nmax=1024
3 expath  : file=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\CUT000AUS_R_20190910000_01D_MN.rnx
3 readrnxfile: file=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\CUT000AUS_R_20190910000_01D_MN.rnx flag=0 index=2
3 rtk_uncompress: file=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\CUT000AUS_R_20190910000_01D_MN.rnx
3 rtk_uncompress: stat=0

2.3、进入readrnxfp函数中:

3 readrnxfp: flag=0 index=2

2.3.1、进入readrnxh函数中:

在标识“N”中,进入decode_navh中,trace显示:

3 readrnxfp: flag=0 index=2
3 readrnxh:
4 decode_navh:

2.3.2、进入readrnxnav函数中:

3 readrnxh:
4 decode_navh:
3 readrnxnav: ver=3.00 sys=0

2.3.2.1、 进入readrnxnavb函数中:

3 readrnxh:
4 decode_navh:
3 readrnxnav: ver=3.00 sys=0
4 readrnxnavb: ver=3.00 sys=0

decode_eph函数,解码星历:

3 readrnxh:
4 decode_navh:
3 readrnxnav: ver=3.00 sys=0
4 readrnxnavb: ver=3.00 sys=0
4 decode_eph: ver=3.00 sat= 1

readrnxnavb函数一直读取导航文件的每颗卫星星历,并把它添加到对应卫星系统的星历结构体中。

while ((stat=readrnxnavb(fp,opt,ver,sys,&type,&eph,&geph,&seph))>=0) {/* add ephemeris to navigation data */if (stat) {switch (type) { //type来判断哪一个卫星系统的星历case 1 : stat=add_geph(nav,&geph); break;case 2 : stat=add_seph(nav,&seph); break;default: stat=add_eph (nav,&eph ); break;}if (!stat) return 0;}}

trace文件中,显示如下:

最后返回到readobsnav函数中;

执行 观测文件排序、删除重复星历两个函数:

    /* sort observation data */nepoch=sortobs(obs);/* delete duplicated ephemeris */uniqnav(nav);

.trace中为:

2、生成日志流文件/.stat

读取完观测文件和导航文件后,返回到 execses函数继续运行,如果在配置中打开了“解决方案文件/日志流文件”,则生成后缀为.stat的文件;同时.trace有如下信息输出:

2.1、生成结果文件/.pos

/* write header to output file -----------------------------------------------*/
static int outhead(const char *outfile, char **infile, int n,const prcopt_t *popt, const solopt_t *sopt)
{FILE *fp=stdout;trace(3,"outhead: outfile=%s n=%d\n",outfile,n);if (*outfile) {createdir(outfile);if (!(fp=fopen(outfile,"w"))) {showmsg("error : open output file %s",outfile);return 0;}}/* output header */outheader(fp,infile,n,popt,sopt);if (*outfile) fclose(fp);return 1;
}

并输出结果文件,文件头(如果你设置了输出文件头)

2.2、初始化rtkinit

    rtkinit(&rtk,popt);

3 rtkclosestat:
3 rtkopenstat: file=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\myposbyVS.pos.stat level=1
3 outhead: outfile=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\myposbyVS.pos n=2
3  1370.658: createdir: path=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\myposbyVS.pos
3 outheader: n=2
3 outprcopt:
3 outprcopts:
3 outsolhead:
3 outsolheads:
3 openfile: outfile=E:\专业资料\网友交流\Curtin GNSS Research Centre\CUT00\myposbyVS.pos
3 procpos : mode=0
3 rtkinit :

 

不太明白的地方?

/* input obs data, navigation messages and sbas correction -------------------*/
static int inputobs(obsd_t *obs, int solq, const prcopt_t *popt)
{gtime_t time={0};int i,nu,nr,n=0;trace(3,"infunc  : revs=%d iobsu=%d iobsr=%d isbs=%d\n",revs,iobsu,iobsr,isbs);if (0<=iobsu&&iobsu<obss.n) {settime((time=obss.data[iobsu].time));if (checkbrk("processing : %s Q=%d",time_str(time,0),solq)) {aborts=1; showmsg("aborted"); return -1;}}if (!revs) { /* input forward data */ /* analysis direction (0:forward,1:backward) */if ((nu=nextobsf(&obss,&iobsu,1))<=0) return -1; //nu 为移动站历元观测卫星数if (popt->intpref) { ///* interpolate reference obs (for post mission) */ 0for (;(nr=nextobsf(&obss,&iobsr,2))>0;iobsr+=nr)if (timediff(obss.data[iobsr].time,obss.data[iobsu].time)>-DTTOL) break;}else {for (i=iobsr;(nr=nextobsf(&obss,&i,2))>0;iobsr=i,i+=nr)//nr 为基准站历元观测微型数if (timediff(obss.data[i].time,obss.data[iobsu].time)>DTTOL) break;}nr=nextobsf(&obss,&iobsr,2);if (nr<=0) {nr=nextobsf(&obss,&iobsr,2);}for (i=0;i<nu&&n<MAXOBS*2;i++) obs[n++]=obss.data[iobsu+i];for (i=0;i<nr&&n<MAXOBS*2;i++) obs[n++]=obss.data[iobsr+i];iobsu+=nu;/* update sbas corrections */while (isbs<sbss.n) {time=gpst2time(sbss.msgs[isbs].week,sbss.msgs[isbs].tow);if (getbitu(sbss.msgs[isbs].msg,8,6)!=9) { /* except for geo nav */sbsupdatecorr(sbss.msgs+isbs,&navs);}if (timediff(time,obs[0].time)>-1.0-DTTOL) break;isbs++;}/* update lex corrections */while (ilex<lexs.n) {if (lexupdatecorr(lexs.msgs+ilex,&navs,&time)) {if (timediff(time,obs[0].time)>-1.0-DTTOL) break;}ilex++;}/* update rtcm ssr corrections */if (*rtcm_file) {update_rtcm_ssr(obs[0].time);}}else { /* input backward data */if ((nu=nextobsb(&obss,&iobsu,1))<=0) return -1;if (popt->intpref) {for (;(nr=nextobsb(&obss,&iobsr,2))>0;iobsr-=nr)if (timediff(obss.data[iobsr].time,obss.data[iobsu].time)<DTTOL) break;}else {for (i=iobsr;(nr=nextobsb(&obss,&i,2))>0;iobsr=i,i-=nr)if (timediff(obss.data[i].time,obss.data[iobsu].time)<-DTTOL) break;}nr=nextobsb(&obss,&iobsr,2);for (i=0;i<nu&&n<MAXOBS*2;i++) obs[n++]=obss.data[iobsu-nu+1+i];for (i=0;i<nr&&n<MAXOBS*2;i++) obs[n++]=obss.data[iobsr-nr+1+i];iobsu-=nu;/* update sbas corrections */while (isbs>=0) {time=gpst2time(sbss.msgs[isbs].week,sbss.msgs[isbs].tow);if (getbitu(sbss.msgs[isbs].msg,8,6)!=9) { /* except for geo nav */sbsupdatecorr(sbss.msgs+isbs,&navs);}if (timediff(time,obs[0].time)<1.0+DTTOL) break;isbs--;}/* update lex corrections */while (ilex>=0) {if (lexupdatecorr(lexs.msgs+ilex,&navs,&time)) {if (timediff(time,obs[0].time)<1.0+DTTOL) break;}ilex--;}}return n;
}

2.3、if (!rtkpos(&rtk,obs,n,&navs)) continue;

输出当前历元观测数据:

traceobs(4,obs,n) 具体实现如下:

extern void traceobs(int level, const obsd_t *obs, int n)
{char str[64],id[16];int i;if (!fp_trace||level>level_trace) return;for (i=0;i<n;i++) {time2str(obs[i].time,str,3);satno2id(obs[i].sat,id);fprintf(fp_trace," (%2d) %s %-3s rcv%d %13.3f %13.3f %13.3f %13.3f %d %d %d %d %3.1f %3.1f\n",i+1,str,id,obs[i].rcv,obs[i].L[0],obs[i].L[1],obs[i].P[0],obs[i].P[1],obs[i].LLI[0],obs[i].LLI[1],obs[i].code[0],obs[i].code[1],obs[i].SNR[0]*0.25,obs[i].SNR[1]*0.25);}fflush(fp_trace);
}

输出的顺序为:

(序号)、时间、卫星号、rcv1?2、载波相位1、载波相位2、伪距1、伪距2、LLI1标识、LLI2标识、频率1的obscodes顺序、频率2的obscodes顺序、信噪比1*0.25、信噪比2*0.25

示例如下:

2.3.1、pntpos

1、单点定位之卫星位置、速度、钟差;.trace输出

单点定位中,首先计算卫星位置、速度、钟差;

(1)先计算卫星钟差;包括遍历星历,选择星历;

(2)计算卫星位置;包括查找对应卫星导航系统,解码星历;遍历星历,选择星历;

(3)再次计算卫星位置;用于计算卫星速度;

.trace中的输出为:不断循环

3 satposs : teph=2019/04/01 00:00:00.000 n=10 ephopt=0
4 ephclk  : time=2019/03/31 23:59:59.924 sat=10
4 seleph  : time=2019/04/01 00:00:00.000 sat=10 iode=-1
4 eph2clk : time=2019/03/31 23:59:59.924 sat=10
4 satpos  : time=2019/03/31 23:59:59.924 sat=10 ephopt=0
4 ephpos  : time=2019/03/31 23:59:59.924 sat=10 iode=-1
4 seleph  : time=2019/04/01 00:00:00.000 sat=10 iode=-1
4 eph2pos : time=2019/03/31 23:59:59.924 sat=10
4 kepler: sat=10 e= 0.00446 n= 3 del= 0.000e+00
4 eph2pos : time=2019/03/31 23:59:59.925 sat=10
4 kepler: sat=10 e= 0.00446 n= 3 del= 0.000e+00

 (4)输出卫星相关信息:顺序为:

卫星发射信号时间、卫星号、卫星ECEF下X、Y、Z位置、卫星钟差/m、卫星星历、钟差方差(sat position and clock error variances (m^2))、卫星健康信息(sat health flag (-1:correction not available))

2、单点定位之利用伪距计算接收机位置;.trace输出

实现函数:estpos

static int estpos(const obsd_t *obs, int n, const double *rs, const double *dts,
                  const double *vare, const int *svh, const nav_t *nav,
                  const prcopt_t *opt, sol_t *sol, double *azel, int *vsat,
                  double *resp, char *msg)

(1)首先计算伪距残差:rescode

        /* pseudorange residuals */ //ns 为参与定位的卫星的个数
        nv=rescode(i,obs,n,rs,dts,vare,svh,nav,x,opt,v,H,var,azel,vsat,resp,
                   &ns);

在rescode函数中,输出大部分信息,信息的输出与设置有关

首先输出:    trace(3,"resprng : n=%d\n",n);

然后 : while(卫星个数)

{

4 ionocorr: time=2019/04/01 00:00:00.000 opt=1 sat=10 pos=-90.000 0.000 azel=0.000 90.000
4 tropcorr: time=2019/04/01 00:00:00.000 opt=1 pos=-90.000 0.000 azel=0.000 90.000
4 sat=10 azel=  0.0 90.0 res=-3608726.259 sig=2.471
4 ionocorr: time=2019/04/01 00:00:00.000 opt=1 sat=15 pos=-90.000 0.000 azel=0.000 90.000
4 tropcorr: time=2019/04/01 00:00:00.000 opt=1 pos=-90.000 0.000 azel=0.000 90.000
4 sat=15 azel=  0.0 90.0 res=-1565446.211 sig=2.471

注释:trace(4,"sat=%2d azel=%5.1f %4.1f res=%7.3f sig=%5.3f\n",obs[i].sat,
              azel[i*2]*R2D,azel[1+i*2]*R2D,resp[i],sqrt(var[nv-1]));
信息为:方位角、高度角、伪距残差、标准差

};

同时在,estpos中,对单点定位有一个迭代计算的过程:

 for (i=0;i<MAXITR;i++)

{

循环输出2.3.2;直到每次迭代的量小于阈值;

再加上:

trace(3,"valsol  : n=%d nv=%d\n",n,nv); // validate solution

}

3、单点定位之利用多普勒计算接收机速度;.trace输出

2.3.2 PMODE_SINGLE

    if (opt->mode==PMODE_SINGLE) {
        outsolstat(rtk);
        return 1;     可以看到,函数执行返回上一级!
    }

.trace文件中输出:outsolstat;

继续执行,输出

迭代循环输出……直到终止!

3 valsol  : n=9 nv=11
3 estvel  : n=9
3 resdop  : n=9
3 resdop  : n=9
3 outsolstat:
3 outsol  :
3 outsols :
3 outpos  :
3 infunc  : revs=0 iobsu=5800 iobsr=5800 isbs=0
3 rtkfree :
3 freeobsnav:
3 freepreceph:
3 free_rtcm:
3 closeses:
3 closegoid:
3 rtkclosestat:

附上三个文件.pos、.stat、.trace 希望对大家有帮助!

RTKLIB代码在VS下调试输出pos.trace.stat文件指南.zip

 


http://chatgpt.dhexx.cn/article/cY3K9wsE.shtml

相关文章

sopt:一个简单的python最优化库

sopt:一个简单的python最优化库引言 最近有些朋友总来问我有关遗传算法的东西&#xff0c;我是在大学搞数学建模的时候接触过一些最优化和进化算法方面的东西&#xff0c;以前也写过几篇博客记录过,比如遗传算法的C语言实现(一):以非线性函数求极值为例和C语言实现粒子群算法(P…

python古诗词生成_Python一日一练02----诗词生成器

要求 编写一段程序&#xff0c;可以自动生成小诗。 格式如下 源码 import random import sys articles ["the", "a", "another", "her", "his"] subjects ["cat", "dog", "horse", "m…

LSTM古诗词生成

Le LSTM古诗词生成 一、简介 基于LSTM的古诗词生成&#xff0c;设计神经网络模型&#xff0c;使模型学习数据是6291首古诗&#xff0c;没有专门的验证数据和测试数据&#xff0c;感觉不会预测正确。边学习边生成古诗&#xff0c;从生成的古诗来看学习的效果。 涉及到的模块有Py…

宋词自动生成

利用宋词语料库&#xff0c;通过单双词的组合与模板的匹配&#xff0c;实现指定词牌宋词的生成 import random import tkinter as tk import re from tkinter import messageboxlist []class Window:# 界面设计def __init__(self, root):label1 tk.Label(root, text输入词牌…

基于Python的宋词生成器

资源下载地址&#xff1a;https://download.csdn.net/download/sheziqiong/85631523 1. 背景 我有两个爱好&#xff0c;一个是传统文化&#xff0c;另一个是高新技术。 传统文化&#xff0c;我喜欢唐诗宋词、笔墨丹青&#xff0c;高新技术我则从事前沿的IT编程&#xff0c;喜…

基于java的古诗词生成管理系统

10161-古诗词生成管理系统 开发工具 eclipse tomact mysql jdk 功能详情&#xff1a; 古诗搜索、古诗问答、机器回复、古诗管理&#xff08;添加古诗、古诗分类、古诗标签、古诗列表&#xff09;、用户管理

田字格字帖生成器、孩子取名系列工具

大家好&#xff0c;我是小寻&#xff0c;欢迎关注公众号:工具优选&#xff0c;免费领取优质项目源码和常用工具&#xff0c;还可以加入我的交流群! 这是是一款2013年上线的在线小工具集&#xff0c;包括了 13 款中文学习工具&#xff0c;有田字格字帖、拼音田字格、古诗词字帖…

有趣的深度学习——使用TensorFlow 2.0 + RNN 实现一个古体诗生成器

一、前言 很早之前&#xff0c;我曾经写过一个古体诗生成器&#xff08;详情可以戳TensorFlow练手项目二&#xff1a;基于循环神经网络(RNN)的古诗生成器&#xff09;&#xff0c;那个时候用的还是Python 2.7和TensorFlow 1.4。 随着框架的迭代&#xff0c;API 的变更&#x…

现在还可以一键自动生成古诗词,你知道吗?

人类在漫长的历史长河中&#xff0c;一直在探索着各种各样的美好&#xff0c;不断地追求着更高的境界。而如今&#xff0c;随着科技的不断发展&#xff0c;人工智能已经成为了我们得力的伙伴之一&#xff0c;为我们带来了更多的便利和可能性。尤其是在艺术和文化领域&#xff0…

古诗词在线起名 - 一刀工具箱

古诗词名字生成器帮助你在线生成古诗词名字&#xff0c;包含&#xff1a;诗经、楚辞、唐诗、宋词、辞赋等古风的名字&#xff0c;这些名字都非常的优美好听&#xff0c;希望你们能够喜欢这款古诗词起名工具。 代码片段 async subName() {let name_arr Object.keys(this.userN…

NLP入门 - 基于Word Embedding + LSTM的古诗生成器

一共实现三个功能&#xff1a; 1. 续写五言诗 2. 续写七言诗 3. 写五言藏头诗 之前用这个做Intro to Computer Science的期末项目折腾太久&#xff0c;不想赘述&#xff0c;内容介绍及实现方法可参考期末presentation的slides&#xff1a; https://docs.google.com/presen…

基于古诗词的名字生成器

数据集 因为数据量庞大&#xff0c;使用本地的 CSV 数据进行测试。 后续改进 CSV 文件保存到 mongodb 数据库&#xff0c;便于聚合查询。 数据分词 我们需要一个分词器将这些数据进行分词&#xff0c;用到的是 Golang 版的 jieba 库如下&#xff1a; "github.com/go-e…

基于LSTM + keras 的古诗生成器

1.语料准备&#xff1a;包含 5.5 万首唐诗、26 万首宋诗、2.1 万首宋词和其他古典文集。诗人包括唐宋两朝近 1.4 万古诗人&#xff0c;和两宋时期 1.5 千古词人。数据来源于互联网。每行一首诗&#xff0c;标题在预处理的时候已经去掉了。2.模型参数配置&#xff1a;预先定义模…

唐诗生成器

使用唐诗语料库&#xff0c;经过去噪预处理、分词、生成搭配、生成主题等过程&#xff0c;生成唐诗。 csdn下载地址&#xff1a;http://download.csdn.net/detail/lijiancheng0614/9840952 github上repository地址&#xff1a;https://github.com/lijiancheng0614/poem_genera…

JQuery中的val()函数

JQuery中的val()函数相当于Javascript中的value属性&#xff0c;可以用来设置和获取元素的值。 下面用一个简单的邮箱登陆界面来举个例子&#xff1a; 在默认情况下邮箱的地址输入框和密码输入框都有相应的提示。 要求&#xff1a;当鼠标聚焦在邮箱地址输入框时&#xff0c;提…

【Python】sklearn中的cross_val_score()函数参数

sklearn 中的cross_val_score函数可以用来进行交叉验证&#xff0c;因此十分常用&#xff0c;这里介绍这个函数的参数含义。 sklearn.cross_validation.cross_val_score(estimator, X, yNone, scoringNone, cvNone, n_jobs1, verbose0, fit_paramsNone, pre_dispatch‘2*n_job…

sklearn交叉验证函数cross_val_score用法及参数解释

文章目录 一 、使用示例二、参数含义三、常见的scoring取值1.分类、回归和聚类scoring参数选择2.f1_micro和f1_macro区别3.负均方误差和均方误差 一 、使用示例 import numpy as np from sklearn.model_selection import train_test_split from sklearn import svm from sklea…

java val_Java中是否有val()函数?

慕尼黑的夜晚无繁华 很少有实际用例能够评估String作为Java代码的一个片段是必要的或可取的。也就是说&#xff0c;询问如何做到这一点实际上是XY问题&#xff1a;你实际上有一个不同的问题&#xff0c;可以用不同的方法来解决。先问问自己&#xff0c;这是怎么回事String你想要…

c语言val函数用法,函数VAL()什么意思怎么用啊?/

满意答案 Dickyshe 2013.03.22 采纳率&#xff1a;50% 等级&#xff1a;12 已帮助&#xff1a;12551人 将一个数据行变量转换成数字长整型变量如 text1.text "10" text2.text "11" text3.text text1.texttext2.text 按道理应该得到10&#xff0b;11(…

mysql中val是什么意思_val是什么函数

val是将由数字符号组成的字符型数据转换成相应的数值型数据的函数&#xff0c;其语法是“Val(S,V,Code)”&#xff0c;若字符串内出现非数字字符&#xff0c;那么只转换非数字字符前面的部分&#xff1b;若字符串的首字符不是数字符号&#xff0c;则返回数值零&#xff0c;但忽…