详解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;
}

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

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

相关文章

第十四届蓝桥杯JavaB组省赛真题 - 阶乘求和

/ 10^9考虑前九位&#xff0c;% 10^9保留后9位 解题思路: 求获取结果的后九位数字&#xff0c;需要对10^9取余&#xff0c;因为202320232023这个数字的阶乘太大&#xff0c;必须要减少计算量&#xff0c;因为当一个整数乘以10^9后对其取余&#xff0c;那么结果都为0。 所以我…

Linux系统------------MySQL事务

目录 一、MySQL事务的概念 二、事务的ACID特点 ●原子性 ●一致性 ●隔离性 ●持久性 事务之间的相互影响有以下几种&#xff1a; ①脏读 ②不可重复读 ③幻读 ④丢失更新 三、Mysql及事务隔离级别 3.1Mysql及事务隔离级别 &#xff08;1&#xff09;read…

【微服务】Feign远程调用

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;微服务 ⛺️稳中求进&#xff0c;晒太阳 先来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; 存在下面的问题&#xff1a;代码可读性差&#xff0c;编程体验不统一参数复杂URL…

vant4实现图片放大预览

页面引入showImagePreview (展示一个全屏的图片预览组件) import { showImagePreview } from vant;van-image 是用来展示的小图 点击小图 调用showImagePreview放大 <van-cell v-if"img ! null && img.length ! 0" title"图片预览"></van…

荒野大镖客2缺少emp.dll的多种解决方法分享,快速搞定游戏报错问题

在计算机游戏运行过程中&#xff0c;如果出现提示“游戏显示emp.dll丢失”的情况&#xff0c;这可能会引发一系列的问题与故障。首先&#xff0c;由于emp.dll是游戏运行所必需的重要动态链接库文件之一&#xff0c;它的缺失将直接影响到游戏程序的正常启动与执行。具体来说&…

搭建GItlab实现自动化部署Springboot项目(超详细)

提示&#xff1a;本例程中使用Docker搭建GItlab&#xff0c;Gitlab runner 通过编写CICD文件实现Springboot项目自动部署。 1、拉取GitLab镜像 命令&#xff1a; docker pull gitlab/gitlab-ce2、部署Gitlab&#xff1a; 我们通过docker搭建的gitlab部署项目的时候会出现一个…

Python Flask框架 -- 模版继承

一个网站中&#xff0c;大部分网页的模块是重复的&#xff0c;比如顶部的导航栏&#xff0c;底部的备案信息。如果在每个页面中都重复的去写这些代码&#xff0c;会让项目变得臃肿&#xff0c;提高后期维护成本。比较好的做法是&#xff0c;通过模板继承&#xff0c;把一些重复…

DP:斐波那契数列模型

创作不易&#xff0c;感谢三连支持 &#xff01; 斐波那契数列用于一维探索的单峰函数之中&#xff0c;用于求解最优值的方法。其主要优势为&#xff0c;在第一次迭代的时候求解两个函数值&#xff0c;之后每次迭代只需求解一次 。 一、第N个泰波那契数 . - 力扣&#xff08;…

[LLM] 大模型基础|预训练|有监督微调SFT | 推理

现在的大模型在进行预训练时大部分都采用了GPT的预训练任务&#xff0c;即 Next token prediction。 要理解大语言模型&#xff08;LLM&#xff09;&#xff0c;首先要理解它的本质&#xff0c;无论预训练、微调还是在推理阶段&#xff0c;核心都是next token prediction&#…

Wireshark 抓包工具与长ping工具pinginfoview使用,安装包

一、Wireshark使用 打开软件&#xff0c;选择以太网 1、时间设置时间显示格式 这个时间戳不易直观&#xff0c;我们修改 2、抓包使用的命令 1&#xff09;IP地址过滤 ip.addr192.168.1.114 //筛选出源IP或者目的IP地址是192.168.1.114的全部数据包。 ip.sr…

ideaSSM 工厂效能管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 工厂效能管理系统是一套完善的信息管理系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff…

显卡基础知识及元器件原理分析

显卡应该算是是目前最为火热的研发方向了&#xff0c;其中的明星公司当属英伟达。 当地时间8月23日&#xff0c;英伟达发布截至7月30日的2024财年第二财季财报&#xff0c;营收和利润成倍增长&#xff0c;均超市场预期。 财报显示&#xff0c;第二财季英伟达营收为135.07 亿美…

leetcode 3075

leetcode 3075 题目 例子 思路 孩子的幸福值最低也是0&#xff0c;所以选择最大的值&#xff0c;被选孩子的幸福值最高。需要使用排序算法 代码实现 class Solution { public:long long maximumHappinessSum(vector<int>& happiness, int k) {//升序sort(happine…

基于SSM+Jsp+Mysql的高校二手交易平台

基于SSMJspMysql的高校二手交易平台 基于SSMJspMysql的高校二手交易平台的设计与实现 开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff0…

Robot Framework 入门指南:高效学习接口自动化测试

开源自动化测试利器&#xff1a;Robot Framework Robot Framework 是一个用于实现自动化测试和机器人流程自动化&#xff08;RPA&#xff09;的开放源代码框架。它由一个名为 Robot Framework Foundation 的组织得到推广&#xff0c;得到了多家领军企业在软件开发中的广泛应用…

移远通信,开启透明天线中的“创新密码”

近日&#xff0c;全球领先的物联网整体解决方案供应商移远通信正式对外宣布&#xff0c;其以远远领先行业的速度推出前沿技术成果——5G透明天线。该天线主体选用透明薄膜材质&#xff0c;具有性能优、重量轻、尺寸灵活、透明度高、环境融合度好等优势&#xff0c;特别适用于智…

处理器方法的返回值--返回对象Object

处理器方法也可以返回Object对象。这个Object可以是Integer&#xff0c;String&#xff0c;自定义对象&#xff0c; Map&#xff0c;List 等。但返回的对象不是作为逻辑视图出现的&#xff0c;而是作为直接在页面显示的数据出现的。 返回对象&#xff0c;需要使用ResponseBody注…

python第三次项目作业

打印课堂上图案 判断一个数是否是质数&#xff08;素数&#xff09; 设计一个程序&#xff0c;完成(英雄)商品的购买&#xff08;界面就是第一天打印的界面&#xff09; 展示商品信息(折扣)->输入商品价格->输入购买数量->提示付款 输入付款金额->打印购买小票&a…

九州家庭教育:关注孩子心理健康,增强亲子沟通

家庭教育现在越来越受重视&#xff0c;尤其孩子心理健康&#xff0c;当下社会&#xff0c;孩子心理健康问题频出&#xff0c;很多地方不时传出孩子轻生的新闻&#xff0c;这就是在教育过程中&#xff0c;沟通出现了严重问题&#xff0c;随着心理变化产生&#xff0c;孩子这时候…

FCN(全卷积神经网络)

目录 一、什么是FCN 1、FCN简介 2、核心思想 二、代码实现 1、FCN结构介绍 2、ResNet-18提取图像特征 3、11卷积层将通道数变换为类别个数 4、转置卷积还原输入图像的高和宽 5、初始化转置卷积层 6、读取数据集 7、训练 8、预测 三、总结 一、什么是FCN 1、FCN简介…