53#define R2D (180.0 / 3.1415926535897932384626433832795)
54#define D2R (3.1415926535897932384626433832795 / 180.0)
58#include "mrtklib/mrtk_version.h"
61#define PROGNAME "rnx2rtkp"
64#define FILEPATHSEP '/'
67extern int showmsg(
const char* format, ...);
71#define MIN(x, y) ((x) < (y) ? (x) : (y))
72#define SQRT(x) ((x) <= 0.0 || (x) != (x) ? 0.0 : sqrt(x))
126 char buff[1024], *p = buff;
130 va_start(arg, format);
131 p += vsprintf(p, format, arg);
144 double pos[3], dms1[3], dms2[3];
145 const char* sep = opt->
sep;
147 trace(NULL, 3,
"outrpos :\n");
154 fprintf(fp,
"%3.0f%s%02.0f%s%08.5f%s%4.0f%s%02.0f%s%08.5f%s%10.4f", dms1[0], sep, dms1[1], sep, dms1[2],
155 sep, dms2[0], sep, dms2[1], sep, dms2[2], sep, pos[2]);
157 fprintf(fp,
"%13.9f%s%14.9f%s%10.4f", pos[0] *
R2D, sep, pos[1] *
R2D, sep, pos[2]);
160 fprintf(fp,
"%14.4f%s%14.4f%s%14.4f", r[0], sep, r[1], sep, r[2]);
165 const char* s1[] = {
"GPST",
"UTC",
"JST"};
171 trace(NULL, 3,
"outheader: n=%d\n", n);
178 fprintf(fp,
"%s program : %s(%s ver.%s)\n",
COMMENTH,
PROGNAME, MRTKLIB_SOFTNAME, MRTKLIB_VERSION_STRING);
182 for (i = 0; i < n; i++) {
183 fprintf(fp,
"%s inp file : %s\n",
COMMENTH, file[i]);
185 for (i = 0; i <
obss.n; i++) {
186 if (
obss.data[i].rcv == 1) {
190 for (j =
obss.n - 1; j >= 0; j--) {
191 if (
obss.data[j].rcv == 1) {
196 fprintf(fp,
"\n%s no rover obs data\n",
COMMENTH);
199 ts =
obss.data[i].time;
200 te =
obss.data[j].time;
203 if (sopt->
times >= 1) {
206 if (sopt->
times >= 1) {
209 if (sopt->
times == 2) {
212 if (sopt->
times == 2) {
217 fprintf(fp,
"%s obs start : %s %s (week%04d %8.1fs)\n",
COMMENTH, s2, s1[sopt->
times], w1, t1);
218 fprintf(fp,
"%s obs end : %s %s (week%04d %8.1fs)\n",
COMMENTH, s3, s1[sopt->
times], w2, t2);
224 fprintf(fp,
"%s ref pos :",
COMMENTH);
239 for (; *i < obs->
n; (*i)++) {
240 if (obs->
data[*i].
rcv == rcv) {
244 for (n = 0; *i + n < obs->
n; n++) {
256 for (; *i >= 0; (*i)--) {
257 if (obs->
data[*i].
rcv == rcv) {
261 for (n = 0; *i - n >= 0; n++) {
271 char path[1024], tstr[32];
287 trace(NULL, 2,
"rtcm file open: %s\n", path);
300 trace(NULL, 3,
"update_rtcm: %s %s\n",
time_str(time, 3), tstr);
303 for (i = 0; i <
MAXSAT; i++) {
304 if (!
rtcm->ssr[i].update ||
rtcm->ssr[i].iod[0] !=
rtcm->ssr[i].iod[1] ||
309 rtcm->ssr[i].update = 0;
317 static int init_flg = 1;
318 char path[1024], tstr[32];
332 trace(NULL, 2,
"qzssl6e file open: %s\n", path);
346 trace(NULL, 3,
"update_qzssl6e: %s %s\n",
time_str(time, 3), tstr);
349 for (i = 0; i <
MAXSAT; i++) {
350 if (!
l6e->ssr[i].update ||
l6e->ssr[i].iod[0] !=
l6e->ssr[i].iod[1] ||
354 navs.ssr_ch[0][i] =
l6e->ssr[i];
355 l6e->ssr[i].update = 0;
365 char path[1024], tstr[32];
379 trace(NULL, 2,
"gal_has file open: %s\n", path);
391 trace(NULL, 3,
"update_gal_has: %s\n", tstr);
394 for (i = 0; i <
MAXSAT; i++) {
409 strcpy(
mdcl6d[k].opt, pppopt);
413 mdcl6d[k].re.area[i].avalid = 0;
414 for (j = 0; j <
MAXSAT; j++) {
415 mdcl6d[k].re.area[i].sat[j].t0.time = 0;
423 static int init_flg = 1;
424 char path[1024], tstr[32];
438 trace(NULL, 2,
"qzssl6d file open: %s\n", path);
440 trace(NULL, 2,
"qzssl6d file open error: %s\n", path);
453 trace(NULL, 3,
"update_qzssl6d: %s %s\n",
time_str(time, 3), tstr);
456 if (
mdcl6d[n].re.rvalid) {
460 mdcl6d[n].re.area[i].avalid = 0;
461 for (j = 0; j <
MAXSAT; j++) {
462 mdcl6d[n].re.area[i].sat[j].t0.time = 0;
474 char path[1024], tstr[32], *p, st[64] =
"";
477 static char buff[4096];
478 static int nbyte = 0;
489 trace(NULL, 2,
"stat file open error: %s\n", path);
500 strncpy(st, p + 1, 4);
505 for (i = 0; i < 4 && st[i]; i++) {
506 st[i] = toupper(st[i]);
513 trace(NULL, 3,
"update_stat: %s %s st=%d\n",
time_str(time, 3), tstr, siteno);
515 navs.stat.time[siteno] = sstat.
time;
523 trace(NULL, 3,
"update_stat: %s %s\n",
time_str(time, 3), tstr);
553 trace(NULL, 2,
"clas week_ref initialized: week=%d\n", week);
569 fp_clas[ch] = fopen(path,
"rb");
571 trace(NULL, 2,
"clas l6 file open: %s\n", path);
617 int i, nu, nr, n = 0;
650 for (i = 0; i < nu && n <
MAXOBS * 2; i++) {
653 for (i = 0; i < nr && n <
MAXOBS * 2; i++) {
694 static int warned_l6mrg_1file = 0;
695 if (!warned_l6mrg_1file) {
696 warned_l6mrg_1file = 1;
697 trace(NULL, 2,
"l6_merge enabled but only one L6 source supplied - running single-channel\n");
724 for (i = 0; i < nu && n <
MAXOBS * 2; i++) {
725 obs[n++] =
obss.data[
iobsu - nu + 1 + i];
727 for (i = 0; i < nr && n <
MAXOBS * 2; i++) {
728 obs[n++] =
obss.data[
iobsr - nr + 1 + i];
754 int i, nobs, n, solstatic, pri[] = {6, 1, 2, 3, 4, 5, 1, 6};
756 trace(ctx, 3,
"procpos : mode=%d\n", mode);
765 for (i = n = 0; i < nobs; i++) {
778 for (i = 0; i < 6; i++) {
787 for (i = 0; i < 3; i++) {
799 for (i = 0; i < 3; i++) {
808 for (i = 0; i < 3; i++) {
814 if (mode == 0 && solstatic && time.
time != 0.0) {
816 outsol(fp, &sol, rb, sopt);
822 double dr[3], var[3];
826 trace(NULL, 3,
"valcomb :\n");
829 for (i = 0; i < 3; i++) {
833 for (i = 0; i < 3; i++) {
834 if (dr[i] * dr[i] <= 16.0 * var[i]) {
839 trace(NULL, 2,
"degrade fix to float: %s dr=%.3f %.3f %.3f std=%.3f %.3f %.3f\n", tstr + 11, dr[0], dr[1],
848 sol_t sols = {{0}}, sol = {{0}};
849 double tt, Qf[9], Qb[9], Qs[9], rbs[3] = {0}, rb[3] = {0}, rr_f[3], rr_b[3], rr_s[3];
850 int i, j, k, solstatic, pri[] = {0, 1, 2, 3, 4, 5, 1, 6};
856 for (i = 0, j =
isolb - 1; i < isolf && j >= 0; i++, j--) {
859 for (k = 0; k < 3; k++) {
860 rbs[k] =
rbf[k + i * 3];
863 }
else if (tt >
DTTOL) {
865 for (k = 0; k < 3; k++) {
866 rbs[k] =
rbb[k + j * 3];
869 }
else if (
solf[i].stat <
solb[j].stat) {
871 for (k = 0; k < 3; k++) {
872 rbs[k] =
rbf[k + i * 3];
874 }
else if (
solf[i].stat >
solb[j].stat) {
876 for (k = 0; k < 3; k++) {
877 rbs[k] =
rbb[k + j * 3];
889 for (k = 0; k < 3; k++) {
890 Qf[k + k * 3] =
solf[i].qr[k];
891 Qb[k + k * 3] =
solb[j].qr[k];
893 Qf[1] = Qf[3] =
solf[i].qr[3];
894 Qf[5] = Qf[7] =
solf[i].qr[4];
895 Qf[2] = Qf[6] =
solf[i].qr[5];
896 Qb[1] = Qb[3] =
solb[j].qr[3];
897 Qb[5] = Qb[7] =
solb[j].qr[4];
898 Qb[2] = Qb[6] =
solb[j].qr[5];
901 for (k = 0; k < 3; k++) {
902 rr_f[k] =
solf[i].rr[k] -
rbf[k + i * 3];
904 for (k = 0; k < 3; k++) {
905 rr_b[k] =
solb[j].rr[k] -
rbb[k + j * 3];
907 if (
smoother(rr_f, Qf, rr_b, Qb, 3, rr_s, Qs)) {
910 for (k = 0; k < 3; k++) {
911 sols.
rr[k] = rbs[k] + rr_s[k];
918 sols.
qr[0] = (float)Qs[0];
919 sols.
qr[1] = (float)Qs[4];
920 sols.
qr[2] = (float)Qs[8];
921 sols.
qr[3] = (float)Qs[1];
922 sols.
qr[4] = (float)Qs[5];
923 sols.
qr[5] = (float)Qs[2];
927 for (k = 0; k < 3; k++) {
928 Qf[k + k * 3] =
solf[i].qv[k];
929 Qb[k + k * 3] =
solb[j].qv[k];
931 Qf[1] = Qf[3] =
solf[i].qv[3];
932 Qf[5] = Qf[7] =
solf[i].qv[4];
933 Qf[2] = Qf[6] =
solf[i].qv[5];
934 Qb[1] = Qb[3] =
solb[j].qv[3];
935 Qb[5] = Qb[7] =
solb[j].qv[4];
936 Qb[2] = Qb[6] =
solb[j].qv[5];
940 sols.
qv[0] = (float)Qs[0];
941 sols.
qv[1] = (float)Qs[4];
942 sols.
qv[2] = (float)Qs[8];
943 sols.
qv[3] = (float)Qs[1];
944 sols.
qv[4] = (float)Qs[5];
945 sols.
qv[5] = (float)Qs[2];
949 outsol(fp, &sols, rbs, sopt);
950 }
else if (time.time == 0 || pri[sols.
stat] <= pri[sol.stat]) {
952 for (k = 0; k < 3; k++) {
955 if (time.time == 0 ||
timediff(sols.
time, time) < 0.0) {
960 if (solstatic && time.
time != 0.0) {
962 outsol(fp, &sol, rb, sopt);
971 trace(NULL, 2,
"readpreceph: n=%d\n", n);
975 sbs->
n = sbs->
nmax = 0;
978 for (i = 0; i < n; i++) {
979 if (strstr(infile[i],
"%r") || strstr(infile[i],
"%b")) {
985 for (i = 0; i < n; i++) {
986 if (strstr(infile[i],
"%r") || strstr(infile[i],
"%b") ||
l6_file_type(infile[i])) {
992 for (i = 0; i < n; i++) {
993 if (strstr(infile[i],
"%r") || strstr(infile[i],
"%b")) {
1001 showmsg(
"error : sbas ephem memory allocation");
1002 trace(NULL, 1,
"error : sbas ephem memory allocation");
1005 for (i = 0; i < nav->
ns; i++) {
1006 nav->
seph[i] = seph0;
1025 for (i = 0; i < n; i++) {
1026 if ((ext = strrchr(infile[i],
'.')) && (!strcmp(ext,
".rtcm3") || !strcmp(ext,
".RTCM3"))) {
1047 for (i = 0; i < n; i++) {
1048 if ((ext = strrchr(infile[i],
'.')) && (!strcmp(ext,
".has") || !strcmp(ext,
".HAS"))) {
1069 int nf_l6d = 0, nf_clas = 0;
1072 strstr(prcopt->
pppopt,
"-clas") != NULL;
1074 for (i = 0; i < n; i++) {
1081 ext = strrchr(infile[i],
'.');
1082 iono = !is_l6e && ext - infile[i] >= 4 && (!strncmp(ext - 4,
".200", 4) || !strncmp(ext - 4,
".201", 4));
1083 if (is_l6d && !iono) {
1085 if (strchr(infile[i],
'%') && ts.
time) {
1086 reppath(infile[i], probe, ts,
"",
"");
1088 snprintf(probe,
sizeof(probe),
"%s", infile[i]);
1096 }
else if (is_l6e && clas_mode) {
1097 showmsg(
"warning: CLAS CMA input not supported yet, ignored: %s", infile[i]);
1098 trace(NULL, 2,
"L6E file ignored in CLAS mode (CMA not supported): %s\n", infile[i]);
1099 }
else if (clas_mode && !is_l6e) {
1101 strcpy(
clas_file[nf_clas++], infile[i]);
1103 }
else if (is_l6d) {
1104 showmsg(
"warning: L6D file ignored outside CLAS mode: %s", infile[i]);
1105 trace(NULL, 2,
"L6D file ignored outside CLAS mode: %s\n", infile[i]);
1126 if (nf_l6d > 0 && !nav->
pppiono) {
1141 for (i = 0; i < n; i++) {
1142 if ((ext = strrchr(infile[i],
'.')) && (!strcmp(ext,
".stat") || !strcmp(ext,
".STAT"))) {
1152 trace(NULL, 3,
"freepreceph:\n");
1165 sbs->
n = sbs->
nmax = 0;
1166 for (i = 0; i < nav->
nt; i++) {
1215 int i, j, ind = 0, nobs = 0, rcv = 1;
1217 trace(NULL, 3,
"readobsnav: ts=%s n=%d\n",
time_str(ts, 0), n);
1220 obs->
n = obs->
nmax = 0;
1222 nav->
n = nav->
nmax = 0;
1229 for (i = 0; i < n; i++) {
1235 if (index[i] != ind) {
1236 if (obs->
n > nobs) {
1246 ext = strrchr(infile[i],
'.');
1247 if (ext && !strcmp(ext,
".bnx")) {
1249 if (
readbnxt(infile[i], rcv, ts, te, ti, prcopt->
rnxopt[rcv <= 1 ? 0 : 1], obs, nav,
1250 rcv <= 2 ? sta + rcv - 1 : NULL, prcopt) < 0) {
1251 checkbrk(
"error : insufficient memory");
1252 trace(NULL, 1,
"insufficient memory\n");
1257 if (
readrnxt(infile[i], rcv, ts, te, ti, prcopt->
rnxopt[rcv <= 1 ? 0 : 1], obs, nav,
1258 rcv <= 2 ? sta + rcv - 1 : NULL) < 0) {
1259 checkbrk(
"error : insufficient memory");
1260 trace(NULL, 1,
"insufficient memory\n");
1267 trace(NULL, 1,
"\n");
1270 if (nav->
n <= 0 && nav->
ng <= 0 && nav->
ns <= 0) {
1272 trace(NULL, 1,
"\n");
1282 if (ts.
time == 0 || te.
time == 0) {
1283 for (i = 0; i < obs->
n; i++) {
1288 for (j = obs->
n - 1; j >= 0; j--) {
1307 trace(NULL, 3,
"freeobsnav:\n");
1311 obs->
n = obs->
nmax = 0;
1314 nav->
n = nav->
nmax = 0;
1330 int i, j, n = 0, m, iobs;
1333 trace(ctx, 3,
"avepos: rcv=%d obs.n=%d\n", rcv, obs->
n);
1335 for (i = 0; i < 3; i++) {
1339 for (iobs = 0; (m =
nextobsf(obs, &iobs, rcv)) > 0; iobs += m) {
1340 for (i = j = 0; i < m && i <
MAXOBS; i++) {
1341 data[j] = obs->
data[iobs + i];
1346 if (j <= 0 || !
screent(data[0].time, ts, ts, 1.0)) {
1350 if (!
pntpos(ctx, data, j, nav, opt, &sol, NULL, NULL, msg)) {
1354 for (i = 0; i < 3; i++) {
1360 trace(ctx, 1,
"no average of base station position\n");
1363 for (i = 0; i < 3; i++) {
1369static int getstapos(
const char* file,
char* name,
double* r) {
1371 char buff[256], sname[256], *p, *q;
1374 trace(NULL, 3,
"getstapos: file=%s name=%s\n", file, name);
1376 if (!(fp = fopen(file,
"r"))) {
1377 trace(NULL, 1,
"station position file open error: %s\n", file);
1380 while (fgets(buff,
sizeof(buff), fp)) {
1381 if ((p = strchr(buff,
'%'))) {
1385 if (sscanf(buff,
"%lf %lf %lf %s", pos, pos + 1, pos + 2, sname) < 4) {
1389 for (p = sname, q = name; *p && *q; p++, q++) {
1390 if (toupper((
int)*p) != toupper((
int)*q)) {
1403 trace(NULL, 1,
"no station position: %s %s\n", name, file);
1408 const char* posfile) {
1409 double *rr = rcvno == 1 ? opt->
ru : opt->
rb, del[3], pos[3], dr[3] = {0};
1410 int i, postype = rcvno == 1 ? opt->
rovpos : opt->
refpos;
1413 trace(ctx, 3,
"antpos : rcvno=%d\n", rcvno);
1416 if (!
avepos(ctx, rr, rcvno, obs, nav, opt)) {
1417 showmsg(
"error : station pos computation");
1421 name =
stas[rcvno == 1 ? 0 : 1].name;
1423 showmsg(
"error : no position of %s in %s", name, posfile);
1427 if (
norm(
stas[rcvno == 1 ? 0 : 1].pos, 3) <= 0.0) {
1428 showmsg(
"error : no position in rinex header");
1429 trace(ctx, 1,
"no position in rinex header\n");
1433 if (
stas[rcvno == 1 ? 0 : 1].deltype == 0) {
1434 for (i = 0; i < 3; i++) {
1435 del[i] =
stas[rcvno == 1 ? 0 : 1].del[i];
1437 del[2] +=
stas[rcvno == 1 ? 0 : 1].hgt;
1441 for (i = 0; i < 3; i++) {
1442 dr[i] =
stas[rcvno == 1 ? 0 : 1].del[i];
1445 for (i = 0; i < 3; i++) {
1446 rr[i] =
stas[rcvno == 1 ? 0 : 1].pos[i] + dr[i];
1454 trace(ctx, 3,
"openses :\n");
1459 trace(ctx, 1,
"sat antenna pcv read error: %s\n", fopt->
satantp);
1465 trace(ctx, 1,
"rec antenna pcv read error: %s\n", fopt->
rcvantp);
1472 trace(ctx, 2,
"no geoid data %s\n", fopt->
geoid);
1479 trace(ctx, 3,
"closeses:\n");
1484 pcvs->
n = pcvs->
nmax = 0;
1487 pcvr->
n = pcvr->
nmax = 0;
1503 pcv_t *pcv, pcv0 = {0};
1504 double pos[3], del[3];
1509 for (i = 0; i <
MAXSAT; i++) {
1510 nav->
pcvs[i] = pcv0;
1514 if (!(pcv =
searchpcv(i + 1,
"", time, pcvs))) {
1516 trace(NULL, 3,
"no satellite antenna pcv: %s\n",
id);
1519 nav->
pcvs[i] = *pcv;
1521 for (i = 0; i < (mode ? 2 : 1); i++) {
1522 popt->
pcvr[i] = pcv0;
1523 if (!strcmp(popt->
anttype[i],
"*")) {
1525 if (sta[i].deltype == 1) {
1526 if (
norm(sta[i].pos, 3) > 0.0) {
1529 for (j = 0; j < 3; j++) {
1530 popt->
antdel[i][j] = del[j];
1534 for (j = 0; j < 3; j++) {
1540 trace(NULL, 2,
"no receiver antenna pcv: %s\n", popt->
anttype[i]);
1545 popt->
pcvr[i] = *pcv;
1552 for (i = 0; i < (mode ? 2 : 1); i++) {
1560 trace(NULL, 3,
"outhead: outfile=%s n=%d\n", outfile, n);
1565 if (!(fp = fopen(outfile,
"wb"))) {
1566 showmsg(
"error : open output file %s", outfile);
1581 trace(NULL, 3,
"openfile: outfile=%s\n", outfile);
1583 return !*outfile ? stdout : fopen(outfile,
"ab");
1587 const filopt_t* fopt,
int flag,
char** infile,
const int* index,
int n,
char* outfile) {
1590 char tracefile[1024], statfile[1024], path[1024], *ext;
1592 trace(ctx, 3,
"execses : n=%d outfile=%s\n", n, outfile);
1595 if (flag && sopt->
trace > 0) {
1597 strcpy(tracefile, outfile);
1598 strcat(tracefile,
".trace");
1600 strcpy(tracefile, fopt->
trace);
1607 if (*fopt->
iono && (ext = strrchr(fopt->
iono,
'.'))) {
1608 if (strlen(ext) == 4 && (ext[3] ==
'i' || ext[3] ==
'I')) {
1616 navs.erp.data = NULL;
1620 showmsg(
"error : no erp data %s", path);
1621 trace(ctx, 2,
"no erp data %s\n", path);
1645 trace(NULL, 1,
"clas grid file error: %s\n", fopt->
grid);
1651 trace(NULL, 3,
"execses: ISB table loaded ni=%d\n",
navs.ni);
1656 trace(NULL, 3,
"execses: L2C table loaded n=%d\n",
navs.sfts.n);
1661 trace(NULL, 1,
"grid blq file error: %s\n", fopt->
blq);
1663 trace(NULL, 3,
"execses: grid BLQ loaded from %s\n", fopt->
blq);
1686 if (flag && sopt->
sstat > 0) {
1687 strcpy(statfile, outfile);
1688 strcat(statfile,
".stat");
1693 if (flag && !
outhead(outfile, infile, n, &popt_, sopt)) {
1700 if (strlen(popt_.
staname) == 0) {
1707 procpos(ctx, fp, &popt_, sopt, 0);
1710 }
else if (popt_.
soltype == 1) {
1715 procpos(ctx, fp, &popt_, sopt, 0);
1726 procpos(ctx, NULL, &popt_, sopt, 1);
1730 procpos(ctx, NULL, &popt_, sopt, 1);
1738 showmsg(
"error : memory allocation");
1752 const filopt_t* fopt,
int flag,
char** infile,
const int* index,
int n,
char* outfile,
1756 char *ifile[
MAXINFILE], ofile[1024], *rov_, *p, *q, s[64] =
"";
1758 trace(ctx, 3,
"execses_r: n=%d outfile=%s\n", n, outfile);
1760 for (i = 0; i < n; i++) {
1761 if (strstr(infile[i],
"%r")) {
1767 if (!(rov_ = (
char*)
malloc(strlen(rov) + 1))) {
1772 for (i = 0; i < n; i++) {
1773 if (!(ifile[i] = (
char*)
malloc(1024))) {
1775 for (; i >= 0; i--) {
1781 for (p = rov_;; p = q + 1) {
1782 if ((q = strchr(p,
' '))) {
1797 for (i = 0; i < n; i++) {
1798 reppath(infile[i], ifile[i], t0, p,
"");
1800 reppath(outfile, ofile, t0, p,
"");
1803 stat =
execses(ctx, ts, te, ti, popt, sopt, fopt, flag, ifile, index, n, ofile);
1805 if (stat == 1 || !q) {
1810 for (i = 0; i < n; i++) {
1815 stat =
execses(ctx, ts, te, ti, popt, sopt, fopt, flag, infile, index, n, outfile);
1821 const filopt_t* fopt,
int flag,
char** infile,
const int* index,
int n,
char* outfile,
1822 const char* rov,
const char* base) {
1825 char *ifile[
MAXINFILE], ofile[1024], *base_, *p, *q, s[64];
1827 trace(ctx, 3,
"execses_b: n=%d outfile=%s\n", n, outfile);
1832 for (i = 0; i < n; i++) {
1833 if (strstr(infile[i],
"%b")) {
1839 if (!(base_ = (
char*)
malloc(strlen(base) + 1))) {
1843 strcpy(base_, base);
1845 for (i = 0; i < n; i++) {
1846 if (!(ifile[i] = (
char*)
malloc(1024))) {
1848 for (; i >= 0; i--) {
1855 for (p = base_;; p = q + 1) {
1856 if ((q = strchr(p,
' '))) {
1871 for (i = 0; i < n; i++) {
1872 reppath(infile[i], ifile[i], t0,
"", p);
1874 reppath(outfile, ofile, t0,
"", p);
1876 stat =
execses_r(ctx, ts, te, ti, popt, sopt, fopt, flag, ifile, index, n, ofile, rov);
1878 if (stat == 1 || !q) {
1883 for (i = 0; i < n; i++) {
1887 stat =
execses_r(ctx, ts, te, ti, popt, sopt, fopt, flag, infile, index, n, outfile, rov);
1939 const solopt_t* sopt,
const filopt_t* fopt,
char** infile,
int n,
char* outfile,
const char* rov,
1943 int i, j, k, nf, stat = 0, week, flag = 1, index[
MAXINFILE] = {0};
1944 char *ifile[
MAXINFILE], ofile[1024], *ext;
1946 trace(ctx, 3,
"postpos : ti=%.0f tu=%.0f n=%d outfile=%s\n", ti, tu, n, outfile);
1957 if (ts.
time != 0 && te.
time != 0 && tu >= 0.0) {
1964 if (!(ifile[i] = (
char*)
malloc(1024))) {
1965 for (; i >= 0; i--) {
1972 if (tu == 0.0 || tu > 86400.0 *
MAXPRCDAYS) {
1976 tunit = tu < 86400.0 ? tu : 86400.0;
1977 tss = tunit * (int)floor(
time2gpst(ts, &week) / tunit);
1998 for (j = k = nf = 0; j < n; j++) {
1999 ext = strrchr(infile[j],
'.');
2001 if ((ext && (!strcmp(ext,
".rtcm3") || !strcmp(ext,
".RTCM3"))) ||
l6_file_type(infile[j])) {
2002 strcpy(ifile[nf++], infile[j]);
2006 if (ext && (!strcmp(ext,
".sp3") || !strcmp(ext,
".SP3") || !strcmp(ext,
".eph") ||
2007 !strcmp(ext,
".EPH"))) {
2009 }
else if (strstr(infile[j],
"brdc")) {
2014 if (ext && (!strcmp(ext,
".bia") || !strcmp(ext,
".BIA"))) {
2015 strcpy(
navs.biapath, infile[j]);
2017 if (ext && (!strcmp(ext,
".fcb") || !strcmp(ext,
".FCB"))) {
2018 strcpy(
navs.fcbpath, infile[j]);
2025 trace(ctx, 2,
"too many input files. trancated\n");
2029 if (!
reppath(outfile, ofile, tts,
"",
"") && i > 0) {
2033 if (strlen(
navs.biapath) == 0 && strlen(fopt->
bia) > 0) {
2034 strcpy(
navs.biapath, fopt->
bia);
2036 if (strlen(
navs.fcbpath) == 0 && strlen(fopt->
fcb) > 0) {
2037 strcpy(
navs.fcbpath, fopt->
fcb);
2040 stat =
execses_b(ctx, tts, tte, ti, popt, sopt, fopt, flag, ifile, index, nf, ofile, rov, base);
2049 }
else if (ts.
time != 0) {
2050 for (i = 0; i < n && i <
MAXINFILE; i++) {
2051 if (!(ifile[i] = (
char*)
malloc(1024))) {
2052 for (; i >= 0; i--) {
2057 reppath(infile[i], ifile[i], ts,
"",
"");
2060 reppath(outfile, ofile, ts,
"",
"");
2063 stat =
execses_b(ctx, ts, te, ti, popt, sopt, fopt, 1, ifile, index, n, ofile, rov, base);
2065 for (i = 0; i < n && i <
MAXINFILE; i++) {
2069 for (i = 0; i < n; i++) {
2074 stat =
execses_b(ctx, ts, te, ti, popt, sopt, fopt, 1, infile, index, n, outfile, rov, base);
int readpcv(const char *file, pcvs_t *pcvs)
Read antenna parameters from file (ANTEX or NGS format).
pcv_t * searchpcv(int sat, const char *type, gtime_t time, const pcvs_t *pcvs)
Search antenna parameter by satellite number or antenna type.
MRTKLIB Antenna Module — Antenna phase center model and parameter I/O.
void satno2id(int sat, char *id)
uint32_t getbitu(const uint8_t *buff, int pos, int len)
Extract unsigned bits from byte data.
MRTKLIB Bits Module — Binary bit operations and CRC functions.
void clas_check_grid_status(clas_ctx_t *ctx, const clas_corr_t *corr, int ch)
Check and update grid status flags based on correction availability.
void clas_ctx_free(clas_ctx_t *ctx)
Free CLAS context (release heap-allocated bank control).
int clas_bank_get_close(const clas_ctx_t *ctx, gtime_t time, int network, int ch, clas_corr_t *corr)
Merge closest corrections from all banks into a clas_corr_t snapshot.
int clas_input_cssrf(clas_ctx_t *ctx, FILE *fp, int ch)
Input CSSR from file (one message at a time, post-processing).
int clas_read_grid_def(clas_ctx_t *ctx, const char *gridfile)
Read CLAS grid definition file.
void clas_check_grid_status_time(clas_ctx_t *ctx, gtime_t time, int ch)
void clas_update_global(nav_t *nav, const clas_corr_t *corr, int ch)
Apply global corrections (orbit/clock/bias) to nav_t.ssr[].
int clas_ctx_init(clas_ctx_t *ctx)
Initialize CLAS context (allocate bank control on heap).
CLAS (QZSS L6D) CSSR decoder and grid correction type definitions.
int readblqgrid(const char *file, clas_ctx_t *ctx)
Read BLQ ocean tide loading parameters for CLAS grid points.
int readL2C(const char *file, nav_t *nav)
Read L2C 1/4 cycle phase shift table from file.
int readisb(const char *file, nav_t *nav)
Read ISB correction table from file.
void setisb(const nav_t *nav, const char *rectype0, const char *rectype1, sta_t *sta0, sta_t *sta1)
Set ISB corrections for rover and reference stations.
void enu2ecef(const double *pos, const double *e, double *r)
Transform local tangential coordinate vector to ECEF.
void pos2ecef(const double *pos, double *r)
Transform geodetic position to ECEF position.
void deg2dms(double deg, double *dms, int ndec)
Convert degree to degree-minute-second.
void ecef2pos(const double *r, double *pos)
Transform ECEF position to geodetic position.
void ecef2enu(const double *pos, const double *r, double *e)
Transform ECEF vector to local tangential coordinate.
MRTKLIB Coordinates Module — Coordinate transformations and geometry.
int satsys(int sat, int *prn)
void closegeoid(void)
Close geoid model file.
int opengeoid(int model, const char *file)
Open geoid model file.
MRTKLIB Geoid Module — Geoid height models.
void has_free(has_t *has)
Free a Galileo HAS decode context.
int has_input_file(has_t *has, FILE *fp, gtime_t tmax)
Read .has records from a file and feed them to has_input_page().
has_t * has_new(void)
Allocate and initialize a Galileo HAS decode context.
MRTKLIB Galileo HAS Module — E6-B C/NAV HAS page collection and Message Type 1 (MT1) decode into ssr_...
void readtec(const char *file, nav_t *nav, int opt)
Read IONEX ionospheric TEC grid file.
MRTKLIB IONEX Module — IONEX ionospheric TEC map I/O and interpolation.
l6_file_type_t l6_file_type(const char *file)
Classify a file name by its QZSS L6 extension (case-insensitive).
l6_service_t l6_file_service(const char *file)
Service of an L6 frame file, from the first non-null frame header.
l6_file_type_t
QZSS L6 file type from the file name extension.
int input_qzssl6ef(rtcm_t *rtcm, FILE *fp)
Fetch next QZSS L6E message and input a message from file.
void init_mcssr(const gtime_t gt)
Initialize MADOCA-PPP CSSR control struct for current channel.
MRTKLIB MADOCA-PPP Module — QZSS L6E CSSR message decode functions.
void init_miono(const gtime_t gt)
Initialize MADOCA-PPP L6D ionospheric correction control.
int input_qzssl6df(mdcl6d_t *mdcl6d, FILE *fp)
Input QZSS L6D message from file.
int input_statf(sstat_t *sstat, FILE *fp, char *buff, int *nbyte)
Fetch next stat message and input a message from file.
int getstano(stat_t *stat, const char *pntname)
Search for a point by name or add a new point if not found.
int block2stat(rtcm_t *rtcm, stat_t *stat)
Convert RTCM3 block data to station statistics.
MRTKLIB MADOCA Local Correction Module — local correction common functions and constants.
int smoother(const double *xf, const double *Qf, const double *xb, const double *Qb, int n, double *xs, double *Qs)
Combine forward and backward filters by fixed-interval smoother.
double norm(const double *a, int n)
Euclidean norm of vector.
MRTKLIB Matrix Module — Matrix/vector operations and estimation.
void uniqnav(nav_t *nav)
Unique ephemerides in navigation data.
int set_bdsopt(const prcopt_t *opt, int warn)
Apply the BeiDou PRN-reassignment options process-wide.
MRTKLIB Navigation Module — Navigation data types and satellite/nav utility functions.
int sortobs(obs_t *obs)
Sort observation data by time, receiver, and satellite.
int screent(gtime_t time, gtime_t ts, gtime_t te, double tint)
Screen data by time range and interval.
MRTKLIB Observation Module — Observation data types and utility functions.
#define PMODE_SSR2OSR_FIXED
void readsp3(const char *file, nav_t *nav, int opt)
Read sp3 precise ephemeris file.
int readdcb(const char *file, nav_t *nav, const sta_t *sta)
Read differential code bias (DCB) parameters.
int readerp(const char *file, erp_t *erp)
Read earth rotation parameters from IGS ERP file (ver.2).
MRTKLIB Precise Ephemeris Module — Earth rotation parameter types and ERP I/O functions.
static int avepos(mrtk_ctx_t *ctx, double *ra, int rcv, const obs_t *obs, const nav_t *nav, const prcopt_t *opt)
static char clas_file[CLAS_CH_NUM][1024]
static void combres(FILE *fp, const prcopt_t *popt, const solopt_t *sopt)
static void init_mdcl6d(gtime_t time, const char *pppopt)
static void freepreceph(nav_t *nav, sbs_t *sbs)
static void update_gal_has(gtime_t time)
static int execses_b(mrtk_ctx_t *ctx, gtime_t ts, gtime_t te, double ti, const prcopt_t *popt, const solopt_t *sopt, const filopt_t *fopt, int flag, char **infile, const int *index, int n, char *outfile, const char *rov, const char *base)
static void outheader(FILE *fp, char **file, int n, const prcopt_t *popt, const solopt_t *sopt)
static void freeobsnav(obs_t *obs, nav_t *nav)
static int execses_r(mrtk_ctx_t *ctx, gtime_t ts, gtime_t te, double ti, const prcopt_t *popt, const solopt_t *sopt, const filopt_t *fopt, int flag, char **infile, const int *index, int n, char *outfile, const char *rov)
static mdcl6d_t mdcl6d[MIONO_MAX_PRN]
static void update_stat(gtime_t time)
static char qzssl6e_file[1024]
static char clas_path[CLAS_CH_NUM][1024]
static char qzssl6d_file[MIONO_MAX_PRN][1024]
static int nextobsb(const obs_t *obs, int *i, int rcv)
static void update_rtcm(gtime_t time)
static char proc_base[64]
static int execses(mrtk_ctx_t *ctx, gtime_t ts, gtime_t te, double ti, const prcopt_t *popt, const solopt_t *sopt, const filopt_t *fopt, int flag, char **infile, const int *index, int n, char *outfile)
static char gal_has_file[1024]
static char qzssl6e_path[1024]
static FILE * fp_clas[CLAS_CH_NUM]
void settime(gtime_t time)
static void update_clas(gtime_t time)
static int getstapos(const char *file, char *name, double *r)
static void closeses(mrtk_ctx_t *ctx, nav_t *nav, pcvs_t *pcvs, pcvs_t *pcvr)
static int antpos(mrtk_ctx_t *ctx, prcopt_t *opt, int rcvno, const obs_t *obs, const nav_t *nav, const sta_t *sta, const char *posfile)
static void update_qzssl6d(gtime_t time, int n, const char *pppopt)
static char rtcm_file[1024]
static int checkbrk(const char *format,...)
static FILE * fp_qzssl6d[MIONO_MAX_PRN]
static sta_t stas[MAXRCV]
int postpos(mrtk_ctx_t *ctx, gtime_t ts, gtime_t te, double ti, double tu, const prcopt_t *popt, const solopt_t *sopt, const filopt_t *fopt, char **infile, int n, char *outfile, const char *rov, const char *base)
Post-processing positioning.
static void procpos(mrtk_ctx_t *ctx, FILE *fp, const prcopt_t *popt, const solopt_t *sopt, int mode)
static int clas_has_orbit_bank(const clas_ctx_t *ctx, int ch)
static int outhead(const char *outfile, char **infile, int n, const prcopt_t *popt, const solopt_t *sopt)
static int openses(mrtk_ctx_t *ctx, const prcopt_t *popt, const solopt_t *sopt, const filopt_t *fopt, nav_t *nav, pcvs_t *pcvs, pcvs_t *pcvr)
static void readpreceph(char **infile, int n, const prcopt_t *prcopt, nav_t *nav, sbs_t *sbs, gtime_t ts)
static char stat_file[1024]
static char rtcm_path[1024]
static int inputobs(obsd_t *obs, int solq, const prcopt_t *popt)
static int valcomb(const sol_t *solf, const sol_t *solb)
static void setpcv(gtime_t time, prcopt_t *popt, nav_t *nav, const pcvs_t *pcvs, const pcvs_t *pcvr, const sta_t *sta)
static int readobsnav(gtime_t ts, gtime_t te, double ti, char **infile, const int *index, int n, const prcopt_t *prcopt, obs_t *obs, nav_t *nav, sta_t *sta)
static char gal_has_path[1024]
static int nextobsf(const obs_t *obs, int *i, int rcv)
static char cstat_file[1024]
static void update_qzssl6e(gtime_t time)
static void outrpos(FILE *fp, const double *r, const solopt_t *opt)
void settspan(gtime_t ts, gtime_t te)
static FILE * openfile(const char *outfile)
int showmsg(const char *format,...)
static char qzssl6d_path[MIONO_MAX_PRN][1024]
static void readotl(prcopt_t *popt, const char *file, const sta_t *sta)
static clas_ctx_t * clas_ctx
MRTKLIB Post-Processing Positioning Module — Post-processing positioning orchestrator.
MRTKLIB Precise Point Positioning (PPP) Module.
int readbnxt(const char *file, int rcv, gtime_t ts, gtime_t te, double tint, const char *opt, obs_t *obs, nav_t *nav, sta_t *sta, const prcopt_t *popt)
Read BINEX observation/navigation data from file(s).
MRTKLIB Receiver Raw Data Module — Receiver raw data types and decoder functions for various GNSS rec...
int readrnxt(const char *file, int rcv, gtime_t ts, gtime_t te, double tint, const char *opt, obs_t *obs, nav_t *nav, sta_t *sta)
Read RINEX OBS and NAV files with time span.
int readrnxc(const char *file, nav_t *nav)
Read RINEX clock files.
MRTKLIB RINEX Module — RINEX file read/write types and functions.
void free_rtcm(rtcm_t *rtcm)
Free RTCM control struct.
int input_rtcm3f(rtcm_t *rtcm, FILE *fp)
Input RTCM 3 message from file.
int init_rtcm(rtcm_t *rtcm)
Initialize RTCM control struct.
MRTKLIB RTCM Module — RTCM message types and functions.
int rtkpos(mrtk_ctx_t *ctx, rtk_t *rtk, const obsd_t *obs, int n, nav_t *nav)
Compute rover position by precise positioning.
void rtkfree(rtk_t *rtk)
Free memory for RTK control struct.
int rtkopenstat(const char *file, int level)
Open solution status file and set output level.
void rtkclosestat(void)
Close solution status file.
void rtkinit(rtk_t *rtk, const prcopt_t *opt)
Initialize RTK control struct.
MRTKLIB RTK Positioning Module — relative and precise positioning.
int sbsreadmsg(const char *file, int sel, sbs_t *sbs)
Read SBAS message file.
int sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav)
Update SBAS corrections in navigation data.
MRTKLIB SBAS Module — SBAS message decoding and corrections.
void outprcopt(FILE *fp, const prcopt_t *opt)
Output processing options to file.
void outsolhead(FILE *fp, const solopt_t *opt)
Output solution header to file.
void outsol(FILE *fp, const sol_t *sol, const double *rb, const solopt_t *opt)
Output solution to file.
MRTKLIB Solution Module — Solution data types and I/O functions.
int pntpos(mrtk_ctx_t *ctx, const obsd_t *obs, int n, const nav_t *nav, const prcopt_t *opt, sol_t *sol, double *azel, ssat_t *ssat, char *msg)
Compute receiver position, velocity, clock bias by single-point positioning with pseudorange and dopp...
MRTKLIB Single-Point Positioning Module — SPP functions.
int readblq(const char *file, const char *sta, double *odisp)
Read BLQ ocean tide loading parameters.
MRTKLIB Station Module — Site environment parameter I/O.
void createdir(const char *path)
Create directory if not exists (recursively).
int reppath(const char *path, char *rpath, gtime_t time, const char *rov, const char *base)
Replace keywords in file path with date, time, rover and base station id.
int reppaths(const char *path, char *rpath[], int nmax, gtime_t ts, gtime_t te, const char *rov, const char *base)
Replace keywords in file path and generate multiple paths.
MRTKLIB System Module — OS/filesystem utility functions.
MRTKLIB Tides Module — Tidal displacement corrections.
gtime_t gpst2time(int week, double sec)
Convert GPS week/tow to gtime_t.
void time2str(gtime_t t, char *s, int n)
Convert gtime_t struct to string.
gtime_t gpst2utc(gtime_t t)
Convert GPS time to UTC considering leap seconds.
double timediff(gtime_t t1, gtime_t t2)
Compute time difference (t1 - t2).
double time2gpst(gtime_t t, int *week)
Convert gtime_t to GPS week/tow.
gtime_t timeadd(gtime_t t, double sec)
Add seconds to gtime_t.
char * time_str(gtime_t t, int n)
Get time string (not reentrant).
gtime_t timeget(void)
Get current time in UTC.
void traceopen(mrtk_ctx_t *ctx, const char *file)
Open trace output (initializes tick counter for tracet).
void tracelevel(mrtk_ctx_t *ctx, int level)
Set trace level.
void traceclose(mrtk_ctx_t *ctx)
Close trace output.
void trace(mrtk_ctx_t *ctx, int level, const char *format,...)
Output trace message.
MRTKLIB Trace Module — debug trace and logging functions.
clas_orbit_bank_t OrbitBank[32]
clas_bank_ctrl_t * bank[2]
GNSS time representation.
QZSS L6D message control struct.
Runtime context for MRTKLIB processing.
Observation data collection.
RTCM control struct type.