794 lines
30 KiB
C
794 lines
30 KiB
C
#include "rtklib.h"
|
|
|
|
/* system options buffer -----------------------------------------------------*/
|
|
prcopt_t prcopt_;
|
|
solopt_t solopt_;
|
|
// static filopt_t filopt_;
|
|
static double elmask_, elmaskar_, elmaskhold_;
|
|
static int antpostype_[2]; /* Êý¾ÝÁ÷ÌìÏßλÖøñʽ */
|
|
static double antpos_[2][3];
|
|
|
|
#ifdef USING_FILE_OPT
|
|
static char exsats_[1024];
|
|
static char snrmask_[NFREQ][1024];
|
|
|
|
/* system options table ------------------------------------------------------*/
|
|
#define SWTOPT "0:off,1:on"
|
|
#define MODOPT "0:single,1:dgps,2:kinematic,3:static,4:static-start,5:movingbase,6:fixed,7:ppp-kine,8:ppp-static,9:ppp-fixed"
|
|
#define FRQOPT "1:l1,2:l1+l2,3:l1+l2+l5,4:l1+l2+l5+l6"
|
|
#define TYPOPT "0:forward,1:backward,2:combined,3:combined-nophasereset"
|
|
#define IONOPT "0:off,1:brdc,2:sbas,3:dual-freq,4:est-stec,5:ionex-tec,6:qzs-brdc"
|
|
#define TRPOPT "0:off,1:saas,2:sbas,3:est-ztd,4:est-ztdgrad"
|
|
#define EPHOPT "0:brdc,1:precise,2:brdc+sbas,3:brdc+ssrapc,4:brdc+ssrcom"
|
|
#define NAVOPT "1:gps+2:sbas+4:glo+8:gal+16:qzs+32:bds+64:navic"
|
|
#define GAROPT "0:off,1:on,2:autocal,3:fix-and-hold"
|
|
#define WEIGHTOPT "0:elevation,1:snr"
|
|
#define SOLOPT "0:llh,1:xyz,2:enu,3:nmea"
|
|
#define TSYOPT "0:gpst,1:utc,2:jst"
|
|
#define TFTOPT "0:tow,1:hms"
|
|
#define DFTOPT "0:deg,1:dms"
|
|
#define HGTOPT "0:ellipsoidal,1:geodetic"
|
|
#define GEOOPT "0:internal,1:egm96,2:egm08_2.5,3:egm08_1,4:gsi2000"
|
|
#define STAOPT "0:all,1:single"
|
|
#define STSOPT "0:off,1:state,2:residual"
|
|
#define ARMOPT "0:off,1:continuous,2:instantaneous,3:fix-and-hold"
|
|
#define POSOPT "0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw"
|
|
#define TIDEOPT "0:off,1:on,2:otl"
|
|
#define PHWOPT "0:off,1:on,2:precise"
|
|
|
|
extern opt_t sysopts[] = {
|
|
{"pos1-posmode", 3, (void *)&prcopt_.mode, MODOPT},
|
|
{"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-arfilter", 3, (void *)&prcopt_.arfilter, SWTOPT},
|
|
{"pos2-arthres", 1, (void *)&prcopt_.thresar[0], ""},
|
|
{"pos2-arthresmin", 1, (void *)&prcopt_.thresar[5], ""},
|
|
{"pos2-arthresmax", 1, (void *)&prcopt_.thresar[6], ""},
|
|
{"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-varholdamb", 1, (void *)&prcopt_.varholdamb, "cyc^2"},
|
|
{"pos2-gainholdamb", 1, (void *)&prcopt_.gainholdamb, ""},
|
|
{"pos2-arlockcnt", 0, (void *)&prcopt_.minlock, ""},
|
|
{"pos2-minfixsats", 0, (void *)&prcopt_.minfixsats, ""},
|
|
{"pos2-minholdsats", 0, (void *)&prcopt_.minholdsats, ""},
|
|
{"pos2-mindropsats", 0, (void *)&prcopt_.mindropsats, ""},
|
|
{"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-dopthres", 1, (void *)&prcopt_.thresdop, "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-eratio5", 1, (void *)&prcopt_.eratio[2], ""},
|
|
{"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-snrmax", 1, (void *)&prcopt_.err[5], "dB.Hz"},
|
|
{"stats-errsnr", 1, (void *)&prcopt_.err[6], "m"},
|
|
{"stats-errrcv", 1, (void *)&prcopt_.err[7], " "},
|
|
{"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 */
|
|
};
|
|
#endif
|
|
const prcopt_t prcopt_default = {
|
|
/* defaults processing options */
|
|
PMODE_KINEMA, /* positioning mode (PMODE_???) */
|
|
0, /* solution type (0:forward,1:backward,2:combined) */
|
|
1, /* number of frequencies (1:L1,2:L1+L2,3:L1+L2+L5) */
|
|
SYS_GPS | SYS_CMP | SYS_QZS, /* navigation system */
|
|
15.0 * D2R, /* elevation mask angle (rad) */
|
|
{{1, 1},
|
|
{{37,37,37,35,35,35,35,35,35},
|
|
{37,37,37,35,35,35,35,35,35},
|
|
{37,37,37,35,35,35,35,35,35}}}, /* SNR mask */
|
|
0, /* satellite ephemeris/clock (EPHOPT_???) */
|
|
1, /* AR mode (0:off,1:continuous,2:instantaneous,3:fix and hold,4:ppp-ar) */
|
|
1, /* GLONASS AR mode (0:off,1:on,2:auto cal,3:ext cal) */
|
|
1, /* GPS AR mode, debug/learning only (0:off,1:on) */
|
|
1, /* BeiDou AR mode (0:off,1:on) */
|
|
1, /* AR filtering to reject bad sats (0:off,1:on) */
|
|
5, /* obs outage count to reset bias */
|
|
10, /* min lock count to fix ambiguity */
|
|
7, /* min sats to fix integer ambiguities */
|
|
7, /* min sats to hold integer ambiguities */
|
|
10, /* min sats to drop sats in AR */
|
|
10, /* min fix count to hold ambiguity */
|
|
1, /* max iteration to resolve ambiguity */
|
|
0, /* ionosphere option (IONOOPT_???) */
|
|
0, /* troposphere option (TROPOPT_???) */
|
|
1, /* dynamics model (0:none,1:velociy,2:accel) */
|
|
0, /* earth tide correction (0:off,1:solid,2:solid+otl+pole) */
|
|
1, /* number of filter iteration */
|
|
0, /* code smoothing window size (0:none) */
|
|
0, /* interpolate reference obs (for post mission) */
|
|
0, /* SBAS correction options */
|
|
0, /* SBAS satellite selection (0:all) */
|
|
0, /* rover position for fixed mode */
|
|
4, /* (0:pos in prcopt, 1:average of single pos, */
|
|
/* 2:read from file, 3:rinex header, 4:rtcm pos) */
|
|
{100.0, 100.0, 300.0}, /* base position for relative mode *//* eratio[] */
|
|
{100.0, 0.015, 0.015, 0.0, 1.0, 52.0, 0.0, 0.0}, /* err[-,base,el,bl,dop,snr_max,snr,rcverr] */
|
|
{30.0, 0.03, 0.3}, /* initial-state std [0]bias,[1]iono [2]trop */
|
|
{1E-4, 1E-3, 1E-4, 1.0, 1.0, 0.0}, /* process-noise std [0]bias,[1]iono [2]trop [3]acch [4]accv [5] pos */
|
|
5E-12, /* satellite clock stability (sec/sec) */
|
|
{3.0, 1, 0.25, 1E-9, 1E-5, 3.0, 3.0, 0.0}, /* AR validation threshold */
|
|
15.0, /* elevation mask of AR for rising satellite (deg) */
|
|
15.0, /* elevation mask to hold ambiguity (deg) */
|
|
0.05, /* slip threshold of geometry-free phase (m) */
|
|
0, /* slip threshold of doppler (m) */
|
|
0.1, /* variance for fix-and-hold psuedo measurements (cycle^2) */
|
|
0.01, /* gain used for GLO and SBAS sats to adjust ambiguity */
|
|
30.0, /* max difference of time (sec) */
|
|
30.0, /* reject threshold of innovation (m) */
|
|
30.0, /* reject threshold of gdop */
|
|
{0}, /* baseline length constraint {const,sigma} (m) */
|
|
{0}, /* rover position for fixed mode {x,y,z} (ecef) (m) */
|
|
{0}, /* base position for relative mode {x,y,z} (ecef) (m) */
|
|
{"", ""}, /* antenna types {rover,base} */
|
|
{{0}}, /* antenna delta {{rov_e,rov_n,rov_u},{ref_e,ref_n,ref_u}} */
|
|
{{0}}, /* receiver antenna parameters {rov,base} */
|
|
{0}, /* excluded satellites (1:excluded,2:included) */
|
|
0, /* max averaging epoches */
|
|
0 /* initialize by restart */
|
|
};
|
|
// const solopt_t solopt_default = {
|
|
// /* defaults solution output options */
|
|
// SOLF_NMEA, /* solution format (SOLF_???) */
|
|
// TIMES_UTC, /* time system (TIMES_???)*/
|
|
// 1, /* time format (0:sssss.s,1:yyyy/mm/dd hh:mm:ss.s) */
|
|
// 3, /* time digits under decimal point */
|
|
// 0, /* latitude/longitude format (0:ddd.ddd,1:ddd mm ss) */
|
|
// 1, /* output header (0:no,1:yes) */
|
|
// 1, /* output processing options (0:no,1:yes) */
|
|
// 0, /* output velocity options (0:no,1:yes) */
|
|
// 0, /* datum (0:WGS84,1:Tokyo) */
|
|
// 0, /* height (0:ellipsoidal,1:geodetic) */
|
|
// 0, /* geoid model (0:EGM96,1:JGD2000) */
|
|
// 0, /* solution of static mode (0:all,1:single) */
|
|
// 0, /* solution statistics level (0:off,1:states,2:residuals) */
|
|
// 0, /* debug trace level (0:off,1-5:debug) */
|
|
// {0.0, 0.0}, /* nmea output interval (s) (<0:no,0:all) */
|
|
// /* nmeaintv[0]:gprmc,gpgga,nmeaintv[1]:gpgsv */
|
|
// " ",/* field separator */
|
|
// "" /* program name */
|
|
// /* solution options type */
|
|
// };
|
|
//const prcopt_t prcopt_default = {
|
|
// /* defaults processing options */
|
|
// PMODE_KINEMA,
|
|
// 0,
|
|
// 2,
|
|
// SYS_GPS | SYS_GLO | SYS_GAL, /* mode,soltype,nf,navsys */
|
|
// 15.0 * D2R,
|
|
// {{0, 0}}, /* elmin,snrmask */
|
|
// 0,
|
|
// 3,
|
|
// 3,
|
|
// 1,
|
|
// 0,
|
|
// 1, /* sateph,modear,glomodear,gpsmodear,bdsmodear,arfilter */
|
|
// 20,
|
|
// 0,
|
|
// 4,
|
|
// 5,
|
|
// 10,
|
|
// 20, /* maxout,minlock,minfixsats,minholdsats,mindropsats,minfix */
|
|
// 1,
|
|
// 1,
|
|
// 1,
|
|
// 1,
|
|
// 0, /* armaxiter,estion,esttrop,dynamics,tidecorr */
|
|
// 1,
|
|
// 0,
|
|
// 0,
|
|
// 0,
|
|
// 0, /* niter,codesmooth,intpref,sbascorr,sbassatsel */
|
|
// 0,
|
|
// 4, /* rovpos,refpos */
|
|
// {300.0, 300.0, 300.0}, /* eratio[] */
|
|
// {100.0, 0.003, 0.003, 0.0, 1.0, 52.0, 0.0, 0.0}, /* err[-,base,el,bl,dop,snr_max,snr,rcverr] */
|
|
// {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.25, 0.0, 1E-9, 1E-5, 3.0, 3.0, 0.0}, /* thresar */
|
|
// 0.0,
|
|
// 0.0,
|
|
// 0.05,
|
|
// 0, /* elmaskar,elmaskhold,thresslip,thresdop, */
|
|
// 0.1,
|
|
// 0.01,
|
|
// 30.0,
|
|
// 5.0,
|
|
// 30.0, /* varholdamb,gainholdamb,maxtdif,maxinno,maxgdop */
|
|
// {0},
|
|
// {0},
|
|
// {0}, /* baseline,ru,rb */
|
|
// {"", ""}, /* anttype */
|
|
// {{0}},
|
|
// {{0}},
|
|
// {0}, /* antdel,pcv,exsats */
|
|
// 1,
|
|
// 1 /* maxaveep,initrst */
|
|
//};
|
|
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 */
|
|
};
|
|
#ifdef USING_FILE_OPT
|
|
/* discard space characters at tail ------------------------------------------*/
|
|
static void chop(char *str)
|
|
{
|
|
char *p;
|
|
if ((p = strchr(str, '#')))
|
|
*p = '\0'; /* comment */
|
|
for (p = str + strlen(str) - 1; p >= str && !isgraph((int)*p); p--)
|
|
*p = '\0';
|
|
}
|
|
/* enum to string ------------------------------------------------------------*/
|
|
static int enum2str(char *s, const char *comment, int val)
|
|
{
|
|
char str[32], *p, *q;
|
|
int n;
|
|
|
|
n = sprintf(str, "%d:", val);
|
|
if (!(p = strstr(comment, str)))
|
|
{
|
|
return sprintf(s, "%d", val);
|
|
}
|
|
if (!(q = strchr(p + n, ',')) && !(q = strchr(p + n, ')')))
|
|
{
|
|
strcpy(s, p + n);
|
|
return (int)strlen(p + n);
|
|
}
|
|
strncpy(s, p + n, q - p - n);
|
|
s[q - p - n] = '\0';
|
|
return (int)(q - p - n);
|
|
}
|
|
/* string to enum ------------------------------------------------------------*/
|
|
static int str2enum(const char *str, const char *comment, int *val)
|
|
{
|
|
const char *p;
|
|
char s[32];
|
|
|
|
for (p = comment;; p++)
|
|
{
|
|
if (!(p = strstr(p, str)))
|
|
break;
|
|
if (*(p - 1) != ':')
|
|
continue;
|
|
for (p -= 2; '0' <= *p && *p <= '9'; p--)
|
|
;
|
|
return sscanf(p + 1, "%d", val) == 1;
|
|
}
|
|
sprintf(s, "%.30s:", str);
|
|
if ((p = strstr(comment, s)))
|
|
{ /* number */
|
|
return sscanf(p, "%d", val) == 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/* search option ---------------------------------------------------------------
|
|
* search option record
|
|
* args : char *name I option name
|
|
* opt_t *opts I options table
|
|
* (terminated with table[i].name="")
|
|
* return : option record (NULL: not found)
|
|
*-----------------------------------------------------------------------------*/
|
|
extern opt_t *searchopt(const char *name, const opt_t *opts)
|
|
{
|
|
int i;
|
|
|
|
trace(4, "searchopt: name=%s\n", name);
|
|
|
|
for (i = 0; *opts[i].name; i++)
|
|
{
|
|
if (strstr(opts[i].name, name))
|
|
return (opt_t *)(opts + i);
|
|
}
|
|
return NULL;
|
|
}
|
|
/* 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)
|
|
{
|
|
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;
|
|
}
|
|
/* option value to string ------------------------------------------------------
|
|
* convert option value to string
|
|
* args : opt_t *opt I option
|
|
* char *str O option value string
|
|
* return : length of output string
|
|
*-----------------------------------------------------------------------------*/
|
|
extern int opt2str(const opt_t *opt, char *str)
|
|
{
|
|
char *p = str;
|
|
|
|
trace(3, "opt2str : name=%s\n", opt->name);
|
|
|
|
switch (opt->format)
|
|
{
|
|
case 0:
|
|
p += sprintf(p, "%d", *(int *)opt->var);
|
|
break;
|
|
case 1:
|
|
p += sprintf(p, "%.15g", *(double *)opt->var);
|
|
break;
|
|
case 2:
|
|
p += sprintf(p, "%s", (char *)opt->var);
|
|
break;
|
|
case 3:
|
|
p += enum2str(p, opt->comment, *(int *)opt->var);
|
|
break;
|
|
}
|
|
return (int)(p - str);
|
|
}
|
|
/* option to string -------------------------------------------------------------
|
|
* convert option to string (keyword=value # comment)
|
|
* args : opt_t *opt I option
|
|
* char *buff O option string
|
|
* return : length of output string
|
|
*-----------------------------------------------------------------------------*/
|
|
extern int opt2buf(const opt_t *opt, char *buff)
|
|
{
|
|
char *p = buff;
|
|
int n;
|
|
|
|
trace(3, "opt2buf : name=%s\n", opt->name);
|
|
|
|
p += sprintf(p, "%-18s =", opt->name);
|
|
p += opt2str(opt, p);
|
|
if (*opt->comment)
|
|
{
|
|
if ((n = (int)(buff + 30 - p)) > 0)
|
|
p += sprintf(p, "%*s", n, "");
|
|
p += sprintf(p, " # (%s)", opt->comment);
|
|
}
|
|
return (int)(p - buff);
|
|
}
|
|
/* load options ----------------------------------------------------------------
|
|
* load options from file
|
|
* args : char *file I options file
|
|
* opt_t *opts IO options table
|
|
* (terminated with table[i].name="")
|
|
* return : status (1:ok,0:error)
|
|
*-----------------------------------------------------------------------------*/
|
|
extern int loadopts(const char *file, opt_t *opts)
|
|
{
|
|
FILE *fp;
|
|
opt_t *opt;
|
|
char buff[2048], *p;
|
|
int n = 0;
|
|
|
|
trace(4, "loadopts: file=%s\n", file);
|
|
|
|
if (!(fp = fopen(file, "r")))
|
|
{
|
|
trace(1, "loadopts: options file open error (%s)\n", file);
|
|
return 0;
|
|
}
|
|
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);
|
|
if (!(opt = searchopt(buff, opts)))
|
|
continue;
|
|
|
|
if (!str2opt(opt, p))
|
|
{
|
|
fprintf(stderr, "invalid option value %s (%s:%d)\n", buff, file, n);
|
|
continue;
|
|
}
|
|
}
|
|
fclose(fp);
|
|
|
|
return 1;
|
|
}
|
|
/* save options to file --------------------------------------------------------
|
|
* save options to file
|
|
* args : char *file I options file
|
|
* char *mode I write mode ("w":overwrite,"a":append);
|
|
* char *comment I header comment (NULL: no comment)
|
|
* opt_t *opts I options table
|
|
* (terminated with table[i].name="")
|
|
* return : status (1:ok,0:error)
|
|
*-----------------------------------------------------------------------------*/
|
|
extern int saveopts(const char *file, const char *mode, const char *comment,
|
|
const opt_t *opts)
|
|
{
|
|
FILE *fp;
|
|
char buff[2048];
|
|
int i;
|
|
|
|
trace(3, "saveopts: file=%s mode=%s\n", file, mode);
|
|
|
|
if (!(fp = fopen(file, mode)))
|
|
{
|
|
trace(1, "saveopts: options file open error (%s)\n", file);
|
|
return 0;
|
|
}
|
|
if (comment)
|
|
fprintf(fp, "# %s\n\n", comment);
|
|
|
|
for (i = 0; *opts[i].name; i++)
|
|
{
|
|
opt2buf(opts + i, buff);
|
|
fprintf(fp, "%s\n", buff);
|
|
}
|
|
fclose(fp);
|
|
return 1;
|
|
}
|
|
/* options to system options buffer ------------------------------------------*/
|
|
static void sysopts2buff(void)
|
|
{
|
|
double pos[3], *rr;
|
|
char id[32], *p;
|
|
int i, j, sat, *ps;
|
|
|
|
elmask_ = prcopt_.elmin * R2D;
|
|
elmaskar_ = prcopt_.elmaskar * R2D;
|
|
elmaskhold_ = prcopt_.elmaskhold * R2D;
|
|
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
ps = i == 0 ? &prcopt_.rovpos : &prcopt_.refpos;
|
|
rr = i == 0 ? prcopt_.ru : prcopt_.rb;
|
|
|
|
if (*ps == 0)
|
|
{
|
|
antpostype_[i] = 0;
|
|
ecef2pos(rr, pos);
|
|
antpos_[i][0] = pos[0] * R2D;
|
|
antpos_[i][1] = pos[1] * R2D;
|
|
antpos_[i][2] = pos[2];
|
|
}
|
|
else
|
|
antpostype_[i] = *ps + 1;
|
|
}
|
|
/* excluded satellites */
|
|
exsats_[0] = '\0';
|
|
for (sat = 1, p = exsats_; sat <= MAXSAT && p - exsats_ < (int)sizeof(exsats_) - 32; sat++)
|
|
{
|
|
if (prcopt_.exsats[sat - 1])
|
|
{
|
|
satno2id(sat, id);
|
|
p += sprintf(p, "%s%s%s", p == exsats_ ? "" : " ",
|
|
prcopt_.exsats[sat - 1] == 2 ? "+" : "", id);
|
|
}
|
|
}
|
|
/* snrmask */
|
|
for (i = 0; i < NFREQ; i++)
|
|
{
|
|
snrmask_[i][0] = '\0';
|
|
p = snrmask_[i];
|
|
for (j = 0; j < 9; j++)
|
|
{
|
|
p += sprintf(p, "%s%.0f", j > 0 ? "," : "", prcopt_.snrmask.mask[i][j]);
|
|
}
|
|
}
|
|
/* number of frequency (4:L1+L5) TODO ???? */
|
|
/*if (prcopt_.nf==3&&prcopt_.freqopt==1) {
|
|
prcopt_.nf=4;
|
|
prcopt_.freqopt=0;
|
|
}*/
|
|
}
|
|
#endif
|
|
/* 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 < MAXSAT; i++)
|
|
prcopt_.exsats[i] = 0;
|
|
|
|
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;
|
|
}
|
|
#ifdef USING_FILE_OPT
|
|
/* excluded satellites */
|
|
if (exsats_[0] != '\0')
|
|
{
|
|
strcpy(buff, exsats_);
|
|
for (p = strtok(buff, " "); p; p = strtok(NULL, " "))
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
#endif
|
|
/* number of frequency (4:L1+L5) TODO ????*/
|
|
/*if (prcopt_.nf==4) {
|
|
prcopt_.nf=3;
|
|
prcopt_.freqopt=1;
|
|
}*/
|
|
}
|
|
|
|
/* reset system options to default ---------------------------------------------
|
|
* reset system options to default
|
|
* args : none
|
|
* return : none
|
|
*-----------------------------------------------------------------------------*/
|
|
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';
|
|
|
|
elmask_ = 15.0;
|
|
elmaskar_ = 0.0;
|
|
elmaskhold_ = 0.0;
|
|
for (i = 0; i < 2; i++)
|
|
antpostype_[i] = 0;
|
|
for (i = 0; i < 2; i++)
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
antpos_[i][j] = 0.0;
|
|
}
|
|
#ifdef USING_FILE_OPT
|
|
exsats_[0] = '\0';
|
|
#endif
|
|
antpostype_[0] = 0;
|
|
antpostype_[1] = 5;
|
|
}
|
|
/* opt_init ---------------------------------------------
|
|
* ¶Ô¹æÔò×ö×Ô¶¨Òå, Ï൱ÓÚÊǵ¼ÈëÎļþµÄдËÀ°æ±¾
|
|
* args : none
|
|
* return : none
|
|
*-----------------------------------------------------------------------------*/
|
|
static void opt_init(void)
|
|
{
|
|
// prcopt_.nf = 1;
|
|
}
|
|
|
|
/* get system options ----------------------------------------------------------
|
|
* get system options
|
|
* args : prcopt_t *popt IO processing options (NULL: no output)
|
|
* solopt_t *sopt IO solution options (NULL: no output)
|
|
* folopt_t *fopt IO file options (NULL: no output)
|
|
* return : none
|
|
* notes : to load system options, use loadopts() before calling the function
|
|
*-----------------------------------------------------------------------------*/
|
|
// extern void getsysopts(prcopt_t *popt, solopt_t *sopt, filopt_t *fopt)
|
|
extern void getsysopts(prcopt_t *popt, solopt_t *sopt)
|
|
{
|
|
trace(3, "getsysopts:\n");
|
|
|
|
opt_init();
|
|
buff2sysopts();
|
|
|
|
/* confirm overwrite */
|
|
if (prcopt_.refpos == 4) /* 4:rtcm pos */
|
|
{ /* rtcm */
|
|
for (char i = 0; i < 3; i++)
|
|
prcopt_.rb[i] = 0.0;
|
|
}
|
|
if (popt)
|
|
*popt = prcopt_;
|
|
if (sopt)
|
|
*sopt = solopt_;
|
|
// if (fopt) *fopt=filopt_;
|
|
}
|
|
/* set system options ----------------------------------------------------------
|
|
* set system options
|
|
* args : prcopt_t *prcopt I processing options (NULL: default)
|
|
* solopt_t *solopt I solution options (NULL: default)
|
|
* filopt_t *filopt I file options (NULL: default)
|
|
* return : none
|
|
* notes : to save system options, use saveopts() after calling the function
|
|
*-----------------------------------------------------------------------------*/
|
|
// extern void setsysopts(const prcopt_t *prcopt, const solopt_t *solopt,
|
|
// const filopt_t *filopt)
|
|
// extern void setsysopts(const prcopt_t *prcopt, const solopt_t *solopt)
|
|
// {
|
|
// trace(3, "setsysopts:\n");
|
|
|
|
// resetsysopts();
|
|
// if (prcopt)
|
|
// prcopt_ = *prcopt;
|
|
// if (solopt)
|
|
// solopt_ = *solopt;
|
|
// // if (filopt) filopt_=*filopt;
|
|
// sysopts2buff();
|
|
// }
|