详解rtklib中main函数如何配置文件(下)

目录

一、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这个指针数组中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/767591.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最长上升子序列

一、题目描述 B3637 最长上升子序列 二、问题简析 2.1 法一&#xff1a; O ( N 2 ) O(N^2) O(N2) 令 d p [ i ] dp[i] dp[i] 以 a i a_i ai​ 结尾的上升子序列的最大长度。 以 a i a_i ai​ 结尾的上升子序列有两种可能&#xff1a; 1、仅有 a i a_i ai​ 一个元素2…

保研复习概率论2

1.什么是随机变量的数学期望&#xff08;expected value&#xff09;&#xff1f; 如果X是离散型随机变量&#xff0c;其分布列为piP{Xxi}(i1,2...)&#xff0c;若级数绝对收敛&#xff0c;则称随机变量X的数学期望存在&#xff0c;并将的和称为随机变量X的数学期望&#xff0…

5.5.7、【AI技术新纪元:Spring AI解码】Redis

Redis Redis 是一款开源(BSD 许可)的内存数据结构存储系统,可用作数据库、缓存、消息代理以及流处理引擎。Redis 提供了诸如字符串、哈希表、列表、集合、带范围查询的有序集合、位图、HyperLogLogs、地理空间索引和流等多种数据结构。 Redis 向量搜索 Redis 向量搜索与查…

【C++】每日一题 位1的个数

编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 ‘1’ 的个数&#xff08;也被称为汉明重量&#xff09;。 #include <iostream> #include <cstdint>int hammingWeight(uint3…

汇编语言中的MVC

一 MVC指令 1&#xff0e;移动字符串指令MVC 移动字符串指令MVC的格式为&#xff1a; MVC D1(L,B1),D2(B2) (移动字符串) 功能&#xff1a;&#xff08;D1&#xff08;B1&#xff09;&#xff09; ← &#xff08;D2&#xff08;B2&#xff09;&#xff09; L个字符 指令的执行…

React面试总结

React中JSX转换为真实Dom的过程 可以从几个大体过程来看 jsx语法解析 jsx语法解析成js代表的对象&#xff0c;即把jsx语法转换为基于js的React.createElement(args1,args2,args3)&#xff0c;args1,args2,args3分别是标签类型、属性和标签内容&#xff0c;主要利用的是babel等…

leetcode 316.去除重复字母

思路&#xff1a;贪心单调栈。 这道题和前几天做的那道“删除k位数字”那道题很像。 这里由于是按照字典序进行输出的&#xff0c;而且删除的地方我们也不知道&#xff0c;是随机的&#xff0c;这个时候其实就应该想到用单调栈进行解答&#xff0c;其实这样才能进行很好的存储…

COPY requires at least two arguments, docker COPY 报错

COPY requires at least two arguments # 使用 Node.js 12.16.0FROM node:12.16.0WORKDIR /appCOPY ..原因&#xff1a;Dockerfile文件COPY后的两个. 要加空格 本内容来源于小豆包&#xff0c;想要更多内容请跳转小豆包 》

【Frida】【Android】01_手把手教你环境搭建

▒ 目录 ▒ &#x1f6eb; 导读开发环境 1️⃣ 环境搭建安装Android模拟器安装Frida CLI安装Frida Server端口重定向&#xff1a;adb forward 2️⃣ 运行测试spwan模式attach模式直接加载脚本 &#x1f4d6; 参考资料 &#x1f6eb; 导读 开发环境 版本号描述文章日期2024-03…

C++按位运算

6.3 按位运算 6.3.1 位运算概述 符号描述运算规则实例&与两个位都为1时&#xff0c;结果才为1。0001&00011,0001&00000,0000&00000000|或两个位都为0时&#xff0c;结果才为0。0001^异或两个位相同为0&#xff0c;相异为1。0001∧00010000,0001∧00001,0000∧…

matlab空间曲线图形

说明&#xff1a;问题来自CSDN-问答板块&#xff0c;题主提问。 需求&#xff1a;如何用子图命令画出平面y2z&#xff0c;z2y与球面x^2y^2z^25相交的空间曲线图形。需要完整代码和结果的图片。 一、先看效果图 二、代码 % 创建figure figure% 创建二维网格&#xff0c;用于定…

element ui实践bug

文章目录 el-table的默认全部展开属性default-expand-all el-table的默认全部展开属性default-expand-all 该属性只有table 初始化时才会生效&#xff0c;后续动态更改无效。 如果想要动态修改default-expand-all 属性&#xff0c;则需要控制table 的重新渲染&#xff0c;可以…

day01_mysql数据类型和运算符_课后练习 - 参考答案

文章目录 day01_mysql_课后练习第1题第2题第3题第4题第5题 day01_mysql_课后练习 第1题 案例&#xff1a; 1、创建数据库day01_test01_library 2、创建表格books 字段名字段说明数据类型允许为空唯一b_id书编号int(11)否是b_name书名varchar&#xff08;50&#xff09;否否…

性能调优专题并发编程专题(持续更新)

一、性能调优专题 MySQL相关 一、深入理解MySQL索引底层数据结构与算法 索引概念&#xff1a;索引是帮助MySQL高效获取数据的排好序的数据结构 索引数据结构&#xff1a; 1、二叉树 缺点&#xff1a;当索引字段有序的时候&#xff0c;不会自动平衡二叉树&#xff0c;数据…

JavaScript单元测试jasmine学习(一)

介绍&#xff1a; jasmine是用于测试JavaScript的一种测试框架,BDD(Behavior Driven Development)行为驱动开发。不依赖于任何其他JavaScript框架&#xff0c;也不需要DOM 准备工作&#xff1a; 1. 首先添加jasmine到自己的项目中 npm install --save-dev jasmine 2. 在项目…

【热门话题】ECMAScript vs JavaScript:理解两者间的联系与区别

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 ECMAScript vs JavaScript&#xff1a;理解两者间的联系与区别1. ECMAScript&am…

小目标检测常见解决策略总结

1. 引言 尽管目标检测算法取得了长足的发展&#xff0c;例如 Faster RCNN、YOLO、SSD、RetinaNet、EfficientDet 等。通常&#xff0c;这些模型是在 COCO数据集上训练的。它是一个包含各种对象类别和标注的大规模数据集&#xff0c;因此在训练对象检测器方面很受欢迎。然而&am…

基础语法——字符串

字符串数组的常用操作 需引用头文件#include<cstring> #include<iostream> #include<cstring>using namespace std;int main(){char str[100];char a[10],b[10];strlen(str); //求字符串的长度&#xff0c;不包括\0 ,O(n)strcmp(a,b); //按字典序比较a,b的…

应急响应实战笔记04Windows实战篇(1)

第1篇&#xff1a;FTP暴力破解 0x00 前言 ​ FTP是一个文件传输协议&#xff0c;用户通过FTP可从客户机程序向远程主机上传或下载文件&#xff0c;常用于网站代码维护、日常源码备份等。如果攻击者通过FTP匿名访问或者弱口令获取FTP权限&#xff0c;可直接上传webshell&#…

RuoYi-Vue-Plus(基础知识点jackson、mybatisplus、redis)

一、JacksonConfig 全局序列化反序列化配置 1.1yml中配置 #时区 spring.jackson.time-zoneGMT8 #日期格式 spring.jackson.date-formatyyyy-MM-dd HH:mm:ss #默认转json的属性&#xff0c;这里设置为非空才转json spring.jackson.default-property-inclusionnon_null #设置属性…