53#define SQR(x) ((x) * (x))
55#define SQRT(x) ((x) <= 0.0 ? 0.0 : sqrt(x))
56#define MIN(x, y) ((x) <= (y) ? (x) : (y))
57#define ROUND(x) (int)floor((x) + 0.5)
59#define VAR_POS SQR(30.0)
60#define VAR_VEL SQR(1.0)
61#define VAR_ACC SQR(1.0)
62#define VAR_HWBIAS SQR(1.0)
63#define VAR_GRA SQR(0.001)
66#define PRN_HWBIAS 1E-6
70#define VAR_HOLDAMB 0.001
72#define TTOL_MOVEB (1.0 + 2 * DTTOL)
83#define LAM_CARR_L1 (CLIGHT / FREQ1)
84#define LAM_CARR_L2 (CLIGHT / FREQ2)
85#define LAM_CARR_L5 (CLIGHT / FREQ5)
90#define NF(opt) ((opt)->ionoopt == IONOOPT_IFLC ? 1 : (opt)->nf)
91#define NP(opt) ((opt)->dynamics == 0 ? 3 : 9)
92#define NI(opt) ((((opt)->ionoopt != IONOOPT_EST) && ((opt)->ionoopt != IONOOPT_EST_ADPT)) ? 0 : MAXSAT)
93#define NT(opt) ((opt)->tropopt < TROPOPT_EST ? 0 : ((opt)->tropopt < TROPOPT_ESTG ? 2 : 6))
94#define NL(opt) ((opt)->glomodear != 2 ? 0 : NFREQGLO)
95#define NB(opt) ((opt)->mode <= PMODE_DGPS ? 0 : MAXSAT * NF(opt))
96#define NR(opt) (NP(opt) + NI(opt) + NT(opt) + NL(opt))
97#define NX(opt) (NR(opt) + NB(opt))
100#define II(s, opt) (NP(opt) + (s) - 1)
101#define IT(r, opt) (NP(opt) + NI(opt) + NT(opt) / 2 * (r))
102#define IL(f, opt) (NP(opt) + NI(opt) + NT(opt) + (f))
103#define IB(s, f, opt) (NR(opt) + MAXSAT * (f) + (s) - 1)
104#define ITT(opt) (NP(opt) + NI(opt))
110 10.8, 13.8, 16.3, 18.5, 20.5, 22.5, 24.3, 26.1, 27.9, 29.6, 31.3, 32.9, 34.5, 36.1, 37.7, 39.3, 40.8,
111 42.3, 43.8, 45.3, 46.8, 48.3, 49.7, 51.2, 52.6, 54.1, 55.5, 56.9, 58.3, 59.7, 61.1, 62.5, 63.9, 65.2,
112 66.6, 68.0, 69.3, 70.7, 72.1, 73.4, 74.7, 76.0, 77.3, 78.6, 80.0, 81.4, 82.7, 84.0, 85.4, 86.7, 88.0,
113 89.3, 90.6, 91.9, 93.3, 94.7, 96.0, 97.4, 98.7, 100, 101, 102, 103, 104, 105, 107, 108, 109,
114 110, 111, 112, 113, 114, 115, 116, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
115 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142};
120 {405284.07, 999.00, 141.11, 53.44, 29.75, 20.03, 15.02, 12.05, 10.11, 8.75, 7.76, 7.00, 6.41, 5.93, 5.54,
121 5.20, 4.92, 4.68, 4.47, 4.29, 4.13, 3.98, 3.85, 3.74, 3.63, 3.53, 3.44, 3.36, 3.29, 3.22,
122 3.15, 3.09, 3.04, 2.98, 2.93, 2.89, 2.84, 2.80, 2.76, 2.73, 2.69, 2.66, 2.63, 2.60, 2.57,
123 2.54, 2.51, 2.49, 2.46, 2.44, 2.42, 2.40, 2.38, 2.36, 2.34, 2.32, 2.30, 2.28, 2.27, 2.25},
125 {16210.72, 199.00, 47.47, 23.15, 14.94, 11.07, 8.89, 7.50, 6.54, 5.85, 5.32, 4.91, 4.57, 4.30, 4.07,
126 3.87, 3.71, 3.56, 3.43, 3.32, 3.22, 3.12, 3.04, 2.97, 2.90, 2.84, 2.78, 2.72, 2.67, 2.63,
127 2.58, 2.54, 2.51, 2.47, 2.44, 2.41, 2.38, 2.35, 2.32, 2.30, 2.27, 2.25, 2.23, 2.21, 2.19,
128 2.17, 2.15, 2.13, 2.11, 2.10, 2.08, 2.07, 2.05, 2.04, 2.02, 2.01, 2.00, 1.99, 1.97, 1.96},
130 {4052.18, 99.00, 29.46, 15.98, 10.97, 8.47, 6.99, 6.03, 5.35, 4.85, 4.46, 4.16, 3.91, 3.70, 3.52,
131 3.37, 3.24, 3.13, 3.03, 2.94, 2.86, 2.78, 2.72, 2.66, 2.60, 2.55, 2.51, 2.46, 2.42, 2.39,
132 2.35, 2.32, 2.29, 2.26, 2.23, 2.21, 2.18, 2.16, 2.14, 2.11, 2.09, 2.08, 2.06, 2.04, 2.02,
133 2.01, 1.99, 1.98, 1.96, 1.95, 1.94, 1.92, 1.91, 1.90, 1.89, 1.88, 1.87, 1.86, 1.85, 1.84},
135 {161.45, 19.00, 9.28, 6.39, 5.05, 4.28, 3.79, 3.44, 3.18, 2.98, 2.82, 2.69, 2.58, 2.48, 2.40,
136 2.33, 2.27, 2.22, 2.17, 2.12, 2.08, 2.05, 2.01, 1.98, 1.96, 1.93, 1.90, 1.88, 1.86, 1.84,
137 1.82, 1.80, 1.79, 1.77, 1.76, 1.74, 1.73, 1.72, 1.70, 1.69, 1.68, 1.67, 1.66, 1.65, 1.64,
138 1.63, 1.62, 1.62, 1.61, 1.60, 1.59, 1.58, 1.58, 1.57, 1.56, 1.56, 1.55, 1.55, 1.54, 1.53},
140 {39.86, 9.00, 5.39, 4.11, 3.45, 3.05, 2.78, 2.59, 2.44, 2.32, 2.23, 2.15, 2.08, 2.02, 1.97,
141 1.93, 1.89, 1.85, 1.82, 1.79, 1.77, 1.74, 1.72, 1.70, 1.68, 1.67, 1.65, 1.63, 1.62, 1.61,
142 1.59, 1.58, 1.57, 1.56, 1.55, 1.54, 1.53, 1.52, 1.51, 1.51, 1.50, 1.49, 1.48, 1.48, 1.47,
143 1.46, 1.46, 1.45, 1.45, 1.44, 1.44, 1.43, 1.43, 1.42, 1.42, 1.41, 1.41, 1.40, 1.40, 1.40},
145 {9.47, 4.00, 2.94, 2.48, 2.23, 2.06, 1.94, 1.86, 1.79, 1.73, 1.69, 1.65, 1.61, 1.58, 1.56,
146 1.54, 1.52, 1.50, 1.48, 1.47, 1.45, 1.44, 1.43, 1.42, 1.41, 1.40, 1.39, 1.38, 1.37, 1.36,
147 1.36, 1.35, 1.34, 1.34, 1.33, 1.33, 1.32, 1.32, 1.31, 1.31, 1.30, 1.30, 1.30, 1.29, 1.29,
148 1.28, 1.28, 1.28, 1.27, 1.27, 1.27, 1.26, 1.26, 1.26, 1.26, 1.25, 1.25, 1.25, 1.25, 1.24}};
154 int sys =
satsys(sat, NULL);
183 return freq > 0.0 ?
CLIGHT / freq : 0.0;
194 char buff[256], tstr[32];
198 n = sprintf(buff,
"%s: ", tstr + 11);
199 va_start(ap, format);
200 n += vsprintf(buff + n, format, ap);
205 trace(NULL, 2,
"%s", buff);
208static double varerr(
int sat,
int sys,
double el,
double bl,
double dt,
int f,
const prcopt_t* opt) {
209 double a, b, c = opt->
err[3] * bl / 1E4, d =
CLIGHT * opt->
sclkstab * dt, fact = 1.0;
210 double sinel = sin(el);
221 }
else if (f < nf && opt->exterr.ena[1]) {
230 fact = opt->
eratio[f - nf];
236 a = fact * opt->
err[1];
237 b = fact * opt->
err[2];
241 return 1.0 * (opt->
ionoopt ==
IONOOPT_IFLC ? 3.0 : 1.0) * (a * a + b * b / sinel / sinel + c * c) + d * d;
244static double baseline(
const double* ru,
const double* rb,
double* dr) {
246 for (i = 0; i < 3; i++) {
247 dr[i] = ru[i] - rb[i];
255 for (j = 0; j < rtk->
nx; j++) {
256 rtk->
P[i + j * rtk->
nx] = rtk->
P[j + i * rtk->
nx] = i == j ? var : 0.0;
260static int selsat(
const obsd_t* obs,
double* azel,
int nu,
int* nr,
const prcopt_t* opt,
int* sat,
int* iu,
int* ir,
262 int i, j, k = 0, st, end;
264 trace(NULL, 3,
"selsat : nu=%d nr[0]=%d nr[1]=%d ch=%d\n", nu, nr[0], nr[1], ch);
265 for (i = 0; i <
MAXSAT; i++) {
271 st = (ch == 0) ? nu : nu + nr[0];
272 end = (ch == 0) ? nu + nr[0] : nu + nr[0] + nr[1];
273 for (i = 0, j = st; i < nu && j < end; i++, j++) {
274 if (obs[i].sat < obs[j].sat) {
276 }
else if (obs[i].sat > obs[j].sat) {
278 }
else if (azel[1 + j * 2] >= opt->
elmin) {
279 if (
timediff(obs[i].time, obs[j].time) < -1.0) {
280 trace(NULL, 5,
"ch:%d obs[i].sat:%d dt:%f\n", ch, obs[i].sat,
timediff(obs[i].time, obs[j].time));
286 trace(NULL, 4,
"(%2d) sat=%3d iu=%2d ir=%2d\n", k - 1, obs[i].sat, i, j);
292 int optf = opt->
posopt[10];
293 if (NFREQ == 1 || optf ==
POSL1) {
306 if (optf ==
POSL1L5_L2 && obs->
L[2] != 0.0 && obs->
P[2] != 0.0) {
314 double *F, *FP, *xp, pos[3], Q[9] = {0}, Qv[9], var = 0.0;
315 double prnpos_h, prnpos_v;
316 int i, j, na, nb, nx, ni, flag_init = 0;
317 double *Fx, *Pxx, *Pxi, *Pxb, *Pxi_, *Pxb_, *xp_, ki;
319 trace(NULL, 3,
"udpos : tt=%.3f\n", tt);
325 for (i = 0; i < 3; i++) {
331 if (
norm(rtk->
x, 3) <= 0.0) {
332 for (i = 0; i < 3; i++) {
336 for (i = 3; i < 6; i++) {
339 for (i = 6; i < 9; i++) {
347 for (i = 0; i < 3; i++) {
348 var += rtk->
P[i + i * nx];
354 for (i = 0; i < 3; i++) {
357 for (i = 3; i < 6; i++) {
360 for (i = 6; i < 9; i++) {
363 trace(NULL, 2,
"reset rtk position due to large variance: var=%.3f\n", var);
373 for (i = 0; i < 6; i++) {
374 F[i + (i + 3) * nx] = tt;
376 for (i = 0; i < 3; i++) {
377 F[i + (i + 6) * nx] =
SQR(tt) / 2.0;
395 for (i = 0; i < na; i++) {
396 for (j = 0; j < na; j++) {
397 Pxx[i + j * na] = rtk->
P[i + j * nx];
400 for (i = 0; i < na; i++) {
401 for (j = 0; j < ni; j++) {
402 Pxi_[i + j * na] = 0.5 * (rtk->
P[i + (na + j) * nx] + rtk->
P[na + j + (i)*nx]);
405 for (i = 0; i < na; i++) {
406 for (j = 0; j < nb; j++) {
407 Pxb_[i + j * na] = 0.5 * (rtk->
P[i + (na + ni + j) * nx] + rtk->
P[na + ni + j + (i)*nx]);
410 for (i = 0; i < na; i++) {
411 for (j = 0; j < na; j++) {
412 Fx[i + j * na] = F[i + j * nx];
415 for (i = 0; i < na; i++) {
420 matmul(
"NN", na, 1, na, 1.0, Fx, xp_, 0.0, xp);
421 for (i = 0; i < na; i++) {
424 for (i = 0; i < ni; i++) {
425 rtk->
x[i + na] *= ki;
429 matmul(
"NN", na, na, na, 1.0, Fx, Pxx, 0.0, FP);
430 matmul(
"NT", na, na, na, 1.0, FP, Fx, 0.0, Pxx);
431 for (i = 0; i < na; i++) {
432 for (j = 0; j < na; j++) {
433 rtk->
P[i + j * nx] = Pxx[i + j * na];
437 matmul(
"NN", na, ni, na, ki, Fx, Pxi_, 0.0, Pxi);
438 for (i = 0; i < na; i++) {
439 for (j = 0; j < ni; j++) {
440 rtk->
P[i + (na + j) * nx] = rtk->
P[(na + j) + i * nx] = Pxi[i + j * na];
444 matmul(
"NN", na, nb, na, 1.0, Fx, Pxb_, 0.0, Pxb);
445 for (i = 0; i < na; i++) {
446 for (j = 0; j < nb; j++) {
447 rtk->
P[i + (na + ni + j) * nx] = rtk->
P[(na + ni + j) + i * nx] = Pxb[i + j * na];
451 for (i = 0; i < ni; i++) {
452 for (j = 0; j < ni; j++) {
453 rtk->
P[(i + na) + (j + na) * nx] *= (ki * ki);
456 for (i = 0; i < ni; i++) {
457 for (j = 0; j < nb; j++) {
458 rtk->
P[(i + na) + (j + na + ni) * nx] *= ki;
461 for (i = 0; i < nb; i++) {
462 for (j = 0; j < ni; j++) {
463 rtk->
P[(i + na + ni) + (j + na) * nx] *= ki;
484 for (i = 0; i < 6; i++) {
485 F[i + (i + 3) * 9] = tt;
487 for (i = 0; i < 3; i++) {
488 F[i + (i + 6) * 9] =
SQR(tt) / 2.0;
492 matmul(
"NN", 9, 1, 9, 1.0, F, rtk->
x, 0.0, xp);
496 for (j = 0; j < nx; j++) {
497 for (i = 0; i < 6; i++) {
498 FP[i + j * nx] += rtk->
P[i + 3 + j * nx] * tt;
503 for (j = 0; j < nx; j++) {
504 for (i = 0; i < 6; i++) {
505 rtk->
P[j + i * nx] += rtk->
P[j + (i + 3) * nx] * tt;
515 Q[0] = Q[4] =
SQR(rtk->
opt.
prn[3]) * fabs(tt);
519 for (i = 0; i < 3; i++) {
520 for (j = 0; j < 3; j++) {
521 rtk->
P[i + 6 + (j + 6) * nx] += Qv[i + j * 3];
525 for (i = 0; i < 9; i++) {
526 for (j = 0; j < 9; j++) {
527 rtk->
P[i + j * nx] += rtk->
Q[i + j * nx] * fabs(tt);
536 Q[0] = Q[4] =
SQR(prnpos_h) * fabs(tt);
537 Q[8] =
SQR(prnpos_v) * fabs(tt);
541 for (i = 0; i < 3; i++) {
542 for (j = 0; j < 3; j++) {
543 rtk->
P[i + j * nx] += Qv[i + j * 3];
547 for (i = 0; i < 3; i++) {
548 for (j = 0; j < 3; j++) {
549 rtk->
P[i + j * nx] += rtk->
Q[i + j * nx] * fabs(tt);
560 trace(NULL, 3,
"udion : tt=%.1f bl=%.0f ns=%d\n", tt, bl, ns);
562 for (i = 1; i <=
MAXSAT; i++) {
563 j =
II(i, &rtk->
opt);
564 if (rtk->
x[j] == 0.0) {
567 for (k = 0; k < ns; k++) {
568 if (obs[k].sat == i) {
573 for (f = 0; f < rtk->
opt.
nf; f++) {
574 if (f > 0 && !(f & m)) {
578 trace(NULL, 3,
"reset iono estimation, sat=%2d outc=%6d \n", i, rtk->
ssat[i - 1].
outc[f]);
583 for (i = 0; i < ns; i++) {
584 j =
II(obs[i].sat, &rtk->
opt);
585 if (rtk->
x[j] == 0.0) {
587 rtk->
Q[j + j * rtk->
nx] = 0.0;
593 if (rtk->
Q[j + j * rtk->
nx] == 0.0) {
598 }
else if (rtk->
Q[j + j * rtk->
nx] <
SQR(rtk->
opt.
prn[1])) {
602 qi = rtk->
Q[j + j * rtk->
nx];
605 rtk->
Q[j + j * rtk->
nx] = qi;
608 rtk->
P[j + j * rtk->
nx] += qi * tt;
616 trace(NULL, 3,
"udtrop : tt=%.1f\n", tt);
618 for (i = 0; i < 2; i++) {
619 j =
IT(i, &rtk->
opt);
621 if (rtk->
x[j] == 0.0) {
625 for (k = 0; k < 2; k++) {
633 for (k = 0; k < 2; k++) {
634 rtk->
P[++j * (1 + rtk->
nx)] +=
SQR(rtk->
opt.
prn[2] * 0.3) * fabs(rtk->
tt);
644 trace(NULL, 3,
"udrcvbias: tt=%.1f\n", tt);
647 j =
IL(i, &rtk->
opt);
649 if (rtk->
x[j] == 0.0) {
654 initx(rtk, rtk->
xa[j], rtk->
Pa[j + j * rtk->
na], j);
664 if (lam0 == 0.0 || lam1 == 0.0 || obs->
L[0] == 0.0 || obs->
L[1] == 0.0) {
667 return lam0 * obs->
L[0] - lam1 * obs->
L[1];
673 if (lam0 == 0.0 || lam2 == 0.0 || obs->
L[0] == 0.0 || obs->
L[2] == 0.0) {
676 return lam0 * obs->
L[0] - lam2 * obs->
L[2];
683 for (i = 0; i < n && i <
MAXOBS; i++) {
684 for (j = 0; j < rtk->
opt.
nf; j++) {
685 if (obs[i].L[j] == 0.0 || !(obs[i].LLI[j] & 3)) {
689 trace(NULL, 2,
"detslp_ll: slip detected sat=%2d f=%d\n", obs[i].sat, j + 1);
701 trace(NULL, 3,
"detslip_gf_L1_L2\n");
704 for (i = 0; i < n && i <
MAXOBS; i++) {
711 trace(NULL, 2,
"detslip_gf_L1_L2: slip detected sat=%2d gf=%8.3f->%8.3f\n", obs[i].sat, g0, g1);
717 trace(NULL, 3,
"detslip_gf_L1_L5\n");
720 if (rtk->
opt.
nf <= 2) {
723 for (i = 0; i < n && i <
MAXOBS; i++) {
730 trace(NULL, 2,
"detslip_gf_L1_L5: slip detected sat=%2d gf=%8.3f->%8.3f\n", obs[i].sat, g0, g1);
737 double offset, lami, cp, pr;
739 int i, j, f, slip, nf =
NF(&rtk->
opt), reset, isat;
741 trace(NULL, 3,
"udbias : tt=%.1f n=%d\n", tt, n);
743 for (i = 0; i <
MAXSAT; i++) {
744 for (j = 0; j < rtk->
opt.
nf; j++) {
756 for (f = 0; f < nf; f++) {
758 for (i = 0; i <
MAXSAT; i++) {
762 initx(rtk, 0.0, 0.0,
IB(i + 1, f, &rtk->
opt));
763 }
else if (reset && rtk->
x[
IB(i + 1, f, &rtk->
opt)] != 0.0) {
765 initx(rtk, 0.0, 0.0,
IB(i + 1, f, &rtk->
opt));
766 trace(NULL, 3,
"udbias : obs outage counter overflow (sat=%3d L%d n=%5d)\n", i + 1, f + 1,
775 for (i = 0; i < n && i <
MAXOBS; i++) {
776 j =
IB(obs[i].sat, f, &rtk->
opt);
794 for (i = j = 0, offset = 0.0; i < n; i++) {
798 if (cp == 0.0 || pr == 0.0 || lami == 0.0) {
802 bias[i] = cp * lami - pr;
805 if (rtk->
x[
IB(obs[i].sat, f, &rtk->
opt)] != 0.0) {
807 offset += bias[i] - rtk->
x[
IB(obs[i].sat, f, &rtk->
opt)] * lami;
812 rtk->
com_bias = j > 0 ? offset / j : 0;
814 for (i = 0; i < n; i++) {
816 if (bias[i] == 0.0 || rtk->
x[
IB(isat, f, &rtk->
opt)] != 0.0) {
819 trace(NULL, 3,
"set initial states of phase-bias, sat=%2d f=%2d\n", obs[i].sat, f + 1);
831 double tt = fabs(rtk->
tt), bl = 0.0, dr[3];
833 trace(NULL, 3,
"udstate : nu=%d\n", nu);
849 udion(rtk, tt, bl, obs, nu);
857static void zdres_sat(
int base,
double r,
const obsd_t* obs,
const nav_t* nav,
const double* azel,
const double* dant,
859 double lam_arr[NFREQ];
860 int i, nf =
NF(opt), qj;
861 for (i = 0; i < NFREQ; i++) {
869 if (qj > 1 && obs->
L[qj] == 0.0 && obs->
P[qj] == 0.0 && (obs->
L[1] != 0.0 || obs->
P[1] != 0.0)) {
873 for (i = 0; i < nf; i++) {
874 if (lam_arr[i] == 0.0) {
882 if (i > 0 && !(i & qj)) {
886 if (obs->
L[i] != 0.0) {
887 y[i] = obs->
L[i] * lam_arr[i] - r - dant[i];
889 if (obs->
P[i] != 0.0) {
890 y[i + nf] = obs->
P[i] - r - dant[i];
895static int zdres(
rtk_t* rtk,
int base,
const obsd_t* obs,
int n,
const double* rs,
const double* dts,
const int* svh,
896 const nav_t* nav,
const double* rr,
const prcopt_t* opt,
int index,
double* y,
double* e,
898 double r, rr_[3], pos[3], dant[
NFREQPCV] = {0}, disp[3];
899 double zhd, zazel[] = {0.0, 90.0 *
D2R}, ydif = 0.0;
900 int i, j, nf =
NF(opt);
902 trace(NULL, 3,
"zdres : n=%d\n", n);
904 for (i = 0; i < n * nf * 2; i++) {
908 if (
norm(rr, 3) <= 0.0) {
912 for (i = 0; i < 3; i++) {
919 for (i = 0; i < 3; i++) {
925 for (i = 0; i < n; i++) {
927 if ((r =
geodist(rs + i * 6, rr_, e + i * 3)) <= 0.0) {
930 if (
satazel(pos, e + i * 3, azel + i * 2) < opt->
elmin) {
935 if (
satexclude(obs[i].sat, 0.0, svh[i], opt)) {
940 r += -
CLIGHT * dts[i * 2];
943 zhd =
tropmodel(obs[0].time, pos, zazel, 0.0);
944 r +=
tropmapf(obs[i].time, pos, azel + i * 2, NULL) * zhd;
950 zdres_sat(base, r, obs + i, nav, azel + i * 2, dant, opt, y + i * nf * 2);
954 for (j = 0; j < nav->
sfts.
n; j++) {
959 y[1 + i * nf * 2] += ydif *
sat_lambda(obs[i].sat, 1, nav);
962 trace(NULL, 4,
"rr_=%.3f %.3f %.3f\n", rr_[0], rr_[1], rr_[2]);
963 trace(NULL, 4,
"pos=%.9f %.9f %.3f\n", pos[0] *
R2D, pos[1] *
R2D, pos[2]);
964 for (i = 0; i < n; i++) {
965 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],
966 rs[2 + i * 6], dts[i * 2], azel[i * 2] *
R2D, azel[1 + i * 2] *
R2D);
968 trace(NULL, 4,
"y=\n");
969 tracemat(NULL, 4, y, nf * 2, n, 13, 3);
974static int validobs(
int* iu,
int* ir,
int jj,
int f,
int nf,
double* y) {
981 if (i < 0 || j < 0) {
985 return y[f + i * nf * 2] != 0.0 && y[f + j * nf * 2] != 0.0 &&
986 (f < nf || (y[f - nf + i * nf * 2] != 0.0 && y[f - nf + j * nf * 2] != 0.0));
989static void ddcov(
const int* nb,
int n,
const double* Ri,
const double* Rj,
int nv,
double* R) {
992 trace(NULL, 3,
"ddcov : n=%d\n", n);
994 for (i = 0; i < nv * nv; i++) {
997 for (b = 0; b < n; k += nb[b++]) {
998 for (i = 0; i < nb[b]; i++) {
999 for (j = 0; j < nb[b]; j++) {
1000 R[k + i + (k + j) * nv] = Ri[k + i] + (i == j ? Rj[k + i] : 0.0);
1004 trace(NULL, 5,
"R=\n");
1005 tracemat(NULL, 5, R, nv, nv, 8, 6);
1010 double m_w = 0.0, cotz, grad_n, grad_e;
1018 cotz = 1.0 / tan(azel[1]);
1019 grad_n = m_w * cotz * cos(azel[0]);
1020 grad_e = m_w * cotz * sin(azel[0]);
1021 m_w += grad_n * x[i + 1] + grad_e * x[i + 2];
1022 dtdx[1] = grad_n * x[i];
1023 dtdx[2] = grad_e * x[i];
1025 dtdx[1] = dtdx[2] = 0.0;
1043static int test_sys(
int sys,
int m,
int qzsmodear,
int code) {
1046 return m == (code ==
CODE_L2X ? 5 : 0);
1048 return m == (qzsmodear == 2 ? 0 : 4);
1062 return (obs[ir[0][0]].facility == obs[ir[1][0]].facility);
1067 for (i = 0; i < ns; i++) {
1068 if (sati == sat[i]) {
1076 int sati,
int iu[][
MAXSAT],
int ir[][
MAXSAT],
int sat[][
MAXSAT],
int* ff,
int* ns,
int* satj,
1077 int* jj,
int* sysi,
int* sysj,
double* lami,
double* lamj) {
1085 if (sati == *satj) {
1088 *sysi = rtk->
ssat[sati - 1].
sys;
1089 *sysj = rtk->
ssat[*satj - 1].
sys;
1090 code = rtk->
ssat[*satj - 1].
code[f % nf];
1094 if (!
validobs(iu[ch], ir[ch], *jj, f, nf, y)) {
1101 if (*lami <= 0.0 || *lamj <= 0.0) {
1111 double offset, lami, cp, pr;
1116 for (i = j = 0, offset = 0.0; i < n; i++) {
1120 if (cp == 0.0 || pr == 0.0 || lami == 0.0) {
1124 bias[i] = cp * lami - pr;
1127 if (rtk->
x[
IB(obs[i].sat, f, &rtk->
opt)] != 0.0) {
1129 offset += bias[i] - rtk->
x[
IB(obs[i].sat, f, &rtk->
opt)] * lami;
1133 rtk->
com_bias = j > 0 ? offset / j : 0;
1135 for (i = 0; i < n; i++) {
1140 if (bias[i] == 0.0) {
1143 trace(NULL, 2,
"set initial states of phase-bias(set_init_pb), sat=%2d f=%2d\n", obs[i].sat, f + 1);
1153 int sat[][
MAXSAT],
double* y,
double* e,
double* azel,
int iu[][
MAXSAT],
int ir[][
MAXSAT],
int* ns,
1154 double* v,
double* H,
double* R,
int* vflg,
int niter,
int order) {
1156 double bl, dr[3], posu[3], posr[3], didxi = 0.0, didxj = 0.0, *im[
SSR_CH_NUM];
1157 double *tropr[
SSR_CH_NUM], *tropu[
SSR_CH_NUM], *dtdxr, *dtdxu, *Ri, *Rj, lami, lamj, fi, fj, df, *Hi = NULL;
1158 int h, i, j, k, m, f, ff, nv = 0, nb[NFREQ * 6 * 2 + 1] = {0}, b = 0, sysi, sysj, nf =
NF(opt);
1160 static int refsat2[NFREQ * 2 * 6 + 1] = {0};
1161 int flg = 0, code, ch, sch, pch = 0, samefac = 0, refchgflg, ns_, sati, satj, refsatch, rch;
1162 int v0, v1, j0, j1, jj, vidx;
1165 double tow =
time2gpst(obs[0].time, NULL);
1167 ns_ = opt->
l6mrg ? ns[0] + ns[1] : ns[0];
1168 trace(NULL, 2,
"ddres : tow=%.1f dt[0]=%.1f dt[1]=%.1f nx=%d ns=%d\n", tow, dt[0], dt[1], rtk->
nx, ns_);
1174 for (f = 0; f < NFREQ; f++) {
1175 for (i = 0; i <
MAXSAT; i++) {
1180 Ri =
mat(ns_ * nf * 2 + 2, 1);
1181 Rj =
mat(ns_ * nf * 2 + 2, 1);
1182 dtdxu =
mat(ns_, 3);
1183 dtdxr =
mat(ns_, 3);
1186 tropu[ch] =
mat(ns[ch], 1);
1187 tropr[ch] =
mat(ns[ch], 1);
1188 im[ch] =
mat(ns[ch], 1);
1191 for (i = 0; i <
MAXSAT; i++) {
1192 for (j = 0; j < NFREQ; j++) {
1198 for (i = 0; i < ns[ch]; i++) {
1200 im[ch][i] = (
ionmapf(posu, azel + iu[ch][i] * 2) +
ionmapf(posr, azel + ir[ch][i] * 2)) / 2.0;
1203 tropu[ch][i] =
prectrop(rtk->
sol.
time, posu, 0, azel + iu[ch][i] * 2, opt, x, dtdxu + i * 3);
1204 tropr[ch][i] =
prectrop(rtk->
sol.
time, posr, 1, azel + ir[ch][i] * 2, opt, x, dtdxr + i * 3);
1214 for (m = 0; m < 6; m++) {
1218 for (h = 0, sch = -1, refchgflg = 0, refsatch = -1; h < ((opt->
l6mrg && !samefac) ?
SSR_CH_NUM : 1); h++) {
1222 for (i = -1, j = 0, flg = 0; j < n; j++) {
1224 sysi = rtk->
ssat[sati - 1].
sys;
1230 for (k = 0; k < niter; k++) {
1231 if (
refsat[NFREQ * 2 *
MAXREF * m + NFREQ * 2 * k + f] == sati) {
1241 if (j0 == -1 && j1 == -1) {
1247 if (samefac || h == 1) {
1249 v0 =
validobs(iu[0], ir[0], j0, f, nf, y);
1250 v1 =
validobs(iu[1], ir[1], j1, f, nf, y);
1254 trace(NULL, 5,
"h:%d sati:%d v0:%d v1:%d ir[0][j0]:%d\n", h, sati, v0, v1,
1255 ir[0][j0 == -1 ? j1 : j0]);
1259 if (!(v0 =
validobs(iu[0], ir[0], j0, f, nf, y))) {
1262 if (opt->
l6mrg && !(v1 =
validobs(iu[1], ir[1], j1, f, nf, y))) {
1271 vidx = v0 ? j0 : j1;
1272 if (i < 0 || azel[1 + iu[ch][vidx] * 2] >= azeli) {
1274 azeli = azel[1 + iu[ch][vidx] * 2];
1281 trace(NULL, 5,
"refsatroop m:%d i:%d sat:%d azel:%f\n", m, i, sati, azeli);
1295 if (f < nf &&
refsat2[NFREQ * 2 * m + NFREQ * 2 + f] != sati &&
1296 refsat2[NFREQ * 2 * m + NFREQ * 2 + f] != 0) {
1297 trace(NULL, 2,
"refsat changed2 %s L%d sat=%2d -> %2d\n",
time_str(rtk->
sol.
time, 0), f % nf + 1,
1298 refsat2[NFREQ * 2 * m + NFREQ * 2 + f], sati);
1301 refsat[NFREQ * 2 *
MAXREF * m + NFREQ * 2 * niter + f] = sati;
1302 refsat2[NFREQ * 2 * m + NFREQ * 2 + f] = sati;
1304 trace(NULL, 2,
"refsat changed %s L%d sat=%2d -> %2d\n",
time_str(rtk->
sol.
time, 0), f % nf + 1,
1305 refsat[NFREQ *
MAXREF * 2 * m + NFREQ * 2 * (niter - 1) + f],
1306 refsat[NFREQ *
MAXREF * 2 * m + NFREQ * 2 * niter + f]);
1309 trace(NULL, 4,
"refsat m:%d L%d %s: %d niter:%d refsatch:%d\n", m, f + 1,
time_str(rtk->
sol.
time, 0),
1310 sati, niter, refsatch);
1315 pch = (ns[0] >= ns[1]) ? 0 : 1;
1317 for (j = 0; j < n; j++) {
1321 rch = (sch != -1) ? sch : pch;
1326 if (!
valid_zd_sig(rtk, obs, nav, y, nf, f, j, m, ch, sati, iu, ir, sat, &ff, ns, &satj, &jj, &sysi,
1327 &sysj, &lami, &lamj)) {
1330 }
else if (sch == -1) {
1333 if (!
valid_zd_sig(rtk, obs, nav, y, nf, f, j, m, ch, sati, iu, ir, sat, &ff, ns, &satj, &jj, &sysi,
1334 &sysj, &lami, &lamj)) {
1335 ch = (ch == 1) ? 0 : 1;
1340 if (!
valid_zd_sig(rtk, obs, nav, y, nf, f, j, m, ch, sati, iu, ir, sat, &ff, ns, &satj, &jj,
1341 &sysi, &sysj, &lami, &lamj)) {
1346 trace(NULL, 3,
"even though it is a clas 2ch case, refsat is selected from one side ch.(ch=%d).\n",
1349 if (!
valid_zd_sig(rtk, obs, nav, y, nf, f, j, m, ch, sati, iu, ir, sat, &ff, ns, &satj, &jj, &sysi,
1350 &sysj, &lami, &lamj)) {
1357 if (order ==
FST && f < nf && opt->l6mrg && !samefac) {
1364 Hi = H + nv * rtk->
nx;
1368 v[nv] = (y[f + iu[rch][i] * nf * 2] - y[f + ir[rch][i] * nf * 2]) -
1369 (y[f + iu[ch][jj] * nf * 2] - y[f + ir[ch][jj] * nf * 2]);
1372 trace(NULL, 5,
"dd_res sati:%d satj:%d rch:%d ch:%d v:%f\n", sati, satj, rch, ch, v[nv]);
1377 for (k = 0; k < 3; k++) {
1378 Hi[k] = -e[k + iu[rch][i] * 3] + e[k + iu[ch][jj] * 3];
1385 didxi = (f < nf ? -1.0 : 1.0) * fi * fi * im[rch][i];
1386 didxj = (f < nf ? -1.0 : 1.0) * fj * fj * im[ch][jj];
1387 v[nv] -= didxi * x[
II(sati, opt)] - didxj * x[
II(satj, opt)];
1389 Hi[
II(sati, opt)] = didxi;
1390 Hi[
II(satj, opt)] = -didxj;
1395 v[nv] -= (tropu[rch][i] - tropu[ch][jj]) - (tropr[rch][i] - tropr[ch][jj]);
1400 Hi[
IT(0, opt) + k] = (dtdxu[k + i * 3] - dtdxu[k + jj * 3]);
1401 Hi[
IT(1, opt) + k] = -(dtdxr[k + i * 3] - dtdxr[k + jj * 3]);
1407 v[nv] -= lami * x[
IB(sati, f, opt)] - lamj * x[
IB(satj, f, opt)];
1409 Hi[
IB(sati, f, opt)] = lami;
1410 Hi[
IB(satj, f, opt)] = -lamj;
1413 v[nv] -= x[
IB(sati, f, opt)] - x[
IB(satj, f, opt)];
1415 Hi[
IB(sati, f, opt)] = 1.0;
1416 Hi[
IB(satj, f, opt)] = -1.0;
1423 v[nv] -= df * x[
IL(ff, opt)];
1425 Hi[
IL(ff, opt)] = df;
1434 rtk->
ssat[satj - 1].
resc[f] = v[nv];
1436 rtk->
ssat[satj - 1].
resp[f - nf] = v[nv];
1440 Ri[nv] =
varerr(sati, sysi, azel[1 + iu[rch][i] * 2], bl, dt[rch], f, opt);
1441 Rj[nv] =
varerr(satj, sysj, azel[1 + iu[ch][jj] * 2], bl, dt[ch], f, opt);
1443 Ri[nv] *=
SQR(2.55 / 1.55);
1444 Rj[nv] *=
SQR(2.55 / 1.55);
1451 trace(NULL, 4,
"sat=%3d-%3d %s%d v=%13.3f R=%8.6f %8.6f\n", sati, satj, f < nf ?
"L" :
"P", f % nf + 1,
1452 v[nv], Ri[nv], Rj[nv]);
1454 vflg[nv++] = (sati << 16) | (satj << 8) | ((f < nf ? 0 : 1) << 4) | (f % nf);
1463 ddcov(nb, b, Ri, Rj, nv, R);
1485 double tt =
timediff(time, obs[0].time), ttb, *p, *q;
1486 int i, j, k, nf =
NF(opt);
1488 trace(NULL, 3,
"intpres : n=%d tt=%.1f\n", n, tt);
1490 if (nb[ch] == 0 || fabs(tt) <
DTTOL) {
1492 for (i = 0; i < n; i++) {
1493 obsb[ch][i] = obs[i];
1497 ttb =
timediff(time, obsb[ch][0].time);
1498 if (fabs(ttb) > opt->
maxtdiff * 2.0 || ttb == tt) {
1502 satposs(time, obsb[ch], nb[ch], nav, opt->
sateph, rs[ch], dts[ch], var[ch], svh[ch]);
1504 if (!
zdres(rtk, 1, obsb[ch], nb[ch], rs[ch], dts[ch], svh[ch], nav, rtk->
rb, opt, 1, yb[ch], e[ch], azel[ch])) {
1507 for (i = 0; i < n; i++) {
1508 for (j = 0; j < nb[ch]; j++) {
1509 if (obsb[ch][j].sat == obs[i].sat) {
1516 for (k = 0, p = y + i * nf * 2, q = yb[ch] + j * nf * 2; k < nf * 2; k++, p++, q++) {
1517 if (*p == 0.0 || *q == 0.0) {
1520 *p = (ttb * (*p) - tt * (*q)) / (ttb - tt);
1524 return fabs(ttb) > fabs(tt) ? ttb : tt;
1528 int i, j, k, m, f, nb = 0, nx = rtk->
nx, na = rtk->
na, nf =
NF(&rtk->
opt), code;
1530 trace(NULL, 3,
"ddmat :\n");
1532 for (i = 0; i <
MAXSAT; i++) {
1533 for (j = 0; j < NFREQ; j++) {
1537 for (i = 0; i < na; i++) {
1538 D[i + i * nx] = 1.0;
1541 for (m = 0; m < 6; m++) {
1553 for (f = 0, k = na; f < nf; f++, k +=
MAXSAT) {
1554 for (i = k; i < k +
MAXSAT; i++) {
1568 for (j = k; j < k +
MAXSAT; j++) {
1576 D[i + (na + nb) * nx] = 1.0;
1577 D[j + (na + nb) * nx] = -1.0;
1586 trace(NULL, 5,
"D=\n");
1587 tracemat(NULL, 5, D, nx, na + nb, 2, 0);
1592 int i, n, m, f, index[
MAXSAT], nv = 0, nf =
NF(&rtk->
opt), code;
1594 trace(NULL, 3,
"restamb :\n");
1596 for (i = 0; i < rtk->
nx; i++) {
1599 for (i = 0; i < rtk->
na; i++) {
1603 for (m = 0; m < 6; m++) {
1604 for (f = 0; f < nf; f++) {
1605 for (n = i = 0; i <
MAXSAT; i++) {
1610 index[n++] =
IB(i + 1, f, &rtk->
opt);
1616 xa[index[0]] = rtk->
x[index[0]];
1618 for (i = 1; i < n; i++) {
1619 xa[index[i]] = xa[index[0]] - bias[nv++];
1627 int i, n, m, f, info, index[
MAXSAT], nb = rtk->
nx - rtk->
na, nv = 0, nf =
NF(&rtk->
opt);
1630 trace(NULL, 3,
"holdamb :\n");
1635 for (m = 0; m < 6; m++) {
1636 for (f = 0; f < nf; f++) {
1637 for (n = i = 0; i <
MAXSAT; i++) {
1643 index[n++] =
IB(i + 1, f, &rtk->
opt);
1647 for (i = 1; i < n; i++) {
1648 v[nv] = (xa[index[0]] - xa[index[i]]) - (rtk->
x[index[0]] - rtk->
x[index[i]]);
1650 H[index[0] + nv * rtk->
nx] = 1.0;
1651 H[index[i] + nv * rtk->
nx] = -1.0;
1658 for (i = 0; i < nv; i++) {
1663 if ((info =
filter(rtk->
x, rtk->
P, H, v, R, rtk->
nx, nv))) {
1664 errmsg(rtk,
"filter error (info=%d)\n", info);
1674 int i, j, ny, nb, info, nx = rtk->
nx, na = rtk->
na;
1675 double *D, *DP, *y, *Qy, *b, *db, *Qb, *Qab, *QQ, s[2];
1676 double *Ds, *Pac, *Pcc, *D_P;
1679 trace(NULL, 3,
"resamb_LAMBDA : nx=%d\n", nx);
1688 if ((nb =
ddmat(rtk, D)) <= 0) {
1689 errmsg(rtk,
"no valid double-difference\n");
1708 for (i = 0; i < nc; i++) {
1709 for (j = 0; j < nb; j++) {
1710 Ds[i + j * nc] = D[na + i + (na + j) * nx];
1713 for (i = 0; i < na; i++) {
1714 for (j = 0; j < nc; j++) {
1715 Pac[i + j * na] = rtk->
P[i + (na + j) * nx];
1718 for (i = 0; i < nc; i++) {
1719 for (j = 0; j < nc; j++) {
1720 Pcc[i + j * nc] = rtk->
P[na + i + (na + j) * nx];
1723 matmul(
"TN", ny, 1, nx, 1.0, D, rtk->
x, 0.0, y);
1724 matmul(
"NN", na, nb, nc, 1.0, Pac, Ds, 0.0, Qab);
1725 matmul(
"TN", nb, nc, nc, 1.0, Ds, Pcc, 0.0, D_P);
1726 matmul(
"NN", nb, nb, nc, 1.0, D_P, Ds, 0.0, Qb);
1732 trace(NULL, 4,
"N(0)=");
1733 tracemat(NULL, 4, y + na, 1, nb, 10, 3);
1736 if (!(info =
lambda(nb, 2, y + na, Qb, b, s))) {
1737 trace(NULL, 4,
"N(1)=");
1738 tracemat(NULL, 4, b, 1, nb, 10, 3);
1739 trace(NULL, 4,
"N(2)=");
1740 tracemat(NULL, 4, b + nb, 1, nb, 10, 3);
1742 rtk->
sol.
ratio = s[0] > 0 ? (float)(s[1] / s[0]) : 0.0f;
1748 if (s[0] <= 0.0 || s[1] / s[0] >=
qfrtk[opt->
alphaar][nb - 1]) {
1750 for (i = 0; i < na; i++) {
1751 rtk->
xa[i] = rtk->
x[i];
1752 for (j = 0; j < na; j++) {
1753 rtk->
Pa[i + j * na] = rtk->
P[i + j * nx];
1756 for (i = 0; i < nb; i++) {
1761 matmul(
"NN", nb, 1, nb, 1.0, Qb, y + na, 0.0, db);
1762 matmul(
"NN", na, 1, nb, -1.0, Qab, db, 1.0, rtk->
xa);
1765 matmul(
"NN", na, nb, nb, 1.0, Qab, Qb, 0.0, QQ);
1766 matmul(
"NT", na, na, nb, -1.0, QQ, Qab, 1.0, rtk->
Pa);
1768 trace(NULL, 3,
"resamb : validation ok (nb=%d ratio=%.2f s=%.2f/%.2f)\n", nb,
1769 s[0] == 0.0 ? 0.0 : s[1] / s[0], s[0], s[1]);
1780 errmsg(rtk,
"lambda error (info=%d)\n", info);
1796 int i, j, k, m = 0, sati;
1798 for (i = 0; i < n; i++) {
1805 for (j = 0; j < m; j++) {
1813 for (k = m; k > j; k--) {
1814 isat[k] = isat[k - 1];
1827static double sddop(
const rtk_t* rtk,
const double* H,
const int* vflg,
const double elmask,
const int nv) {
1828 int i, cnt, freq, type, sat;
1829 double *H_, Q[9], dop = 1000.0;
1833 for (i = cnt = 0; i < nv; i++) {
1834 sat = (vflg[i] >> 8) & 0xFF;
1835 type = (vflg[i] >> 4) & 0xF;
1836 freq = (vflg[i]) & 0xF;
1837 if (freq > 0 || type > 0 || rtk->
ssat[sat - 1].
vsat[0] == 0 || rtk->
ssat[sat - 1].
azel[1] <= elmask) {
1840 H_[cnt * 3] = H[i * rtk->
nx];
1841 H_[cnt * 3 + 1] = H[i * rtk->
nx + 1];
1842 H_[cnt * 3 + 2] = H[i * rtk->
nx + 2];
1845 matmul(
"NT", 3, 3, cnt, 1.0, H_, H_, 0.0, Q);
1846 if (cnt > 0 && !
matinv(Q, 3)) {
1847 dop = sqrt(Q[0] + Q[4] + Q[8]);
1856static double zddop(
const rtk_t* rtk,
const double* azel,
const obsd_t* obs,
const double elmask,
const int n) {
1858 double *azel_, dop[4];
1862 for (i = j = 0; i < n; i++) {
1866 azel_[j * 2] = azel[i * 2];
1867 azel_[j * 2 + 1] = azel[i * 2 + 1];
1871 dops(j, azel_, elmask, dop);
1879static double calpdop(
const rtk_t* rtk,
const double* H,
const double* azel,
const int* vflg,
const obsd_t* obs,
1880 const double elmask,
const int n,
const int nv) {
1883 return zddop(rtk, azel, obs, elmask, n);
1886 return sddop(rtk, H, vflg, elmask, nv);
1898 static int savefacility[
SSR_CH_NUM] = {-1, -1};
1901 for (ch = 0; ch < (l6mrg ?
SSR_CH_NUM : 1); ch++) {
1902 idx = (ch == 0) ? nu : nu + nr[0];
1903 if (savefacility[ch] != obs[idx].facility) {
1904 if (savefacility[ch] != -1) {
1905 trace(NULL, 1,
"VRS facility changed[ch:%d], %d ---> %d\n", ch, savefacility[ch], obs[idx].facility);
1908 trace(NULL, 1,
"VRS facility changed[ch:%d], ---> %d\n", ch, obs[idx].facility);
1911 savefacility[ch] = obs[idx].
facility;
1918static int residual_test(
rtk_t* rtk,
const int* vflg,
const double* v,
const double* Q,
int* iv,
const int m,
int* ns,
1920 int i, k, sat1, sat2, type, freq, freq_, nf = rtk->
opt.
nf;
1923 double *resc, *resp, sig2, vv0_, vvf_, vv = 0.0;
1924 int qi, qj, cnt, cnt2;
1930 for (i = cnt2 = 0; i < m; i++) {
1931 sat2 = (vflg[i] >> 8) & 0xFF;
1932 type = (vflg[i] >> 4) & 0xF;
1933 freq = (vflg[i]) & 0xF;
1936 }
else if (type == 1) {
1943 resc[(sat2 - 1) * nf + freq] = v[i];
1944 resp[(sat2 - 1) * nf + freq] = Q[i + i * m];
1949 for (i = 0; i <
MAXSAT; i++) {
1950 for (k = 1; k < nf; k++) {
1954 if (resp[i * nf + qi] == 0.0 || resp[i * nf + qj] == 0.0) {
1957 vvf_ =
FREQ1 /
FREQ2 * (resc[i * nf + qi] - resc[i * nf + qj]) / (1.0 - gamma);
1958 vv0_ = (gamma * resc[i * nf + qi] - resc[i * nf + qj]) / (gamma - 1.0);
1959 sig2 = resp[i * nf + qi] > resp[i * nf + qj] ? resp[i * nf + qi] : resp[i * nf + qj];
1962 if ((inno[1] > 0.0) && (vvf_ * vvf_ > inno[1] * inno[1] * sig2)) {
1967 "Residuals validation:freq outlier detected (stage=%1d sat=%2d f=%d %d v=%6.3f sig=%.3f)\n", flg,
1968 i + 1, qi, qj, vvf_, sqrt(sig2));
1972 if ((inno[2] > 0.0) && (vv0_ * vv0_ > inno[2] * inno[2] * sig2)) {
1976 trace(NULL, 2,
"Residuals validation:L0 outlier detected (stage=%1d sat=%2d v=%6.3f sig=%.3f)\n", flg,
1977 i + 1, vv0_, sqrt(sig2));
1984 for (i = k = cnt = 0; i < m; i++) {
1985 sat1 = (vflg[i] >> 16) & 0xFF;
1986 sat2 = (vflg[i] >> 8) & 0xFF;
1987 type = (vflg[i] >> 4) & 0xF;
1988 freq = (vflg[i]) & 0xF;
1991 }
else if (type == 1) {
1997 freq_ = type < 1 ? freq : freq * type + nf;
2000 if (!Q[i + i * m] || inno[0] == 0 || (v[i] * v[i] < Q[i + i * m] * inno[0] * inno[0])) {
2002 if (!rtk->
ssat[sat2 - 1].
vsat[freq]) {
2005 vv += v[i] * v[i] / Q[i + i * m];
2012 rtk->
ssat[sat2 - 1].
vsat[freq] = 0;
2014 trace(NULL, 2,
"meas update outlier detected (sat=%2d-%2d %s%d v=%6.3f sig=%6.3f outc=%2d)\n", sat1, sat2,
2015 stype, freq + 1, v[i], sqrt(Q[i + i * m]), rtk->
ssat[sat2 - 1].
outc[freq]);
2020 if (cnt >
NP(&rtk->
opt)) {
2022 trace(NULL, 2,
"L1/L2 chi-square validation failed (stage=%d cnt=%d np=%d vv=%.2f cs=%5.3f)\n", flg, cnt,
2027 vrs_chisq = ((double)cnt / cnt2) < 0.5 ? 100.0 : 0.0;
2039static int filter2_(
rtk_t* rtk,
const double* x,
const double* P,
const double* H,
const double* v,
const double* R,
2040 const int n,
const int m,
double* xp,
double* Pp,
double*
Qp,
const int* vflg,
const int flg) {
2041 double *K, *v_, *Q_, *F_, *H_, *I, *F, *Q, *vd;
2042 int i, j, k, info = 0, *iv, nn[3 * 2];
2047 nn[0] = nn[1] = nn[2] = nn[3] = 0;
2050 matmul(
"NN", n, m, n, 1.0, P, H, 0.0, F);
2051 matmul(
"TN", m, m, n, 1.0, H, F, 1.0, Q);
2054 if (!(k =
residual_test(rtk, vflg, v, Q, iv, m, nn, flg))) {
2055 trace(NULL, 2,
"filter status (all measurements are rejected): stage=%1d\n", flg);
2057 trace(NULL, 2,
"filter status : stage=%1d refsat=%2d states=%2d obs=%2d,vobs=%2d,vsat(L1)=%2d,chi-val=%5.3f\n",
2058 flg, (vflg[iv[0]] >> 16) & 0xFF, n, m, k, nn[0],
vrs_chisq);
2061 if (flg > 0 || k == 0) {
2075 for (i = 0; i < k; i++) {
2077 for (j = 0; j < k; j++) {
2078 Q_[i + j * k] = Q[iv[i] + iv[j] * m];
2080 for (j = 0; j < n; j++) {
2081 F_[j + i * n] = F[j + iv[i] * n];
2083 for (j = 0; j < n; j++) {
2084 H_[j + i * n] = H[j + iv[i] * n];
2090 if (!(info =
matinv(Q_, k))) {
2091 matmul(
"NN", n, k, k, 1.0, F_, Q_, 0.0, K);
2092 matmul(
"NN", n, 1, k, 1.0, K, v_, 1.0, xp);
2093 matmul(
"NT", n, n, k, -1.0, K, H_, 1.0, I);
2094 matmul(
"NN", n, n, n, 1.0, I, P, 0.0, Pp);
2096 matmul(
"NN", n, 1, k, 1.0, K, v_, 0.0, vd);
2097 matmul(
"NT", n, n, 1, 1.0, vd, vd, 0.0,
Qp);
2115static int filter2(
rtk_t* rtk,
double* x,
double* P,
double* Q,
const double* H,
const double* v,
const double* R,
2116 const int n,
const int m,
const int* vflg,
const int flg) {
2117 double *x_, *xp_, *P_, *Pp_, *Qp_, *H_;
2118 int i, j, k, info, *ix;
2121 for (i = k = 0; i < n; i++) {
2122 if (x[i] != 0.0 && P[i + i * n] > 0.0) {
2132 for (i = 0; i < k; i++) {
2134 for (j = 0; j < k; j++) {
2135 P_[i + j * k] = P[ix[i] + ix[j] * n];
2137 for (j = 0; j < m; j++) {
2138 H_[i + j * k] = H[ix[i] + j * n];
2141 info =
filter2_(rtk, x_, P_, H_, v, R, k, m, xp_, Pp_, Qp_, vflg, flg);
2142 for (i = 0; i < k; i++) {
2144 for (j = 0; j < k; j++) {
2145 P[ix[i] + ix[j] * n] = Pp_[i + j * k];
2148 for (j = 0; j < k; j++) {
2149 Q[ix[i] + ix[j] * n] = Qp_[i + j * k];
2164 static gtime_t regularly = {-1, 0.0};
2167 double *rs, *dts, *var, *y, *e, *azel, *v, *H, *R, *xp, *Pp, *
Qp, *xa, *bias, dt[
SSR_CH_NUM];
2168 int i, j, k = 0, f, l, n, ns[
SSR_CH_NUM] = {0}, ny, nv = 0, sat[
SSR_CH_NUM][
MAXSAT], iu[
SSR_CH_NUM][
MAXSAT],
2170 int info, vflg[
MAXOBS * NFREQ * 2 + 1], svh[
MAXOBS * 2];
2177 static int resetcnt = 0,
cntdiffp = 0, np;
2178 double tow =
time2gpst(obs[0].time, NULL);
2180 trace(NULL, 2,
"relposvrs : time=%s nx=%d nu=%d nr[0]=%d nr[1]=%d\n",
time_str(obs[0].time, 0), rtk->
nx, nu, nr[0],
2183 n = opt->
l6mrg ? nu + nr[0] + nr[1] : nu + nr[0];
2187 regularly = (regularly.
time == -1 ? obs[0].
time : regularly);
2189 trace(NULL, 1,
"relposvrs(): regularly reset filter, tow=%.1f\n", tow);
2190 for (i = 0; i < rtk->
nx; i++) {
2194 regularly = obs[0].
time;
2201 trace(NULL, 1,
"relposvrs(): reset filter, tow=%.1f\n",
time2gpst(obs[0].time, NULL));
2202 for (i =
NP(opt); i < rtk->
nx; i++) {
2215 dt[0] =
timediff(time, obs[nu].time);
2217 dt[1] =
timediff(time, obs[nu + nr[0]].time);
2227 for (i = 0; i <
MAXSAT; i++) {
2229 for (j = 0; j < NFREQ; j++) {
2237 ofst = ch == 1 ? nu + nr[0] : nu;
2239 if (!
zdres(rtk, 1, obs + ofst, nr[ch], rs + ofst * 6, dts + ofst * 2, svh + ofst, nav, rtk->
rb, opt, 1,
2240 y + ofst * nf * 2, e + ofst * 3, azel + ofst * 2)) {
2241 errmsg(rtk,
"initial base station position error\n");
2253 dt[ch] =
intpres(time, obs + ofst, nr[ch], nav, rtk, ch, y + ofst * nf * 2);
2256 ns[ch] =
selsat(obs, azel, nu, nr, opt, sat[ch], iu[ch], ir[ch], ch);
2258 if (ns[0] + ns[1] == 0) {
2259 errmsg(rtk,
"no common satellite\n");
2269 trace(NULL, 4,
"x(0)=");
2272 xp =
mat(rtk->
nx, 1);
2274 xa =
mat(rtk->
nx, 1);
2277 ny = (ns[0] + ns[1]) * nf * 2 + 2;
2281 bias =
mat(rtk->
nx, 1);
2285 for (i = 0; i < rtk->
opt.
niter; i++) {
2286 for (k = 0; k <
MAXREF; k++) {
2287 nv =
zdres(rtk, 0, obs, nu, rs, dts, svh, nav, xp, opt, 0, y, e, azel);
2294 for (l = 0; l < 2; l++) {
2295 initx(rtk, 1E-6, 0.0, ++j);
2300 trace(NULL, 2,
"rover initial position error\n");
2305 if ((nv =
ddres(rtk, nav, dt, xp, Pp, obs, nu, sat, y, e, azel, iu, ir, ns, v, H, R, vflg, k,
FST)) <= 0) {
2306 trace(NULL, 2,
"no double-differenced residual\n");
2312 if ((info =
filter2(rtk, xp, Pp,
Qp, H, v, R, rtk->
nx, nv, vflg, 0)) != 0) {
2317 if (
zdres(rtk, 0, obs, nu, rs, dts, svh, nav, xp, opt, 0, y, e, azel)) {
2318 nv =
ddres(rtk, nav, dt, xp, Pp, obs, nu, sat, y, e, azel, iu, ir, ns, v, H, R, vflg, k,
SND);
2320 filter2(rtk, xp, Pp, NULL, H, v, R, rtk->
nx, nv, vflg, 1);
2328 trace(NULL, 2,
"measurement update failed \n");
2335 for (i = 0; i < nu; i++) {
2336 j =
II(obs[i].sat, &rtk->
opt);
2344 for (i = 0; i < np; i++) {
2345 for (j = 0; j < np; j++) {
2358 for (i = 0; i < nu; i++) {
2360 for (f = 0; f < nf; f++) {
2361 if (!rtk->
ssat[sati - 1].
vsat[f]) {
2372 if (rtk->
sol.
ns < 4) {
2378 for (i = 0; i < rtk->
nx; i++) {
2379 for (j = 0; j < i; j++) {
2380 rtk->
P[i + j * rtk->
nx] = rtk->
P[j + i * rtk->
nx] =
2381 (rtk->
P[i + j * rtk->
nx] + rtk->
P[j + i * rtk->
nx]) * 0.5;
2391 elsort(rtk, obs, isat, el, nu);
2393 for (i = 0; i < nu; i++) {
2398 for (f = j = 0; f < nf; f++) {
2406 for (f = 0; f < nf; f++) {
2412 trace(NULL, 2,
"PAR OK l=%d i=%2d nb=%2d excluded sat=%2d el=%4.1f ratio=%5.2f\n", l, i, nb,
2416 for (f = 0; f < nf; f++) {
2419 if (ratio < rtk->sol.ratio) {
2428 for (f = 0; f < nf; f++) {
2435 if (nb > 1 &&
zdres(rtk, 0, obs, nu, rs, dts, svh, nav, rtk->
opt.
mode ==
PMODE_FIXED ? rtk->
opt.
ru : xa, opt, 0,
2438 nv =
ddres(rtk, nav, dt, xa, NULL, obs, nu, sat, y, e, azel, iu, ir, ns, v, NULL, R, vflg, k,
TRD);
2440 filter2(rtk, xp, Pp, NULL, H, v, R, rtk->
nx, nv, vflg, 2);
2462 trace(NULL, 2,
"reset all states due to large pos error dist = %.2f\n", sqrt(dist));
2464 for (i = 0; i < 3; i++) {
2465 rtk->
x[i] = rtk->
sol.
rr[i];
2466 rtk->
P[i + i * rtk->
nx] = (double)rtk->
sol.
qr[i];
2477 for (i = 0; i < 3; i++) {
2479 rtk->
sol.
qr[i] = (float)rtk->
Pa[i + i * rtk->
na];
2481 rtk->
sol.
qr[3] = (float)rtk->
Pa[1];
2482 rtk->
sol.
qr[4] = (float)rtk->
Pa[1 + 2 * rtk->
na];
2483 rtk->
sol.
qr[5] = (float)rtk->
Pa[2];
2485 for (i = 0; i < 3; i++) {
2486 rtk->
sol.
rr[i] = rtk->
x[i];
2487 rtk->
sol.
qr[i] = (float)rtk->
P[i + i * rtk->
nx];
2489 rtk->
sol.
qr[3] = (float)rtk->
P[1];
2490 rtk->
sol.
qr[4] = (float)rtk->
P[1 + 2 * rtk->
nx];
2491 rtk->
sol.
qr[5] = (float)rtk->
P[2];
2494 for (i = 0; i < n; i++) {
2495 for (j = 0; j < nf; j++) {
2496 if (obs[i].L[j] == 0.0) {
2500 rtk->
ssat[obs[i].
sat - 1].
ph[obs[i].
rcv - 1][j] = obs[i].
L[j];
2503 for (i = 0; i < ns[ch]; i++) {
2504 for (j = 0; j < nf; j++) {
2506 rtk->
ssat[sat[ch][i] - 1].
snr[j] = obs[iu[ch][i]].
SNR[j];
2509 for (i = 0; i <
MAXSAT; i++) {
2510 for (j = 0; j < nf; j++) {
2540 for (i = 0; i < rtk->
nx; i++) {
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.
CLAS (QZSS L6D) CSSR decoder and grid correction type definitions.
int isL2C(int code)
Check if observation code is L2C.
double sat2freq(int sat, uint8_t code, const nav_t *nav)
MRTKLIB Constants — Physical, navigation, and system constants.
MRTKLIB Context — runtime context for processing, trace, and error handling.
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 dops(int ns, const double *azel, double elmin, double *dop)
Compute DOP (dilution of precision).
void ecef2pos(const double *r, double *pos)
Transform ECEF position to geodetic position.
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.
MRTKLIB Broadcast Ephemeris Module — Satellite orbit/clock types and Kepler/GLONASS/SBAS orbit comput...
MRTKLIB Foundation — Common types, standard includes, and system constants (MAXSAT,...
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.
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.
MRTKLIB Navigation Module — Navigation data types and satellite/nav utility functions.
int testsnr(int base, int idx, double el, double snr, const snrmask_t *mask)
Test SNR mask.
MRTKLIB Observation Module — Observation data types and utility functions.
MRTKLIB Options Module — Processing and solution option types.
static int resamb_LAMBDA(rtk_t *rtk, double *bias, double *xa)
Resolve integer ambiguity by LAMBDA.
static int test_sys(int sys, int m, int qzsmodear, int code)
Test if satellite system matches group index.
static const double chisqr[100]
static const double lam_carr[3]
static int validobs(int i, int f, int nf, double *y)
Check if zero-difference observation is valid.
int pre_use_ch[5][MAXSAT+1]
MRTKLIB RTK Positioning Module — relative and precise positioning.
MRTKLIB Solution Module — Solution data types and I/O 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).
MRTKLIB Time Module — GNSS time types and conversion functions.
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.
static void clearsatcorr(void)
static void errmsg(rtk_t *rtk, const char *format,...)
static void detslp_ll(rtk_t *rtk, const obsd_t *obs, int n)
static int validobs(int *iu, int *ir, int jj, int f, int nf, double *y)
static int resamb_LAMBDA(rtk_t *rtk, double *bias, double *xa)
static int get_iriu_index(int sati, int ns, const int *sat)
static int zdres(rtk_t *rtk, int base, const obsd_t *obs, int n, const double *rs, const double *dts, const int *svh, const nav_t *nav, const double *rr, const prcopt_t *opt, int index, double *y, double *e, double *azel)
static double zddop(const rtk_t *rtk, const double *azel, const obsd_t *obs, const double elmask, const int n)
static int test_sys(int sys, int m, int qzsmodear, int code)
static void holdamb(rtk_t *rtk, const double *xa)
static int valid_zd_sig(rtk_t *rtk, const obsd_t *obs, const nav_t *nav, double *y, int nf, int f, int j, int m, int ch, int sati, int iu[][MAXSAT], int ir[][MAXSAT], int sat[][MAXSAT], int *ff, int *ns, int *satj, int *jj, int *sysi, int *sysj, double *lami, double *lamj)
static int ddmat(rtk_t *rtk, double *D)
static int ddres(rtk_t *rtk, const nav_t *nav, double *dt, const double *x, const double *P, const obsd_t *obs, int n, int sat[][MAXSAT], double *y, double *e, double *azel, int iu[][MAXSAT], int ir[][MAXSAT], int *ns, double *v, double *H, double *R, int *vflg, int niter, int order)
static void initx(rtk_t *rtk, double xi, double var, int i)
static double sddop(const rtk_t *rtk, const double *H, const int *vflg, const double elmask, const int nv)
static double baseline(const double *ru, const double *rb, double *dr)
static double varerr(int sat, int sys, double el, double bl, double dt, int f, const prcopt_t *opt)
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)
static int filter2_(rtk_t *rtk, const double *x, const double *P, const double *H, const double *v, const double *R, const int n, const int m, double *xp, double *Pp, double *Qp, const int *vflg, const int flg)
static int selsat(const obsd_t *obs, double *azel, int nu, int *nr, const prcopt_t *opt, int *sat, int *iu, int *ir, int ch)
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)
static int residual_test(rtk_t *rtk, const int *vflg, const double *v, const double *Q, int *iv, const int m, int *ns, const int flg)
static int check_same_fac(const obsd_t *obs, int ir[][MAXSAT])
int relposvrs(rtk_t *rtk, const obsd_t *obs, int nu, int *nr, nav_t *nav)
VRS-RTK relative positioning.
static int selfreqpair(const int sat, const prcopt_t *opt, const obsd_t *obs)
static double gfmeasL1L2(const obsd_t *obs, const nav_t *nav)
static void resetfilterflag(nav_t *nav)
static const double qfrtk[6][60]
static double gloicbcorr(int sat1, int sat2, const prcopt_t *opt, double lam1, double lam2, int f)
static uint8_t obs_code_for_freq_vrs(int sat, int f)
static void ddcov(const int *nb, int n, const double *Ri, const double *Rj, int nv, double *R)
static void check_vrs_facility(nav_t *nav, const obsd_t *obs, int nu, int *nr, int l6mrg)
static void udpos(rtk_t *rtk, const obsd_t *obs, double tt)
static void restamb(rtk_t *rtk, const double *bias, int nb, double *xa)
static double intpres(gtime_t time, const obsd_t *obs, int n, const nav_t *nav, rtk_t *rtk, int ch, double *y)
static void elsort(rtk_t *rtk, const obsd_t *obs, int *isat, double *el, const int n)
static void udstate(rtk_t *rtk, const obsd_t *obs, int nu, const nav_t *nav)
static void detslp_gf(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav)
static void udrcvbias(rtk_t *rtk, double tt)
static void udion(rtk_t *rtk, double tt, double bl, const obsd_t *obs, int ns)
static double calpdop(const rtk_t *rtk, const double *H, const double *azel, const int *vflg, const obsd_t *obs, const double elmask, const int n, const int nv)
static void udbias_ppp(rtk_t *rtk, double tt, const obsd_t *obs, int n, const nav_t *nav)
static int filter2(rtk_t *rtk, double *x, double *P, double *Q, const double *H, const double *v, const double *R, const int n, const int m, const int *vflg, const int flg)
static double gfmeasL1L5(const obsd_t *obs, const nav_t *nav)
static double sat_lambda(int sat, int f, const nav_t *nav)
static void set_init_pb(rtk_t *rtk, const nav_t *nav, const obsd_t *obs, int n, int f, int satj)
MRTKLIB VRS-RTK Module — double-differenced RTK using CLAS VRS.
GNSS time representation.