目录
一、main函数流程总结
二、分析识别 -k 后如何配置
三、最后传参的数据文件处理方式
一、main函数流程总结
详解rtklib中main函数如何配置文件(上)-CSDN博客
在这片文章中讲解了rtklib中main函数的整个流程。
(1)通过两种方法给main函数传递参数,并放在 argv 这个指针数组中。
(2)初始化三个主要结构体及其它参数。
prcopt_t prcopt=prcopt_default; //process option 定位配置-默认值solopt_t solopt=solopt_default; //solotion option 结果配置-默认值filopt_t filopt={""}; //fileoption 文件配置-默认空
(3) 首先识别给main函数的参数中是否有 -k,如果有则根据 -k 后面的配置文件信息给 prcopt、solopt、filopt 这三个结构体赋值。下面这段代码也是本文第二点详细讲解的内容。
/* load options from configuration file */ for (i=1;i<argc;i++) {if (!strcmp(argv[i],"-k")&&i+1<argc) {resetsysopts();if (!loadopts(argv[++i],sysopts)) return -1; //加载配置文件getsysopts(&prcopt,&solopt,&filopt);}}
(4)随后再依次遍历传递的参数中是否有和代码中的 ‘ -××× ’对应,如果有则直接赋值给结构体中的变量,假如前面读取 -k 里面哪些信息有误,通过后面的代码还可以修改。
(5)通过postpos函数进入下一步。
//开始时间、结束时间、采样频率、process option、solution option、file option、输入文件、输入文件个数、输出文件ret=postpos(ts,te,tint,0.0,&prcopt,&solopt,&filopt,infile,n,outfile,"","");
要记住最主要的这三个结构体prcopt、solopt、filopt都包含哪些成员。
typedef struct { /* 处理选项类型-配置定义 */int mode; /* positioning mode (PMODE_???) */int soltype; /* solution type (0:forward,1:backward,2:combined) */int nf; /* number of frequencies (1:L1,2:L1+L2,3:L1+L2+L5) */int navsys; /* navigation system */double elmin; /* elevation mask angle (rad) */snrmask_t snrmask; /* SNR mask */int sateph; /* satellite ephemeris/clock (EPHOPT_???) */int modear; /* AR mode (0:off,1:continuous,2:instantaneous,3:fix and hold,4:ppp-ar) */int glomodear; /* GLONASS AR mode (0:off,1:on,2:auto cal,3:ext cal) */int bdsmodear; /* BeiDou AR mode (0:off,1:on) */int maxout; /* obs outage count to reset bias */int minlock; /* min lock count to fix ambiguity */int minfix; /* min fix count to hold ambiguity */int armaxiter; /* max iteration to resolve ambiguity */int ionoopt; /* ionosphere option (IONOOPT_???) */int tropopt; /* troposphere option (TROPOPT_???) */int dynamics; /* dynamics model (0:none,1:velociy,2:accel) */int tidecorr; /* earth tide correction (0:off,1:solid,2:solid+otl+pole) */int niter; /* number of filter iteration */int codesmooth; /* code smoothing window size (0:none) */int intpref; /* interpolate reference obs (for post mission) */int sbascorr; /* SBAS correction options */int sbassatsel; /* SBAS satellite selection (0:all) */int rovpos; /* rover position for fixed mode */int refpos; /* base position for relative mode *//* (0:pos in prcopt, 1:average of single pos, *//* 2:read from file, 3:rinex header, 4:rtcm pos) */double eratio[NFREQ]; /* code/phase error ratio */double err[5]; /* measurement error factor *//* [0]:reserved *//* [1-3]:error factor a/b/c of phase (m) *//* [4]:doppler frequency (hz) */double std[3]; /* initial-state std [0]bias,[1]iono [2]trop */double prn[6]; /* process-noise std [0]bias,[1]iono [2]trop [3]acch [4]accv [5] pos */double sclkstab; /* satellite clock stability (sec/sec) */double thresar[8]; /* AR validation threshold */double elmaskar; /* elevation mask of AR for rising satellite (deg) */double elmaskhold; /* elevation mask to hold ambiguity (deg) */double thresslip; /* slip threshold of geometry-free phase (m) */double maxtdiff; /* max difference of time (sec) */double maxinno; /* reject threshold of innovation (m) */double maxgdop; /* reject threshold of gdop */double baseline[2]; /* baseline length constraint {const,sigma} (m) */double ru[3]; /* rover position for fixed mode {x,y,z} (ecef) (m) */double rb[3]; /* base position for relative mode {x,y,z} (ecef) (m) */char anttype[2][MAXANT]; /* antenna types {rover,base} */double antdel[2][3]; /* antenna delta {{rov_e,rov_n,rov_u},{ref_e,ref_n,ref_u}} */pcv_t pcvr[2]; /* receiver antenna parameters {rov,base} */uint8_t exsats[MAXSAT]; /* excluded satellites (1:excluded,2:included) */int maxaveep; /* max averaging epoches */int initrst; /* initialize by restart */int outsingle; /* output single by dgps/float/fix/ppp outage */char rnxopt[2][256]; /* rinex options {rover,base} */int posopt[6]; /* positioning options */int syncsol; /* solution sync mode (0:off,1:on) */double odisp[2][6*11]; /* ocean tide loading parameters {rov,base} */int freqopt; /* disable L2-AR */char pppopt[256]; /* ppp option */
} prcopt_t;
typedef struct { /* solution options type */int posf; /* solution format (SOLF_???) */int times; /* time system (TIMES_???) */int timef; /* time format (0:sssss.s,1:yyyy/mm/dd hh:mm:ss.s) */int timeu; /* time digits under decimal point */int degf; /* latitude/longitude format (0:ddd.ddd,1:ddd mm ss) */int outhead; /* output header (0:no,1:yes) */int outopt; /* output processing options (0:no,1:yes) */int outvel; /* output velocity options (0:no,1:yes) */int datum; /* datum (0:WGS84,1:Tokyo) */int height; /* height (0:ellipsoidal,1:geodetic) */int geoid; /* geoid model (0:EGM96,1:JGD2000) */int solstatic; /* solution of static mode (0:all,1:single) */int sstat; /* solution statistics level (0:off,1:states,2:residuals) */int trace; /* debug trace level (0:off,1-5:debug) */double nmeaintv[2]; /* nmea output interval (s) (<0:no,0:all) *//* nmeaintv[0]:gprmc,gpgga,nmeaintv[1]:gpgsv */char sep[64]; /* field separator */char prog[64]; /* program name */double maxsolstd; /* max std-dev for solution output (m) (0:all) */
} solopt_t;
typedef struct { /* file options type */char satantp[MAXSTRPATH]; /* satellite antenna parameters file */char rcvantp[MAXSTRPATH]; /* receiver antenna parameters file */char stapos [MAXSTRPATH]; /* station positions file */char geoid [MAXSTRPATH]; /* external geoid data file */char iono [MAXSTRPATH]; /* ionosphere data file */char dcb [MAXSTRPATH]; /* dcb data file */char eop [MAXSTRPATH]; /* eop data file */char blq [MAXSTRPATH]; /* ocean tide loading blq file */char tempdir[MAXSTRPATH]; /* ftp/http temporaly directory */char geexe [MAXSTRPATH]; /* google earth exec file */char solstat[MAXSTRPATH]; /* solution statistics file */char trace [MAXSTRPATH]; /* debug trace file */
} filopt_t;
二、分析识别 -k 后如何配置
/* load options from configuration file */ for (i=1;i<argc;i++) {if (!strcmp(argv[i],"-k")&&i+1<argc) {resetsysopts();if (!loadopts(argv[++i],sysopts)) return -1; //加载配置文件getsysopts(&prcopt,&solopt,&filopt);}}
当在main函数参数中找到 -k后首先进入resetsysopts()函数,可以发现仍然是在给结构体初始化。但是要注意这里首先初始化的是prcopt_、solopt_、filopt_,和main函数中最终给postpos传参的prcopt、solopt、filopt不同。在这个for循环内其实都在给prcopt_、solopt_、filopt_这三个全局变量赋值,最后再通过 getsysopts(&prcopt,&solopt,&filopt);函数将prcopt_、solopt_、filopt_的值传给prcopt、solopt、filopt。
extern void resetsysopts(void)
{int i,j;trace(3,"resetsysopts:\n");prcopt_=prcopt_default;solopt_=solopt_default;filopt_.satantp[0]='\0';filopt_.rcvantp[0]='\0';filopt_.stapos [0]='\0';filopt_.geoid [0]='\0';filopt_.dcb [0]='\0';filopt_.blq [0]='\0';filopt_.solstat[0]='\0';filopt_.trace [0]='\0';for (i=0;i<2;i++) antpostype_[i]=0;elmask_=15.0;elmaskar_=0.0;elmaskhold_=0.0;for (i=0;i<2;i++) for (j=0;j<3;j++) {antpos_[i][j]=0.0;}exsats_[0] ='\0';
}
随后通过下述代码,来加载配置文件,即将你自定义的配置文件参数全部都传递给prcopt_、solopt_、filopt_这三个全局变量。
if (!loadopts(argv[++i],sysopts)) return -1; //加载配置文件
首先记住loadopts函数传递的两个参数,第一个是argv[++i],即 -k 后配置文件路径即自定义的配置文件,第二个参数是 sysopts ,它是一个结构体数组,声明的结构体以及内容如下:
typedef struct { /* option type */const char *name; /* option name */int format; /* option format (0:int,1:double,2:string,3:enum) */void *var; /* pointer to option variable */const char *comment; /* 选项注释/enum labels/unit */
} opt_t;
EXPORT opt_t sysopts[]={ {"pos1-posmode", 3, (void *)&prcopt_.mode, MODOPT }, //(void *)&prcopt_.mode,将结构体成员prcopt_.mode地址强制类型转换为void* 指针{"pos1-frequency", 3, (void *)&prcopt_.nf, FRQOPT },{"pos1-soltype", 3, (void *)&prcopt_.soltype, TYPOPT },{"pos1-elmask", 1, (void *)&elmask_, "deg" },{"pos1-snrmask_r", 3, (void *)&prcopt_.snrmask.ena[0],SWTOPT},{"pos1-snrmask_b", 3, (void *)&prcopt_.snrmask.ena[1],SWTOPT},{"pos1-snrmask_L1", 2, (void *)snrmask_[0], "" },{"pos1-snrmask_L2", 2, (void *)snrmask_[1], "" },{"pos1-snrmask_L5", 2, (void *)snrmask_[2], "" },{"pos1-dynamics", 3, (void *)&prcopt_.dynamics, SWTOPT },{"pos1-tidecorr", 3, (void *)&prcopt_.tidecorr, TIDEOPT},{"pos1-ionoopt", 3, (void *)&prcopt_.ionoopt, IONOPT },{"pos1-tropopt", 3, (void *)&prcopt_.tropopt, TRPOPT },{"pos1-sateph", 3, (void *)&prcopt_.sateph, EPHOPT },{"pos1-posopt1", 3, (void *)&prcopt_.posopt[0], SWTOPT },{"pos1-posopt2", 3, (void *)&prcopt_.posopt[1], SWTOPT },{"pos1-posopt3", 3, (void *)&prcopt_.posopt[2], PHWOPT },{"pos1-posopt4", 3, (void *)&prcopt_.posopt[3], SWTOPT },{"pos1-posopt5", 3, (void *)&prcopt_.posopt[4], SWTOPT },{"pos1-posopt6", 3, (void *)&prcopt_.posopt[5], SWTOPT },{"pos1-exclsats", 2, (void *)exsats_, "prn ..."},{"pos1-navsys", 0, (void *)&prcopt_.navsys, NAVOPT },{"pos2-armode", 3, (void *)&prcopt_.modear, ARMOPT },{"pos2-gloarmode", 3, (void *)&prcopt_.glomodear, GAROPT },{"pos2-bdsarmode", 3, (void *)&prcopt_.bdsmodear, SWTOPT },{"pos2-arthres", 1, (void *)&prcopt_.thresar[0], "" },{"pos2-arthres1", 1, (void *)&prcopt_.thresar[1], "" },{"pos2-arthres2", 1, (void *)&prcopt_.thresar[2], "" },{"pos2-arthres3", 1, (void *)&prcopt_.thresar[3], "" },{"pos2-arthres4", 1, (void *)&prcopt_.thresar[4], "" },{"pos2-arlockcnt", 0, (void *)&prcopt_.minlock, "" },{"pos2-arelmask", 1, (void *)&elmaskar_, "deg" },{"pos2-arminfix", 0, (void *)&prcopt_.minfix, "" },{"pos2-armaxiter", 0, (void *)&prcopt_.armaxiter, "" },{"pos2-elmaskhold", 1, (void *)&elmaskhold_, "deg" },{"pos2-aroutcnt", 0, (void *)&prcopt_.maxout, "" },{"pos2-maxage", 1, (void *)&prcopt_.maxtdiff, "s" },{"pos2-syncsol", 3, (void *)&prcopt_.syncsol, SWTOPT },{"pos2-slipthres", 1, (void *)&prcopt_.thresslip, "m" },{"pos2-rejionno", 1, (void *)&prcopt_.maxinno, "m" },{"pos2-rejgdop", 1, (void *)&prcopt_.maxgdop, "" },{"pos2-niter", 0, (void *)&prcopt_.niter, "" },{"pos2-baselen", 1, (void *)&prcopt_.baseline[0],"m" },{"pos2-basesig", 1, (void *)&prcopt_.baseline[1],"m" },{"out-solformat", 3, (void *)&solopt_.posf, SOLOPT },{"out-outhead", 3, (void *)&solopt_.outhead, SWTOPT },{"out-outopt", 3, (void *)&solopt_.outopt, SWTOPT },{"out-outvel", 3, (void *)&solopt_.outvel, SWTOPT },{"out-timesys", 3, (void *)&solopt_.times, TSYOPT },{"out-timeform", 3, (void *)&solopt_.timef, TFTOPT },{"out-timendec", 0, (void *)&solopt_.timeu, "" },{"out-degform", 3, (void *)&solopt_.degf, DFTOPT },{"out-fieldsep", 2, (void *) solopt_.sep, "" },{"out-outsingle", 3, (void *)&prcopt_.outsingle, SWTOPT },{"out-maxsolstd", 1, (void *)&solopt_.maxsolstd, "m" },{"out-height", 3, (void *)&solopt_.height, HGTOPT },{"out-geoid", 3, (void *)&solopt_.geoid, GEOOPT },{"out-solstatic", 3, (void *)&solopt_.solstatic, STAOPT },{"out-nmeaintv1", 1, (void *)&solopt_.nmeaintv[0],"s" },{"out-nmeaintv2", 1, (void *)&solopt_.nmeaintv[1],"s" },{"out-outstat", 3, (void *)&solopt_.sstat, STSOPT },{"stats-eratio1", 1, (void *)&prcopt_.eratio[0], "" },{"stats-eratio2", 1, (void *)&prcopt_.eratio[1], "" },{"stats-errphase", 1, (void *)&prcopt_.err[1], "m" },{"stats-errphaseel",1, (void *)&prcopt_.err[2], "m" },{"stats-errphasebl",1, (void *)&prcopt_.err[3], "m/10km"},{"stats-errdoppler",1, (void *)&prcopt_.err[4], "Hz" },{"stats-stdbias", 1, (void *)&prcopt_.std[0], "m" },{"stats-stdiono", 1, (void *)&prcopt_.std[1], "m" },{"stats-stdtrop", 1, (void *)&prcopt_.std[2], "m" },{"stats-prnaccelh", 1, (void *)&prcopt_.prn[3], "m/s^2"},{"stats-prnaccelv", 1, (void *)&prcopt_.prn[4], "m/s^2"},{"stats-prnbias", 1, (void *)&prcopt_.prn[0], "m" },{"stats-prniono", 1, (void *)&prcopt_.prn[1], "m" },{"stats-prntrop", 1, (void *)&prcopt_.prn[2], "m" },{"stats-prnpos", 1, (void *)&prcopt_.prn[5], "m" },{"stats-clkstab", 1, (void *)&prcopt_.sclkstab, "s/s" },{"ant1-postype", 3, (void *)&antpostype_[0], POSOPT },{"ant1-pos1", 1, (void *)&antpos_[0][0], "deg|m"},{"ant1-pos2", 1, (void *)&antpos_[0][1], "deg|m"},{"ant1-pos3", 1, (void *)&antpos_[0][2], "m|m" },{"ant1-anttype", 2, (void *)prcopt_.anttype[0], "" },{"ant1-antdele", 1, (void *)&prcopt_.antdel[0][0],"m" },{"ant1-antdeln", 1, (void *)&prcopt_.antdel[0][1],"m" },{"ant1-antdelu", 1, (void *)&prcopt_.antdel[0][2],"m" },{"ant2-postype", 3, (void *)&antpostype_[1], POSOPT },{"ant2-pos1", 1, (void *)&antpos_[1][0], "deg|m"},{"ant2-pos2", 1, (void *)&antpos_[1][1], "deg|m"},{"ant2-pos3", 1, (void *)&antpos_[1][2], "m|m" },{"ant2-anttype", 2, (void *)prcopt_.anttype[1], "" },{"ant2-antdele", 1, (void *)&prcopt_.antdel[1][0],"m" },{"ant2-antdeln", 1, (void *)&prcopt_.antdel[1][1],"m" },{"ant2-antdelu", 1, (void *)&prcopt_.antdel[1][2],"m" },{"ant2-maxaveep", 0, (void *)&prcopt_.maxaveep ,"" },{"ant2-initrst", 3, (void *)&prcopt_.initrst, SWTOPT },{"misc-timeinterp", 3, (void *)&prcopt_.intpref, SWTOPT },{"misc-sbasatsel", 0, (void *)&prcopt_.sbassatsel, "0:all"},{"misc-rnxopt1", 2, (void *)prcopt_.rnxopt[0], "" },{"misc-rnxopt2", 2, (void *)prcopt_.rnxopt[1], "" },{"misc-pppopt", 2, (void *)prcopt_.pppopt, "" },{"file-satantfile", 2, (void *)&filopt_.satantp, "" },{"file-rcvantfile", 2, (void *)&filopt_.rcvantp, "" },{"file-staposfile", 2, (void *)&filopt_.stapos, "" },{"file-geoidfile", 2, (void *)&filopt_.geoid, "" },{"file-ionofile", 2, (void *)&filopt_.iono, "" },{"file-dcbfile", 2, (void *)&filopt_.dcb, "" },{"file-eopfile", 2, (void *)&filopt_.eop, "" },{"file-blqfile", 2, (void *)&filopt_.blq, "" },{"file-tempdir", 2, (void *)&filopt_.tempdir, "" },{"file-geexefile", 2, (void *)&filopt_.geexe, "" },{"file-solstatfile",2, (void *)&filopt_.solstat, "" },{"file-tracefile", 2, (void *)&filopt_.trace, "" },{"",0,NULL,""} /* terminator */
};
随后进入loadopts函数, 我对这个函数内的代码做了详细的注释。其中file即自定义的配置文件,opts即指向 sysopts这个结构体数组的指针。只需要注意在函数的开始定义了一个char类型的字符数组 buff [2048],用来存放自定义配置文件中每一行的信息,所以说不管是名称、还是后面所跟的值都是以字符串的形式进行处理。
可以看到在loadopts这个函数内,使用了while循环,每次循环提取自定义配置文件内的一行信息进行处理,如下:
extern int loadopts(const char *file, opt_t *opts)
{ // file == 配置文件 opts == sysopts FILE *fp;opt_t *opt;char buff[2048],*p;int n=0;trace(3,"loadopts: file=%s\n",file);if (!(fp=fopen(file,"r"))) {trace(1,"loadopts: options file open error (%s)\n",file);return 0;} //从文件中读取一行数据,并将其存储到 buff 缓冲区中while (fgets(buff,sizeof(buff),fp)) { n++;chop(buff); //去除字符串中结尾的空白字符和 # 号后面的内容if (buff[0]=='\0') continue;if (!(p=strstr(buff,"="))) {//在字符串中查找指定子字符串的函数,返回该位置地址fprintf(stderr,"invalid option %s (%s:%d)\n",buff,file,n);//被后续的参数依次填充并输出到标准错误流中continue;}*p++='\0';chop(buff); //buff == 每一行数据 opts == sysoptsif (!(opt=searchopt(buff,opts))) continue;
//找到这一行的名称和sysopts对应,返回的是sysopts[i]的结构体地址,并赋给结构体指针opt_t * optif (!str2opt(opt,p)) {fprintf(stderr,"invalid option value %s (%s:%d)\n",buff,file,n);continue;}}fclose(fp);return 1;
}
loadopts函数中除了打印trace信息总共调用了三个涉及处理配置文件的函数。
第一个函数是chop函数,主要目的是截断将提取的一行信息 # 后面的内容,只保留名称和值,如下图所示:
/* 去除字符串中结尾的空白字符和 # 号后面的内容 ------------------------------------------*/
static void chop(char *str) // str指向首字符地址
{char *p;if ((p=strchr(str,'#'))) *p='\0'; /*在字符串str中查找#的位置并将指针p指向#的位置,并将该位置的字符改为字符串结束标记 \0,从而截断字符串 */for (p=str+strlen(str)-1;p>=str&&!isgraph((int)*p);p--) *p='\0';
} /*从字符串末尾开始向前遍历,找到第一个不是空白字符的位置,然后将该位置之后的字符截断(即将该位置之后的字符改为字符串结束标记 \0)。这里使用了 isgraph 函数来判断字符是否为可打印字符(不是空白字符)。*/
第二个函数是 opt = searchopt( buff,opts ),可以看到 searchopt 函数的第一个参数是提取的自定义配置文件的某一行的去除过注释,只保留名称和对应值的信息,第二个参数仍是sysopts这个包含所有配置信息的结构体数组,最终返回的值赋给同样是 opt_t 的结构体指针。
分析下述代码,不难发现,searchopt 函数其实是比较自定义配置文件的某一行的名称和rtklib中定义的 sysopts 结构体数组中的名称是否对应,即下图所示,如果在 sysopts 结构体数组中找到了这个名称,则返回 sysopts 结构体数组中这行所在位置的地址,然后用同样是 opt_t 类型的结构体指针 opt 指向 sysopts[ i ]。
extern opt_t *searchopt(const char *name, const opt_t *opts) //name==buff == 每一行数据
{ // opts == sysoptsint i;trace(3,"searchopt: name=%s\n",name);//strstr --- 从前面的字符串找后面的字符串for (i=0;*opts[i].name;i++) {if (strstr(opts[i].name,name)) return (opt_t *)(opts+i);//此时opts是结构体数组,+i 表示opts[i]}return NULL;
}
当找到这行的配置信息的名称后进入了下一个函数 str2opt, 这个函数的第一个参数是刚刚找到的sysopts 结构体数组中的对应位置,第二个参数 p 根据下图划线代码可以明显发现是自定义配置文件该行 = 号后面的值。
直接进入str2opt 函数,因为之间说过,提取的每一行信息都是以字符串的形式,所以这个函数的目的就是将=号后面的值进行形式转换,随后赋值给全局变量 prcopt_、solopt_、filopt_等。这样通过while循环将自定义配置文件内的所有信息全部提取好了,但此时还是在全局变量中,而不是main 函数定义的局部变量中。
/* string to option value ------------------------------------------------------
* convert string to option value
* args : opt_t *opt O option
* char *str I option value string
* return : status (1:ok,0:error)
*-----------------------------------------------------------------------------*/
extern int str2opt(opt_t *opt, const char *str) //该行sysopts结构体地址,‘=’后面值的地址
{switch (opt->format) {case 0: *(int *)opt->var=atoi(str); break; //字符串转换成整数case 1: *(double *)opt->var=atof(str); break; //字符串转换成浮点数case 2: strcpy((char *)opt->var,str); break;case 3: return str2enum(str,opt->comment,(int *)opt->var);default: return 0;}return 1;
}
所以还要来到 for 循环内最后一个函数,将这三个全局变量 prcopt_、solopt_、filopt_结构体的值传给了main 函数中的局部变量 prcopt、solopt、filopt。
在 getsysopts 函数中还有一个 buff2sysopts 函数,则是对读入自定义配置文件数据后的全局变量prcopt_、solopt_、filopt_等做进一步处理,比如频率,卫星系统prn号、坐标转换等,暂时没有细看。
/* system options buffer to options ------------------------------------------*/
static void buff2sysopts(void)
{double pos[3],*rr;char buff[1024],*p,*id;int i,j,sat,*ps;//角度转弧度prcopt_.elmin =elmask_ *D2R;prcopt_.elmaskar =elmaskar_ *D2R;prcopt_.elmaskhold=elmaskhold_*D2R;for (i=0;i<2;i++) {ps=i==0?&prcopt_.rovpos:&prcopt_.refpos;rr=i==0?prcopt_.ru:prcopt_.rb;if (antpostype_[i]==0) { /* lat/lon/hgt */*ps=0;pos[0]=antpos_[i][0]*D2R;pos[1]=antpos_[i][1]*D2R;pos[2]=antpos_[i][2];pos2ecef(pos,rr);}else if (antpostype_[i]==1) { /* xyz-ecef */*ps=0;rr[0]=antpos_[i][0];rr[1]=antpos_[i][1];rr[2]=antpos_[i][2];}else *ps=antpostype_[i]-1;}/* excluded satellites */for (i=0;i<MAXSAT;i++) prcopt_.exsats[i]=0;if (exsats_[0]!='\0') {strcpy(buff,exsats_);for (p=strtok(buff," ");p;p=strtok(NULL," ")) { //strtok - 将字符串分割,返回子字符串if (*p=='+') id=p+1; else id=p;if (!(sat=satid2no(id))) continue;prcopt_.exsats[sat-1]=*p=='+'?2:1;}}/* snrmask */ //频率for (i=0;i<NFREQ;i++) {for (j=0;j<9;j++) prcopt_.snrmask.mask[i][j]=0.0;strcpy(buff,snrmask_[i]);for (p=strtok(buff,","),j=0;p&&j<9;p=strtok(NULL,",")) {prcopt_.snrmask.mask[i][j++]=atof(p);}}/* number of frequency (4:L1+L5) */if (prcopt_.nf==4) {prcopt_.nf=3;prcopt_.freqopt=1;}
}
三、最后传参的数据文件处理方式
输出 .pos文件路径:在识别 -o 后,直接 char* outfile指向了路径字符串的首地址。
而传参中的观测文件和星历文件是放在了最后,全部放在了infile这个指针数组中。