46#define CLIGHT 299792458.0
47#define D2R (3.1415926535897932384626433832795 / 180.0)
48#define R2D (180.0 / 3.1415926535897932384626433832795)
49#define FREQ1 1.57542E9
64#define INT_SWAP_STAT 86400.0
65#define SSR_VENDOR_L6 0
66#define SSR_VENDOR_RTCM 1
67#define MAXAGESSRL6 60.0
74#define SQR(x) ((x) * (x))
75#define SQRT(x) ((x) <= 0.0 || (x) != (x) ? 0.0 : sqrt(x))
76#define MIN(x, y) ((x) <= (y) ? (x) : (y))
77#define ROUND(x) (int)floor((x) + 0.5)
79#define VAR_POS SQR(30.0)
80#define VAR_VEL SQR(10.0)
81#define VAR_ACC SQR(10.0)
82#define VAR_HWBIAS SQR(1.0)
83#define VAR_GRA SQR(0.001)
86#define PRN_HWBIAS 1E-6
90#define VAR_HOLDAMB 0.001
92#define TTOL_MOVEB (1.0 + 2 * DTTOL)
96#define NF(opt) ((opt)->ionoopt == IONOOPT_IFLC ? 1 : (opt)->nf)
97#define NP(opt) ((opt)->dynamics == 0 ? 3 : 9)
98#define NI(opt) (((opt)->ionoopt != IONOOPT_EST && (opt)->ionoopt != IONOOPT_EST_ADPT) ? 0 : MAXSAT)
99#define NT(opt) ((opt)->tropopt < TROPOPT_EST ? 0 : ((opt)->tropopt < TROPOPT_ESTG ? 2 : 6))
100#define NL(opt) ((opt)->glomodear != 2 ? 0 : NFREQGLO)
101#define NB(opt) ((opt)->mode <= PMODE_DGPS ? 0 : MAXSAT * NF(opt))
102#define NR(opt) (NP(opt) + NI(opt) + NT(opt) + NL(opt))
103#define NX(opt) (NR(opt) + NB(opt))
106#define II(s, opt) (NP(opt) + (s) - 1)
107#define IT(r, opt) (NP(opt) + NI(opt) + NT(opt) / 2 * (r))
108#define IL(f, opt) (NP(opt) + NI(opt) + NT(opt) + (f))
109#define IB(s, f, opt) (NR(opt) + MAXSAT * (f) + (s) - 1)
114 {-1.94058448e-01, -7.79023476e+00, 1.24231120e+02, -4.03126050e+02, 3.50413202e+02},
115 {6.42237302e-01, -8.39813962e+00, 2.92107285e+01, -2.37577308e+01, -1.14307128e+00},
116 {-2.22600390e-02, 3.23169103e-01, -1.39837429e+00, 2.19282996e+00, -5.34583971e-02}};
197 trace(NULL, 3,
"rtkopenstat: file=%s level=%d\n", file, level);
203 reppath(file, path, time,
"",
"");
205 if (!(
fp_stat = fopen(path,
"w"))) {
206 trace(NULL, 1,
"rtkopenstat: file open error path=%s\n", path);
220 trace(NULL, 3,
"rtkclosestat:\n");
232 double tow, pos[3], vel[3], acc[3], vela[3] = {0}, acca[3] = {0}, xa[3];
233 int i, j, week, est, nfreq, nf =
NF(&rtk->
opt);
234 char id[32], *p = buff;
244 nfreq = est ? nf : 1;
249 for (i = 0; i < 3; i++) {
250 xa[i] = i < rtk->
na ? rtk->
xa[i] : 0.0;
252 p += sprintf(p,
"$POS,%d,%.3f,%d,%.4f,%.4f,%.4f,%.4f,%.4f,%.4f\n", week, tow, rtk->
sol.
stat, rtk->
x[0],
253 rtk->
x[1], rtk->
x[2], xa[0], xa[1], xa[2]);
255 p += sprintf(p,
"$POS,%d,%.3f,%d,%.4f,%.4f,%.4f,%.4f,%.4f,%.4f\n", week, tow, rtk->
sol.
stat, rtk->
sol.
rr[0],
256 rtk->
sol.
rr[1], rtk->
sol.
rr[2], 0.0, 0.0, 0.0);
269 p += sprintf(p,
"$VELACC,%d,%.3f,%d,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f\n", week, tow,
270 rtk->
sol.
stat, vel[0], vel[1], vel[2], acc[0], acc[1], acc[2], vela[0], vela[1], vela[2], acca[0],
275 p += sprintf(p,
"$VELACC,%d,%.3f,%d,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f\n", week, tow,
276 rtk->
sol.
stat, vel[0], vel[1], vel[2], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
279 p += sprintf(p,
"$CLK,%d,%.3f,%d,%d,%.3f,%.3f,%.3f,%.3f\n", week, tow, rtk->
sol.
stat, 1, rtk->
sol.
dtr[0] * 1E9,
284 for (i = 0; i <
MAXSAT; i++) {
285 ssat = rtk->
ssat + i;
290 j =
II(i + 1, &rtk->
opt);
291 xa[0] = j < rtk->
na ? rtk->
xa[j] : 0.0;
292 p += sprintf(p,
"$ION,%d,%.3f,%d,%s,%.1f,%.1f,%.4f,%.4f\n", week, tow, rtk->
sol.
stat,
id,
298 for (i = 0; i < 2; i++) {
299 j =
IT(i, &rtk->
opt);
300 xa[0] = j < rtk->
na ? rtk->
xa[j] : 0.0;
301 p += sprintf(p,
"$TROP,%d,%.3f,%d,%d,%.4f,%.4f\n", week, tow, rtk->
sol.
stat, i + 1, rtk->
x[j], xa[0]);
306 for (i = 0; i < nfreq; i++) {
307 j =
IL(i, &rtk->
opt);
308 xa[0] = j < rtk->
na ? rtk->
xa[j] : 0.0;
309 p += sprintf(p,
"$HWBIAS,%d,%.3f,%d,%d,%.4f,%.4f\n", week, tow, rtk->
sol.
stat, i + 1, rtk->
x[j], xa[0]);
312 return (
int)(p - buff);
331 if (!(
fp_stat = fopen(path,
"w"))) {
332 trace(NULL, 2,
"swapsolstat: file open error path=%s\n", path);
335 trace(NULL, 3,
"swapsolstat: path=%s\n", path);
342 int i, j, n, week, nfreq, nf =
NF(&rtk->
opt);
348 trace(NULL, 3,
"outsolstat:\n");
367 for (i = 0; i <
MAXSAT; i++) {
368 ssat = rtk->
ssat + i;
373 for (j = 0; j < nfreq; j++) {
374 fprintf(
fp_stat,
"$SAT,%d,%.3f,%s,%d,%.1f,%.1f,%.4f,%.4f,%d,%.1f,%d,%d,%d,%d,%d,%d\n", week, tow,
id, j + 1,
383 char buff[256], tstr[32];
387 n = sprintf(buff,
"%s: ", tstr + 11);
388 va_start(ap, format);
389 n += vsprintf(buff + n, format, ap);
394 trace(NULL, 2,
"%s", buff);
398 double pi = (k < NFREQ) ? obs[i].L[k] : obs[i].
P[k - NFREQ];
399 double pj = (k < NFREQ) ? obs[j].L[k] : obs[j].
P[k - NFREQ];
400 return pi == 0.0 || pj == 0.0 ? 0.0 : pi - pj;
404 double freq1, freq2, L1, L2;
406 freq1 =
sat2freq(obs[i].sat, obs[i].code[0], nav);
407 freq2 =
sat2freq(obs[i].sat, obs[i].code[k], nav);
408 L1 =
sdobs(obs, i, j, 0);
409 L2 =
sdobs(obs, i, j, k);
410 if (freq1 == 0.0 || freq2 == 0.0 || L1 == 0.0 || L2 == 0.0) {
417static int seliflc(
int optnf,
int sys) {
return (optnf == 2 || sys !=
SYS_GAL) ? 1 : 2; }
418static double varerr(
int sat,
int sys,
double el,
double snr_rover,
double snr_base,
double bl,
double dt,
int f,
421 double sinel = sin(el), var;
422 int nf =
NF(opt), frq, code;
425 code = (f < nf) ? 0 : 1;
463 a = fact * opt->
err[1];
464 b = fact * opt->
err[2];
466 var = 2.0 * (a * a + b * b / sinel / sinel + c * c) + d * d;
468 if (opt->
err[6] > 0.0) {
469 double e = fact * opt->
err[6];
470 double snr_max = opt->
err[5];
471 double dr = snr_max - snr_rover, db = snr_max - snr_base;
472 var += e * e * (pow(10.0, 0.1 * (dr > 0.0 ? dr : 0.0)) + pow(10.0, 0.1 * (db > 0.0 ? db : 0.0)));
479static double baseline(
const double* ru,
const double* rb,
double* dr) {
481 for (i = 0; i < 3; i++) {
482 dr[i] = ru[i] - rb[i];
490 for (j = 0; j < rtk->
nx; j++) {
491 rtk->
P[i + j * rtk->
nx] = rtk->
P[j + i * rtk->
nx] = i == j ? var : 0.0;
495static int selsat(
const obsd_t* obs,
double* azel,
int nu,
int nr,
const prcopt_t* opt,
int* sat,
int* iu,
int* ir) {
498 trace(NULL, 3,
"selsat : nu=%d nr=%d\n", nu, nr);
500 for (i = 0, j = nu; i < nu && j < nu + nr; i++, j++) {
501 if (obs[i].sat < obs[j].sat) {
503 }
else if (obs[i].sat > obs[j].sat) {
505 }
else if (azel[1 + j * 2] >= opt->
elmin) {
509 trace(NULL, 4,
"(%2d) sat=%3d iu=%2d ir=%2d\n", k - 1, obs[i].sat, i, j);
516 double *F, *P, *FP, *x, *xp, pos[3], Q[9] = {0}, Qv[9], var = 0.0;
519 trace(NULL, 3,
"udpos : tt=%.3f\n", tt);
523 for (i = 0; i < 3; i++) {
529 if (
norm(rtk->
x, 3) <= 0.0) {
530 for (i = 0; i < 3; i++) {
534 for (i = 3; i < 6; i++) {
537 for (i = 6; i < 9; i++) {
549 for (i = 0; i < 3; i++) {
555 for (i = 0; i < 3; i++) {
556 var += rtk->
P[i + i * rtk->
nx];
562 for (i = 0; i < 3; i++) {
565 for (i = 3; i < 6; i++) {
568 for (i = 6; i < 9; i++) {
571 trace(NULL, 2,
"reset rtk position due to large variance: var=%.3f\n", var);
576 for (i = nx = 0; i < rtk->
nx; i++) {
577 if (rtk->
x[i] != 0.0 && rtk->
P[i + i * rtk->
nx] > 0.0) {
592 for (i = 0; i < 6; i++) {
593 F[i + (i + 3) * nx] = tt;
596 if (var < rtk->opt.thresar[1]) {
597 for (i = 0; i < 3; i++) {
598 F[i + (i + 6) * nx] = (tt >= 0.0 ? 1.0 : -1.0) *
SQR(tt) / 2.0;
601 trace(NULL, 3,
"pos var too high for accel term: var=%.4f\n", var);
603 for (i = 0; i < nx; i++) {
604 x[i] = rtk->
x[ix[i]];
605 for (j = 0; j < nx; j++) {
606 P[i + j * nx] = rtk->
P[ix[i] + ix[j] * rtk->
nx];
610 matmul(
"NN", nx, 1, nx, 1.0, F, x, 0.0, xp);
611 matmul(
"NN", nx, nx, nx, 1.0, F, P, 0.0, FP);
612 matmul(
"NT", nx, nx, nx, 1.0, FP, F, 0.0, P);
614 for (i = 0; i < nx; i++) {
615 rtk->
x[ix[i]] = xp[i];
616 for (j = 0; j < nx; j++) {
617 rtk->
P[ix[i] + ix[j] * rtk->
nx] = P[i + j * nx];
621 Q[0] = Q[4] =
SQR(rtk->
opt.
prn[3]) * fabs(tt);
625 for (i = 0; i < 3; i++) {
626 for (j = 0; j < 3; j++) {
627 rtk->
P[i + 6 + (j + 6) * rtk->
nx] += Qv[i + j * 3];
638static void udion(
rtk_t* rtk,
double tt,
double bl,
const int* sat,
int ns) {
642 trace(NULL, 3,
"udion : tt=%.3f bl=%.0f ns=%d\n", tt, bl, ns);
644 for (i = 1; i <=
MAXSAT; i++) {
645 j =
II(i, &rtk->
opt);
650 for (i = 0; i < ns; i++) {
651 j =
II(sat[i], &rtk->
opt);
653 if (rtk->
x[j] == 0.0) {
659 rtk->
P[j + j * rtk->
nx] +=
SQR(rtk->
opt.
prn[1] * bl / 1E4 * fact) * fabs(tt);
667 trace(NULL, 3,
"udtrop : tt=%.3f\n", tt);
669 for (i = 0; i < 2; i++) {
670 j =
IT(i, &rtk->
opt);
672 if (rtk->
x[j] == 0.0) {
676 for (k = 0; k < 2; k++) {
681 rtk->
P[j + j * rtk->
nx] +=
SQR(rtk->
opt.
prn[2]) * fabs(tt);
684 for (k = 0; k < 2; k++) {
685 rtk->
P[++j * (1 + rtk->
nx)] +=
SQR(rtk->
opt.
prn[2] * 0.3) * fabs(tt);
695 trace(NULL, 3,
"udrcvbias: tt=%.3f\n", tt);
698 j =
IL(i, &rtk->
opt);
700 if (rtk->
x[j] == 0.0) {
705 initx(rtk, rtk->
xa[j], rtk->
Pa[j + j * rtk->
na], j);
714 int f, sat = obs[i].
sat, nf = rtk->
opt.
nf < NFREQ ? rtk->
opt.
nf : NFREQ;
715 for (f = 0; f < nf; f++) {
716 uint8_t code = obs[i].
code[f];
720 uint8_t ccode = rtk->
ssat[sat - 1].
codeprev[f][rcv - 1];
727 "slip detected code change (sat=%2d rcv=%d F=%d "
737 int f, sat = obs[i].
sat;
739 trace(NULL, 3,
"detslp_ll: i=%d rcv=%d\n", i, rcv);
741 for (f = 0; f < rtk->
opt.
nf; f++) {
742 if (obs[i].L[f] == 0.0 || fabs(
timediff(obs[i].time, rtk->
ssat[sat - 1].
pt[rcv - 1][f])) <
DTTOL) {
753 if (rtk->
tt >= 0.0) {
754 if (obs[i].LLI[f] & 1) {
755 errmsg(rtk,
"slip detected forward (sat=%2d rcv=%d F=%d LLI=%x)\n", sat, rcv, f + 1, obs[i].LLI[f]);
757 slip = obs[i].
LLI[f];
760 errmsg(rtk,
"slip detected backward (sat=%2d rcv=%d F=%d LLI=%x)\n", sat, rcv, f + 1, LLI);
765 if (((LLI & 2) && !(obs[i].LLI[f] & 2)) || (!(LLI & 2) && (obs[i].LLI[f] & 2))) {
766 errmsg(rtk,
"slip detected half-cyc (sat=%2d rcv=%d F=%d LLI=%x->%x)\n", sat, rcv, f + 1, LLI,
778 rtk->
ssat[sat - 1].
slip[f] |= (uint8_t)slip;
779 rtk->
ssat[sat - 1].
half[f] = (obs[i].
LLI[f] & 2) ? 0 : 1;
784 int k, sat = obs[i].
sat;
787 trace(NULL, 3,
"detslp_gf: i=%d j=%d\n", i, j);
793 for (k = 0; k < rtk->
opt.
nf; k++) {
794 if (rtk->
ssat[sat - 1].
slip[k] & 1) {
799 for (k = 1; k < rtk->
opt.
nf; k++) {
800 if ((g1 =
gfobs(obs, i, j, k, nav)) == 0.0) {
804 g0 = rtk->
ssat[sat - 1].
gf[k - 1];
805 rtk->
ssat[sat - 1].
gf[k - 1] = g1;
810 errmsg(rtk,
"slip detected GF jump (sat=%2d L1-L%d GF=%.3f %.3f)\n", sat, k + 1, g0, g1);
821 int i, ii, f, sat, ndop = 0, nf =
MIN(rtk->
opt.
nf, NFREQ);
822 double dph, dpt, mean_dop = 0.0;
825 trace(NULL, 4,
"detslp_dop: rcv=%d\n", rcv);
832 for (i = 0; i < ns; i++) {
835 for (f = 0; f < nf; f++) {
838 if (obs[ii].L[f] == 0.0 || obs[ii].D[f] == 0.0 || rtk->
ssat[sat - 1].
ph[rcv - 1][f] == 0.0) {
844 dph = (obs[ii].
L[f] - rtk->
ssat[sat - 1].
ph[rcv - 1][f]) / tt[i][f];
846 dopdif[i][f] = dph - dpt;
848 if (fabs(dopdif[i][f]) < 3.0 * rtk->
opt.
thresdop) {
849 mean_dop += dopdif[i][f];
860 for (i = 0; i < ns; i++) {
861 sat = obs[ix[i]].
sat;
862 for (f = 0; f < nf; f++) {
863 if (dopdif[i][f] == 0.0) {
866 if (fabs(dopdif[i][f] - mean_dop) > rtk->
opt.
thresdop) {
869 "slip detected doppler (sat=%2d rcv=%d dL%d=%.3f "
870 "off=%.3f tt=%.2f)\n",
871 sat, rcv, f + 1, dopdif[i][f] - mean_dop, mean_dop, tt[i][f]);
877static void udbias(
rtk_t* rtk,
double tt,
const obsd_t* obs,
const int* sat,
const int* iu,
const int* ir,
int ns,
879 double cp, pr, cp1, cp2, pr1, pr2, *bias, offset, freqi, freq1, freq2, C1, C2;
880 int i, j, k, slip, rejc, reset, nf =
NF(&rtk->
opt);
882 trace(NULL, 3,
"udbias : tt=%.3f ns=%d\n", tt, ns);
885 for (i = 0; i < ns; i++) {
886 for (k = 0; k < rtk->
opt.
nf; k++) {
887 rtk->
ssat[sat[i] - 1].
slip[k] &= 0xFC;
895 for (i = 0; i < ns; i++) {
908 for (k = 0; k < nf; k++) {
909 rtk->
ssat[sat[i] - 1].
half[k] = !((obs[iu[i]].
LLI[k] & 2) || (obs[ir[i]].
LLI[k] & 2));
912 for (k = 0; k < nf; k++) {
914 for (i = 1; i <=
MAXSAT; i++) {
919 }
else if (reset && rtk->
x[
IB(i, k, &rtk->
opt)] != 0.0) {
921 trace(NULL, 3,
"udbias : obs outage counter overflow (sat=%3d L%d n=%d)\n", i, k + 1,
930 for (i = 0; i < ns; i++) {
931 j =
IB(sat[i], k, &rtk->
opt);
932 rtk->
P[j + j * rtk->
nx] += rtk->
opt.
prn[0] * rtk->
opt.
prn[0] * fabs(tt);
933 slip = rtk->
ssat[sat[i] - 1].
slip[k];
936 slip |= rtk->
ssat[sat[i] - 1].
slip[f2i];
938 rejc = rtk->
ssat[sat[i] - 1].
rejc[k];
949 for (i = j = 0, offset = 0.0; i < ns; i++) {
951 cp =
sdobs(obs, iu[i], ir[i], k);
952 pr =
sdobs(obs, iu[i], ir[i], k + NFREQ);
953 freqi =
sat2freq(sat[i], obs[iu[i]].code[k], nav);
954 if (cp == 0.0 || pr == 0.0 || freqi == 0.0) {
958 bias[i] = cp - pr * freqi /
CLIGHT;
961 cp1 =
sdobs(obs, iu[i], ir[i], 0);
962 cp2 =
sdobs(obs, iu[i], ir[i], f2b);
963 pr1 =
sdobs(obs, iu[i], ir[i], NFREQ);
964 pr2 =
sdobs(obs, iu[i], ir[i], NFREQ + f2b);
965 freq1 =
sat2freq(sat[i], obs[iu[i]].code[0], nav);
966 freq2 =
sat2freq(sat[i], obs[iu[i]].code[f2b], nav);
967 if (cp1 == 0.0 || cp2 == 0.0 || pr1 == 0.0 || pr2 == 0.0 || freq1 == 0.0 || freq2 <= 0.0) {
971 C1 =
SQR(freq1) / (
SQR(freq1) -
SQR(freq2));
972 C2 = -
SQR(freq2) / (
SQR(freq1) -
SQR(freq2));
973 bias[i] = (C1 * cp1 *
CLIGHT / freq1 + C2 * cp2 *
CLIGHT / freq2) - (C1 * pr1 + C2 * pr2);
975 if (rtk->
x[
IB(sat[i], k, &rtk->
opt)] != 0.0) {
976 offset += bias[i] - rtk->
x[
IB(sat[i], k, &rtk->
opt)];
982 for (i = 1; i <=
MAXSAT; i++) {
983 if (rtk->
x[
IB(i, k, &rtk->
opt)] != 0.0) {
984 rtk->
x[
IB(i, k, &rtk->
opt)] += offset / j;
989 for (i = 0; i < ns; i++) {
990 if (bias[i] == 0.0 || rtk->
x[
IB(sat[i], k, &rtk->
opt)] != 0.0) {
999static void udstate(
rtk_t* rtk,
const obsd_t* obs,
const int* sat,
const int* iu,
const int* ir,
int ns,
1001 double tt = rtk->
tt, bl, dr[3];
1003 trace(NULL, 3,
"udstate : ns=%d\n", ns);
1011 udion(rtk, tt, bl, sat, ns);
1023 udbias(rtk, tt, obs, sat, iu, ir, ns, nav);
1027static void zdres_sat(
int base,
double r,
const obsd_t* obs,
const nav_t* nav,
const double* azel,
const double* dant,
1028 const prcopt_t* opt,
double* y,
double* freq) {
1029 double freq1, freq2, C1, C2, dant_if;
1030 int i, nf =
NF(opt), f2;
1036 if (freq1 == 0.0 || freq2 == 0.0) {
1045 C1 =
SQR(freq1) / (
SQR(freq1) -
SQR(freq2));
1046 C2 = -
SQR(freq2) / (
SQR(freq1) -
SQR(freq2));
1047 dant_if = C1 * dant[0] + C2 * dant[f2];
1049 if (obs->
L[0] != 0.0 && obs->
L[f2] != 0.0) {
1050 y[0] = C1 * obs->
L[0] *
CLIGHT / freq1 + C2 * obs->
L[f2] *
CLIGHT / freq2 - r - dant_if;
1052 if (obs->
P[0] != 0.0 && obs->
P[f2] != 0.0) {
1053 y[1] = C1 * obs->
P[0] + C2 * obs->
P[f2] - r - dant_if;
1057 for (i = 0; i < nf; i++) {
1067 if (obs->
L[i] != 0.0) {
1068 y[i] = obs->
L[i] *
CLIGHT / freq[i] - r - dant[i];
1070 if (obs->
P[i] != 0.0) {
1071 y[i + nf] = obs->
P[i] - r - dant[i];
1077static int zdres(
int base,
const obsd_t* obs,
int n,
const double* rs,
const double* dts,
const double* var,
1078 const int* svh,
const nav_t* nav,
const double* rr,
const prcopt_t* opt,
int index,
double* y,
1079 double* e,
double* azel,
double* freq) {
1080 double r, rr_[3], pos[3], dant[
NFREQPCV] = {0}, disp[3];
1081 double zhd, zazel[] = {0.0, 90.0 *
D2R};
1082 int i, nf =
NF(opt);
1084 trace(NULL, 3,
"zdres : n=%d\n", n);
1086 for (i = 0; i < n * nf * 2; i++) {
1090 if (
norm(rr, 3) <= 0.0) {
1094 for (i = 0; i < 3; i++) {
1101 for (i = 0; i < 3; i++) {
1107 for (i = 0; i < n; i++) {
1109 if ((r =
geodist(rs + i * 6, rr_, e + i * 3)) <= 0.0) {
1112 if (
satazel(pos, e + i * 3, azel + i * 2) < opt->
elmin) {
1122 if (
satexclude(obs[i].sat, var[i], svh[i], opt)) {
1127 r += -
CLIGHT * dts[i * 2];
1130 zhd =
tropmodel(obs[0].time, pos, zazel, 0.0);
1131 r +=
tropmapf(obs[i].time, pos, azel + i * 2, NULL) * zhd;
1137 zdres_sat(base, r, obs + i, nav, azel + i * 2, dant, opt, y + i * nf * 2, freq + i * nf);
1139 trace(NULL, 4,
"rr_=%.3f %.3f %.3f\n", rr_[0], rr_[1], rr_[2]);
1140 trace(NULL, 4,
"pos=%.9f %.9f %.3f\n", pos[0] *
R2D, pos[1] *
R2D, pos[2]);
1141 for (i = 0; i < n; i++) {
1142 trace(NULL, 4,
"sat=%2d %13.3f %13.3f %13.3f %13.10f %6.1f %5.1f\n", obs[i].sat, rs[i * 6], rs[1 + i * 6],
1143 rs[2 + i * 6], dts[i * 2], azel[i * 2] *
R2D, azel[1 + i * 2] *
R2D);
1145 trace(NULL, 4,
"y=\n");
1146 tracemat(NULL, 4, y, nf * 2, n, 13, 3);
1151static int validobs(
int i,
int j,
int f,
int nf,
double* y) {
1153 return y[f + i * nf * 2] != 0.0 && y[f + j * nf * 2] != 0.0 &&
1154 (f < nf || (y[f - nf + i * nf * 2] != 0.0 && y[f - nf + j * nf * 2] != 0.0));
1157static void ddcov(
const int* nb,
int n,
const double* Ri,
const double* Rj,
int nv,
double* R) {
1160 trace(NULL, 3,
"ddcov : n=%d\n", n);
1162 for (i = 0; i < nv * nv; i++) {
1165 for (b = 0; b < n; k += nb[b++]) {
1166 for (i = 0; i < nb[b]; i++) {
1167 for (j = 0; j < nb[b]; j++) {
1168 R[k + i + (k + j) * nv] = Ri[k + i] + (i == j ? Rj[k + i] : 0.0);
1172 trace(NULL, 5,
"R=\n");
1173 tracemat(NULL, 5, R, nv, nv, 8, 6);
1176static int constbl(
rtk_t* rtk,
const double* x,
const double* P,
double* v,
double* H,
double* Ri,
double* Rj,
1178 const double thres = 0.1;
1179 double xb[3], b[3], bb, var = 0.0;
1182 trace(NULL, 3,
"constbl : \n");
1190 for (i = 0; i < 3; i++) {
1192 b[i] = x[i] - xb[i];
1198 for (i = 0; i < 3; i++) {
1199 var += P[i + i * rtk->
nx];
1204 if (var >
SQR(thres * bb)) {
1205 trace(NULL, 3,
"constbl : equation nonlinear (bb=%.3f var=%.3f)\n", bb, var);
1211 for (i = 0; i < 3; i++) {
1212 H[i + index * rtk->
nx] = b[i] / bb;
1218 trace(NULL, 4,
"baseline len v=%13.3f R=%8.6f %8.6f\n", v[index], Ri[index], Rj[index]);
1225 double m_w = 0.0, cotz, grad_n, grad_e;
1233 cotz = 1.0 / tan(azel[1]);
1234 grad_n = m_w * cotz * cos(azel[0]);
1235 grad_e = m_w * cotz * sin(azel[0]);
1236 m_w += grad_n * x[i + 1] + grad_e * x[i + 2];
1237 dtdx[1] = grad_n * x[i];
1238 dtdx[2] = grad_e * x[i];
1240 dtdx[1] = dtdx[2] = 0.0;
1267 const int* sat,
double* y,
double* e,
double* azel,
double* freq,
const int* iu,
const int* ir,
int ns,
1268 double* v,
double* H,
double* R,
int* vflg) {
1270 double bl, dr[3], posu[3], posr[3], didxi = 0.0, didxj = 0.0, *im;
1271 double *tropr, *tropu, *dtdxr, *dtdxu, *Ri, *Rj, freqi, freqj, *Hi = NULL;
1272 int i, j, k, m, f, nv = 0, nb[NFREQ * 4 * 2 + 2] = {0}, b = 0, sysi, sysj, nf =
NF(opt);
1274 trace(NULL, 3,
"ddres : dt=%.1f nx=%d ns=%d\n", dt, rtk->
nx, ns);
1280 Ri =
mat(ns * nf * 2 + 2, 1);
1281 Rj =
mat(ns * nf * 2 + 2, 1);
1288 for (i = 0; i <
MAXSAT; i++) {
1289 for (j = 0; j < NFREQ; j++) {
1294 for (i = 0; i < ns; i++) {
1296 im[i] = (
ionmapf(posu, azel + iu[i] * 2) +
ionmapf(posr, azel + ir[i] * 2)) / 2.0;
1299 tropu[i] =
prectrop(rtk->
sol.
time, posu, 0, azel + iu[i] * 2, opt, x, dtdxu + i * 3);
1300 tropr[i] =
prectrop(rtk->
sol.
time, posr, 1, azel + ir[i] * 2, opt, x, dtdxr + i * 3);
1303 for (m = 0; m < 6; m++) {
1307 for (i = -1, j = 0; j < ns; j++) {
1308 sysi = rtk->
ssat[sat[j] - 1].
sys;
1312 if (!
validobs(iu[j], ir[j], f, nf, y)) {
1315 if (i < 0 || azel[1 + iu[j] * 2] >= azel[1 + iu[i] * 2]) {
1324 for (j = 0; j < ns; j++) {
1328 sysi = rtk->
ssat[sat[i] - 1].
sys;
1329 sysj = rtk->
ssat[sat[j] - 1].
sys;
1330 freqi = freq[f % nf + iu[i] * nf];
1331 freqj = freq[f % nf + iu[j] * nf];
1335 if (!
validobs(iu[j], ir[j], f, nf, y)) {
1340 Hi = H + nv * rtk->
nx;
1341 for (k = 0; k < rtk->
nx; k++) {
1347 (y[f + iu[i] * nf * 2] - y[f + ir[i] * nf * 2]) - (y[f + iu[j] * nf * 2] - y[f + ir[j] * nf * 2]);
1351 for (k = 0; k < 3; k++) {
1352 Hi[k] = -e[k + iu[i] * 3] + e[k + iu[j] * 3];
1357 didxi = (f < nf ? -1.0 : 1.0) * im[i] *
SQR(
FREQ1 / freqi);
1358 didxj = (f < nf ? -1.0 : 1.0) * im[j] *
SQR(
FREQ1 / freqj);
1359 v[nv] -= didxi * x[
II(sat[i], opt)] - didxj * x[
II(sat[j], opt)];
1361 Hi[
II(sat[i], opt)] = didxi;
1362 Hi[
II(sat[j], opt)] = -didxj;
1367 v[nv] -= (tropu[i] - tropu[j]) - (tropr[i] - tropr[j]);
1372 Hi[
IT(0, opt) + k] = (dtdxu[k + i * 3] - dtdxu[k + j * 3]);
1373 Hi[
IT(1, opt) + k] = -(dtdxr[k + i * 3] - dtdxr[k + j * 3]);
1379 v[nv] -=
CLIGHT / freqi * x[
IB(sat[i], f, opt)] -
CLIGHT / freqj * x[
IB(sat[j], f, opt)];
1381 Hi[
IB(sat[i], f, opt)] =
CLIGHT / freqi;
1382 Hi[
IB(sat[j], f, opt)] = -
CLIGHT / freqj;
1385 v[nv] -= x[
IB(sat[i], f, opt)] - x[
IB(sat[j], f, opt)];
1387 Hi[
IB(sat[i], f, opt)] = 1.0;
1388 Hi[
IB(sat[j], f, opt)] = -1.0;
1393 rtk->
ssat[sat[j] - 1].
resc[f] = v[nv];
1395 rtk->
ssat[sat[j] - 1].
resp[f - nf] = v[nv];
1401 double threshadj = 1.0;
1403 int ii =
IB(sat[i], f, opt), jj =
IB(sat[j], f, opt);
1404 if (P[ii + rtk->
nx * ii] ==
SQR(opt->
std[0]) || P[jj + rtk->
nx * jj] ==
SQR(opt->
std[0])) {
1408 if (fabs(v[nv]) > opt->
maxinno * threshadj) {
1414 errmsg(rtk,
"outlier rejected (sat=%3d-%3d %s%d v=%.3f)\n", sat[i], sat[j], f < nf ?
"L" :
"P",
1421 int frq = f % nf, code = (f < nf) ? 0 : 1;
1422 Ri[nv] =
varerr(sat[i], sysi, azel[1 + iu[i] * 2], obs[iu[i]].SNR[frq] *
SNR_UNIT,
1423 obs[ir[i]].SNR[frq] *
SNR_UNIT, bl, dt, f, opt);
1424 Rj[nv] =
varerr(sat[j], sysj, azel[1 + iu[j] * 2], obs[iu[j]].SNR[frq] *
SNR_UNIT,
1425 obs[ir[j]].SNR[frq] *
SNR_UNIT, bl, dt, f, opt);
1427 if (!code && (obs[iu[i]].LLI[frq] &
LLI_HALFC)) {
1430 if (!code && (obs[iu[j]].LLI[frq] &
LLI_HALFC)) {
1440 trace(NULL, 4,
"sat=%3d-%3d %s%d v=%13.3f R=%8.6f %8.6f\n", sat[i], sat[j], f < nf ?
"L" :
"P",
1441 f % nf + 1, v[nv], Ri[nv], Rj[nv]);
1443 vflg[nv++] = (sat[i] << 16) | (sat[j] << 8) | ((f < nf ? 0 : 1) << 4) | (f % nf);
1453 vflg[nv++] = 3 << 4;
1457 trace(NULL, 5,
"H=\n");
1462 ddcov(nb, b, Ri, Rj, nv, R);
1479 static int nb = 0, svh[
MAXOBS * 2];
1481 double tt =
timediff(time, obs[0].time), ttb, *p, *q;
1482 int i, j, k, nf =
NF(opt);
1484 trace(NULL, 3,
"intpres : n=%d tt=%.1f\n", n, tt);
1486 if (nb == 0 || fabs(tt) <
DTTOL) {
1488 for (i = 0; i < n; i++) {
1493 ttb =
timediff(time, obsb[0].time);
1494 if (fabs(ttb) > opt->
maxtdiff * 2.0 || ttb == tt) {
1498 satposs(time, obsb, nb, nav, opt->
sateph, rs, dts, var, svh);
1500 if (!
zdres(1, obsb, nb, rs, dts, var, svh, nav, rtk->
rb, opt, 1, yb, e, azel, freq)) {
1503 for (i = 0; i < n; i++) {
1504 for (j = 0; j < nb; j++) {
1505 if (obsb[j].sat == obs[i].sat) {
1512 for (k = 0, p = y + i * nf * 2, q = yb + j * nf * 2; k < nf * 2; k++, p++, q++) {
1513 if (*p == 0.0 || *q == 0.0) {
1516 *p = (ttb * (*p) - tt * (*q)) / (ttb - tt);
1520 return fabs(ttb) > fabs(tt) ? ttb : tt;
1523static int ddidx(
rtk_t* rtk,
int* ix,
int gps,
int glo,
int sbs) {
1524 int i, j, k, m, f, n, nb = 0, na = rtk->
na, nf =
NF(&rtk->
opt), nofix;
1526 trace(NULL, 3,
"ddidx : gps=%d glo=%d sbs=%d\n", gps, glo, sbs);
1529 for (i = 0; i <
MAXSAT; i++) {
1530 for (j = 0; j < NFREQ; j++) {
1534 for (m = 0; m < 6; m++) {
1537 nofix = (m == 0 && gps == 0) || (m == 1 && glo == 0) || (m == 3 && rtk->
opt.
bdsmodear == 0);
1539 for (f = 0, k = na; f < nf; f++, k +=
MAXSAT) {
1542 for (i = k; i < k +
MAXSAT; i++) {
1560 for (n = 0, j = k; j < k +
MAXSAT; j++) {
1589 int i, n, m, f, index[
MAXSAT], nv = 0, nf =
NF(&rtk->
opt);
1591 trace(NULL, 3,
"restamb :\n");
1593 for (i = 0; i < rtk->
nx; i++) {
1596 for (i = 0; i < rtk->
na; i++) {
1600 for (m = 0; m < 5; m++) {
1601 for (f = 0; f < nf; f++) {
1602 for (n = i = 0; i <
MAXSAT; i++) {
1606 index[n++] =
IB(i + 1, f, &rtk->
opt);
1612 xa[index[0]] = rtk->
x[index[0]];
1614 for (i = 1; i < n; i++) {
1615 xa[index[i]] = xa[index[0]] - bias[nv++];
1623 int i, n, m, f, info, index[
MAXSAT], nb = rtk->
nx - rtk->
na, nv = 0, nf =
NF(&rtk->
opt);
1625 trace(NULL, 3,
"holdamb :\n");
1630 for (m = 0; m < 6; m++) {
1631 for (f = 0; f < nf; f++) {
1632 for (n = i = 0; i <
MAXSAT; i++) {
1637 index[n++] =
IB(i + 1, f, &rtk->
opt);
1641 for (i = 1; i < n; i++) {
1642 v[nv] = (xa[index[0]] - xa[index[i]]) - (rtk->
x[index[0]] - rtk->
x[index[i]]);
1644 H[index[0] + nv * rtk->
nx] = 1.0;
1645 H[index[i] + nv * rtk->
nx] = -1.0;
1652 trace(NULL, 3,
"holdamb: not enough sats to hold ambiguity (nv=%d)\n", nv);
1661 for (i = 0; i < nv; i++) {
1666 if ((info =
filter(rtk->
x, rtk->
P, H, v, R, rtk->
nx, nv))) {
1667 errmsg(rtk,
"filter error (info=%d)\n", info);
1677 int i, j, nb, info, nx = rtk->
nx, na = rtk->
na;
1678 double *DP, *y, *b, *db, *Qb, *Qab, *QQ, s[2];
1681 trace(NULL, 3,
"resamb_LAMBDA : nx=%d\n", nx);
1689 errmsg(rtk,
"not enough valid double-differences\n");
1696 DP =
mat(nb, nx - na);
1704 for (i = 0; i < nb; i++) {
1705 y[i] = rtk->
x[ix[i * 2]] - rtk->
x[ix[i * 2 + 1]];
1707 for (j = 0; j < nx - na; j++) {
1708 for (i = 0; i < nb; i++) {
1709 DP[i + j * nb] = rtk->
P[ix[i * 2] + (na + j) * nx] - rtk->
P[ix[i * 2 + 1] + (na + j) * nx];
1712 for (j = 0; j < nb; j++) {
1713 for (i = 0; i < nb; i++) {
1714 Qb[i + j * nb] = DP[i + (ix[j * 2] - na) * nb] - DP[i + (ix[j * 2 + 1] - na) * nb];
1717 for (j = 0; j < nb; j++) {
1718 for (i = 0; i < na; i++) {
1719 Qab[i + j * na] = rtk->
P[i + ix[j * 2] * nx] - rtk->
P[i + ix[j * 2 + 1] * nx];
1723 if (!(info =
lambda(nb, 2, y, Qb, b, s))) {
1724 trace(NULL, 4,
"N(1)=");
1725 tracemat(NULL, 4, b, 1, nb, 10, 3);
1726 trace(NULL, 4,
"N(2)=");
1727 tracemat(NULL, 4, b + nb, 1, nb, 10, 3);
1729 rtk->
sol.
ratio = s[0] > 0 ? (float)(s[1] / s[0]) : 0.0f;
1736 int nb1 = nb < 50 ? nb : 50;
1739 for (
int ki = 0; ki < 3; ki++) {
1741 for (
int kj = 1; kj < 5; kj++) {
1747 for (
int ki = 1; ki < 3; ki++) {
1748 rtk->
sol.
thres = rtk->
sol.
thres * 1.0f / (float)(nb1 + 1) + (float)coeff[ki];
1762 if (s[0] <= 0.0 || s[1] / s[0] >= rtk->
sol.
thres) {
1764 for (i = 0; i < na; i++) {
1765 rtk->
xa[i] = rtk->
x[i];
1766 for (j = 0; j < na; j++) {
1767 rtk->
Pa[i + j * na] = rtk->
P[i + j * nx];
1770 for (i = 0; i < nb; i++) {
1775 matmul(
"NN", nb, 1, nb, 1.0, Qb, y, 0.0, db);
1776 matmul(
"NN", na, 1, nb, -1.0, Qab, db, 1.0, rtk->
xa);
1779 matmul(
"NN", na, nb, nb, 1.0, Qab, Qb, 0.0, QQ);
1780 matmul(
"NT", na, na, nb, -1.0, QQ, Qab, 1.0, rtk->
Pa);
1782 trace(NULL, 3,
"resamb : validation ok (nb=%d ratio=%.2f thresh=%.2f s=%.2f/%.2f)\n", nb,
1783 s[0] == 0.0 ? 0.0 : s[1] / s[0], rtk->
sol.
thres, s[0], s[1]);
1791 errmsg(rtk,
"ambiguity validation failed (nb=%d ratio=%.2f thresh=%.2f s=%.2f/%.2f)\n", nb, s[1] / s[0],
1796 errmsg(rtk,
"lambda error (info=%d)\n", info);
1812 int gps1 = -1, glo1 = -1, sbas1 = -1, gps2, glo2, sbas2, nb, rerun, dly;
1813 float ratio1, posvar = 0.0f;
1816 for (
int i = 0; i < 3; i++) {
1817 posvar += rtk->
P[i + i * rtk->
nx];
1821 trace(NULL, 3,
"manage_amb_LAMBDA: posvar=%.6f prevR=%.3f/%.3f nb_ar=%d\n", posvar, rtk->
sol.
prev_ratio1,
1827 trace(NULL, 3,
"manage_amb_LAMBDA: skip AR\n");
1835 int lockc[NFREQ], excsat = 0;
1840 for (; i < ns; i++) {
1841 if (rtk->
excsat == sat[i]) {
1851 for (; i < ns; i++) {
1852 for (
int f = 0; f < nf; f++) {
1864 for (
int f = 0; f < nf; f++) {
1865 lockc[f] = rtk->
ssat[excsat - 1].
lock[f];
1869 trace(NULL, 3,
"manage_amb_LAMBDA: exclude sat %d\n", excsat);
1888 trace(NULL, 3,
"manage_amb_LAMBDA: low ratio, check new sats\n");
1890 for (
int i = 0; i < ns; i++) {
1891 for (
int f = 0; f < nf; f++) {
1892 if (rtk->
ssat[sat[i] - 1].
fix[f] != 2) {
1895 if (rtk->
ssat[sat[i] - 1].
lock[f] == 0) {
1896 trace(NULL, 3,
"manage_amb_LAMBDA: remove sat %d:%d\n", sat[i], f);
1905 trace(NULL, 3,
"manage_amb_LAMBDA: rerun with new sats removed\n");
1916 if (glo1 != glo2 || gps1 != gps2) {
1923 for (
int f = 0; f < nf; f++) {
1924 rtk->
ssat[excsat - 1].
lock[f] = lockc[f];
1926 trace(NULL, 3,
"manage_amb_LAMBDA: restore sat %d\n", excsat);
1935static int valpos(
rtk_t* rtk,
const double* v,
const double* R,
const int* vflg,
int nv,
double thres) {
1936 double fact = thres * thres;
1937 int i, stat = 1, sat1, sat2, type, freq;
1940 trace(NULL, 3,
"valpos : nv=%d thres=%.1f\n", nv, thres);
1943 for (i = 0; i < nv; i++) {
1944 if (v[i] * v[i] <= fact * R[i + i * nv]) {
1947 sat1 = (vflg[i] >> 16) & 0xFF;
1948 sat2 = (vflg[i] >> 8) & 0xFF;
1949 type = (vflg[i] >> 4) & 0xF;
1950 freq = vflg[i] & 0xF;
1951 stype = type == 0 ?
"L" : (type == 1 ?
"L" :
"C");
1952 errmsg(rtk,
"large residual (sat=%2d-%2d %s%d v=%6.3f sig=%.3f)\n", sat1, sat2, stype, freq + 1, v[i],
1953 SQRT(R[i + i * nv]));
1961 double *rs, *dts, *var, *y, *e, *azel, *freq, *v, *H, *R, *xp, *Pp, *xa, *bias, dt;
1962 int i, j, f, n = nu + nr, ns, ny, nv, sat[
MAXSAT], iu[
MAXSAT], ir[
MAXSAT], niter;
1963 int info, vflg[
MAXOBS * NFREQ * 2 + 1], svh[
MAXOBS * 2];
1967 trace(NULL, 3,
"relpos : nx=%d nu=%d nr=%d\n", rtk->
nx, nu, nr);
1977 freq =
zeros(nf, n);
1979 for (i = 0; i <
MAXSAT; i++) {
1981 for (j = 0; j < NFREQ; j++) {
1984 for (j = 1; j < NFREQ; j++) {
1992 if (!
zdres(1, obs + nu, nr, rs + nu * 6, dts + nu * 2, var + nu, svh + nu, nav, rtk->
rb, opt, 1, y + nu * nf * 2,
1993 e + nu * 3, azel + nu * 2, freq + nu * nf)) {
1994 errmsg(rtk,
"initial base station position error\n");
2007 dt =
intpres(time, obs + nu, nr, nav, rtk, y + nu * nf * 2);
2010 if ((ns =
selsat(obs, azel, nu, nr, opt, sat, iu, ir)) <= 0) {
2011 errmsg(rtk,
"no common satellite\n");
2023 udstate(rtk, obs, sat, iu, ir, ns, nav);
2025 trace(NULL, 4,
"x(0)=");
2028 xp =
mat(rtk->
nx, 1);
2030 xa =
mat(rtk->
nx, 1);
2033 ny = ns * nf * 2 + 2;
2037 bias =
mat(rtk->
nx, 1);
2042 for (i = 0; i < niter; i++) {
2044 if (!
zdres(0, obs, nu, rs, dts, var, svh, nav, xp, opt, 0, y, e, azel, freq)) {
2045 errmsg(rtk,
"rover initial position error\n");
2050 if ((nv =
ddres(rtk, nav, obs, dt, xp, Pp, sat, y, e, azel, freq, iu, ir, ns, v, H, R, vflg)) < 4) {
2051 errmsg(rtk,
"insufficient double-differenced residuals (%d)\n", nv);
2057 if ((info =
filter(xp, Pp, H, v, R, rtk->
nx, nv))) {
2058 errmsg(rtk,
"filter error (info=%d)\n", info);
2062 trace(NULL, 4,
"x(%d)=", i + 1);
2065 if (stat !=
SOLQ_NONE &&
zdres(0, obs, nu, rs, dts, var, svh, nav, xp, opt, 0, y, e, azel, freq)) {
2067 nv =
ddres(rtk, nav, obs, dt, xp, Pp, sat, y, e, azel, freq, iu, ir, ns, v, NULL, R, vflg);
2070 if (
valpos(rtk, v, R, vflg, nv, 4.0)) {
2077 for (i = 0; i < ns; i++) {
2078 for (f = 0; f < nf; f++) {
2079 if (!rtk->
ssat[sat[i] - 1].
vsat[f]) {
2093 if (rtk->
sol.
ns < 4) {
2102 if (
zdres(0, obs, nu, rs, dts, var, svh, nav, xa, opt, 0, y, e, azel, freq)) {
2104 nv =
ddres(rtk, nav, obs, dt, xa, NULL, sat, y, e, azel, freq, iu, ir, ns, v, NULL, R, vflg);
2107 if (
valpos(rtk, v, R, vflg, nv, 4.0)) {
2118 for (i = 0; i < 3; i++) {
2120 rtk->
sol.
qr[i] = (float)rtk->
Pa[i + i * rtk->
na];
2122 rtk->
sol.
qr[3] = (float)rtk->
Pa[1];
2123 rtk->
sol.
qr[4] = (float)rtk->
Pa[1 + 2 * rtk->
na];
2124 rtk->
sol.
qr[5] = (float)rtk->
Pa[2];
2127 for (i = 3; i < 6; i++) {
2129 rtk->
sol.
qv[i - 3] = (float)rtk->
Pa[i + i * rtk->
na];
2131 rtk->
sol.
qv[3] = (float)rtk->
Pa[4 + 3 * rtk->
na];
2132 rtk->
sol.
qv[4] = (float)rtk->
Pa[5 + 4 * rtk->
na];
2133 rtk->
sol.
qv[5] = (float)rtk->
Pa[5 + 3 * rtk->
na];
2136 for (i = 0; i < 3; i++) {
2137 rtk->
sol.
rr[i] = rtk->
x[i];
2138 rtk->
sol.
qr[i] = (float)rtk->
P[i + i * rtk->
nx];
2140 rtk->
sol.
qr[3] = (float)rtk->
P[1];
2141 rtk->
sol.
qr[4] = (float)rtk->
P[1 + 2 * rtk->
nx];
2142 rtk->
sol.
qr[5] = (float)rtk->
P[2];
2145 for (i = 3; i < 6; i++) {
2146 rtk->
sol.
rr[i] = rtk->
x[i];
2147 rtk->
sol.
qv[i - 3] = (float)rtk->
P[i + i * rtk->
nx];
2149 rtk->
sol.
qv[3] = (float)rtk->
P[4 + 3 * rtk->
nx];
2150 rtk->
sol.
qv[4] = (float)rtk->
P[5 + 4 * rtk->
nx];
2151 rtk->
sol.
qv[5] = (float)rtk->
P[5 + 3 * rtk->
nx];
2155 for (i = 0; i < n; i++) {
2156 for (j = 0; j < nf; j++) {
2157 if (obs[i].L[j] == 0.0) {
2161 rtk->
ssat[obs[i].
sat - 1].
ph[obs[i].
rcv - 1][j] = obs[i].
L[j];
2164 for (i = 0; i < ns; i++) {
2165 for (j = 0; j < nf; j++) {
2167 rtk->
ssat[sat[i] - 1].
snr[j] = obs[iu[i]].
SNR[j];
2170 for (i = 0; i <
MAXSAT; i++) {
2171 for (j = 0; j < nf; j++) {
2212 trace(NULL, 3,
"rtkinit :\n");
2215 for (i = 0; i < 6; i++) {
2235 for (i = 0; i <
MAXSAT; i++) {
2236 rtk->
ambc[i] = ambc0;
2237 rtk->
ssat[i] = ssat0;
2242 for (i = 0; i < 6; i++) {
2262 trace(NULL, 3,
"rtkfree :\n");
2264 rtk->
nx = rtk->
na = 0;
2279 int i, j, sys, udcnt = 0, ssrcode =
CODE_NONE;
2284 for (i = 0; i <
MAXSAT; i++) {
2286 if ((p = strstr(popt->
rtcmopt,
"-RTCM_CB_VALID=")) && sscanf(p,
"-RTCM_CB_VALID=%lf", &vp) == 1) {
2296 for (i = 0; i <
MAXSAT; i++) {
2297 sys =
satsys(i + 1, NULL);
2301 for (j = 0; j <
MAXCODE; j++) {
2315 if (0 < udcnt || popt->
pppsatcb == 1) {
2316 trace(NULL, 4,
"%s ssr update satellite code bias cnt=%d vp=%.f\n",
time_str(gt, 0), udcnt, vp);
2322 for (i = 0; i <
MAXSAT; i++) {
2323 for (j = 0; j <
MAXCODE; j++) {
2324 if (biaosb->
vscb[i][j] != 0) {
2332 for (i = 0; i <
MAXSAT; i++) {
2333 for (j = 0; j <
MAXCODE; j++) {
2334 nav->
osb.
scb[i][j] *= -1;
2337 nav->
osb.
gt[0] = biaosb->
gt[0];
2341 if (0 < udcnt || popt->
pppsatcb == 2) {
2342 trace(NULL, 4,
"%s bia update satellite code bias cnt=%d dt=%.f\n",
time_str(gt, 0), udcnt, popt->
maxbiasdt);
2348 for (i = 0; i <
MAXSAT; i++) {
2352 if (nav->
cbias[i][1] != 0.0) {
2358 if (nav->
cbias[i][2] != 0.0) {
2366 trace(NULL, 4,
"%s dcb update satellite code bias cnt=%d\n",
time_str(gt, 0), udcnt);
2369 trace(NULL, 3,
"%s no update satellite code bias \n",
time_str(gt, 0));
2375 int i, j, sys, udcnt = 0, ssrcode =
CODE_NONE;
2380 for (i = 0; i <
MAXSAT; i++) {
2382 if ((p = strstr(popt->
rtcmopt,
"-RTCM_PB_VALID=")) && sscanf(p,
"-RTCM_PB_VALID=%lf", &vp) == 1) {
2390 for (i = 0; i <
MAXSAT; i++) {
2391 sys =
satsys(i + 1, NULL);
2395 for (j = 0; j <
MAXCODE; j++) {
2403 nav->
osb.
spb[i][j] *= -1;
2412 if (0 < udcnt || popt->
pppsatpb == 1) {
2413 trace(NULL, 4,
"%s ssr update satellite phase bias cnt=%d vp=%.f\n",
time_str(gt, 0), udcnt, vp);
2419 for (i = 0; i <
MAXSAT; i++) {
2420 for (j = 0; j <
MAXCODE; j++) {
2421 if (fcbosb->
vspb[i][j] != 0) {
2429 for (i = 0; i <
MAXSAT; i++) {
2430 for (j = 0; j <
MAXCODE; j++) {
2431 nav->
osb.
spb[i][j] *= -1;
2434 nav->
osb.
gt[0] = fcbosb->
gt[0];
2438 trace(NULL, 4,
"%s fcb update satellite phase bias cnt=%d\n",
time_str(gt, 0), udcnt);
2448 for (i = 0; i <
MAXSAT; i++) {
2449 for (j = 0; j <
MAXCODE; j++) {
2450 if (biaosb->
vspb[i][j] != 0) {
2458 for (i = 0; i <
MAXSAT; i++) {
2459 for (j = 0; j <
MAXCODE; j++) {
2460 nav->
osb.
spb[i][j] *= -1;
2463 nav->
osb.
gt[0] = biaosb->
gt[0];
2466 if (0 < udcnt || popt->
pppsatpb == 2) {
2474 trace(NULL, 4,
"%s bia update satellite phase bias cnt=%d dt=%.f\n",
time_str(gt, 0), udcnt, popt->
maxbiasdt);
2478 trace(NULL, 3,
"%s no update satellite phase bias \n",
time_str(gt, 0));
2484 int i, j, udcnt = 0;
2489 for (j = 0; j <
MAXCODE; j++) {
2490 if (biaosb->
vrsyscb[i][j] != 0) {
2499 for (j = 0; j <
MAXCODE; j++) {
2503 nav->
osb.
gt[1] = biaosb->
gt[1];
2505 for (i = 0; i <
MAXSAT; i++) {
2506 for (j = 0; j <
MAXCODE; j++) {
2507 if (biaosb->
vrsatcb[i][j] != 0) {
2515 for (i = 0; i <
MAXSAT; i++) {
2516 for (j = 0; j <
MAXCODE; j++) {
2520 nav->
osb.
gt[1] = biaosb->
gt[1];
2525 trace(NULL, 4,
"%s bia update station code bias cnt=%d dt=%.f\n",
time_str(gt, 0), udcnt, popt->
maxbiasdt);
2529 trace(NULL, 3,
"%s no update station code bias \n",
time_str(gt, 0));
2536 osb_t *biaosb = NULL, *fcbosb = NULL;
2542 if (!biaosb || !fcbosb) {
2549 if (strlen(nav->
biapath) > 0) {
2553 trace(NULL, 3,
"update bias sinex file data %s -> %s\n", nav->
pr_biapath, path);
2558 if ((ret =
udosb_sat(biaosb, gt, 0)) == 0) {
2560 if ((ret =
udosb_sat(biaosb, gt, 1)) != 0) {
2568 memset(biaosb->
scb, 0x00,
sizeof(biaosb->
scb));
2569 memset(biaosb->
spb, 0x00,
sizeof(biaosb->
spb));
2570 memset(biaosb->
vscb, 0x00,
sizeof(biaosb->
vscb));
2571 memset(biaosb->
vspb, 0x00,
sizeof(biaosb->
vspb));
2573 trace(NULL, 4,
"update satellite osb: %s num=%d\n",
time_str(gt, 3), ret);
2591 trace(NULL, 4,
"update station osb: %s num=%d\n",
time_str(gt, 3), ret);
2594 if (strlen(nav->
fcbpath) > 0) {
2598 trace(NULL, 3,
"update fcb product file data %s -> %s\n", nav->
pr_fcbpath, path);
2603 if ((ret =
udfcb_sat(fcbosb, gt, 0)) == 0) {
2605 if ((ret =
udfcb_sat(fcbosb, gt, 1)) != 0) {
2613 memset(fcbosb->spb, 0x00,
sizeof(fcbosb->scb));
2614 memset(fcbosb->vspb, 0x00,
sizeof(fcbosb->vscb));
2616 trace(NULL, 4,
"update satellite fcb: %s num=%d\n",
time_str(gt, 3), ret);
2620 udsatcb(gt, nav, biaosb, popt);
2621 udsatpb(gt, nav, biaosb, fcbosb, popt);
2622 udstacb(gt, nav, biaosb, popt);
2690 int i, nu, nr[2] = {0};
2693 trace(ctx, 3,
"rtkpos : time=%s n=%d\n",
time_str(obs[0].time, 3), n);
2697 for (i = 0; i < 6; i++) {
2698 rtk->
rb[i] = i < 3 ? opt->
rb[i] : 0.0;
2702 for (nu = 0; nu < n && obs[nu].
rcv == 1; nu++) {
2705 for (nr[0] = 0; nu + nr[0] < n && obs[nu + nr[0]].
rcv == 2; nr[0]++) {
2709 for (nr[1] = 0; nu + nr[0] + nr[1] < n && obs[nu + nr[0] + nr[1]].
rcv == 3; nr[1]++) {
2717 udbiass(obs[0].time, opt, nav);
2741 sppopt.
err[5] = 50.0;
2742 sppopt.
err[6] = 0.5;
2761 if (!
pntpos(ctx, obs, nu, nav, &sppopt, &rtk->
sol, NULL, rtk->
ssat, msg)) {
2762 errmsg(rtk,
"point pos error (%s)\n", msg);
2765 trace(ctx, 4,
"obs=\n");
2772 if (time.
time != 0) {
2778 trace(ctx, 4,
"obs=\n");
2792 int nobs =
clas_ssr2osr(rtk, obs, nu, nav, osr_buf, 0, clas);
2795 for (i = 0; i < 3; i++) {
2796 rtk->
sol.
rr[i] = rtk->
x[i];
2800 rtk->
sol.
ns = (uint8_t)nobs;
2808 trace(ctx, 4,
"obs=\n");
2816 static int floatcnt = 0;
2817 trace(ctx, 4,
"obs=\n");
2822 trace(ctx, 1,
"float status continued than %d epoch: filter reset.\n", opt->
floatcnt);
2835 trace(ctx, 4,
"obs=\n");
2837 pppos(ctx, rtk, obs, nu, nav);
2841 trace(ctx, 4,
"obs=\n");
2845 errmsg(rtk,
"no base station observation data for rtk\n");
2852 if (!
pntpos(ctx, obs + nu, nr[0], nav, &rtk->
opt, &
solb, NULL, NULL, msg)) {
2853 errmsg(rtk,
"base station position error (%s)\n", msg);
2859 errmsg(rtk,
"time sync error for moving-base (age=%.1f)\n", rtk->
sol.
age);
2862 for (i = 0; i < 6; i++) {
2867 for (i = 0; i < 3; i++) {
2874 errmsg(rtk,
"age of differential error (age=%.1f)\n", rtk->
sol.
age);
2880 relpos(rtk, obs, nu, nr[0], nav);
void antmodel(const pcv_t *pcv, const double *del, const double *azel, int opt, double *dant)
Compute receiver antenna offset by antenna phase center parameters.
MRTKLIB Antenna Module — Antenna phase center model and parameter I/O.
double tropmodel(gtime_t time, const double *pos, const double *azel, double humi)
Compute tropospheric delay by standard atmosphere and Saastamoinen.
double tropmapf(gtime_t time, const double pos[], const double azel[], double *mapfw)
double ionmapf(const double *pos, const double *azel)
Compute ionospheric delay mapping function by single layer model.
MRTKLIB Atmosphere Module — Ionospheric and tropospheric models.
void satno2id(int sat, char *id)
int udosb_station(osb_t *osb, gtime_t gt, int mode, char *name)
Update station OSB structure with current biases.
int readbsnx(const char *file)
Read BIAS-SINEX file.
char * code2obs(uint8_t code)
int udosb_sat(osb_t *osb, gtime_t gt, int mode)
Update satellite OSB structure with current biases.
MRTKLIB Bias SINEX Module — BIAS-SINEX data types and I/O functions.
void setbitu(uint8_t *buff, int pos, int len, uint32_t data)
Set unsigned bits in byte data.
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.
CLAS (QZSS L6D) CSSR decoder and grid correction type definitions.
int clas_ssr2osr(rtk_t *rtk, obsd_t *obs, int n, nav_t *nav, clas_osrd_t *osr, int mode, clas_ctx_t *clas)
Convert compact SSR corrections to observation-space representations.
double sat2freq(int sat, uint8_t code, const nav_t *nav)
MRTKLIB Constants — Physical, navigation, and system constants.
double geodist(const double *rs, const double *rr, double *e)
Compute geometric distance and receiver-to-satellite unit vector.
double satazel(const double *pos, const double *e, double *azel)
Compute satellite azimuth/elevation angle.
void covecef(const double *pos, const double *Q, double *P)
Transform local ENU covariance to ECEF coordinate.
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 satposs(gtime_t teph, const obsd_t *obs, int n, const nav_t *nav, int ephopt, double *rs, double *dts, double *var, int *svh)
Compute satellite positions, velocities and clocks.
int udfcb_sat(osb_t *osb, gtime_t gt, int mode)
Update satellite FCB structure with current biases.
int readfcb(const char *file)
Read FCB (Fractional Cycle Bias) file.
MRTKLIB FCB Module — Fractional Cycle Bias data types and functions.
int lambda(int n, int m, const double *a, const double *Q, double *F, double *s)
Integer least-square estimation (LAMBDA/MLAMBDA).
MRTKLIB Integer Ambiguity Resolution Module — LAMBDA method.
int mcssr_sel_biascode(const int sys, const int code)
Select MADOCA-PPP code/phase bias code from observation code.
MRTKLIB MADOCA-PPP Module — QZSS L6E CSSR message decode functions.
double * mat(int n, int m)
Allocate memory for a double matrix.
int matinv(double *A, int n)
Inverse of matrix (A = A^-1).
double * zeros(int n, int m)
Allocate a new zero matrix.
void matcpy(double *A, const double *B, int n, int m)
Copy matrix.
int * imat(int n, int m)
Allocate memory for an integer matrix.
int filter(double *x, double *P, const double *H, const double *v, const double *R, int n, int m)
Kalman filter state update.
double norm(const double *a, int n)
Euclidean norm of vector.
void matmul(const char *tr, int n, int k, int m, double alpha, const double *A, const double *B, double beta, double *C)
Multiply matrix by matrix (C = alpha*A*B + beta*C).
double * eye(int n)
Generate a new identity matrix.
MRTKLIB Matrix Module — Matrix/vector operations and estimation.
int satexclude(int sat, double var, int svh, const struct prcopt_t *opt)
Test excluded satellite.
int set_bdsopt(const prcopt_t *opt, int warn)
Apply the BeiDou PRN-reassignment options process-wide.
int testelmask(const double *azel, const int16_t *elmask)
Test elevation mask.
int testsnr(int base, int idx, double el, double snr, const snrmask_t *mask)
Test SNR mask.
#define GLO_ARMODE_FIXHOLD
#define PMODE_SSR2OSR_FIXED
MRTKLIB Precise Ephemeris Module — Earth rotation parameter types and ERP I/O functions.
int pppoutstat(rtk_t *rtk, char *buff)
Write PPP solution status to buffer.
void pppos(mrtk_ctx_t *ctx, rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav)
Precise point positioning.
int pppnx(const prcopt_t *opt)
Number of estimated states for PPP.
MRTKLIB Precise Point Positioning (PPP) Module.
void ppp_rtk_pos(rtk_t *rtk, const obsd_t *obs, int n, nav_t *nav)
PPP-RTK positioning for one epoch (CLAS).
static int test_sys(int sys, int m, int qzsmodear, int code)
Test if satellite system matches group index.
int ppp_rtk_na(const prcopt_t *opt)
Compute number of non-ambiguity states for PPP-RTK.
int ppp_rtk_nx(const prcopt_t *opt)
Compute number of estimated states for PPP-RTK.
PPP-RTK positioning engine declarations.
static void errmsg(rtk_t *rtk, const char *format,...)
static int selsat(const obsd_t *obs, double *azel, int nu, int nr, const prcopt_t *opt, int *sat, int *iu, int *ir)
int rtkpos(mrtk_ctx_t *ctx, rtk_t *rtk, const obsd_t *obs, int n, nav_t *nav)
Compute rover position by precise positioning.
static int valpos(rtk_t *rtk, const double *v, const double *R, const int *vflg, int nv, double thres)
static double sdobs(const obsd_t *obs, int i, int j, int k)
static void udsatcb(gtime_t gt, nav_t *nav, osb_t *biaosb, const prcopt_t *popt)
int rtkoutstat(rtk_t *rtk, char *buff)
Write solution status to buffer.
static int test_sys(int sys, int m)
static void holdamb(rtk_t *rtk, const double *xa)
int miono_get_corr(const double *rr, nav_t *nav)
static int ddidx(rtk_t *rtk, int *ix, int gps, int glo, int sbs)
static void udbias(rtk_t *rtk, double tt, const obsd_t *obs, const int *sat, const int *iu, const int *ir, int ns, const nav_t *nav)
static void zdres_sat(int base, double r, const obsd_t *obs, const nav_t *nav, const double *azel, const double *dant, const prcopt_t *opt, double *y, double *freq)
static void udpos(rtk_t *rtk, double tt)
static void initx(rtk_t *rtk, double xi, double var, int i)
static double baseline(const double *ru, const double *rb, double *dr)
static void detslp_code(rtk_t *rtk, const obsd_t *obs, int i, int rcv)
static void restamb(rtk_t *rtk, const double *bias, double *xa)
static void udtrop(rtk_t *rtk, double tt, double bl)
static double prectrop(gtime_t time, const double *pos, int r, const double *azel, const prcopt_t *opt, const double *x, double *dtdx)
void rtkfree(rtk_t *rtk)
Free memory for RTK control struct.
static void udstate(rtk_t *rtk, const obsd_t *obs, const int *sat, const int *iu, const int *ir, int ns, const nav_t *nav)
static double intpres(gtime_t time, const obsd_t *obs, int n, const nav_t *nav, rtk_t *rtk, double *y)
static int manage_amb_LAMBDA(rtk_t *rtk, double *bias, double *xa, const int *sat, int nf, int ns)
static void swapsolstat(void)
int rtkopenstat(const char *file, int level)
Open solution status file and set output level.
static double varerr(int sat, int sys, double el, double snr_rover, double snr_base, double bl, double dt, int f, const prcopt_t *opt)
static void udstacb(gtime_t gt, nav_t *nav, osb_t *biaosb, const prcopt_t *popt)
void rtkclosestat(void)
Close solution status file.
static void udbiass(gtime_t gt, prcopt_t *popt, nav_t *nav)
static void udsatpb(gtime_t gt, nav_t *nav, osb_t *biaosb, osb_t *fcbosb, const prcopt_t *popt)
static int resamb_LAMBDA(rtk_t *rtk, double *bias, double *xa, int gps, int glo, int sbs)
static void detslp_dop(rtk_t *rtk, const obsd_t *obs, const int *ix, int ns, int rcv, const nav_t *nav)
static void detslp_gf(rtk_t *rtk, const obsd_t *obs, int i, int j, const nav_t *nav)
static void ddcov(const int *nb, int n, const double *Ri, const double *Rj, int nv, double *R)
static int zdres(int base, const obsd_t *obs, int n, const double *rs, const double *dts, const double *var, const int *svh, const nav_t *nav, const double *rr, const prcopt_t *opt, int index, double *y, double *e, double *azel, double *freq)
static void udrcvbias(rtk_t *rtk, double tt)
static int seliflc(int optnf, int sys)
static int ddres(rtk_t *rtk, const nav_t *nav, const obsd_t *obs, double dt, const double *x, const double *P, const int *sat, double *y, double *e, double *azel, double *freq, const int *iu, const int *ir, int ns, double *v, double *H, double *R, int *vflg)
static int validobs(int i, int j, int f, int nf, double *y)
static void outsolstat(rtk_t *rtk)
static double gfobs(const obsd_t *obs, int i, int j, int k, const nav_t *nav)
static char file_stat[1024]
static void udion(rtk_t *rtk, double tt, double bl, const int *sat, int ns)
void rtkinit(rtk_t *rtk, const prcopt_t *opt)
Initialize RTK control struct.
static int relpos(rtk_t *rtk, const obsd_t *obs, int nu, int nr, const nav_t *nav)
static const double ar_poly_coeffs[3][5]
static void detslp_ll(rtk_t *rtk, const obsd_t *obs, int i, int rcv)
static int constbl(rtk_t *rtk, const double *x, const double *P, double *v, double *H, double *Ri, double *Rj, int index)
MRTKLIB RTK Positioning Module — relative and precise positioning.
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 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.
MRTKLIB System Module — OS/filesystem utility functions.
void tidedisp(gtime_t tutc, const double *rr, int opt, const erp_t *erp, const double *odisp, double *dr)
Compute displacements by earth tides.
MRTKLIB Tides Module — Tidal displacement corrections.
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.
char * time_str(gtime_t t, int n)
Get time string (not reentrant).
gtime_t utc2gpst(gtime_t t)
Convert UTC to GPS time considering leap seconds.
gtime_t timeget(void)
Get current time in UTC.
void traceobs(mrtk_ctx_t *ctx, int level, const obsd_t *obs, int n)
Output trace observation data.
void tracemat(mrtk_ctx_t *ctx, int level, const double *A, int n, int m, int p, int q)
Output trace matrix.
void trace(mrtk_ctx_t *ctx, int level, const char *format,...)
Output trace message.
MRTKLIB Trace Module — debug trace and logging functions.
int relposvrs(rtk_t *rtk, const obsd_t *obs, int nu, int *nr, nav_t *nav)
VRS-RTK relative positioning.
MRTKLIB VRS-RTK Module — double-differenced RTK using CLAS VRS.
GNSS time representation.
Runtime context for MRTKLIB processing.
char pr_biapath[MAXSTRPATH]
ssr_t ssr_ch[SSR_CH_NUM][MAXSAT]
char pr_fcbpath[MAXSTRPATH]
double rsyscb[MAXBSNXSYS][MAXCODE]
double scb[MAXSAT][MAXCODE]
int vrsatcb[MAXSAT][MAXCODE]
int vspb[MAXSAT][MAXCODE]
int vscb[MAXSAT][MAXCODE]
int vrsyscb[MAXBSNXSYS][MAXCODE]
double spb[MAXSAT][MAXCODE]
double rsatcb[MAXSAT][MAXCODE]