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

2024-03-22 23:28

本文主要是介绍详解rtklib中main函数如何配置文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

Step1:如何给rtklib中的主函数 rnx2rtkp 传参

Step2:给配置选项结构体赋默认值

 Step3:继续配置

Step4:寻找 main 函数参数中的 -k

 Step5:依次遍历参数


Step1:如何给rtklib中的主函数 rnx2rtkp 传参

关于C语言中 main 函数如何传参在这篇文章里有详细讲解,如果不懂请先进行学习。

详解main函数参数argc、argv及如何传参-CSDN博客

        要想在代码中运行 rtklib 进行定位就必须先进行文件配置,就是通过选项设置决定要进行哪种定位模式、文件的输入输出路径以及中间处理参数等,说白了等价于设置 rtkpost 中的Options 选项,只不过通过代码的形式。

        关于如何给 rtklib 主函数传参在 rtklib_manual 的 A.2 RNX2RTKP 部分有详细说明,我把它翻译了出来如下:

       以单点定位为例,那么给 main 函数传参时要进行如下格式输入(具体需求参照上面options,假如 -p 后面有模式选项,那么-p 后就要输入对应数字,-u 后没要求输入那么在传参时只输入 -u即可):(考虑到转义字符,假如想表示路径 C:\myfolder\myfile.txt,在输入时时,需要写成 "C:\\myfolder\\myfile.txt" )

-p 0 -x 3 -m 10 -o 输出文件路径 o文件路径 n文件路径

 这是我的配置路径:

       在主函数直接F11进行调试,可以发现总共传入12个参数,且 argv 这个指针数组的第一个指针 argv[0] 始终指向Debug中可执行程序的地址。其他指针依次指向输入的参数,且输入的参数以空格分隔,每个参数代表一个字符串,后续的代码就是识别这些字符串并进行配置处理。

Step2:给配置选项结构体赋默认值

          主要给 prcopt_t (process option 定位配置)、solopt_t (solotion option 结果配置)、filopt_t(fileoption 文件配置)、gtime_t (时间)结构体设置初始默认值。

源代码如下:

    prcopt_t prcopt=prcopt_default;   //process option 定位配置-默认值solopt_t solopt=solopt_default;   //solotion option 结果配置-默认值filopt_t filopt={""};       //fileoption 文件配置-默认空gtime_t ts={0},te={0};double tint=0.0,es[]={2000,1,1,0,0,0},ee[]={2000,12,31,23,59,59},pos[3];

 各结构体定义如下:

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;
typedef struct {        time_t time;        //标准时间整数的秒数double sec;         //非整数秒数的小数部分
} gtime_t;

       上述是几个主要配置结构体的声明,第一行代码 prcopt_t prcopt = prcopt_default; 将提前设置好的默认参数 prcopt_default 赋值给 prcopt_t 类型的结构体 prcopt ,里面包含了各项的基础配置,prcopt_default 的默认参数设置如下:

const prcopt_t prcopt_default={ /* defaults processing options */PMODE_SINGLE,0,2,SYS_GPS,   /* mode,soltype,nf,navsys */15.0*D2R,{{0,0}},           /* elmin,snrmask */0,1,1,1,                    /* sateph,modear,glomodear,bdsmodear */5,0,10,1,                   /* maxout,minlock,minfix,armaxiter */0,0,0,0,                    /* estion,esttrop,dynamics,tidecorr */1,0,0,0,0,                  /* niter,codesmooth,intpref,sbascorr,sbassatsel */0,0,                        /* rovpos,refpos */{100.0,100.0},              /* eratio[] */{100.0,0.003,0.003,0.0,1.0}, /* err[] */{30.0,0.03,0.3},            /* std[] */{1E-4,1E-3,1E-4,1E-1,1E-2,0.0}, /* prn[] */5E-12,                      /* sclkstab */{3.0,0.9999,0.25,0.1,0.05}, /* thresar */0.0,0.0,0.05,               /* elmaskar,almaskhold,thresslip */30.0,30.0,30.0,             /* maxtdif,maxinno,maxgdop */{0},{0},{0},                /* baseline,ru,rb */{"",""},                    /* anttype */{{0}},{{0}},{0}             /* antdel,pcv,exsats */
};

第二行代码 solopt_t solopt=solopt_default;同理,是对输出文件格式的配置,默认参数如下:

const solopt_t solopt_default={ /* defaults solution output options */SOLF_LLH,TIMES_GPST,1,3,    /* posf,times,timef,timeu */0,1,0,0,0,0,0,              /* degf,outhead,outopt,outvel,datum,height,geoid */0,0,0,                      /* solstatic,sstat,trace */{0.0,0.0},                  /* nmeaintv */" ",""                      /* separator/program name */
};

第三行第四行代码设置为空,因为需要接下来读取文件路径,进行处理,ts、te 代表观测文件中的起止时间,先设置为0。

    filopt_t filopt={""};       //fileoption 文件配置-默认空gtime_t ts={0},te={0};

第五行代码如下,tint 表示采样频率,es、ee 表示以日历形式的时间,后续会转换成秒的形式赋值给ts,pos是用来存储 xyz 坐标的数组。

double tint=0.0,es[]={2000,1,1,0,0,0},ee[]={2000,12,31,23,59,59},pos[3];

 Step3:继续配置

        这里 prcopt solopt 结构体是需要重点关注的,因为二者内包含了全部的处理选项以及文件输出格式,后续的定位解算与输出也是根据这两个结构体的内容进行处理。

         下面代码定义了几个变量,设置了输入文件个数最大值为16,然后继续对 prcopt结构体内容进行设置。

   int i,j,n,ret;   //定义变量char *infile[MAXFILE],*outfile="",*p;   //MAXFILE == 16
//设置默认值   prcopt.mode  =PMODE_KINEMA;prcopt.navsys=0;prcopt.refpos=1;prcopt.glomodear=1;solopt.timef=0;sprintf(solopt.prog ,"%s ver.%s %s",PROGNAME,VER_RTKLIB,PATCH_LEVEL);sprintf(filopt.trace,"%s.trace",PROGNAME);

Step4:寻找 main 函数参数中的 -k

首先了解一下什么是配置文件,从rtklib manual中可知,-k 对应的就是配置文件,如果输入 -k 作为参数,那么后面应该对应配置文件的路径。

配置文件所在的路径如下:

以文本文件形式打开后可以发现配置文件中详细记录了所有选项参数,所以说假如我们在配置文件中将各个参数设置好后,就不需要在给main函数传递参数时输入别的配置符号了,只需要输入

-k 配置文件路径 -o 输出文件路径 o文件路径 n文件路径

 /* 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);}}

接下来就是开始对传递的参数进行解读,argc 为参数的个数,用 for 循环依次遍历参数。

分析 if 中的判断语句,首先是通过strcmp函数依次比较 argv[ i ]中的参数是否与 -k 相同,如果相同则返回 0 ,由于0代表假,所以前面加了 !,这样就找到了 -k 所在的位置。同时还要保证 -k后面所跟配置文件路径这个参数的位置是否小于总参数的个数。

(!strcmp(argv[i],"-k")&&i+1<argc)

当找到参数中的 -k 后,进入函数 resetsysopts();中,该函数代码如下,可以看到其作用还是初始值的设定,为后续读取配置文件做准备。

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';
}

然后仍然是一个判断语句,可以看到 loadopts函数中传递了两个参数,第一个参数是 -k 后面的字符串即对应的配置文件的路径,ctrl + 左键 打开第二个参数 sysopts。

if (!loadopts(argv[++i],sysopts)) return -1;  //加载配置文件

 可以发现它是一个结构体数组,总共有四列,同时其内容与配置文件的内容相同。

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 */
};

找到这个结构体 opt_t 的声明,可以发现上述结构体数组中第一列为选项名称,第二列是参数的格式,决定着参数是数字、字符串还是枚举类型,第三列将每个地址转换成void类型的指针,第四列只是一些说明,并不重要。

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; /* option comment/enum labels/unit */
} opt_t;

通过上述可以发现这行代码中的 loadopts 函数就是用来加载 -k 后面配置文件路径下的配置文件的内容,然后读取。

            if (!loadopts(argv[++i],sysopts)) return -1;  //加载配置文件getsysopts(&prcopt,&solopt,&filopt);

 Step5:依次遍历参数

for (i=1,n=0;i<argc;i++) {if      (!strcmp(argv[i],"-o")&&i+1<argc) outfile=argv[++i];else if (!strcmp(argv[i],"-ts")&&i+2<argc) {sscanf(argv[++i],"%lf/%lf/%lf",es,es+1,es+2);sscanf(argv[++i],"%lf:%lf:%lf",es+3,es+4,es+5);ts=epoch2time(es);}else if (!strcmp(argv[i],"-te")&&i+2<argc) {sscanf(argv[++i],"%lf/%lf/%lf",ee,ee+1,ee+2);sscanf(argv[++i],"%lf:%lf:%lf",ee+3,ee+4,ee+5);te=epoch2time(ee);}else if (!strcmp(argv[i],"-ti")&&i+1<argc) tint=atof(argv[++i]);   //atof-字符串转doubleelse if (!strcmp(argv[i],"-k")&&i+1<argc) {++i; continue;}else if (!strcmp(argv[i],"-p")&&i+1<argc) prcopt.mode=atoi(argv[++i]);else if (!strcmp(argv[i],"-f")&&i+1<argc) prcopt.nf=atoi(argv[++i]);else if (!strcmp(argv[i],"-sys")&&i+1<argc) {for (p=argv[++i];*p;p++) {switch (*p) {case 'G': prcopt.navsys|=SYS_GPS;case 'R': prcopt.navsys|=SYS_GLO;case 'E': prcopt.navsys|=SYS_GAL;case 'J': prcopt.navsys|=SYS_QZS;case 'C': prcopt.navsys|=SYS_CMP;case 'I': prcopt.navsys|=SYS_IRN;}if (!(p=strchr(p,','))) break;}}else if (!strcmp(argv[i],"-m")&&i+1<argc) prcopt.elmin=atof(argv[++i])*D2R;    // -m 后面跟了一个值读取else if (!strcmp(argv[i],"-v")&&i+1<argc) prcopt.thresar[0]=atof(argv[++i]);else if (!strcmp(argv[i],"-s")&&i+1<argc) strcpy(solopt.sep,argv[++i]);else if (!strcmp(argv[i],"-d")&&i+1<argc) solopt.timeu=atoi(argv[++i]);else if (!strcmp(argv[i],"-b")) prcopt.soltype=1;  // -b 后面没有值读取else if (!strcmp(argv[i],"-c")) prcopt.soltype=2;else if (!strcmp(argv[i],"-i")) prcopt.modear=2;else if (!strcmp(argv[i],"-h")) prcopt.modear=3;else if (!strcmp(argv[i],"-t")) solopt.timef=1;else if (!strcmp(argv[i],"-u")) solopt.times=TIMES_UTC;else if (!strcmp(argv[i],"-e")) solopt.posf=SOLF_XYZ;else if (!strcmp(argv[i],"-a")) solopt.posf=SOLF_ENU;else if (!strcmp(argv[i],"-n")) solopt.posf=SOLF_NMEA;else if (!strcmp(argv[i],"-g")) solopt.degf=1;else if (!strcmp(argv[i],"-r")&&i+3<argc) {prcopt.refpos=prcopt.rovpos=0;for (j=0;j<3;j++) prcopt.rb[j]=atof(argv[++i]);matcpy(prcopt.ru,prcopt.rb,3,1);}else if (!strcmp(argv[i],"-l")&&i+3<argc) {prcopt.refpos=prcopt.rovpos=0;for (j=0;j<3;j++) pos[j]=atof(argv[++i]);for (j=0;j<2;j++) pos[j]*=D2R;pos2ecef(pos,prcopt.rb);matcpy(prcopt.ru,prcopt.rb,3,1);}else if (!strcmp(argv[i],"-y")&&i+1<argc) solopt.sstat=atoi(argv[++i]);else if (!strcmp(argv[i],"-x")&&i+1<argc) solopt.trace=atoi(argv[++i]);else if (*argv[i]=='-') printhelp();else if (n<MAXFILE) infile[n++]=argv[i];
}
if (!prcopt.navsys) {prcopt.navsys=SYS_GPS|SYS_GLO;
}
if (n<=0) {showmsg("error : no input file");return -2;
}

接下来的代码仍然是继续匹配 main 参数,最终读取的所有配置都存在了prcopt 、solopt 结构体中,为后续函数传参做好配置准备。

通过上述代码可以发现,即使通过 -k 读取配置文件后,仍可以通过传参时对指定参数进行更改。

最后调用postpos函数开始处理数据。

//开始时间、结束时间、采样频率、process option、solution option、file option、输入文件、输入文件个数、输出文件
ret=postpos(ts,te,tint,0.0,&prcopt,&solopt,&filopt,infile,n,outfile,"","");  

整体的main函数代码如下:

/* rnx2rtkp main -------------------------------------------------------------*/
int main(int argc, char **argv)  //参数个数、参数value
{prcopt_t prcopt=prcopt_default;   //process option 定位配置-默认值solopt_t solopt=solopt_default;   //solotion option 结果配置-默认值filopt_t filopt={""};       //fileoption 文件配置-默认空gtime_t ts={0},te={0};double tint=0.0,es[]={2000,1,1,0,0,0},ee[]={2000,12,31,23,59,59},pos[3];int i,j,n,ret;char *infile[MAXFILE],*outfile="",*p;   //MAXFILE == 16//设置默认值   prcopt.mode  =PMODE_KINEMA;prcopt.navsys=0;prcopt.refpos=1;prcopt.glomodear=1;solopt.timef=0;sprintf(solopt.prog ,"%s ver.%s %s",PROGNAME,VER_RTKLIB,PATCH_LEVEL);sprintf(filopt.trace,"%s.trace",PROGNAME);/* 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);}}for (i=1,n=0;i<argc;i++) {if      (!strcmp(argv[i],"-o")&&i+1<argc) outfile=argv[++i];else if (!strcmp(argv[i],"-ts")&&i+2<argc) {sscanf(argv[++i],"%lf/%lf/%lf",es,es+1,es+2);sscanf(argv[++i],"%lf:%lf:%lf",es+3,es+4,es+5);ts=epoch2time(es);}else if (!strcmp(argv[i],"-te")&&i+2<argc) {sscanf(argv[++i],"%lf/%lf/%lf",ee,ee+1,ee+2);sscanf(argv[++i],"%lf:%lf:%lf",ee+3,ee+4,ee+5);te=epoch2time(ee);}else if (!strcmp(argv[i],"-ti")&&i+1<argc) tint=atof(argv[++i]);   //atof-字符串转doubleelse if (!strcmp(argv[i],"-k")&&i+1<argc) {++i; continue;}else if (!strcmp(argv[i],"-p")&&i+1<argc) prcopt.mode=atoi(argv[++i]);else if (!strcmp(argv[i],"-f")&&i+1<argc) prcopt.nf=atoi(argv[++i]);else if (!strcmp(argv[i],"-sys")&&i+1<argc) {for (p=argv[++i];*p;p++) {switch (*p) {case 'G': prcopt.navsys|=SYS_GPS;case 'R': prcopt.navsys|=SYS_GLO;case 'E': prcopt.navsys|=SYS_GAL;case 'J': prcopt.navsys|=SYS_QZS;case 'C': prcopt.navsys|=SYS_CMP;case 'I': prcopt.navsys|=SYS_IRN;}if (!(p=strchr(p,','))) break;}}else if (!strcmp(argv[i],"-m")&&i+1<argc) prcopt.elmin=atof(argv[++i])*D2R;    // -m 后面跟了一个值读取else if (!strcmp(argv[i],"-v")&&i+1<argc) prcopt.thresar[0]=atof(argv[++i]);else if (!strcmp(argv[i],"-s")&&i+1<argc) strcpy(solopt.sep,argv[++i]);else if (!strcmp(argv[i],"-d")&&i+1<argc) solopt.timeu=atoi(argv[++i]);else if (!strcmp(argv[i],"-b")) prcopt.soltype=1;  // -b 后面没有值读取else if (!strcmp(argv[i],"-c")) prcopt.soltype=2;else if (!strcmp(argv[i],"-i")) prcopt.modear=2;else if (!strcmp(argv[i],"-h")) prcopt.modear=3;else if (!strcmp(argv[i],"-t")) solopt.timef=1;else if (!strcmp(argv[i],"-u")) solopt.times=TIMES_UTC;else if (!strcmp(argv[i],"-e")) solopt.posf=SOLF_XYZ;else if (!strcmp(argv[i],"-a")) solopt.posf=SOLF_ENU;else if (!strcmp(argv[i],"-n")) solopt.posf=SOLF_NMEA;else if (!strcmp(argv[i],"-g")) solopt.degf=1;else if (!strcmp(argv[i],"-r")&&i+3<argc) {prcopt.refpos=prcopt.rovpos=0;for (j=0;j<3;j++) prcopt.rb[j]=atof(argv[++i]);matcpy(prcopt.ru,prcopt.rb,3,1);}else if (!strcmp(argv[i],"-l")&&i+3<argc) {prcopt.refpos=prcopt.rovpos=0;for (j=0;j<3;j++) pos[j]=atof(argv[++i]);for (j=0;j<2;j++) pos[j]*=D2R;pos2ecef(pos,prcopt.rb);matcpy(prcopt.ru,prcopt.rb,3,1);}else if (!strcmp(argv[i],"-y")&&i+1<argc) solopt.sstat=atoi(argv[++i]);else if (!strcmp(argv[i],"-x")&&i+1<argc) solopt.trace=atoi(argv[++i]);else if (*argv[i]=='-') printhelp();else if (n<MAXFILE) infile[n++]=argv[i];}if (!prcopt.navsys) {prcopt.navsys=SYS_GPS|SYS_GLO;}if (n<=0) {showmsg("error : no input file");return -2;}//开始时间、结束时间、采样频率、process option、solution option、file option、输入文件、输入文件个数、输出文件ret=postpos(ts,te,tint,0.0,&prcopt,&solopt,&filopt,infile,n,outfile,"","");  if (!ret) fprintf(stderr,"%40s\r","");return ret;
}

这篇关于详解rtklib中main函数如何配置文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/836425

相关文章

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

Java中switch-case结构的使用方法举例详解

《Java中switch-case结构的使用方法举例详解》:本文主要介绍Java中switch-case结构使用的相关资料,switch-case结构是Java中处理多个分支条件的一种有效方式,它... 目录前言一、switch-case结构的基本语法二、使用示例三、注意事项四、总结前言对于Java初学者

Linux内核之内核裁剪详解

《Linux内核之内核裁剪详解》Linux内核裁剪是通过移除不必要的功能和模块,调整配置参数来优化内核,以满足特定需求,裁剪的方法包括使用配置选项、模块化设计和优化配置参数,图形裁剪工具如makeme... 目录简介一、 裁剪的原因二、裁剪的方法三、图形裁剪工具四、操作说明五、make menuconfig

详解Java中的敏感信息处理

《详解Java中的敏感信息处理》平时开发中常常会遇到像用户的手机号、姓名、身份证等敏感信息需要处理,这篇文章主要为大家整理了一些常用的方法,希望对大家有所帮助... 目录前后端传输AES 对称加密RSA 非对称加密混合加密数据库加密MD5 + Salt/SHA + SaltAES 加密平时开发中遇到像用户的

Springboot使用RabbitMQ实现关闭超时订单(示例详解)

《Springboot使用RabbitMQ实现关闭超时订单(示例详解)》介绍了如何在SpringBoot项目中使用RabbitMQ实现订单的延时处理和超时关闭,通过配置RabbitMQ的交换机、队列和... 目录1.maven中引入rabbitmq的依赖:2.application.yml中进行rabbit

C语言线程池的常见实现方式详解

《C语言线程池的常见实现方式详解》本文介绍了如何使用C语言实现一个基本的线程池,线程池的实现包括工作线程、任务队列、任务调度、线程池的初始化、任务添加、销毁等步骤,感兴趣的朋友跟随小编一起看看吧... 目录1. 线程池的基本结构2. 线程池的实现步骤3. 线程池的核心数据结构4. 线程池的详细实现4.1 初

Python绘制土地利用和土地覆盖类型图示例详解

《Python绘制土地利用和土地覆盖类型图示例详解》本文介绍了如何使用Python绘制土地利用和土地覆盖类型图,并提供了详细的代码示例,通过安装所需的库,准备地理数据,使用geopandas和matp... 目录一、所需库的安装二、数据准备三、绘制土地利用和土地覆盖类型图四、代码解释五、其他可视化形式1.

SpringBoot使用Apache POI库读取Excel文件的操作详解

《SpringBoot使用ApachePOI库读取Excel文件的操作详解》在日常开发中,我们经常需要处理Excel文件中的数据,无论是从数据库导入数据、处理数据报表,还是批量生成数据,都可能会遇到... 目录项目背景依赖导入读取Excel模板的实现代码实现代码解析ExcelDemoInfoDTO 数据传输

如何用Java结合经纬度位置计算目标点的日出日落时间详解

《如何用Java结合经纬度位置计算目标点的日出日落时间详解》这篇文章主详细讲解了如何基于目标点的经纬度计算日出日落时间,提供了在线API和Java库两种计算方法,并通过实际案例展示了其应用,需要的朋友... 目录前言一、应用示例1、天安门升旗时间2、湖南省日出日落信息二、Java日出日落计算1、在线API2

使用Spring Cache时设置缓存键的注意事项详解

《使用SpringCache时设置缓存键的注意事项详解》在现代的Web应用中,缓存是提高系统性能和响应速度的重要手段之一,Spring框架提供了强大的缓存支持,通过​​@Cacheable​​、​​... 目录引言1. 缓存键的基本概念2. 默认缓存键生成器3. 自定义缓存键3.1 使用​​@Cacheab