.trace文件是调试文件,帮助用户在程序、输入数据时,进行分析的一个很好的提示!
.trace文件的生成、trace文件内容的生成,均在execses中!
以单点定位为例,大体流程为:
/* read obs and nav data */
if (!readobsnav(ts,te,ti,infile,index,n,&popt_,&obss,&navs,stas)) 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);
}
在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中相关信息如下:
在readobsnav中,循环读取观测文件、导航文件;先读取观测文件……
其中,trace中每一行的开头都标记有函数信息,即调用时间顺序!
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
忽略重复的数据,此图仅仅是示意
函数: 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中,开始循环读取每一个历元的观测数据:
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函数中,进行读取下一个文件,即导航文件!
如果是相对定位,输入两个观测文件,先读移动站观测文件、接着读基准站观测文件:
紧接着读取导航电文:
.trace文件中
开始进行导航文件读取:
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
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中为:
读取完观测文件和导航文件后,返回到 execses函数继续运行,如果在配置中打开了“解决方案文件/日志流文件”,则生成后缀为.stat的文件;同时.trace有如下信息输出:
/* 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;
}
并输出结果文件,文件头(如果你设置了输出文件头)
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&&iobsuintpref) { ///* interpolate reference obs (for post mission) */ 0
for (;(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-1.0-DTTOL) break;
isbs++;
}
/* update lex corrections */
while (ilex-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)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=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;
}
输出当前历元观测数据:
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
输出的顺序为:
(序号)、时间、卫星号、rcv1?2、载波相位1、载波相位2、伪距1、伪距2、LLI1标识、LLI2标识、频率1的obscodes顺序、频率2的obscodes顺序、信噪比1*0.25、信噪比2*0.25
示例如下:
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
{
循环输出2.3.2;直到每次迭代的量小于阈值;
再加上:
trace(3,"valsol : n=%d nv=%d\n",n,nv); // validate solution
}
3、单点定位之利用多普勒计算接收机速度;.trace输出
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