58#define SQR(x) ((x) * (x))
59#define SQRT(x) ((x) <= 0.0 || (x) != (x) ? 0.0 : sqrt(x))
60#define MIN(x, y) ((x) <= (y) ? (x) : (y))
65#define VAR_POS SQR(30.0)
66#define VAR_VEL SQR(1.0)
67#define VAR_ACC SQR(1.0)
68#define VAR_GRA SQR(0.001)
73#define MAXPBCORSSR 20.0
76#define VARHOLDAMB 0.001
77#define ALPHAAR_DEFAULT 3
78#define MINAMB_DEFAULT 2
79#define MAXOBSLOSS_DEFAULT 300.0
82#define LAM_CARR_L1 (CLIGHT / FREQ1)
83#define LAM_CARR_L2 (CLIGHT / FREQ2)
84#define LAM_CARR_L5 (CLIGHT / FREQ5)
98#define NF_RTK(opt) ((opt)->nf)
99#define NP_RTK(opt) ((opt)->dynamics == 0 ? 3 : 9)
100#define NI_RTK(opt) (((opt)->ionoopt == IONOOPT_EST || (opt)->ionoopt == IONOOPT_EST_ADPT) ? MAXSAT : 0)
101#define NT_RTK(opt) ((opt)->tropopt < TROPOPT_EST ? 0 : ((opt)->tropopt < TROPOPT_ESTG ? 1 : 3))
102#define NR_RTK(opt) (NP_RTK(opt) + NI_RTK(opt) + NT_RTK(opt))
103#define NB_RTK(opt) (MAXSAT * NF_RTK(opt))
104#define NX_RTK(opt) (NR_RTK(opt) + NB_RTK(opt))
107#define II_RTK(s, opt) (NP_RTK(opt) + (s) - 1)
108#define IT_RTK(opt) (NP_RTK(opt) + NI_RTK(opt))
109#define IB_RTK(s, f, opt) (NR_RTK(opt) + MAXSAT * (f) + (s) - 1)
115 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,
116 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,
117 66.6, 68.0, 69.3, 70.7, 72.1, 73.4, 74.7, 76.0, 77.3, 78.6, 80.0, 81.3, 82.6, 84.0, 85.4, 86.7, 88.0,
118 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,
119 110, 112, 113, 114, 115, 116, 118, 119, 120, 122, 123, 125, 126, 127, 128, 129, 131,
120 132, 133, 134, 135, 137, 138, 139, 140, 142, 143, 144, 145, 147, 148, 149};
125static const double qf[6][60] = {
127 {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,
128 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,
129 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,
130 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},
132 {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,
133 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,
134 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,
135 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},
137 {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,
138 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,
139 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,
140 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},
142 {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,
143 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,
144 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,
145 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},
147 {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,
148 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,
149 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,
150 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},
152 {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,
153 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,
154 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,
155 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}};
202 for (f = 0; f < NFREQ; f++) {
203 for (i = 0; i <
MAXSAT; i++) {
207 for (i = 0; i <
MAXSAT; i++) {
215 for (f = 0; f < NFREQ; f++) {
216 for (i = 0; i <
MAXSAT; i++) {
220 for (i = 0; i <
MAXSAT; i++) {
236 int sys =
satsys(sat, NULL);
277 int prn = 0, sys =
satsys(sat, &prn);
283 if (sys ==
SYS_GLO && nav && prn >= 1 && prn <= 32 && nav->glo_fcn[prn - 1] > 0) {
284 fcn = nav->
glo_fcn[prn - 1] - 8;
292 if (!obs || strlen(obs) < 2) {
334static double varerr(
int sat,
int sys,
double el,
int type,
const prcopt_t* opt) {
335 double a, b, c = 0.0, d = 0.0, fact = 1.0;
336 double sinel = sin(el);
342 }
else if (type == 3) {
361 a = fact * opt->
err[1];
362 b = fact * opt->
err[2];
370 return a * a + b * b / sinel / sinel + c * c + d * d;
387 for (j = 0; j < rtk->
nx; j++) {
388 rtk->
P[i + j * rtk->
nx] = rtk->
P[j + i * rtk->
nx] = i == j ? var : 0.0;
404 double *F, *FP, *xp, pos[3], Q[9] = {0}, Qv[9], var = 0.0;
405 double *Fx, *Pxx, *Pxi, *Pxb, *Pxi_, *Pxb_, *xp_;
406 double prnpos_h, prnpos_v;
408 int i, j, nx, na, ni, nb;
413 trace(NULL, 3,
"udpos_ppp:\n");
419 for (i = 0; i < 3; i++) {
426 if (
norm(rtk->
x, 3) <= 0.0) {
427 for (i = 0; i < 3; i++) {
431 for (i = 3; i < 6; i++) {
434 for (i = 6; i < 9; i++) {
442 for (i = 0; i < 3; i++) {
443 var += rtk->
P[i + i * nx];
449 for (i = 0; i < 3; i++) {
452 for (i = 3; i < 6; i++) {
455 for (i = 6; i < 9; i++) {
458 trace(NULL, 2,
"reset rtk position due to large variance: var=%.3f\n", var);
470 for (i = 0; i < 6; i++) {
471 F[i + (i + 3) * nx] = tt;
473 for (i = 0; i < 3; i++) {
474 F[i + (i + 6) * nx] =
SQR(tt) / 2.0;
493 for (i = 0; i < na; i++) {
494 for (j = 0; j < na; j++) {
495 Pxx[i + j * na] = rtk->
P[i + j * nx];
498 for (i = 0; i < na; i++) {
499 for (j = 0; j < ni; j++) {
500 Pxi_[i + j * na] = 0.5 * (rtk->
P[i + (na + j) * nx] + rtk->
P[na + j + i * nx]);
503 for (i = 0; i < na; i++) {
504 for (j = 0; j < nb; j++) {
505 Pxb_[i + j * na] = 0.5 * (rtk->
P[i + (na + ni + j) * nx] + rtk->
P[na + ni + j + i * nx]);
508 for (i = 0; i < na; i++) {
509 for (j = 0; j < na; j++) {
510 Fx[i + j * na] = F[i + j * nx];
515 matmul(
"NN", na, 1, na, 1.0, Fx, xp_, 0.0, xp);
516 for (i = 0; i < na; i++) {
519 for (i = 0; i < ni; i++) {
520 rtk->
x[na + i] *= ki;
523 matmul(
"NN", na, na, na, 1.0, Fx, Pxx, 0.0, FP);
524 matmul(
"NT", na, na, na, 1.0, FP, Fx, 0.0, Pxx);
525 for (i = 0; i < na; i++) {
526 for (j = 0; j < na; j++) {
527 rtk->
P[i + j * nx] = Pxx[i + j * na];
531 matmul(
"NN", na, ni, na, ki, Fx, Pxi_, 0.0, Pxi);
532 for (i = 0; i < na; i++) {
533 for (j = 0; j < ni; j++) {
534 rtk->
P[i + (na + j) * nx] = rtk->
P[(na + j) + i * nx] = Pxi[i + j * na];
538 matmul(
"NN", na, nb, na, 1.0, Fx, Pxb_, 0.0, Pxb);
539 for (i = 0; i < na; i++) {
540 for (j = 0; j < nb; j++) {
541 rtk->
P[i + (na + ni + j) * nx] = rtk->
P[(na + ni + j) + i * nx] = Pxb[i + j * na];
545 for (i = 0; i < ni; i++) {
546 for (j = 0; j < ni; j++) {
547 rtk->
P[(na + i) + (na + j) * nx] *= ki * ki;
550 for (i = 0; i < ni; i++) {
551 for (j = 0; j < nb; j++) {
552 rtk->
P[(na + i) + (na + ni + j) * nx] *= ki;
555 for (i = 0; i < nb; i++) {
556 for (j = 0; j < ni; j++) {
557 rtk->
P[(na + ni + i) + (na + j) * nx] *= ki;
576 for (i = 0; i < 6; i++) {
577 F[i + (i + 3) * 9] = tt;
579 for (i = 0; i < 3; i++) {
580 F[i + (i + 6) * 9] =
SQR(tt) / 2.0;
583 matmul(
"NN", 9, 1, 9, 1.0, F, rtk->
x, 0.0, xp);
587 for (j = 0; j < nx; j++) {
588 for (i = 0; i < 6; i++) {
589 FP[i + j * nx] += rtk->
P[i + 3 + j * nx] * tt;
594 for (j = 0; j < nx; j++) {
595 for (i = 0; i < 6; i++) {
596 rtk->
P[j + i * nx] += rtk->
P[j + (i + 3) * nx] * tt;
607 Q[0] = Q[4] =
SQR(rtk->
opt.
prn[3]) * fabs(tt);
611 for (i = 0; i < 3; i++) {
612 for (j = 0; j < 3; j++) {
613 rtk->
P[i + 6 + (j + 6) * nx] += Qv[i + j * 3];
622 Q[0] = Q[4] =
SQR(prnpos_h) * fabs(tt);
623 Q[8] =
SQR(prnpos_v) * fabs(tt);
626 for (i = 0; i < 3; i++) {
627 for (j = 0; j < 3; j++) {
628 rtk->
P[i + j * nx] += Qv[i + j * 3];
646 trace(NULL, 3,
"udtrop : tt=%.1f\n", tt);
650 if (rtk->
x[j] == 0.0) {
653 for (k = 0; k < 2; k++) {
660 for (k = 0; k < 2; k++) {
661 rtk->
P[++j * (1 + rtk->
nx)] +=
SQR(rtk->
opt.
prn[2] * 0.3) * fabs(rtk->
tt);
685 trace(NULL, 3,
"udion : tt=%.1f ns=%d\n", tt, ns);
687 for (i = 1; i <=
MAXSAT; i++) {
689 if (rtk->
x[j] == 0.0) {
692 for (k = 0; k < ns; k++) {
693 if (obs[k].sat == i) {
701 for (f = 0; f < rtk->
opt.
nf; f++) {
702 if (f > 0 && !(f & m)) {
706 trace(NULL, 3,
"reset iono estimation, sat=%2d outc=%6d\n", i, rtk->
ssat[i - 1].
outc[f]);
711 for (i = 0; i < ns; i++) {
713 if (rtk->
x[j] == 0.0) {
715 rtk->
Q[j + j * rtk->
nx] = 0.0;
722 if (rtk->
Q[j + j * rtk->
nx] == 0.0) {
727 }
else if (rtk->
Q[j + j * rtk->
nx] <
SQR(rtk->
opt.
prn[1])) {
731 qi = rtk->
Q[j + j * rtk->
nx];
734 rtk->
Q[j + j * rtk->
nx] = qi;
736 rtk->
P[j + j * rtk->
nx] += qi * tt;
754 for (i = 0; i < n && i <
MAXOBS; i++) {
755 for (j = 0; j < rtk->
opt.
nf; j++) {
756 if (obs[i].L[j] == 0.0 || !(obs[i].LLI[j] & 3)) {
759 trace(NULL, 2,
"detslp_ll: slip detected sat=%2d f=%d\n", obs[i].sat, j + 1);
775 if (lam0 == 0.0 || lam1 == 0.0 || obs->
L[0] == 0.0 || obs->
L[1] == 0.0) {
778 return lam0 * obs->
L[0] - lam1 * obs->
L[1];
787 if (lam0 == 0.0 || lam2 == 0.0 || obs->
L[0] == 0.0 || obs->
L[2] == 0.0) {
790 return lam0 * obs->
L[0] - lam2 * obs->
L[2];
808 trace(NULL, 3,
"detslp_gf_L1_L2\n");
811 for (i = 0; i < n && i <
MAXOBS; i++) {
818 trace(NULL, 2,
"detslp_gf_L1_L2: slip detected sat=%2d gf=%8.3f->%8.3f\n", obs[i].sat, g0, g1);
824 trace(NULL, 3,
"detslp_gf_L1_L5\n");
827 if (rtk->
opt.
nf <= 2) {
830 for (i = 0; i < n && i <
MAXOBS; i++) {
837 trace(NULL, 2,
"detslp_gf_L1_L5: slip detected sat=%2d gf=%8.3f->%8.3f\n", obs[i].sat, g0, g1);
857 double offset, lami, cp, pr, com_bias;
859 int i, j, f, slip, nf =
NF_RTK(&rtk->
opt), reset, isat;
861 trace(NULL, 3,
"udbias : tt=%.1f n=%d\n", tt, n);
863 for (i = 0; i <
MAXSAT; i++) {
864 for (j = 0; j < rtk->
opt.
nf; j++) {
876 for (f = 0; f < nf; f++) {
878 for (i = 0; i <
MAXSAT; i++) {
883 }
else if (reset && rtk->
x[
IB_RTK(i + 1, f, &rtk->
opt)] != 0.0) {
885 trace(NULL, 3,
"udbias : obs outage counter overflow (sat=%3d L%d n=%5d)\n", i + 1, f + 1,
894 for (i = 0; i < n && i <
MAXOBS; i++) {
914 for (i = j = 0, offset = 0.0; i < n; i++) {
918 if (cp == 0.0 || pr == 0.0 || lami == 0.0) {
922 bias[i] = cp * lami - pr;
925 if (rtk->
x[
IB_RTK(obs[i].sat, f, &rtk->
opt)] != 0.0) {
927 offset += bias[i] - rtk->
x[
IB_RTK(obs[i].sat, f, &rtk->
opt)] * lami;
932 com_bias = j > 0 ? offset / j : 0.0;
935 for (i = 0; i < n; i++) {
937 if (bias[i] == 0.0 || rtk->
x[
IB_RTK(isat, f, &rtk->
opt)] != 0.0) {
940 trace(NULL, 3,
"set initial states of phase-bias, sat=%2d f=%2d\n", obs[i].sat, f + 1);
972 double tt = fabs(rtk->
tt);
974 trace(NULL, 3,
"udstate_ppp: n=%d tt=%f\n", n, tt);
1009 const double* x,
double* dtdx) {
1010 double m_w = 0.0, cotz, grad_n, grad_e;
1020 cotz = 1.0 / tan(azel[1]);
1021 grad_n = m_w * cotz * cos(azel[0]);
1022 grad_e = m_w * cotz * sin(azel[0]);
1023 m_w += grad_n * x[i + 1] + grad_e * x[i + 2];
1024 dtdx[1] = grad_n * x[i];
1025 dtdx[2] = grad_e * x[i];
1027 dtdx[1] = dtdx[2] = 0.0;
1046 return y[f + i * nf * 2] != 0.0 && (f < nf || (y[f - nf + i * nf * 2] != 0.0));
1062static void ddcov(
const int* nb,
int n,
const double* Ri,
const double* Rj,
int nv,
double* R) {
1065 for (i = 0; i < nv * nv; i++) {
1068 for (b = 0; b < n; k += nb[b++]) {
1069 for (i = 0; i < nb[b]; i++) {
1070 for (j = 0; j < nb[b]; j++) {
1071 R[k + i + (k + j) * nv] = Ri[k + i] + ((i == j) ? Rj[k + i] : 0.0);
1089static int test_sys(
int sys,
int m,
int qzsmodear,
int code) {
1092 return m == (code ==
CODE_L2X ? 5 : 0);
1094 return m == (qzsmodear == 2 ? 0 : 4);
1123static int residual_test(
rtk_t* rtk,
const int* vflg,
const double* v,
const double* Q,
int* iv,
const int m,
int* ns,
1125 int i, k, sat2, type, freq, nf = rtk->
opt.
nf;
1126 double inno0, inno1, inno2, gamma;
1127 double *resc, *resp, sig2, vv0_, vvf_, vv = 0.0;
1140 for (i = cnt2 = 0; i < m; i++) {
1141 sat2 = (vflg[i] >> 8) & 0xFF;
1142 type = (vflg[i] >> 4) & 0xF;
1143 freq = (vflg[i]) & 0xF;
1145 resc[(sat2 - 1) * nf + freq] = v[i];
1146 resp[(sat2 - 1) * nf + freq] = Q[i + i * m];
1152 for (i = 0; i <
MAXSAT; i++) {
1153 for (k = 1; k < nf; k++) {
1157 if (resp[i * nf + qi] == 0.0 || resp[i * nf + qj] == 0.0) {
1161 q0 = resp[i * nf + qi];
1162 q1 = resp[i * nf + qj];
1163 vvf_ =
FREQ1 /
FREQ2 * (resc[i * nf + qi] - resc[i * nf + qj]) / (1.0 - gamma);
1164 vv0_ = (gamma * resc[i * nf + qi] - resc[i * nf + qj]) / (gamma - 1.0);
1165 sig2 = q0 > q1 ? q0 : q1;
1168 if ((inno1 > 0.0) && (vvf_ * vvf_ > inno1 * inno1 * sig2)) {
1173 "Residuals validation:freq outlier detected "
1174 "(stage=%1d sat=%2d f=%d %d v=%6.3f sig=%.3f)\n",
1175 flg, i + 1, qi, qj, vvf_, sqrt(sig2));
1179 if ((inno2 > 0.0) && (vv0_ * vv0_ > inno2 * inno2 * sig2)) {
1184 "Residuals validation:L0 outlier detected "
1185 "(stage=%1d sat=%2d v=%6.3f sig=%.3f)\n",
1186 flg, i + 1, vv0_, sqrt(sig2));
1193 for (i = k = cnt = 0; i < m; i++) {
1194 sat2 = (vflg[i] >> 8) & 0xFF;
1195 type = (vflg[i] >> 4) & 0xF;
1196 freq = (vflg[i]) & 0xF;
1199 }
else if (type == 1) {
1207 double qdiag = Q[i + i * m];
1208 if (!qdiag || inno0 == 0 || (v[i] * v[i] < qdiag * inno0 * inno0)) {
1210 if (!rtk->
ssat[sat2 - 1].
vsat[freq]) {
1213 vv += v[i] * v[i] / qdiag;
1216 ns[type < 1 ? freq : freq * type + nf]++;
1220 rtk->
ssat[sat2 - 1].
vsat[freq] = 0;
1223 "meas update outlier detected "
1224 "(sat=%2d %s%d v=%6.3f sig=%6.3f outc=%2d)\n",
1225 sat2, stype, freq + 1, v[i], sqrt(qdiag), rtk->
ssat[sat2 - 1].
outc[freq]);
1233 "L1/L2 chi-square validation failed "
1234 "(stage=%d cnt=%d np=%d vv=%.2f cs=%5.3f)\n",
1239 prtk_ctx.chisq = ((double)cnt / (cnt2 > 0 ? cnt2 : 1)) < 0.5 ? 100.0 : 0.0;
1268static int filter2_(
rtk_t* rtk,
const double* x,
const double* P,
const double* H,
const double* v,
const double* R,
1269 const int n,
const int m,
double* xp,
double* Pp,
double*
Qp,
const int* vflg,
const int flg) {
1270 double *K, *v_, *Q_, *F_, *H_, *I, *F, *Q;
1271 int i, j, k, info = 0, *iv, nn[6];
1276 memset(nn, 0,
sizeof(nn));
1279 matmul(
"NN", n, m, n, 1.0, P, H, 0.0, F);
1280 matmul(
"TN", m, m, n, 1.0, H, F, 1.0, Q);
1283 if (!(k =
residual_test(rtk, vflg, v, Q, iv, m, nn, flg))) {
1284 trace(NULL, 2,
"filter status (all measurements rejected): stage=%1d\n", flg);
1287 "filter status: stage=%1d refsat=%2d states=%2d obs=%2d "
1288 "vobs=%2d vsat(L1)=%2d chi-val=%5.3f\n",
1289 flg, (vflg[iv[0]] >> 16) & 0xFF, n, m, k, nn[0],
prtk_ctx.chisq);
1292 if (flg > 0 || k == 0) {
1305 for (i = 0; i < k; i++) {
1307 for (j = 0; j < k; j++) {
1308 Q_[i + j * k] = Q[iv[i] + iv[j] * m];
1310 for (j = 0; j < n; j++) {
1311 F_[j + i * n] = F[j + iv[i] * n];
1313 for (j = 0; j < n; j++) {
1314 H_[j + i * n] = H[j + iv[i] * n];
1319 if (!(info =
matinv(Q_, k))) {
1320 matmul(
"NN", n, k, k, 1.0, F_, Q_, 0.0, K);
1321 matmul(
"NN", n, 1, k, 1.0, K, v_, 1.0, xp);
1322 matmul(
"NT", n, n, k, -1.0, K, H_, 1.0, I);
1323 matmul(
"NN", n, n, n, 1.0, I, P, 0.0, Pp);
1328 double* vd =
mat(n, 1);
1329 matmul(
"NN", n, 1, k, 1.0, K, v_, 0.0, vd);
1330 matmul(
"NT", n, n, 1, 1.0, vd, vd, 0.0,
Qp);
1370static int filter2(
rtk_t* rtk,
double* x,
double* P,
const double* H,
const double* v,
const double* R,
const int n,
1371 const int m,
const int* vflg,
const int flg) {
1372 double *x_, *xp_, *P_, *Pp_, *Qp_, *H_;
1373 int i, j, k, info, *ix;
1377 for (i = k = 0; i < n; i++) {
1378 if (x[i] != 0.0 && P[i + i * n] > 0.0) {
1389 for (i = 0; i < k; i++) {
1391 for (j = 0; j < k; j++) {
1392 P_[i + j * k] = P[ix[i] + ix[j] * n];
1394 for (j = 0; j < m; j++) {
1395 H_[i + j * k] = H[ix[i] + j * n];
1399 info =
filter2_(rtk, x_, P_, H_, v, R, k, m, xp_, Pp_, Qp_, vflg, flg);
1403 if (adapt &&
prtk_ctx.Qp_nx != n) {
1412 for (i = 0; i < k; i++) {
1414 for (j = 0; j < k; j++) {
1415 P[ix[i] + ix[j] * n] = Pp_[i + j * k];
1417 if (adapt && info == 0) {
1418 for (j = 0; j < k; j++) {
1419 prtk_ctx.Qp[ix[i] + ix[j] * n] = Qp_[i + j * k];
1483 int sati,
int* satj,
int* sysi,
int* sysj,
double* lami,
double* lamj) {
1491 *sysi = rtk->
ssat[sati - 1].
sys;
1492 *sysj = rtk->
ssat[*satj - 1].
sys;
1503 if (*lami <= 0.0 || *lamj <= 0.0) {
1525 double offset, lami, cp, pr, com_bias;
1526 double* bias =
zeros(n, 1);
1529 for (i = j = 0, offset = 0.0; i < n; i++) {
1533 if (cp == 0.0 || pr == 0.0 || lami == 0.0) {
1537 bias[i] = cp * lami - pr;
1540 if (rtk->
x[
IB_RTK(obs[i].sat, f, &rtk->
opt)] != 0.0) {
1541 offset += bias[i] - rtk->
x[
IB_RTK(obs[i].sat, f, &rtk->
opt)] * lami;
1545 com_bias = j > 0 ? offset / j : 0.0;
1548 for (i = 0; i < n; i++) {
1550 if (isat != satj || bias[i] == 0.0) {
1557 trace(NULL, 3,
"set initial states of phase-bias, sat=%2d f=%2d\n", isat, f + 1);
1598 double** y,
double* e,
double* azel,
int n,
double* v,
double* H,
double* R,
int* vflg,
int niter,
1599 int pch,
int order) {
1601 double pos[3], lami, lamj, *Ri, *Rj, *Hi = NULL;
1602 double *tropu, *im, *dtdxu, didxi = 0.0, didxj = 0.0, fi, fj;
1605 int i, j, k, l, m, f, nv = 0, nb[NFREQ * 6 * 2 + 1] = {0}, b = 0;
1606 int sati, satj, sysi, sysj, nf =
NF_RTK(opt), flg = 0;
1607 int h, ch = -1, sch, refsatch, refchgflg, ch_sig_cnt[
SSR_CH_NUM] = {0};
1613 trace(NULL, 3,
"ddres :niter=%2d nx=%d n=%d\n", niter, rtk->
nx, n);
1618 Ri =
mat(n * nf * 2 * 2, 1);
1619 Rj =
mat(n * nf * 2 * 2, 1);
1624 for (f = 0; f < NFREQ; f++) {
1625 for (i = 0; i <=
MAXSAT; i++) {
1631 for (i = 0; i <
MAXSAT; i++) {
1632 for (j = 0; j < NFREQ; j++) {
1638 for (i = 0; i < n; i++) {
1640 im[i] =
ionmapf(pos, azel + i * 2);
1643 tropu[i] =
prectrop2(rtk->
sol.
time, pos, 0, azel + i * 2, opt, x, dtdxu + i * 3);
1648 if (opt->
l6mrg && clas) {
1653 for (m = 0; m < 6; m++) {
1666 for (j = 0; j < n; j++) {
1694 for (h = 0, sch = -1, refchgflg = 0, refsatch = -1; h < ((opt->
l6mrg && !samefac) ?
SSR_CH_NUM : 1); h++) {
1695 for (i = -1, j = 0; j < n; j++) {
1698 sysi = rtk->
ssat[sati - 1].
sys;
1703 for (k = 0; k < niter; k++) {
1704 if (
prtk_ctx.refsat[NFREQ * 2 *
MAXREF * m + NFREQ * 2 * k + f] == sati) {
1716 }
else if (samefac || h == 1) {
1724 if (l > 1 &&
timediff(obs[0].time, nav->
ssr_ch[k][sati - 1].
t0[1]) >= 5.0) {
1738 if (l > 1 &&
timediff(obs[0].time, nav->
ssr_ch[0][sati - 1].
t0[1]) >= 5.0) {
1741 if (l > 1 &&
timediff(obs[0].time, nav->
ssr_ch[1][sati - 1].
t0[1]) >= 5.0) {
1745 if (i < 0 || azel[1 + j * 2] >= azel[1 + i * 2]) {
1767 if (
prtk_ctx.refsat2[NFREQ * 2 * m + f] != sati &&
prtk_ctx.refsat2[NFREQ * 2 * m + f] != 0) {
1769 f % nf + 1,
prtk_ctx.refsat2[NFREQ * 2 * m + f], sati);
1774 prtk_ctx.refsat[NFREQ * 2 *
MAXREF * m + NFREQ * 2 * niter + f] = sati;
1775 prtk_ctx.refsat2[NFREQ * 2 * m + f] = sati;
1778 trace(NULL, 2,
"refsat changed %s L%d sat=%2d -> %2d\n",
time_str(rtk->
sol.
time, 0), f % nf + 1,
1779 prtk_ctx.refsat[NFREQ *
MAXREF * 2 * m + NFREQ * 2 * (niter - 1) + f],
1780 prtk_ctx.refsat[NFREQ *
MAXREF * 2 * m + NFREQ * 2 * niter + f]);
1784 trace(NULL, 4,
"refsat m:%d L%d %s: %d niter:%d\n", m, f + 1,
time_str(rtk->
sol.
time, 0), sati, niter);
1788 if (f < nf && pbslip != NULL) {
1789 for (ch = 0; ch < nch; ch++) {
1790 x[
IB_RTK(sati, f, opt)] += pbslip[ch][
IB_RTK(sati, f, opt)];
1791 pbslip[ch][
IB_RTK(sati, f, opt)] = 0.0;
1797 if (opt->
l6mrg && samefac) {
1802 for (j = 0; j < n; j++) {
1805 if (!
valid_zd_sig(rtk, obs, nav, y[ch], nf, f, i, j, m, sati, &satj, &sysi, &sysj, &lami, &lamj)) {
1808 }
else if (sch == -1) {
1809 if (opt->
l6mrg == 1) {
1813 ch = ch_sig_cnt[0] <= ch_sig_cnt[1] ? 0 : 1;
1815 if (!
valid_zd_sig(rtk, obs, nav, y[ch], nf, f, i, j, m, sati, &satj, &sysi, &sysj, &lami, &lamj)) {
1816 ch = ch == 1 ? 0 : 1;
1817 if (!
valid_zd_sig(rtk, obs, nav, y[ch], nf, f, i, j, m, sati, &satj, &sysi, &sysj, &lami,
1826 if (!
valid_zd_sig(rtk, obs, nav, y[ch], nf, f, i, j, m, sati, &satj, &sysi, &sysj, &lami, &lamj)) {
1831 if (opt->
l6mrg && f < nf) {
1839 if (order ==
FST && !samefac) {
1840 if ((
prtk_ctx.pre_use_ch[f][sati] != ch && refchgflg) || (
prtk_ctx.pre_use_ch[f][satj] != ch)) {
1847 if (f < nf && pbslip != NULL) {
1848 x[
IB_RTK(satj, f, opt)] += pbslip[ch][
IB_RTK(satj, f, opt)];
1849 pbslip[ch][
IB_RTK(satj, f, opt)] = 0.0;
1853 Hi = H + nv * rtk->
nx;
1854 for (k = 0; k < rtk->
nx; k++) {
1861 double yi = refsatch < 0 ? y[ch][f + i * nf * 2] : y[refsatch][f + i * nf * 2];
1862 double yj = y[ch][f + j * nf * 2];
1863 double raw = yi - yj;
1864 double ion = 0.0, trop = 0.0, amb = 0.0;
1869 for (k = 0; k < 3; k++) {
1870 Hi[k] = -e[k + i * 3] + e[k + j * 3];
1878 didxi = (f < nf ? -1.0 : 1.0) * fi * fi * im[i];
1879 didxj = (f < nf ? -1.0 : 1.0) * fj * fj * im[j];
1880 ion = didxi * x[
II_RTK(sati, opt)] - didxj * x[
II_RTK(satj, opt)];
1883 Hi[
II_RTK(sati, opt)] = didxi;
1884 Hi[
II_RTK(satj, opt)] = -didxj;
1890 trop = tropu[i] - tropu[j];
1896 Hi[
IT_RTK(opt) + k] = (dtdxu[k + i * 3] - dtdxu[k + j * 3]);
1902 amb = lami * x[
IB_RTK(sati, f, opt)] - lamj * x[
IB_RTK(satj, f, opt)];
1905 Hi[
IB_RTK(sati, f, opt)] = lami;
1906 Hi[
IB_RTK(satj, f, opt)] = -lamj;
1912 rtk->
ssat[satj - 1].
resc[f] = v[nv];
1913 Ri[nv] =
varerr(sati, sysi, azel[1 + i * 2], 0, opt);
1914 Rj[nv] =
varerr(satj, sysj, azel[1 + j * 2], 0, opt);
1917 Ri[nv] *=
SQR(2.55 / 1.55);
1918 Rj[nv] *=
SQR(2.55 / 1.55);
1921 rtk->
ssat[satj - 1].
resp[f - nf] = v[nv];
1922 Ri[nv] =
varerr(sati, sysi, azel[1 + i * 2], 1, opt);
1923 Rj[nv] =
varerr(satj, sysj, azel[1 + j * 2], 1, opt);
1936 rtk->
ssat[sati - 1].
vs = 1;
1937 rtk->
ssat[satj - 1].
vs = 1;
1940 vflg[nv++] = (sati << 16) | (satj << 8) | ((f < nf ? 0 : 1) << 4) | (f % nf);
1954 ddcov(nb, b, Ri, Rj, nv, R);
1978 int i, j, k, m, f, nb = 0, nx = rtk->
nx, na = rtk->
na, code;
1981 trace(NULL, 3,
"ddmat :\n");
1983 for (i = 0; i <
MAXSAT; i++) {
1984 for (j = 0; j < NFREQ; j++) {
1988 for (i = 0; i < na; i++) {
1989 D[i + i * nx] = 1.0;
1992 for (m = 0; m < 6; m++) {
2000 for (f = 0, k = na; f < nf; f++, k +=
MAXSAT) {
2002 for (i = k; i < k +
MAXSAT; i++) {
2017 for (j = k; j < k +
MAXSAT; j++) {
2025 D[i + (na + nb) * nx] = 1.0;
2026 D[j + (na + nb) * nx] = -1.0;
2038 trace(NULL, 5,
"D=\n");
2039 tracemat(NULL, 5, D, nx, na + nb, 2, 0);
2058 trace(NULL, 3,
"restamb :\n");
2063 for (i = 0; i < rtk->
nx; i++) {
2067 for (i = 0; i < rtk->
na; i++) {
2071 for (m = 0; m < 6; m++) {
2079 for (f = 0; f < nf; f++) {
2080 for (n = i = 0; i <
MAXSAT; i++) {
2085 index[n++] =
IB_RTK(i + 1, f, &rtk->
opt);
2092 xa[index[0]] = rtk->
x[index[0]];
2094 for (i = 1; i < n; i++) {
2095 xa[index[i]] = xa[index[0]] - bias[nv++];
2112 int i, n, m, f, info, index[
MAXSAT], nb = rtk->
nx - rtk->
na;
2115 trace(NULL, 3,
"holdamb :\n");
2120 for (m = 0; m < 6; m++) {
2128 for (f = 0; f < nf; f++) {
2129 for (n = i = 0; i <
MAXSAT; i++) {
2134 index[n++] =
IB_RTK(i + 1, f, &rtk->
opt);
2138 for (i = 1; i < n; i++) {
2139 v[nv] = (xa[index[0]] - xa[index[i]]) - (rtk->
x[index[0]] - rtk->
x[index[i]]);
2141 H[index[0] + nv * rtk->
nx] = 1.0;
2142 H[index[i] + nv * rtk->
nx] = -1.0;
2151 for (i = 0; i < nv; i++) {
2157 if ((info =
filter(rtk->
x, rtk->
P, H, v, R, rtk->
nx, nv))) {
2158 trace(NULL, 2,
"filter error (info=%d)\n", info);
2180 int i, j, k, m = 0, sati;
2182 for (i = 0; i < n; i++) {
2189 for (j = 0; j < m; j++) {
2197 for (k = m; k > j; k--) {
2198 isat[k] = isat[k - 1];
2211static double sddop(
const rtk_t* rtk,
const double* H,
const int* vflg,
double elmask,
int nv) {
2212 double *H_, Q[9], dop = 1000.0;
2213 int i, cnt, freq, type, sat;
2216 for (i = cnt = 0; i < nv; i++) {
2217 sat = (vflg[i] >> 8) & 0xFF;
2218 type = (vflg[i] >> 4) & 0xF;
2219 freq = vflg[i] & 0xF;
2220 if (freq > 0 || type > 0 || rtk->
ssat[sat - 1].
vsat[0] == 0 || rtk->
ssat[sat - 1].
azel[1] <= elmask) {
2223 H_[cnt * 3] = H[i * rtk->
nx];
2224 H_[cnt * 3 + 1] = H[i * rtk->
nx + 1];
2225 H_[cnt * 3 + 2] = H[i * rtk->
nx + 2];
2228 matmul(
"NT", 3, 3, cnt, 1.0, H_, H_, 0.0, Q);
2229 if (cnt > 0 && !
matinv(Q, 3)) {
2230 dop = sqrt(Q[0] + Q[4] + Q[8]);
2238static double zddop(
const rtk_t* rtk,
const double* azel,
const obsd_t* obs,
double elmask,
int n) {
2239 double *azel_, dop[4];
2243 for (i = j = 0; i < n; i++) {
2247 azel_[j * 2] = azel[i * 2];
2248 azel_[j * 2 + 1] = azel[i * 2 + 1];
2251 dops(j, azel_, elmask, dop);
2258static double calpdop(
const rtk_t* rtk,
const double* H,
const double* azel,
const int* vflg,
const obsd_t* obs,
2259 double elmask,
int n,
int nv) {
2262 return zddop(rtk, azel, obs, elmask, n);
2264 return sddop(rtk, H, vflg, elmask, nv);
2281 int i, j, nb, nc, info, nx = rtk->
nx, na = rtk->
na;
2282 int minamb, alpha = -1;
2284 double *D, *y, *b, *db, *Qb, *Qab, *QQ, s[2], thres = 0.0, ratio = 0.0;
2287 trace(NULL, 3,
"resamb_LAMBDA : nx=%d\n", nx);
2297 nb =
ddmat(rtk, D, indI, indJ);
2301 trace(NULL, 2,
"no valid double-difference\n");
2306 trace(NULL, 2,
"less than minimum number of ambiguities nb=%2d minamb=%d\n", nb, minamb);
2311 y =
mat(na + nb, 1);
2320 for (i = 0; i < na; i++) {
2322 for (j = 0; j < nb; j++) {
2323 Qab[i + j * na] = rtk->
P[i + (na + indI[j]) * nx] - rtk->
P[i + (na + indJ[j]) * nx];
2326 for (i = 0; i < nb; i++) {
2327 y[i + na] = rtk->
x[na + indI[i]] - rtk->
x[na + indJ[i]];
2328 for (j = 0; j < nc; j++) {
2329 D_P[i + j * nb] = rtk->
P[na + indI[i] + (na + j) * nx] - rtk->
P[na + indJ[i] + (na + j) * nx];
2332 for (i = 0; i < nb; i++) {
2333 for (j = 0; j < nb; j++) {
2334 Qb[i + j * nb] = D_P[i + indI[j] * nb] - D_P[i + indJ[j] * nb];
2340 if (!(info =
lambda(nb, 2, y + na, Qb, b, s))) {
2341 trace(NULL, 5,
"N(1)=\n");
2342 tracemat(NULL, 5, b, 1, nb, 10, 3);
2343 trace(NULL, 5,
"N(2)=\n");
2344 tracemat(NULL, 5, b + nb, 1, nb, 10, 3);
2346 rtk->
sol.
ratio = (s[0] > 0) ? (
float)(s[1] / s[0]) : 0.0f;
2353 thres = (alpha < 6 && nb - 1 < 60) ?
qf[alpha][nb - 1] : 1.5;
2354 ratio = (s[0] == 0.0) ? 0.0 : s[1] / s[0];
2357 if (s[0] <= 0.0 || ratio >= thres) {
2358 for (i = 0; i < na; i++) {
2359 rtk->
xa[i] = rtk->
x[i];
2360 for (j = 0; j < na; j++) {
2361 rtk->
Pa[i + j * na] = rtk->
P[i + j * nx];
2364 for (i = 0; i < nb; i++) {
2370 matmul(
"NN", nb, 1, nb, 1.0, Qb, y + na, 0.0, db);
2371 matmul(
"NN", na, 1, nb, -1.0, Qab, db, 1.0, rtk->
xa);
2374 matmul(
"NN", na, nb, nb, 1.0, Qab, Qb, 0.0, QQ);
2375 matmul(
"NT", na, na, nb, -1.0, QQ, Qab, 1.0, rtk->
Pa);
2377 trace(NULL, 3,
"resamb : validation ok (nb=%d ratio=%.2f s=%.2f/%.2f)\n", nb, ratio, s[1], s[0]);
2382 trace(NULL, 2,
"lambda error nb=%d\n", nb);
2387 "ambiguity validation failed "
2388 "(nb=%d thres=%.2f ratio=%.2f s=%.2f/%.2f)\n",
2389 nb, thres, ratio, s[1], s[0]);
2393 trace(NULL, 2,
"lambda error (info=%d)\n", info);
2425 double tow, pos[3], vel[3], acc[3], *x;
2426 int i, j, week, nx = rtk->
nx;
2427 char id[32], *p = buff;
2437 p += sprintf(p,
"$POS,%d,%.3f,%d,%.4f,%.4f,%.4f,%.4f,%.4f,%.4f\n", week, tow, rtk->
sol.
stat, x[0], x[1], x[2],
2446 "$VELACC,%d,%.3f,%d,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f,%.4f,%.4f,"
2447 "%.4f,%.5f,%.5f,%.5f\n",
2448 week, tow, rtk->
sol.
stat, vel[0], vel[1], vel[2], acc[0], acc[1], acc[2], 0.0, 0.0, 0.0, 0.0, 0.0,
2457 p += sprintf(p,
"$TROP,%d,%.3f,%d,%d,%.4f,%.4f\n", week, tow, rtk->
sol.
stat, 1, x[i],
2458 SQRT(rtk->
P[i + i * nx]));
2464 p += sprintf(p,
"$TRPG,%d,%.3f,%d,%d,%.5f,%.5f,%.5f,%.5f\n", week, tow, rtk->
sol.
stat, 1, x[i + 1],
2465 x[i + 2],
SQRT(rtk->
P[(i + 1) + (i + 1) * nx]),
SQRT(rtk->
P[(i + 2) + (i + 2) * nx]));
2470 for (i = 0; i <
MAXSAT; i++) {
2471 ssat = rtk->
ssat + i;
2476 if (j >= nx || rtk->
x[j] == 0.0) {
2480 p += sprintf(p,
"$ION,%d,%.3f,%d,%s,%.1f,%.1f,%.4f,%.4f\n", week, tow, rtk->
sol.
stat,
id,
2484 return (
int)(p - buff);
2501 static int savefacility[
SSR_CH_NUM] = {-1, -1};
2506 for (ch = 0; ch < nch; ch++) {
2513 if (savefacility[ch] != facility) {
2514 if (savefacility[ch] != -1) {
2517 savefacility[ch] = facility;
2541 static gtime_t regularly = {-1, 0.0};
2545 double *v, *H, *R, *Pp, *bias, *xp, *xa, *azel, *e;
2548 double pos[3], pdop;
2549 int i, j, k, f, l, nv, nvtmp[
SSR_CH_NUM], nvsum, info, nf = rtk->
opt.
nf, sati;
2553 int nn, use_backup = 0;
2557 trace(NULL, 2,
"ppp_rtk_pos: time=%s nx=%d n=%d\n",
time_str(obs[0].time, 0), rtk->
nx, n);
2560 trace(NULL, 2,
"ppp_rtk_pos: no CLAS context\n");
2569 nv = n * nf * 2 * 3;
2571 for (ch = 0; ch < nch; ch++) {
2572 y[ch] =
zeros(nv, 1);
2574 dts[ch] =
mat(2, n);
2575 var[ch] =
mat(1, n);
2579 for (i = 0; i <
MAXSAT; i++) {
2581 for (j = 0; j < NFREQ; j++) {
2586 for (i = 0; i <
MAXSAT; i++) {
2592 for (i = 0; i < rtk->
nx; i++) {
2602 regularly = (regularly.
time == -1 ? obs[0].
time : regularly);
2604 trace(NULL, 1,
"ppp_rtk_pos: regularly reset filter, tow=%.1f\n",
time2gpst(obs[0].time, NULL));
2605 for (i = 0; i < rtk->
nx; i++) {
2609 regularly = obs[0].
time;
2614 for (ch = 0; ch < nch; ch++) {
2625 trace(NULL, 2,
"ppp_rtk_pos: float persisted %d epochs, resetting filter\n",
prtk_ctx.float_count);
2628 for (i = 0; i < rtk->
nx; i++) {
2633 for (i =
NP_RTK(opt); i < rtk->
nx; i++) {
2642 trace(NULL, 1,
"ppp_rtk_pos: reset filter, tow=%.1f\n",
time2gpst(obs[0].time, NULL));
2644 for (i = 0; i < rtk->
nx; i++) {
2648 for (i =
NP_RTK(opt); i < rtk->
nx; i++) {
2661 grid = &clas->
grid[0];
2665 trace(NULL, 2,
"ppp_rtk_pos: no valid grid\n");
2668 for (ch = 0; ch < nch; ch++) {
2688 for (ch = 0; ch < nch && !use_backup; ch++) {
2698 trace(NULL, 3,
"ppp_rtk_pos: bank lookup failed ch=%d\n", ch);
2706 if (opt->
l6mrg && nok == 1) {
2707 static int warned_single_ch = 0;
2708 if (!warned_single_ch) {
2709 warned_single_ch = 1;
2711 "ppp_rtk_pos: l6_merge running single-channel on ch=%d (only one L6 transmit pattern "
2712 "received so far)\n",
2716 if (!use_backup && nok == 0) {
2720 for (ch = 0; ch < nch; ch++) {
2731 }
else if (!use_backup) {
2735 for (ch = 0; ch < nch; ch++) {
2741 for (ch = 0; ch < nch; ch++) {
2748 trace(NULL, 4,
"x(0)=\n");
2754 for (i = 0; i < 3; i++) {
2755 prtk_ctx.osr_ctx.saved_rr[i] = rtk->
x[i];
2757 for (ch = 0; ch < nch; ch++) {
2759 satposs(obs[0].time, obs, n, nav, rtk->
opt.
sateph, rs[ch], dts[ch], var[ch], svh[ch]);
2760 for (i = 0; i <
MAXSAT; i++) {
2765 xp =
mat(rtk->
nx, 1);
2767 xa =
mat(rtk->
nx, 1);
2768 for (ch = 0; ch < nch; ch++) {
2769 pbslip[ch] =
zeros(rtk->
nx, 1);
2775 for (i = 0; i < rtk->
nx * rtk->
nx; i++) {
2782 H =
mat(rtk->
nx, nv);
2783 bias =
mat(rtk->
nx, 1);
2786 for (i = 0; i < rtk->
opt.
niter; i++) {
2787 for (k = 0; k <
MAXREF; k++) {
2790 for (ch = 0, nvsum = 0; ch < nch; ch++) {
2791 for (j = 0; j <
MAXSAT; j++) {
2793 for (f = 0; f < NFREQ; f++) {
2797 for (j = 0; j < 3; j++) {
2798 pbslip[ch][j] = xp[j];
2801 nvtmp[ch] =
clas_osr_zdres(obs, n, rs[ch], dts[ch], var[ch], svh[ch], nav, pbslip[ch], y[ch], e, azel,
2803 &rtk->
sol, NULL, ch);
2808 if (ch != 0 && opt->
l6mrg) {
2809 pch = nvtmp[0] >= nvtmp[1] ? 0 : 1;
2814 trace(NULL, 2,
"rover initial position error\n");
2819 if ((nv =
ddres(rtk, nav, xp, pbslip, Pp, obs, y, e, azel, n, v, H, R, vflg, k, pch,
FST)) <= 0) {
2820 trace(NULL, 2,
"no double-differenced residual\n");
2827 if ((info =
filter2(rtk, xp, Pp, H, v, R, rtk->
nx, nv, vflg, 0)) != 0) {
2836 for (ch = 0, nvsum = 0; ch < nch; ch++) {
2838 nvtmp[ch] =
clas_osr_zdres(obs, n, rs[ch], dts[ch], var[ch], svh[ch], nav, xp, y[ch], e, azel, rtk, 0,
2843 if (ch != 0 && opt->
l6mrg) {
2844 pch = nvtmp[0] >= nvtmp[1] ? 0 : 1;
2849 nv =
ddres(rtk, nav, xp, NULL, Pp, obs, y, e, azel, n, v, NULL, R, vflg, k, pch,
SND);
2851 filter2(rtk, xp, Pp, H, v, R, rtk->
nx, nv, vflg, 1);
2859 trace(NULL, 2,
"measurement update failed\n");
2866 for (ch = 0; ch < nch; ch++) {
2867 for (i = 0; i < n && i <
MAXOBS; i++) {
2871 if (rtk->
sol.
age > age) {
2881 for (i = 0; i < n; i++) {
2884 rtk->
Q[j + j * rtk->
nx] =
2892 for (i = 0; i < np; i++) {
2893 for (j = 0; j < np; j++) {
2895 rtk->
Q[i + j * rtk->
nx] =
2910 for (i = 0; i < n; i++) {
2912 for (f = 0; f < nf; f++) {
2913 if (!rtk->
ssat[sati - 1].
vsat[f]) {
2923 trace(NULL, 5,
"valid sat(L1=%d)\n", rtk->
sol.
ns);
2926 if (rtk->
sol.
ns < 4) {
2927 trace(NULL, 2,
"lack of valid satellites.\n");
2933 for (i = 0; i < rtk->
nx; i++) {
2934 for (j = 0; j < i; j++) {
2935 rtk->
P[i + j * rtk->
nx] = rtk->
P[j + i * rtk->
nx] =
2936 (rtk->
P[i + j * rtk->
nx] + rtk->
P[j + i * rtk->
nx]) * 0.5;
2946 double posvar = 0.0;
2947 for (i = 0; i < 3; i++) {
2948 posvar += rtk->
P[i + i * rtk->
nx];
2952 trace(NULL, 3,
"ppprtk: skip AR (posvar=%.4f>thresar1=%.4f)\n", posvar, rtk->
opt.
thresar[1]);
2954 goto ppprtk_ar_done;
2960 if (nb <= 1 && rtk->opt.
posopt[6]) {
2962 double el[
MAXOBS], ratio = 0.0;
2963 elsort(rtk, obs, isat, el, n);
2966 for (i = 0; i < n; i++) {
2972 for (f = j = 0; f < nf2; f++) {
2981 for (f = 0; f < nf2; f++) {
2987 trace(NULL, 2,
"PAR OK: excluded sat=%2d el=%.1f nb=%d ratio=%.2f\n", sati, el[i] *
R2D, nb,
2992 for (f = 0; f < nf2; f++) {
2995 if (ratio < rtk->sol.ratio) {
3006 for (f = 0; f < nf2; f++) {
3014 if (nb <= 1 && rtk->opt.
arfilter) {
3015 int nf2 =
NF_RTK(&rtk->
opt), rerun = 0, dly = 2, sat;
3016 for (sat = 0; sat <
MAXSAT; sat++) {
3017 for (f = 0; f < nf2; f++) {
3026 trace(NULL, 3,
"ppprtk arfilter: rerun with newly-locked sats excluded\n");
3034 for (ch = 0, nvsum = 0; ch < nch; ch++) {
3036 nvtmp[ch] =
clas_osr_zdres(obs, n, rs[ch], dts[ch], var[ch], svh[ch], nav, xa, y[ch], e, azel, rtk, 0,
3041 if (ch != 0 && opt->
l6mrg) {
3042 pch = nvtmp[0] >= nvtmp[1] ? 0 : 1;
3047 nv =
ddres(rtk, nav, xa, NULL, NULL, obs, y, e, azel, n, v, NULL, R, vflg, k, pch,
TRD);
3049 filter2(rtk, xp, Pp, H, v, R, rtk->
nx, nv, vflg, 2);
3079 trace(NULL, 2,
"reset all states due to large pos error dist=%.2f\n", sqrt(dist2));
3081 for (i = 0; i < 3; i++) {
3082 rtk->
x[i] = rtk->
sol.
rr[i];
3083 rtk->
P[i + i * rtk->
nx] = (double)rtk->
sol.
qr[i];
3094 for (i = 0; i < 3; i++) {
3096 rtk->
sol.
qr[i] = (float)rtk->
Pa[i + i * rtk->
na];
3098 rtk->
sol.
qr[3] = (float)rtk->
Pa[1];
3099 rtk->
sol.
qr[4] = (float)rtk->
Pa[1 + 2 * rtk->
na];
3100 rtk->
sol.
qr[5] = (float)rtk->
Pa[2];
3102 for (i = 0; i < 3; i++) {
3103 rtk->
sol.
rr[i] = rtk->
x[i];
3104 rtk->
sol.
qr[i] = (float)rtk->
P[i + i * rtk->
nx];
3106 rtk->
sol.
qr[3] = (float)rtk->
P[1];
3107 rtk->
sol.
qr[4] = (float)rtk->
P[1 + 2 * rtk->
nx];
3108 rtk->
sol.
qr[5] = (float)rtk->
P[2];
3113 for (i = 0; i < n; i++) {
3114 for (j = 0; j < nf; j++) {
3115 if (obs[i].L[j] == 0.0) {
3119 rtk->
ssat[obs[i].
sat - 1].
ph[obs[i].
rcv - 1][j] = obs[i].
L[j];
3123 for (i = 0; i < n; i++) {
3124 for (j = 0; j < nf; j++) {
3129 for (i = 0; i <
MAXSAT; i++) {
3130 for (j = 0; j < nf; j++) {
3156 for (i = 0; i < rtk->
nx; i++) {
3160 for (i =
NP_RTK(opt); i < rtk->
nx; i++) {
3167 for (ch = 0; ch < nch; ch++) {
3168 for (j = 0; j <
MAXSAT; j++) {
3170 for (f = 0; f < NFREQ; f++) {
3187 for (ch = 0; ch < nch; ch++) {
3206 trace(NULL, 3,
"rtkinit_ppp_rtk:\n");
3224 trace(NULL, 3,
"rtkfree_ppp_rtk:\n");
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)
char * code2obs(uint8_t code)
void clas_check_grid_status(clas_ctx_t *ctx, const clas_corr_t *corr, int ch)
Check and update grid status flags based on correction availability.
void clas_restore_backup(clas_ctx_t *ctx, gtime_t time, clas_grid_t *grid, int l6mrg)
int clas_bank_get_close(const clas_ctx_t *ctx, gtime_t time, int network, int ch, clas_corr_t *corr)
Merge closest corrections from all banks into a clas_corr_t snapshot.
void clas_update_global(nav_t *nav, const clas_corr_t *corr, int ch)
Apply global corrections (orbit/clock/bias) to nav_t.ssr[].
int clas_backup_valid(const clas_ctx_t *ctx, gtime_t obstime, int l6mrg)
Save/restore the latest usable CSSR snapshot for short correction gaps.
void clas_update_local(nav_t *nav, const clas_corr_t *corr, int ch)
Apply local corrections (trop/STEC) to nav_t.
void clas_backup_current(clas_ctx_t *ctx, const clas_grid_t *grid, int l6mrg)
void clas_clear_current(clas_ctx_t *ctx, int ch)
Drop the current correction snapshot of one channel.
CLAS (QZSS L6D) CSSR decoder and grid correction type definitions.
int clas_get_grid_index(clas_ctx_t *ctx, const double *pos, clas_grid_t *grid, int gridsel, gtime_t obstime)
Select surrounding grid points and compute interpolation weights.
int clas_osr_selfreqpair(int sat, const prcopt_t *opt, const obsd_t *obs)
Select frequency pair for multi-frequency processing.
int clas_osr_zdres(const obsd_t *obs, int n, const double *rs, const double *dts, const double *vare, const int *svh, nav_t *nav, double *x, double *y, double *e, double *azel, rtk_t *rtk, int osrlog, clas_osr_ctx_t *osr_ctx, clas_grid_t *grid, clas_corr_t *corr, ssat_t *ssat, prcopt_t *opt, sol_t *sol, clas_osrd_t *osr, int ch)
Compute zero-differenced phase/code residuals with CLAS corrections.
int clas_osr_satcorr_update(gtime_t time, gtime_t teph, int sat, const prcopt_t *opt, const nav_t *nav, int ch, clas_osr_ctx_t *ctx)
Update per-satellite SIS correction state for IODE adjustment.
#define IB_RTK(s, f, opt)
MRTKLIB Constants — Physical, navigation, and system constants.
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.
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 set_ssr_ch_idx(int ch)
Set SSR channel index for satpos_ssr() (multi-L6E).
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.
double freq_num2freq(int sys, int freq_num, int fcn)
Convert frequency number to frequency in Hz.
int freq_idx2freq_num(int sys, int freq_idx)
Convert frequency index to frequency number using obsdef table.
MRTKLIB Navigation Module — Navigation data types and satellite/nav utility functions.
static int ddres(rtk_t *rtk, const nav_t *nav, double *x, double **pbslip, const double *P, const obsd_t *obs, double **y, double *e, double *azel, int n, double *v, double *H, double *R, int *vflg, int niter, int pch, int order)
Compute DD residuals and measurement matrix, merging L6 channels.
static void detslp_ll(rtk_t *rtk, const obsd_t *obs, int n)
Detect cycle slip by LLI flag.
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 resamb_LAMBDA(rtk_t *rtk, double *bias, double *xa)
Resolve integer ambiguity by LAMBDA.
gtime_t pt0[SSR_CH_NUM][MAXSAT]
void rtkinit_ppp_rtk(rtk_t *rtk, const prcopt_t *opt)
Initialize RTK control struct for PPP-RTK positioning.
static double gfmeas_L1L2(const obsd_t *obs, const nav_t *nav)
L1/L2 geometry-free phase measurement.
static int test_sys(int sys, int m, int qzsmodear, int code)
Test if satellite system matches group index.
static void check_clas_facility(nav_t *nav, const clas_ctx_t *clas, const clas_grid_t *grid, const prcopt_t *opt)
static void holdamb(rtk_t *rtk, const double *xa)
Hold fixed ambiguities via pseudomeasurement constraint.
static struct @371154060365014213017353377321306024134051277272 prtk_ctx
static int valid_zd_sig(rtk_t *rtk, const obsd_t *obs, const nav_t *nav, double *y, int nf, int f, int i, int j, int m, int sati, int *satj, int *sysi, int *sysj, double *lami, double *lamj)
Check that a satellite yields a usable zero-difference signal.
static void initx(rtk_t *rtk, double xi, double var, int i)
Initialize a state and its covariance.
static double varerr(int sat, int sys, double el, int type, const prcopt_t *opt)
Compute measurement error variance.
int ppp_rtk_na(const prcopt_t *opt)
Compute number of non-ambiguity states for PPP-RTK.
static double sddop(const rtk_t *rtk, const double *H, const int *vflg, double elmask, int nv)
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)
Inner KF measurement update with residual test.
static void udpos_ppp(rtk_t *rtk, const obsd_t *obs, int n, double tt)
Temporal update of position states.
static void save_ppp_osr_cpc(const clas_osr_ctx_t *ctx, double *cpc, gtime_t *pt0)
static double prectrop2(gtime_t time, const double *pos, int r, const double *azel, const prcopt_t *opt, const double *x, double *dtdx)
Compute precise tropospheric delay for KF.
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)
Validate residuals and reject outliers.
static uint8_t obs_code_for_freq(int sat, int f)
Return default observation code for frequency index and system.
static double gfmeas_L1L5(const obsd_t *obs, const nav_t *nav)
L1/L5 geometry-free phase measurement.
static int filter2(rtk_t *rtk, double *x, double *P, const double *H, const double *v, const double *R, const int n, const int m, const int *vflg, const int flg)
KF measurement update with state compaction.
int ppprtk_outstat(rtk_t *rtk, char *buff)
Write PPP-RTK solution status to buffer.
static void udtrop(rtk_t *rtk, double tt)
Temporal update of tropospheric parameters.
static int check_same_fac(const clas_ctx_t *clas)
Test whether the two L6 channels currently carry the same facility.
static int ddmat(rtk_t *rtk, double *D, int *indI, int *indJ)
Build SD-to-DD transformation matrix D.
static void ddcov(const int *nb, int n, const double *Ri, const double *Rj, int nv, double *R)
Build DD covariance from SD variances.
static double calpdop(const rtk_t *rtk, const double *H, const double *azel, const int *vflg, const obsd_t *obs, double elmask, int n, int nv)
double cpc[SSR_CH_NUM][MAXSAT *5]
static void restamb(rtk_t *rtk, const double *bias, int nb, double *xa)
Restore SD ambiguities from DD fixed values.
static void load_ppp_osr_cpc(clas_osr_ctx_t *ctx, const double *cpc, const gtime_t *pt0)
static double zddop(const rtk_t *rtk, const double *azel, const obsd_t *obs, double elmask, int n)
#define MAXOBSLOSS_DEFAULT
static void elsort(rtk_t *rtk, const obsd_t *obs, int *isat, double *el, int n)
Sort satellites by elevation angle (ascending) for partial AR.
static void detslp_gf(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav)
Detect cycle slip by geometry-free phase jump.
static const double chisqr[100]
static void udion(rtk_t *rtk, double tt, double bl, const obsd_t *obs, int ns)
Temporal update of ionospheric parameters.
static const double lam_carr[3]
static void udbias_ppp(rtk_t *rtk, double tt, const obsd_t *obs, int n, const nav_t *nav)
Temporal update of phase biases.
static int validobs(int i, int f, int nf, double *y)
Check if zero-difference observation is valid.
int ppp_rtk_nx(const prcopt_t *opt)
Compute number of estimated states for PPP-RTK.
static void udstate_ppp(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav)
Temporal update of all PPP-RTK states.
int pre_use_ch[5][MAXSAT+1]
static double sat_lambda(int sat, int f, const nav_t *nav)
Compute satellite-specific wavelength for frequency index.
static void set_init_pb(rtk_t *rtk, const nav_t *nav, const obsd_t *obs, int n, int f, int satj)
Re-initialize the phase-bias state of one satellite from phase-code.
#define IB_RTK(s, f, opt)
static const double qf[6][60]
void rtkfree_ppp_rtk(rtk_t *rtk)
Free RTK control struct for PPP-RTK positioning.
PPP-RTK positioning engine declarations.
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.
double cpctmp[MAXSAT *(5+5)]
gtime_t pt0tmp[MAXSAT *(5+5)]
GNSS time representation.
ssr_t ssr_ch[SSR_CH_NUM][MAXSAT]