54extern int satsys(
int sat,
int* prn);
56extern void satno2id(
int sat,
char*
id);
64extern double norm(
const double* a,
int n);
65extern void matcpy(
double* A,
const double* B,
int n,
int m);
66extern void matmul(
const char* tr,
int n,
int k,
int m,
double alpha,
const double* A,
const double* B,
double beta,
68extern double*
mat(
int n,
int m);
69extern double*
zeros(
int n,
int m);
70extern int filter(
double* x,
double* P,
const double* H,
const double* v,
const double* R,
int n,
int m);
71extern int lambda(
int n,
int m,
const double* a,
const double* Q,
double* F,
double* s);
72extern unsigned int tickget(
void);
78#define CONST_AMB_BDS 0.05
79#define CONST_AMB_BDS_B2a 0.10
80#define CONST_AMB_GAL_E6 0.10
81#define CONST_AMB_EWL 0.10
82#define MAX_STD_FIX 0.15
83#define MIN_MATCH_RATE 0.10
84#define REL_MATCH_RATE 0.90
85#define MAX_FRAC_WL_FIX 0.20
86#define MAX_STD_WL_FIX 1.00
92#define MIN(x, y) ((x) < (y) ? (x) : (y))
93#define MAX(x, y) ((x) > (y) ? (x) : (y))
94#define SQR(x) ((x) * (x))
95#define ROUND(x) (int)floor((x) + 0.5)
102#define SWAP_D(x, y) \
110#define NF(opt) ((opt)->ionoopt == IONOOPT_IFLC ? 1 : (opt)->nf)
111#define NP(opt) ((opt)->dynamics ? 9 : 3)
112#define NC(opt) (NSYS + 1)
118#define NI(opt) ((opt)->ionoopt == IONOOPT_EST ? MAXSAT : 0)
119#define N3(opt) (NF(opt) >= 3 ? NC(opt) : 0)
120#define N4(opt) (NF(opt) >= 4 ? NC(opt) : 0)
121#define NR(opt) (NP(opt) + NC(opt) + NT(opt) + NI(opt) + N3(opt) + N4(opt))
122#define IT(opt) (NP(opt) + NC(opt))
123#define IB(s, f, opt) (NR(opt) + MAXSAT * (f) + (s) - 1)
131 for (i = 0; i < NFREQ; i++) {
156 trace(NULL, 4,
"exc_sat_sd(%4d): nf=%d arsys=%d elmaskar=%2.0f\n", __LINE__, nf, arsys, rtk->
opt.
elmaskar);
167 if (!rtk->
ssat[obs->
sat - 1].
vsat[0] || el < elmask) {
168 trace(NULL, 2,
"exc_sat_sd(%4d): sys=%2d sat=%3d excluded by el=%4.1f / %4.1f\n", __LINE__,
172 trace(NULL, 4,
"exc_sat_sd(%4d): sat=%d\n", __LINE__, obs->
sat);
178 int* sat2,
double* el1,
double* el2) {
180 double elmask, el[
MAXOBS], maxel;
181 int i, j, k, m, f, ns = 0, sat[
MAXOBS];
182 int stat = 0, maxsat, excmask[
MAXOBS];
185 trace(NULL, 3,
"gen_sat_sd(%4d): nf=%d arsys=%d elmaskar=%2.0f\n", __LINE__, nf, rtk->
opt.
arsys,
190 for (i = 0; sys[i]; i++) {
192 for (j = 0; j < n; j++) {
197 for (j = 0, maxsat = 0, maxel = 0.0; j < n; j++) {
198 if (!
exc_sat_sd(rtk, obs + j, exc[j], azel[1 + j * 2], nf, sys[i])) {
202 for (f = 0, stat = 0; f < 2; f++) {
203 stat |= (obs[j].
L[f] == 0.0);
204 trace(NULL, 4,
"gen_sat_sd(%4d): sys=%d sat=%3d f=%d obs[j].L[f]=%14.3f stat=%d\n", __LINE__, sys[i],
205 obs[j].sat, f, obs[j].L[f], stat);
216 if (azel[1 + j * 2] > maxel) {
217 maxel = azel[1 + j * 2];
222 trace(NULL, 4,
"gen_sat_sd(%4d): no reference satellite sys=%d maxsat=%3d maxel=%4.1f\n", __LINE__, sys[i],
223 maxsat, maxel *
R2D);
226 trace(NULL, 4,
"gen_sat_sd(%4d): sys=%d maxsat=%3d maxel=%4.1f\n", __LINE__, sys[i], maxsat, maxel *
R2D);
229 for (j = m = 0; j < n; j++) {
233 if (obs[j].sat == maxsat) {
238 el[m++] = azel[1 + j * 2];
240 for (j = 0; j < m - 1; j++) {
241 for (k = j + 1; k < m; k++) {
242 if (el[j] >= el[k]) {
250 for (j = 0; j < m; j++) {
259 trace(NULL, 3,
"gen_sat_sd(%4d): %s %s el=%4.1f %4.1f[deg]\n", __LINE__, s1, s2, el[j] *
R2D, maxel *
R2D);
262 trace(NULL, 4,
"gen_sat_sd(%4d): ns=%d\n", __LINE__, ns);
266static void write_trace_amb(
rtk_t* rtk,
const double* a,
const double* Q,
int na,
const int* sat1s,
const int* sat2s,
267 const int* frqs,
const char label[NFREQ][10],
int step) {
269 double ep[6] = {0.0};
280 for (i = 0; i < na; i++) {
283 trace(NULL, 2,
"write_trace_amb:, STEP_%d, %5.0f, %s_%s, %s, %14.3f, %7.3f, %7.3f\n", step,
284 timediff(rtk->
sol.
time, t0), s2, s1, label[frqs[i]], a[i], sqrt(Q[i + i * na]),
ROUND(a[i]) - a[i]);
288 int nf,
int* sat1s,
int* sat2s,
int* frqs,
double* a,
int post,
int step) {
289 int i, f, j, k, j1, j2, k1, k2, na = 0;
292 const char label1[NFREQ][10] = {
"PRE-N1 ",
"PRE-WL ",
"PRE-EWL",
"PRE-EW2"};
293 const char label2[NFREQ][10] = {
"POST-N1 ",
"POST-WL ",
"POST-EWL",
"POST-EW2"};
295 if (!strstr(rtk->
opt.
pppopt,
"-TRACE_AR")) {
298 trace(NULL, 4,
"write_trace_sd_amb(%4d): ns=%d nf=%d\n", __LINE__, ns, nf);
301 Q =
mat(ns * NFREQ, ns * nf);
304 for (i = 0; i < ns; i++) {
305 if (sat1[i] <= 0 || sat2[i] <= 0) {
310 for (f = 0; f < nf; f++) {
316 j =
IB(sat1[i], 0, &rtk->
opt);
317 k =
IB(sat2[i], 0, &rtk->
opt);
322 if (x[j] == 0.0 || x[k] == 0.0) {
326 D[j + na * rtk->
nx] = 1.0 / lam[0];
327 D[k + na * rtk->
nx] = -1.0 / lam[0];
330 j1 =
IB(sat1[i], 0, &rtk->
opt);
331 j2 =
IB(sat1[i], 1, &rtk->
opt);
332 k1 =
IB(sat2[i], 0, &rtk->
opt);
333 k2 =
IB(sat2[i], 1, &rtk->
opt);
335 if (lam[0] == 0.0 || lam[1] == 0.0) {
338 if (x[j1] == 0.0 || x[j2] == 0.0) {
341 if (x[k1] == 0.0 || x[k2] == 0.0) {
345 D[j1 + na * rtk->
nx] = 1.0 / lam[0];
346 D[j2 + na * rtk->
nx] = -1.0 / lam[1];
347 D[k1 + na * rtk->
nx] = -1.0 / lam[0];
348 D[k2 + na * rtk->
nx] = 1.0 / lam[1];
351 j1 =
IB(sat1[i], 1, &rtk->
opt);
352 j2 =
IB(sat1[i], 2, &rtk->
opt);
353 k1 =
IB(sat2[i], 1, &rtk->
opt);
354 k2 =
IB(sat2[i], 2, &rtk->
opt);
356 if (lam[1] == 0.0 || lam[2] == 0.0) {
359 if (x[j1] == 0.0 || x[j2] == 0.0) {
362 if (x[k1] == 0.0 || x[k2] == 0.0) {
366 D[j1 + na * rtk->
nx] = 1.0 / lam[1];
367 D[j2 + na * rtk->
nx] = -1.0 / lam[2];
368 D[k1 + na * rtk->
nx] = -1.0 / lam[1];
369 D[k2 + na * rtk->
nx] = 1.0 / lam[2];
372 j1 =
IB(sat1[i], 1, &rtk->
opt);
373 j2 =
IB(sat1[i], 3, &rtk->
opt);
374 k1 =
IB(sat2[i], 1, &rtk->
opt);
375 k2 =
IB(sat2[i], 3, &rtk->
opt);
377 if (lam[1] == 0.0 || lam[3] == 0.0) {
380 if (x[j1] == 0.0 || x[j2] == 0.0) {
383 if (x[k1] == 0.0 || x[k2] == 0.0) {
387 D[j1 + na * rtk->
nx] = 1.0 / lam[1];
388 D[j2 + na * rtk->
nx] = -1.0 / lam[3];
389 D[k1 + na * rtk->
nx] = -1.0 / lam[1];
390 D[k2 + na * rtk->
nx] = 1.0 / lam[3];
397 W =
mat(rtk->
nx, na);
398 matmul(
"TN", na, 1, rtk->
nx, 1.0, D, x, 0.0, a);
399 matmul(
"TN", na, rtk->
nx, rtk->
nx, 1.0, D, P, 0.0, W);
400 matmul(
"NN", na, na, rtk->
nx, 1.0, W, D, 0.0, Q);
413static int search_amb_ewl(
rtk_t* rtk,
const double* x,
const double* P,
const int* sat1,
const int* sat2,
int ns,
414 int nf,
int* sat1s,
int* sat2s,
int* frqs,
double* a,
double* N,
double* D) {
415 int i, j1, j2, k1, k2, na = 0;
418 double b, n, var, frac;
427 for (i = 0; i < rtk->
nx * (ns * 2); i++) {
432 for (i = 0; i < ns; i++) {
433 if (sat1[i] <= 0 || sat2[i] <= 0) {
440 for (f = 2; f < rtk->
opt.
nf; f++) {
449 j1 =
IB(sat1[i], f1, &rtk->
opt);
450 j2 =
IB(sat1[i], f2, &rtk->
opt);
451 k1 =
IB(sat2[i], f1, &rtk->
opt);
452 k2 =
IB(sat2[i], f2, &rtk->
opt);
454 if (lam[f1] == 0.0 || lam[f2] == 0.0 || x[j1] == 0.0 || x[j2] == 0.0 || x[k1] == 0.0 || x[k2] == 0.0) {
455 trace(NULL, 3,
"search_amb_ewl(%4d): skipped %s %s x(j1,j2,k1,k2)=%8.3f %8.3f %8.3f %8.3f\n", __LINE__,
456 s1, s2, x[j1], x[j2], x[k1], x[k2]);
460 b = (x[j1] / lam[f1] - x[j2] / lam[f2]) - (x[k1] / lam[f1] - x[k2] / lam[f2]);
463 var = P[j1 + j1 * rtk->
nx] /
SQR(lam[f1]) + P[j2 + j2 * rtk->
nx] /
SQR(lam[f2]) -
464 2.0 * P[j1 + j2 * rtk->
nx] / (lam[f1] * lam[f2]);
465 var += P[k1 + k1 * rtk->
nx] /
SQR(lam[f1]) + P[k2 + k2 * rtk->
nx] /
SQR(lam[f2]) -
466 2.0 * P[k1 + k2 * rtk->
nx] / (lam[f1] * lam[f2]);
468 if (sqrt(var) > th_std || frac > th_frac) {
470 "search_amb_ewl(%4d): excluded %s %s N,a= %8.3f %8.3f "
471 "sig=%8.3f frac=%8.3f/%8.3f std=%8.3f/%8.3f\n",
472 __LINE__, s1, s2, n, b, sqrt(var), frac, th_frac, sqrt(var), th_std);
482 D[j1 + na * rtk->
nx] = 1.0 / lam[f1];
483 D[j2 + na * rtk->
nx] = -1.0 / lam[f2];
484 D[k1 + na * rtk->
nx] = -1.0 / lam[f1];
485 D[k2 + na * rtk->
nx] = 1.0 / lam[f2];
486 rtk->
ssat[sat1s[na] - 1].
fix[f2] = rtk->
ssat[sat2s[na] - 1].
fix[f2] = 1;
489 if (strstr(rtk->
opt.
pppopt,
"-TRACE_AR")) {
490 trace(NULL, 3,
"search_amb_ewl(%4d): %s %s N,a= %8.3f %8.3f sig=%8.3f\n", __LINE__, s1, s2, n, b,
495 trace(NULL, 4,
"search_amb_ewl(%4d): number of fixed extra wide-lane ambiguity = %d / %d\n", __LINE__, na, ns);
499static int search_amb_wl(
rtk_t* rtk,
const double* x,
const double* P,
int* sat1,
int* sat2,
int ns,
int nf,
int* sat1s,
500 int* sat2s,
int* frqs,
double* a,
double* N,
double* D) {
501 int i, j1, j2, k1, k2, na = 0;
503 double b, n, var, frac;
512 for (i = 0; i < rtk->
nx * ns; i++) {
517 for (i = 0; i < ns; i++) {
518 if (sat1[i] <= 0 || sat2[i] <= 0) {
525 j1 =
IB(sat1[i], 0, &rtk->
opt);
526 j2 =
IB(sat1[i], 1, &rtk->
opt);
527 k1 =
IB(sat2[i], 0, &rtk->
opt);
528 k2 =
IB(sat2[i], 1, &rtk->
opt);
530 if (lam[0] == 0.0 || lam[1] == 0.0 || x[j1] == 0.0 || x[j2] == 0.0 || x[k1] == 0.0 || x[k2] == 0.0) {
531 trace(NULL, 3,
"search_amb_wl(%4d): excluded %s %s x(j1,j2,k1,k2)=%.3f %.3f %.3f %.3f\n", __LINE__, s1, s2,
532 x[j1], x[j2], x[k1], x[k2]);
539 b = (x[j1] / lam[0] - x[j2] / lam[1]) - (x[k1] / lam[0] - x[k2] / lam[1]);
542 var = P[j1 + j1 * rtk->
nx] /
SQR(lam[0]) + P[j2 + j2 * rtk->
nx] /
SQR(lam[1]) -
543 2.0 * P[j1 + j2 * rtk->
nx] / (lam[0] * lam[1]);
544 var += P[k1 + k1 * rtk->
nx] /
SQR(lam[0]) + P[k2 + k2 * rtk->
nx] /
SQR(lam[1]) -
545 2.0 * P[k1 + k2 * rtk->
nx] / (lam[0] * lam[1]);
547 if (sqrt(var) > th_std || frac > th_frac) {
549 "search_amb_wl(%4d): excluded %s %s N,a= %8.3f %8.3f "
550 "sig=%8.3f frac=%8.3f/%8.3f std=%8.3f/%8.3f\n",
551 __LINE__, s1, s2, n, b, sqrt(var), frac, th_frac, sqrt(var), th_std);
565 D[j1 + na * rtk->
nx] = 1.0 / lam[0];
566 D[j2 + na * rtk->
nx] = -1.0 / lam[1];
567 D[k1 + na * rtk->
nx] = -1.0 / lam[0];
568 D[k2 + na * rtk->
nx] = 1.0 / lam[1];
569 rtk->
ssat[sat1s[na] - 1].
fix[1] = rtk->
ssat[sat2s[na] - 1].
fix[1] = 1;
572 if (strstr(rtk->
opt.
pppopt,
"-TRACE_AR")) {
573 trace(NULL, 3,
"search_amb_wl(%4d): %s %s N,a= %8.3f %8.3f sig=%8.3f\n", __LINE__, s1, s2, n, b, sqrt(var));
576 trace(NULL, 4,
"search_amb_wl(%4d): number of fixed wide-lane ambiguity = %d / %d\n", __LINE__, na, ns);
581 int nf,
int* sat1s,
int* sat2s,
int* frqs,
double* a,
double* Q,
double* D) {
582 int i, j, k, na = 0, ind[
MAXOBS][2], i0, i1, j0, j1;
583 double q, lam[NFREQ];
585 const char label[NFREQ][10] = {
"N1 ",
"WL ",
"EWL",
"EW2"};
589 for (i = 0; i < rtk->
nx * ns; i++) {
594 for (i = 0; i < ns; i++) {
595 if (sat1[i] <= 0 || sat2[i] <= 0) {
606 j =
IB(sat1[i], 0, &rtk->
opt);
607 k =
IB(sat2[i], 0, &rtk->
opt);
612 if (x[j] == 0.0 || x[k] == 0.0) {
616 D[j + na * rtk->
nx] = 1.0 / lam[0];
617 D[k + na * rtk->
nx] = -1.0 / lam[0];
622 trace(NULL, 3,
"gen_sd_matrix_n1(%4d): ns=%d proc_time=%d [ms]\n", __LINE__, ns, (
int)(
tickget() - tick));
625 for (j = 0; j < na; j++) {
628 a[j] = D[j0 + j * rtk->
nx] * x[j0] + D[j1 + j * rtk->
nx] * x[j1];
630 for (i = j; i < na; i++) {
633 q = D[i0 + i * rtk->
nx] * P[i0 + j0 * rtk->
nx] * D[j0 + j * rtk->
nx];
634 q += D[i0 + i * rtk->
nx] * P[i0 + j1 * rtk->
nx] * D[j1 + j * rtk->
nx];
635 q += D[i1 + i * rtk->
nx] * P[i1 + j0 * rtk->
nx] * D[j0 + j * rtk->
nx];
636 q += D[i1 + i * rtk->
nx] * P[i1 + j1 * rtk->
nx] * D[j1 + j * rtk->
nx];
637 Q[i + j * na] = Q[j + i * na] = q;
640 if (strstr(rtk->
opt.
pppopt,
"-TRACE_AR")) {
643 trace(NULL, 3,
"gen_sd_matrix_n1(%4d): na=%d proc_time=%d [ms]\n", __LINE__, na, (
int)(
tickget() - tick));
648 const int* sat2s,
const int* frq,
const double* x,
const double* P,
const double* D,
649 const double* Q,
const double* a,
double* N,
int na,
int* exc_sat_flag) {
650 const double thres_fact[] = {5.0, 5.0, 3.0, 2.0, 1.5};
651 double s[2], thres = 0.0;
652 int i, trace_AR = 0, nm = 0;
653 char s1[32], s2[32], tstr[30];
655 trace(NULL, 3,
"search_amb_lambda(%4d): na=%d\n", __LINE__, na);
657 if (strstr(rtk->
opt.
pppopt,
"-TRACE_AR")) {
664 if (
lambda(na, 2, a, Q, N, s) || s[0] <= 0.0) {
665 trace(NULL, 2,
"search_amb_lambda(%4d): error lambda\n", __LINE__);
671 if (na -
MIN_AMB_RES < (
sizeof(thres_fact) /
sizeof(thres_fact[0]))) {
673 trace(NULL, 2,
"search_amb_lambda(%4d): inflated threshold na-MIN_AMB_RES=%d thres_fact=%.2f thres=%.2f\n",
676 for (i = 0; i <
MAXSAT; i++) {
679 for (i = 0; i < na; i++) {
680 if (fabs(N[i] - N[i + na]) < 0.001) {
683 exc_sat_flag[sat1s[i] - 1] = (int)fabs(N[i] - N[i + na]);
686 trace(NULL, 3,
"search_amb_lambda(%4d): %s na=%2d nm= %2d match_rate=%7.2f\n", __LINE__, tstr, na, nm,
687 (
double)nm / (
double)na);
696 trace(NULL, 2,
"search_amb_lambda(%4d): na= %2d ratio= %.3f (s[1](%.3f)/s[0](%.3f)) thres= %.3f\n", __LINE__,
697 na, s[1] / s[0], s[1], s[0], thres);
698 trace(NULL, 2,
"search_amb_lambda(%4d): first candidate\n", __LINE__);
699 for (i = 0; i < na; i++) {
702 trace(NULL, 2,
"search_amb_lambda(%4d): i= %2d na= %2d %s %s N,a= %8.3f %8.3f frac=%8.3f\n", __LINE__, i,
703 na, s1, s2, N[i], a[i], N[i] - a[i]);
705 trace(NULL, 2,
"search_amb_lambda(%4d): second candidate\n", __LINE__);
706 for (i = 0; i < na; i++) {
709 trace(NULL, 2,
"search_amb_lambda(%4d): i= %2d na= %2d %s %s N,a= %8.3f %8.3f frac=%8.3f\n", __LINE__, i,
710 na, s1, s2, N[i + na], a[i], N[i + na] - a[i]);
712 trace(NULL, 2,
"search_amb_lambda(%4d): difference\n", __LINE__);
713 for (i = 0; i < na; i++) {
716 trace(NULL, 2,
"search_amb_lambda(%4d): i= %2d na= %2d %s %s N1,N2= %8.3f %8.3f diff=%8.3f\n", __LINE__, i,
717 na, s1, s2, N[i], N[i + na], N[i] - N[i + na]);
722 if (s[1] / s[0] < thres) {
723 trace(NULL, 2,
"search_amb_lambda(%4d): failed to fix. na=%d ratio=%.2f/%.2f proc_time=%d [ms]\n", __LINE__, na,
724 s[1] / s[0], thres, (
int)(
tickget() - tick));
729 for (i = 0; i < na; i++) {
730 rtk->
ssat[sat1s[i] - 1].
fix[frq[i]] = rtk->
ssat[sat2s[i] - 1].
fix[frq[i]] = 2;
733 trace(NULL, 2,
"search_amb_lambda(%4d): successed to fix. na=%d ratio=%.2f/%.2f proc_time=%d [ms]\n", __LINE__, na,
734 s[1] / s[0], thres, (
int)(
tickget() - tick));
738static int update_states(
double* x,
double* P,
const double* D,
int nx,
const double* N,
const double* a,
int na,
739 const int* sats,
const int* frqs,
int step) {
740 double *R, b[
MAXOBS * NFREQ * 2];
755 for (i = 0; i < na; i++) {
792 "update_states(%4d): sat=%3d frqs=%d fn=%d i=%2d na=%2d N,a=%10.3f %10.3f frac=%8.3f sig=%6.3f\n",
793 __LINE__, sats[i], frqs[i],
freq_idx2freq_num(sys, frqs[i]), i, na, N[i], a[i], b[i], sqrt(var));
795 if ((info =
filter(x, P, D, b, R, nx, na))) {
796 trace(NULL, 1,
"update_states(%4d): filter error (info=%d)\n", __LINE__, info);
800 trace(NULL, 3,
"update_states(%4d): na=%d proc_time=%d [ms]\n", __LINE__, na, (
int)(
tickget() - tick));
804static int exc_sat_par(
rtk_t* rtk,
int* sat1,
int* sat2,
const double* el1,
const double* el2,
int ns,
805 const int* exc_sat_flag) {
806 int i, minidx = 0, sys;
807 double minel = 9999.9;
808 double el, offset =
PI / 2.0;
811 for (i = 0; i < ns; i++) {
815 if (!exc_sat_flag[sat1[i] - 1]) {
836 trace(NULL, 4,
"exc_sat_par(%4d): i=%2d sat1=%3d sat2=%3d el=%4.1f %4.1f minidx=%2d minel=%.3f\n", __LINE__, i,
837 sat1[i], sat2[i], el1[i] *
R2D, el2[i] *
R2D, minidx, minel *
R2D);
841 trace(NULL, 2,
"exc_sat_par(%4d): excluded %s %s sat1=%3d sat2=%3d el=%4.1f %4.1f\n", __LINE__, s1, s2,
842 sat1[minidx], sat2[minidx], el1[minidx] *
R2D, el2[minidx] *
R2D);
846 for (i = 0; i < ns; i++) {
847 trace(NULL, 4,
"exc_sat_par(%4d): i=%2d sat1=%3d sat2=%3d el1=%4.1f\n", __LINE__, i, sat1[i], sat2[i],
856 double *D, *Q, a[
MAXOBS * NFREQ], N[
MAXOBS * NFREQ * 2], *xp, *Pp;
860 int i, ns, na = 0, info = 0;
861 int nf = rtk->
opt.
nf, sol_fix_wl = 1;
865 if (strstr(rtk->
opt.
pppopt,
"-AR_NOFIX_WL")) {
870 trace(NULL, 3,
"ppp_amb_ILS(%4d): nf=%d\n", __LINE__, nf);
873 ns =
gen_sat_sd(rtk, obs, n, exc, azel, nf, sat1, sat2, el1, el2);
875 trace(NULL, 2,
"ppp_amb_ILS(%4d): no generated satellite SD ns= %d\n", __LINE__, ns);
878 trace(NULL, 3,
"ppp_amb_ILS(%4d): %s generate satellite SD ns= %d\n", __LINE__, tstr, ns);
881 xp =
mat(rtk->
nx, 1);
883 Q =
mat(ns * nf, ns * nf);
885 write_trace_sd_amb(rtk, x, P, sat1, sat2, ns, nf, sat1s, sat2s, frqs, a, 0,
STEP_EWL);
888 na =
search_amb_ewl(rtk, x, P, sat1, sat2, ns, nf, sat1s, sat2s, frqs, a, N, D);
891 trace(NULL, 1,
"ppp_amb_ILS(%4d): %s update error\n", __LINE__, tstr);
898 trace(NULL, 3,
"ppp_amb_ILS(%4d): %s extra wide-lane ambiguity fixed. nfix=%2d nsat=%2d\n", __LINE__, tstr, na, ns);
900 write_trace_sd_amb(rtk, x, P, sat1, sat2, ns, nf, sat1s, sat2s, frqs, a, 0,
STEP_WL);
903 na =
search_amb_wl(rtk, x, P, sat1, sat2, ns, nf, sat1s, sat2s, frqs, a, N, D);
905 trace(NULL, 2,
"ppp_amb_ILS(%4d): %s wide-lane ambiguity search error\n", __LINE__, tstr);
915 trace(NULL, 1,
"ppp_amb_ILS(%4d): %s update error\n", __LINE__, tstr);
922 trace(NULL, 3,
"ppp_amb_ILS(%4d): %s wide-lane ambiguity fixed. nfix=%2d nsat=%2d proc_time=%d [ms]\n", __LINE__,
923 tstr, na, ns, (
int)(
tickget() - tick));
927 write_trace_sd_amb(rtk, x, P, sat1, sat2, ns, nf, sat1s, sat2s, frqs, a, 0,
STEP_NL);
930 for (i = 0; i < 3; i++) {
931 std[i] = sqrt(P[i + i * rtk->
nx]);
934 trace(NULL, 3,
"ppp_amb_ILS(%4d): %s narrow-lane search. nsat=%d std=%.2f\n", __LINE__, tstr, ns,
norm(std, 3));
937 na =
gen_sd_matrix_n1(rtk, x, P, sat1, sat2, ns, nf, sat1s, sat2s, frqs, a, Q, D);
939 trace(NULL, 2,
"ppp_amb_ILS(%4d): %s no integer ambiguity candidate. na=%d/%d\n", __LINE__, tstr, na,
945 na =
search_amb_lambda(rtk, obs, n, azel, sat1s, sat2s, frqs, x, P, D, Q, a, N, na, exc_sat_flag);
951 exc_sat_par(rtk, sat1, sat2, el1, el2, ns, exc_sat_flag);
956 trace(NULL, 2,
"ppp_amb_ILS(%4d): %s std is greater than the threshold. std=%.2f / %.2f\n", __LINE__, tstr,
965 trace(NULL, 2,
"ppp_amb_ILS(%4d): %s narrow-lane search error. iter=%d proc_time=%d [ms]\n", __LINE__, tstr,
973 for (i = 0; i < 3; i++) {
974 std[i] = sqrt(P[i + i * rtk->
nx]);
978 for (i = 0; i < na; i++) {
979 rtk->
ssat[sat1s[i] - 1].
fix[0] = rtk->
ssat[sat2s[i] - 1].
fix[0] = 0;
987 trace(NULL, 2,
"ppp_amb_ILS(%4d): %s failed to std test. std=%.3f / %.3f iter=%d proc_time=%d [ms]\n", __LINE__,
992 write_trace_sd_amb(rtk, x, P, sat1, sat2, ns, nf, sat1s, sat2s, frqs, a, 1, 9);
993 trace(NULL, 3,
"ppp_amb_ILS(%4d): %s ambiguity fixed. nfix=%2d nsat=%2d std=%.3f iter=%d proc_time=%d [ms]\n",
994 __LINE__, tstr, na, ns,
norm(std, 3), (
int)rtk->
sol.
age, (
int)(
tickget() - tick));
1000 return info ? sol_fix_wl : 2;
1004 double* x,
double* P) {
1012 return ppp_amb_ILS(rtk, obs, n, exc, nav, azel, x, P);
MRTKLIB Constants — Physical, navigation, and system constants.
MRTKLIB Context — runtime context for processing, trace, and error handling.
MRTKLIB Integer Ambiguity Resolution Module — LAMBDA method.
MRTKLIB MADOCA-PPP Module — QZSS L6E CSSR message decode functions.
MRTKLIB Matrix Module — Matrix/vector operations and estimation.
int is_bds3igso(int prn)
Test whether a BeiDou PRN is listed as BDS-3 IGSO (see set_bds3igso()).
MRTKLIB Observation Module — Observation data types and utility functions.
void satno2id(int sat, char *id)
#define CONST_AMB_BDS_B2a
int satsys(int sat, int *prn)
static int ppp_amb_ILS(rtk_t *rtk, const obsd_t *obs, int n, int *exc, const nav_t *nav, const double *azel, double *x, double *P)
double * mat(int n, int m)
static int exc_sat_sd(rtk_t *rtk, const obsd_t *obs, int exc, double el, int nf, int sys)
gtime_t epoch2time(const double *ep)
int lambda(int n, int m, const double *a, const double *Q, double *F, double *s)
static int exc_sat_par(rtk_t *rtk, int *sat1, int *sat2, const double *el1, const double *el2, int ns, const int *exc_sat_flag)
double * zeros(int n, int m)
static void write_trace_amb(rtk_t *rtk, const double *a, const double *Q, int na, const int *sat1s, const int *sat2s, const int *frqs, const char label[5][10], int step)
static int search_amb_lambda(rtk_t *rtk, const obsd_t *obs, int n, const double *azel, const int *sat1s, const int *sat2s, const int *frq, const double *x, const double *P, const double *D, const double *Q, const double *a, double *N, int na, int *exc_sat_flag)
void matcpy(double *A, const double *B, int n, int m)
unsigned int tickget(void)
void time2epoch(gtime_t t, double *ep)
void time2str(gtime_t t, char *s, int n)
static void write_trace_sd_amb(rtk_t *rtk, const double *x, const double *P, const int *sat1, const int *sat2, int ns, int nf, int *sat1s, int *sat2s, int *frqs, double *a, int post, int step)
static int search_amb_wl(rtk_t *rtk, const double *x, const double *P, int *sat1, int *sat2, int ns, int nf, int *sat1s, int *sat2s, int *frqs, double *a, double *N, double *D)
int filter(double *x, double *P, const double *H, const double *v, const double *R, int n, int m)
double timediff(gtime_t t1, gtime_t t2)
int satid2no(const char *id)
static int is_bds3_igso(int sat)
gtime_t timeadd(gtime_t t, double sec)
double norm(const double *a, int n)
int satsys_bd2(int sat, int *prn)
char * time_str(gtime_t t, int n)
static int gen_sat_sd(rtk_t *rtk, const obsd_t *obs, int n, const int *exc, const double *azel, int nf, int *sat1, int *sat2, double *el1, double *el2)
double freq_num2freq(int sys, int freq_num, int fcn)
static int gen_sd_matrix_n1(rtk_t *rtk, const double *x, const double *P, const int *sat1, const int *sat2, int ns, int nf, int *sat1s, int *sat2s, int *frqs, double *a, double *Q, double *D)
void matmul(const char *tr, int n, int k, int m, double alpha, const double *A, const double *B, double beta, double *C)
static int update_states(double *x, double *P, const double *D, int nx, const double *N, const double *a, int na, const int *sats, const int *frqs, int step)
int freq_idx2freq_num(int sys, int freq_idx)
static void get_wavelength(int sat, double *lam)
int ppp_ar(mrtk_ctx_t *ctx, rtk_t *rtk, const obsd_t *obs, int n, int *exc, const nav_t *nav, const double *azel, double *x, double *P)
Ambiguity resolution in PPP.
static int search_amb_ewl(rtk_t *rtk, const double *x, const double *P, const int *sat1, const int *sat2, int ns, int nf, int *sat1s, int *sat2s, int *frqs, double *a, double *N, double *D)
MRTKLIB PPP Ambiguity Resolution Module.
MRTKLIB System Module — OS/filesystem utility functions.
uint32_t tickget(void)
Get current tick in milliseconds.
void trace(mrtk_ctx_t *ctx, int level, const char *format,...)
Output trace message.
MRTKLIB Trace Module — debug trace and logging functions.
GNSS time representation.
Runtime context for MRTKLIB processing.