00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <clapack.h>
00014 #include <inttypes.h>
00015 #include <cblas.h>
00016 #include <stdio.h>
00017 #include <string.h>
00018 #include "ambiguity_test.h"
00019 #include "common.h"
00020 #include "constants.h"
00021 #include "linear_algebra.h"
00022 #include "single_diff.h"
00023 #include "amb_kf.h"
00024 #include "lambda.h"
00025
00026 #define RAW_PHASE_BIAS_VAR 0
00027 #define DECORRELATED_PHASE_BIAS_VAR 0
00028 #define NUM_SEARCH_STDS 5
00029 #define LOG_PROB_RAT_THRESHOLD -90
00030
00031 #define DEBUG_AMBIGUITY_TEST 0
00032
00033
00038 void create_ambiguity_test(ambiguity_test_t *amb_test)
00039 {
00040 static u8 pool_buff[MAX_HYPOTHESES*(sizeof(hypothesis_t) + sizeof(void *))];
00041 static memory_pool_t pool;
00042 amb_test->pool = &pool;
00043 memory_pool_init(amb_test->pool, MAX_HYPOTHESES, sizeof(hypothesis_t), pool_buff);
00044 amb_test->sats.num_sats = 0;
00045 amb_test->amb_check.initialized = 0;
00046 }
00047
00050 s8 filter_all(void *arg, element_t *elem)
00051 {
00052 (void) arg; (void) elem;
00053 return false;
00054 }
00055
00056
00057 void reset_ambiguity_test(ambiguity_test_t *amb_test)
00058 {
00059 if (DEBUG_AMBIGUITY_TEST) {
00060 printf("<RESET_AMBIGUITY_TEST>\n");
00061 }
00062 u8 x = 0;
00063 memory_pool_filter(amb_test->pool, (void *) &x, &filter_all);
00064
00065
00066
00067
00068 hypothesis_t *empty_element = (hypothesis_t *)memory_pool_add(amb_test->pool);
00069
00070 empty_element->ll = 0;
00071 amb_test->sats.num_sats = 0;
00072 amb_test->amb_check.initialized = 0;
00073 if (DEBUG_AMBIGUITY_TEST) {
00074 printf("</RESET_AMBIGUITY_TEST>\n");
00075 }
00076 }
00077
00078
00079 void destroy_ambiguity_test(ambiguity_test_t *amb_test)
00080 {
00081 memory_pool_destroy(amb_test->pool);
00082 }
00083
00084
00094 void print_double_mtx(double *m, u32 _r, u32 _c) {
00095 for (u32 _i = 0; _i < (_r); _i++) {
00096 printf(" [% 12lf", (m)[_i*(_c) + 0]);
00097 for (u32 _j = 1; _j < (_c); _j++)
00098 printf(" % 12lf", (m)[_i*(_c) + _j]);
00099 printf("]\n");
00100 }
00101 }
00102
00103
00116 void print_pearson_mtx(double *m, u32 dim) {
00117 for (u32 _i = 0; _i < dim; _i++) {
00118 printf(" [% 12lf", m[_i*dim + 0] / sqrt(m[_i*dim + _i]) / sqrt(m[0]));
00119 for (u32 _j = 1; _j < dim; _j++)
00120 printf(" % 12lf", m[_i*dim + _j] / sqrt(m[_i*dim + _i]) / sqrt(m[_j * dim + _j]));
00121 printf("]\n");
00122 }
00123 }
00124
00125
00136 void print_s32_mtx_diff(u32 m, u32 n, s32 *mat1, s32 *mat2)
00137 {
00138 for (u32 i=0; i < m; i++) {
00139 for (u32 j=0; j < n; j++) {
00140 printf("%"PRId32", ", mat1[i*n + j] - mat2[i*n + j]);
00141 }
00142 printf("\n");
00143 }
00144 printf("\n");
00145 }
00146
00153 void print_s32_mtx(u32 m, u32 n, s32 *mat)
00154 {
00155 for (u32 i=0; i < m; i++) {
00156 for (u32 j=0; j < n; j++) {
00157 printf("%"PRId32", ", mat[i*n + j]);
00158 }
00159 printf("\n");
00160 }
00161 printf("\n");
00162 }
00163
00172 void print_s32_gemv(u32 m, u32 n, s32 *M, s32 *v)
00173 {
00174 s32 mv[m];
00175 memset(mv, 0, m * sizeof(s32));
00176 printf("[");
00177 for (u32 i=0; i < m; i++) {
00178 for (u32 j=0; j < n; j++) {
00179 mv[i] += M[i*n + j] * v[j];
00180 }
00181 if (i+1 == m) {
00182 printf("%"PRId32" ]\n", mv[i]);
00183 }
00184 else {
00185 printf("%"PRId32", ", mv[i]);
00186 }
00187 }
00188 }
00189
00199 s8 get_single_hypothesis(ambiguity_test_t *amb_test, s32 *hyp_N)
00200 {
00201 if (memory_pool_n_allocated(amb_test->pool) == 1) {
00202 hypothesis_t hyp;
00203 memory_pool_to_array(amb_test->pool, &hyp);
00204 memcpy(hyp_N, hyp.N, (amb_test->sats.num_sats-1) * sizeof(s32));
00205 return 0;
00206 }
00207 return -1;
00208 }
00209
00213 typedef struct {
00214 u8 num_dds;
00215 s32 N[MAX_CHANNELS-1];
00216 u8 found;
00217 } fold_contains_t;
00218
00226 void fold_contains(void *x, element_t *elem)
00227 {
00228 fold_contains_t *acc = (fold_contains_t *) x;
00229 hypothesis_t *hyp = (hypothesis_t *) elem;
00230 if (acc->found == 1) {
00231 return;
00232 }
00233 for (u8 i=0; i<acc->num_dds; i++) {
00234 if (hyp->N[i] != acc->N[i]) {
00235 return;
00236 }
00237 }
00238 acc->found = 1;
00239 }
00240
00247 u8 ambiguity_test_pool_contains(ambiguity_test_t *amb_test, double *ambs)
00248 {
00249 fold_contains_t acc;
00250 acc.num_dds = amb_test->sats.num_sats-1;
00251 for (u8 i=0; i<acc.num_dds; i++) {
00252 acc.N[i] = lround(ambs[i]);
00253 }
00254 acc.found = 0;
00255 memory_pool_fold(amb_test->pool, (void *) &acc, &fold_contains);
00256 return acc.found;
00257 }
00258
00259
00263 typedef struct {
00264 u8 started;
00265 double max_ll;
00266 u8 num_dds;
00267 s32 N[MAX_CHANNELS-1];
00268 } fold_mle_t;
00269
00277 void fold_mle(void *x, element_t *elem)
00278 {
00279 hypothesis_t *hyp = (hypothesis_t *) elem;
00280 fold_mle_t *mle = (fold_mle_t *) x;
00281 if (mle->started == 0 || hyp->ll > mle->max_ll) {
00282 mle->started = 1;
00283 mle->max_ll = hyp->ll;
00284 memcpy(mle->N, hyp->N, mle->num_dds * sizeof(s32));
00285 }
00286 }
00287
00296 void ambiguity_test_MLE_ambs(ambiguity_test_t *amb_test, s32 *ambs)
00297 {
00298 fold_mle_t mle;
00299 mle.started = 0;
00300 mle.num_dds = MAX(1,amb_test->sats.num_sats)-1;
00301 memory_pool_fold(amb_test->pool, (void *) &mle, &fold_mle);
00302 memcpy(ambs, mle.N, mle.num_dds * sizeof(s32));
00303 }
00304
00324 void init_ambiguity_test(ambiguity_test_t *amb_test, u8 state_dim, u8 *float_prns, sdiff_t *sdiffs, double *float_mean,
00325 double *float_cov, double *DE_mtx, double *obs_cov)
00326 {
00327 (void) sdiffs;
00328 u8 num_dds = state_dim;
00329 double float_cov_N[num_dds * num_dds];
00330
00331
00332 for (u8 i=0; i<num_dds; i++) {
00333 for (u8 j=0; j<num_dds; j++) {
00334 float_cov_N[i*num_dds + j] = float_cov[i*state_dim + j];
00335 }
00336 }
00337
00338
00339
00340
00341
00342 hypothesis_t *empty_element = (hypothesis_t *)memory_pool_add(amb_test->pool);
00343
00344 empty_element->ll = 0;
00345 amb_test->sats.num_sats = 0;
00346 s32 Z_inv[num_dds * num_dds];
00347 s32 lower_bounds[num_dds];
00348 s32 upper_bounds[num_dds];
00349 u8 num_dds_to_add;
00350 s8 add_any_sats = determine_sats_addition(amb_test,
00351 float_cov_N, num_dds, &float_mean[6],
00352 lower_bounds, upper_bounds, &num_dds_to_add,
00353 Z_inv);
00354
00355 if (add_any_sats == 1) {
00356 add_sats(amb_test, float_prns[0], num_dds_to_add, &float_prns[1], lower_bounds, upper_bounds, Z_inv);
00357
00358 init_residual_matrices(&amb_test->res_mtxs, num_dds, DE_mtx, obs_cov);
00359 }
00360
00361 }
00362
00363
00385 void update_ambiguity_test(double ref_ecef[3], double phase_var, double code_var,
00386 ambiguity_test_t *amb_test, u8 state_dim, sdiff_t *sdiffs,
00387 u8 changed_sats)
00388 {
00389 if (DEBUG_AMBIGUITY_TEST) {
00390 printf("<UPDATE_AMBIGUITY_TEST>\n");
00391 }
00392 u8 num_sdiffs = state_dim + 1;
00393
00394 if (amb_test->sats.num_sats < 5) {
00395 if (DEBUG_AMBIGUITY_TEST) {
00396 printf("</UPDATE_AMBIGUITY_TEST>\n");
00397 }
00398 return;
00399 }
00400
00401 sdiff_t ambiguity_sdiffs[amb_test->sats.num_sats];
00402 double ambiguity_dd_measurements[2*(amb_test->sats.num_sats-1)];
00403 s8 valid_sdiffs = make_ambiguity_dd_measurements_and_sdiffs(
00404 amb_test, num_sdiffs, sdiffs, ambiguity_dd_measurements, ambiguity_sdiffs);
00405
00406
00407 if (valid_sdiffs != 0) {
00408 printf("update_ambiguity_test: Invalid sdiffs. return code: %i\n", valid_sdiffs);
00409 for (u8 k=0; k < num_sdiffs; k++) {
00410 printf("%u, ", sdiffs[k].prn);
00411 }
00412 printf("}\n");
00413 print_sats_management_short(&amb_test->sats);
00414 return;
00415 }
00416
00417 if (1 == 1 || changed_sats == 1) {
00418 double DE_mtx[(amb_test->sats.num_sats-1) * 3];
00419 assign_de_mtx(amb_test->sats.num_sats, ambiguity_sdiffs, ref_ecef, DE_mtx);
00420 double obs_cov[(amb_test->sats.num_sats-1) * (amb_test->sats.num_sats-1) * 4];
00421 memset(obs_cov, 0, (amb_test->sats.num_sats-1) * (amb_test->sats.num_sats-1) * 4 * sizeof(double));
00422 u8 num_dds = amb_test->sats.num_sats-1;
00423 for (u8 i=0; i<num_dds; i++) {
00424 for (u8 j=0; j<num_dds; j++) {
00425 u8 i_ = i+num_dds;
00426 u8 j_ = j+num_dds;
00427 if (i==j) {
00428 obs_cov[i*2*num_dds + j] = phase_var * 2;
00429 obs_cov[i_*2*num_dds + j_] = code_var * 2;
00430 }
00431 else {
00432 obs_cov[i*2*num_dds + j] = phase_var;
00433 obs_cov[i_*2*num_dds + j_] = code_var;
00434 }
00435 }
00436 }
00437
00438
00439 init_residual_matrices(&amb_test->res_mtxs, amb_test->sats.num_sats-1, DE_mtx, obs_cov);
00440 }
00441
00442 test_ambiguities(amb_test, ambiguity_dd_measurements);
00443
00444 if (DEBUG_AMBIGUITY_TEST) {
00445 printf("</UPDATE_AMBIGUITY_TEST>\n");
00446 }
00447 }
00448
00449
00454 u32 ambiguity_test_n_hypotheses(ambiguity_test_t *amb_test)
00455 {
00456 return memory_pool_n_allocated(amb_test->pool);
00457 }
00458
00462 typedef struct {
00463 u8 num_dds;
00464 double r_vec[2*MAX_CHANNELS-5];
00465 double max_ll;
00466 residual_mtxs_t *res_mtxs;
00467 unanimous_amb_check_t *unanimous_amb_check;
00468 } hyp_filter_t;
00469
00480 void update_and_get_max_ll(void *x_, element_t *elem) {
00481 hyp_filter_t *x = (hyp_filter_t *) x_;
00482 hypothesis_t *hyp = (hypothesis_t *) elem;
00483 double hypothesis_N[x->num_dds];
00484
00485 for (u8 i=0; i < x->num_dds; i++) {
00486 hypothesis_N[i] = hyp->N[i];
00487 }
00488
00489 hyp->ll += get_quadratic_term(x->res_mtxs, x->num_dds, hypothesis_N, x->r_vec);
00490 x->max_ll = MAX(x->max_ll, hyp->ll);
00491 }
00492
00498 void check_unanimous_ambs(u8 num_dds, hypothesis_t *hyp,
00499 unanimous_amb_check_t *amb_check)
00500 {
00501 if (amb_check->initialized) {
00502 u8 j = 0;
00503 for (u8 i = 0; i < amb_check->num_matching_ndxs; i++) {
00504 if (amb_check->ambs[i] == hyp->N[amb_check->matching_ndxs[i]]) {
00505 if (i != j) {
00506 amb_check->matching_ndxs[j] = amb_check->matching_ndxs[i];
00507 amb_check->ambs[j] = amb_check->ambs[i];
00508 }
00509 j++;
00510 }
00511 }
00512 amb_check->num_matching_ndxs = j;
00513 } else {
00514 amb_check->initialized = 1;
00515 amb_check->num_matching_ndxs = num_dds;
00516 for (u8 i=0; i < num_dds; i++) {
00517 amb_check->matching_ndxs[i] = i;
00518 }
00519 memcpy(amb_check->ambs, hyp->N, num_dds * sizeof(s32));
00520 }
00521 }
00522
00542 s8 filter_and_renormalize(void *arg, element_t *elem) {
00543 hypothesis_t *hyp = (hypothesis_t *) elem;
00544
00545 u8 keep_it = (hyp->ll > LOG_PROB_RAT_THRESHOLD);
00546 if (keep_it) {
00547 hyp->ll -= ((hyp_filter_t *) arg)->max_ll;
00548 }
00549 return keep_it;
00550 }
00551
00552 static void _check_unanimous(void *arg, element_t *elem)
00553 {
00554 hypothesis_t *hyp = (hypothesis_t *) elem;
00555
00556 check_unanimous_ambs(((hyp_filter_t *) arg)->num_dds, hyp,
00557 ((hyp_filter_t *) arg)->unanimous_amb_check);
00558 }
00559
00560 void update_unanimous_ambiguities(ambiguity_test_t *amb_test)
00561 {
00562 hyp_filter_t x;
00563 if (amb_test->sats.num_sats <= 1) {
00564 amb_test->amb_check.num_matching_ndxs = 0;
00565 return;
00566 }
00567 x.num_dds = amb_test->sats.num_sats-1;
00568 x.unanimous_amb_check = &amb_test->amb_check;
00569 x.unanimous_amb_check->initialized = 0;
00570
00571 memory_pool_map(amb_test->pool, (void *) &x, &_check_unanimous);
00572 }
00573
00574
00575
00576
00577
00578 void test_ambiguities(ambiguity_test_t *amb_test, double *dd_measurements)
00579 {
00580 if (DEBUG_AMBIGUITY_TEST) {
00581 printf("<TEST_AMBIGUITIES>\n");
00582 }
00583 hyp_filter_t x;
00584 x.num_dds = amb_test->sats.num_sats-1;
00585 assign_r_vec(&amb_test->res_mtxs, x.num_dds, dd_measurements, x.r_vec);
00586
00587 x.max_ll = -1e20;
00588 x.res_mtxs = &amb_test->res_mtxs;
00589 x.unanimous_amb_check = &amb_test->amb_check;
00590 x.unanimous_amb_check->initialized = 0;
00591
00592 memory_pool_fold(amb_test->pool, (void *) &x, &update_and_get_max_ll);
00593
00594 memory_pool_filter(amb_test->pool, (void *) &x, &filter_and_renormalize);
00595 if (memory_pool_empty(amb_test->pool)) {
00596
00597
00598
00599
00600 hypothesis_t *empty_element = (hypothesis_t *)memory_pool_add(amb_test->pool);
00601
00602 empty_element->ll = 0;
00603 amb_test->sats.num_sats = 0;
00604 amb_test->amb_check.initialized = 0;
00605 }
00606 if (DEBUG_AMBIGUITY_TEST) {
00607 memory_pool_map(amb_test->pool, &x.num_dds, &print_hyp);
00608 printf("num_unanimous_ndxs=%u\n</TEST_AMBIGUITIES>\n", x.unanimous_amb_check->num_matching_ndxs);
00609 }
00610 }
00611
00612
00613
00614 u8 ambiguity_iar_can_solve(ambiguity_test_t *amb_test)
00615 {
00616 return amb_test->amb_check.initialized &&
00617 amb_test->amb_check.num_matching_ndxs >= 3;
00618 }
00619
00620 bool is_prn_set(u8 len, u8 *prns)
00621 {
00622 if (len == 0) {
00623 return true;
00624 }
00625 u8 current = prns[0];
00626 for (u8 i = 1; i < len; i++) {
00627 if (prns[i] <= current) {
00628 return false;
00629 }
00630 current = prns[i];
00631 }
00632 return true;
00633 }
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 s8 make_dd_measurements_and_sdiffs(u8 ref_prn, u8 *non_ref_prns, u8 num_dds,
00659 u8 num_sdiffs, sdiff_t *sdiffs,
00660 double *ambiguity_dd_measurements, sdiff_t *amb_sdiffs)
00661 {
00662 if (DEBUG_AMBIGUITY_TEST) {
00663 printf("<MAKE_DD_MEASUREMENTS_AND_SDIFFS>\n");
00664 printf("ref_prn = %u\nnon_ref_prns = {", ref_prn);
00665 for (u8 i=0; i < num_dds; i++) {
00666 printf("%d, ", non_ref_prns[i]);
00667 }
00668 printf("}\nnum_dds = %u\nnum_sdiffs = %u\nsdiffs[*].prn = {", num_dds, num_sdiffs);
00669 for (u8 i=0; i < num_sdiffs; i++) {
00670 printf("%d, ", sdiffs[i].prn);
00671 }
00672 printf("}\n");
00673 }
00674
00675 if (!is_prn_set(num_dds, non_ref_prns)) {
00676 printf("There is disorder in the amb_test sats.\n");
00677 printf("amb_test sat prns = {%u, ", ref_prn);
00678 for (u8 k=0; k < num_dds; k++) {
00679 printf("%u, ", non_ref_prns[k]);
00680 }
00681 printf("}\n");
00682 return -2;
00683 }
00684
00685 double ref_phase = 0;
00686 double ref_pseudorange = 0;
00687 u8 i=0;
00688 u8 j=0;
00689 u8 found_ref = 0;
00690
00691
00692 while (i < num_dds) {
00693 if (non_ref_prns[i] == sdiffs[j].prn) {
00694
00695 memcpy(&amb_sdiffs[i+1], &sdiffs[j], sizeof(sdiff_t));
00696 ambiguity_dd_measurements[i] = sdiffs[j].carrier_phase;
00697 ambiguity_dd_measurements[i+num_dds] = sdiffs[j].pseudorange;
00698 i++;
00699 j++;
00700 } else if (ref_prn == sdiffs[j].prn) {
00701
00702 memcpy(&amb_sdiffs[0], &sdiffs[j], sizeof(sdiff_t));
00703 ref_phase = sdiffs[j].carrier_phase;
00704 ref_pseudorange = sdiffs[j].pseudorange;
00705 j++;
00706 found_ref = 1;
00707 }
00708 else if (non_ref_prns[i] > sdiffs[j].prn) {
00709
00710
00711
00712 j++;
00713 } else {
00714
00715
00716
00717
00718
00719 return -1;
00720 }
00721 }
00722
00723
00724
00725
00726 while (!found_ref && j < num_sdiffs ) {
00727 if (ref_prn == sdiffs[j].prn) {
00728 memcpy(&amb_sdiffs[0], &sdiffs[j], sizeof(sdiff_t));
00729 ref_phase = sdiffs[j].carrier_phase;
00730 ref_pseudorange = sdiffs[j].pseudorange;
00731 found_ref = 1;
00732 }
00733 j++;
00734 }
00735
00736 if (found_ref == 0) {
00737 return -1;
00738 }
00739 for (u8 i=0; i < num_dds; i++) {
00740 ambiguity_dd_measurements[i] -= ref_phase;
00741 ambiguity_dd_measurements[i+num_dds] -= ref_pseudorange;
00742 }
00743 if (DEBUG_AMBIGUITY_TEST) {
00744 printf("amb_sdiff_prns = {");
00745 for (i = 0; i < num_dds; i++) {
00746 printf("%u, ", amb_sdiffs[i].prn);
00747 }
00748 printf("}\ndd_measurements = {");
00749 for (i=0; i < 2 * num_dds; i++) {
00750 printf("%f, \t", ambiguity_dd_measurements[i]);
00751 }
00752 printf("}\n</MAKE_DD_MEASUREMENTS_AND_SDIFFS>\n");
00753 }
00754 return 0;
00755 }
00756
00757
00778 s8 make_ambiguity_resolved_dd_measurements_and_sdiffs(
00779 ambiguity_test_t *amb_test, u8 num_sdiffs, sdiff_t *sdiffs,
00780 double *ambiguity_dd_measurements, sdiff_t *amb_sdiffs)
00781 {
00782 if (DEBUG_AMBIGUITY_TEST) {
00783 printf("<MAKE_AMBIGUITY_RESOLVED_DD_MEASUREMENTS_AND_SDIFFS>\n");
00784 printf("amb_test->sats.prns = {");
00785 for (u8 i=0; i < amb_test->sats.num_sats; i++) {
00786 printf("%u, ", amb_test->sats.prns[i]);
00787 }
00788 printf("}\n");
00789 }
00790
00791 u8 ref_prn = amb_test->sats.prns[0];
00792 u8 num_dds = amb_test->amb_check.num_matching_ndxs;
00793 u8 non_ref_prns[num_dds];
00794 for (u8 i=0; i < num_dds; i++) {
00795 non_ref_prns[i] = amb_test->sats.prns[1 + amb_test->amb_check.matching_ndxs[i]];
00796 if (DEBUG_AMBIGUITY_TEST) {
00797 printf("non_ref_prns[%u] = %u, \t (ndx=%u) \t amb[%u] = %"PRId32"\n",
00798 i, non_ref_prns[i], amb_test->amb_check.matching_ndxs[i],
00799 i, amb_test->amb_check.ambs[i]);
00800 }
00801 }
00802 s8 valid_sdiffs =
00803 make_dd_measurements_and_sdiffs(ref_prn, non_ref_prns, num_dds, num_sdiffs,
00804 sdiffs, ambiguity_dd_measurements,
00805 amb_sdiffs);
00806 if (DEBUG_AMBIGUITY_TEST) {
00807 printf("</MAKE_AMBIGUITY_RESOLVED_DD_MEASUREMENTS_AND_SDIFFS>\n");
00808 }
00809 return valid_sdiffs;
00810 }
00811
00812
00827 s8 make_ambiguity_dd_measurements_and_sdiffs(ambiguity_test_t *amb_test, u8 num_sdiffs, sdiff_t *sdiffs,
00828 double *ambiguity_dd_measurements, sdiff_t *amb_sdiffs)
00829 {
00830 if (DEBUG_AMBIGUITY_TEST) {
00831 printf("<MAKE_AMBIGUITY_DD_MEASUREMENTS_AND_SDIFFS>\n");
00832 }
00833 u8 ref_prn = amb_test->sats.prns[0];
00834 u8 *non_ref_prns = &amb_test->sats.prns[1];
00835 u8 num_dds = MAX(1, amb_test->sats.num_sats)-1;
00836 s8 valid_sdiffs = make_dd_measurements_and_sdiffs(ref_prn, non_ref_prns,
00837 num_dds, num_sdiffs, sdiffs,
00838 ambiguity_dd_measurements, amb_sdiffs);
00839 if (DEBUG_AMBIGUITY_TEST) {
00840 printf("</MAKE_AMBIGUITY_DD_MEASUREMENTS_AND_SDIFFS>\n");
00841 }
00842 return valid_sdiffs;
00843 }
00844
00845
00846 s8 sats_match(ambiguity_test_t *amb_test, u8 num_sdiffs, sdiff_t *sdiffs)
00847 {
00848 if (DEBUG_AMBIGUITY_TEST) {
00849 printf("<SATS_MATCH>\namb_test.sats.prns = {");
00850 for (u8 i=0; i< amb_test->sats.num_sats; i++) {
00851 printf("%u, ", amb_test->sats.prns[i]);
00852 }
00853 printf("}\nsdiffs[*].prn = {");
00854 for (u8 i=0; i < num_sdiffs; i++) {
00855 printf("%u, ", sdiffs[i].prn);
00856 }
00857 printf("}\n");
00858 }
00859 if (amb_test->sats.num_sats != num_sdiffs) {
00860 if (DEBUG_AMBIGUITY_TEST) {
00861 printf("sats don't match (different length)\n</SATS_MATCH>\n");
00862 }
00863 return 0;
00864 }
00865 u8 *prns = amb_test->sats.prns;
00866 u8 amb_ref = amb_test->sats.prns[0];
00867 u8 j=0;
00868 for (u8 i = 1; i<amb_test->sats.num_sats; i++) {
00869 if (j >= num_sdiffs) {
00870 if (DEBUG_AMBIGUITY_TEST) {
00871 printf("sats don't match\n</SATS_MATCH>\n");
00872 }
00873 return 0;
00874 }
00875 if (prns[i] == sdiffs[j].prn) {
00876 j++;
00877 }
00878 else if (amb_ref == sdiffs[j].prn) {
00879 j++;
00880 i--;
00881 }
00882 else {
00883 if (DEBUG_AMBIGUITY_TEST) {
00884 printf("sats don't match\n</SATS_MATCH>\n");
00885 }
00886 return 0;
00887 }
00888 }
00889 if (DEBUG_AMBIGUITY_TEST) {
00890 printf("sats match\n</SATS_MATCH>\n");
00891 }
00892 return 1;
00893 }
00894
00895 typedef struct {
00896 u8 num_sats;
00897 u8 old_prns[MAX_CHANNELS];
00898 u8 new_prns[MAX_CHANNELS];
00899 } rebase_prns_t;
00900
00901 void rebase_hypothesis(void *arg, element_t *elem)
00902 {
00903 rebase_prns_t *prns = (rebase_prns_t *) arg;
00904 u8 num_sats = prns->num_sats;
00905 u8 *old_prns = prns->old_prns;
00906 u8 *new_prns = prns->new_prns;
00907
00908 hypothesis_t *hypothesis = (hypothesis_t *)elem;
00909
00910 u8 old_ref = old_prns[0];
00911 u8 new_ref = new_prns[0];
00912
00913 s32 new_N[num_sats-1];
00914 s32 index_of_new_ref_in_old = find_index_of_element_in_u8s(num_sats, new_ref, &old_prns[1]);
00915 s32 val_for_new_ref_in_old_basis = hypothesis->N[index_of_new_ref_in_old];
00916 for (u8 i=0; i<num_sats-1; i++) {
00917 u8 new_prn = new_prns[1+i];
00918 if (new_prn == old_ref) {
00919 new_N[i] = - val_for_new_ref_in_old_basis;
00920 }
00921 else {
00922 s32 index_of_this_sat_in_old_basis = find_index_of_element_in_u8s(num_sats, new_prn, &old_prns[1]);
00923 new_N[i] = hypothesis->N[index_of_this_sat_in_old_basis] - val_for_new_ref_in_old_basis;
00924 }
00925 }
00926 memcpy(hypothesis->N, new_N, (num_sats-1) * sizeof(s32));
00927 }
00928
00929 u8 ambiguity_update_reference(ambiguity_test_t *amb_test, u8 num_sdiffs, sdiff_t *sdiffs, sdiff_t *sdiffs_with_ref_first)
00930 {
00931 if (DEBUG_AMBIGUITY_TEST) {
00932 printf("<AMBIGUITY_UPDATE_REFERENCE>\n");
00933 }
00934 u8 changed_ref = 0;
00935 u8 old_prns[amb_test->sats.num_sats];
00936 memcpy(old_prns, amb_test->sats.prns, amb_test->sats.num_sats * sizeof(u8));
00937
00938
00939 s8 sats_management_code = rebase_sats_management(&amb_test->sats, num_sdiffs, sdiffs, sdiffs_with_ref_first);
00940
00941 if (sats_management_code != OLD_REF) {
00942 if (DEBUG_AMBIGUITY_TEST) {
00943 printf("updating iar reference sat\n");
00944 }
00945 changed_ref = 1;
00946 u8 new_prns[amb_test->sats.num_sats];
00947 memcpy(new_prns, amb_test->sats.prns, amb_test->sats.num_sats * sizeof(u8));
00948
00949 rebase_prns_t prns = {.num_sats = amb_test->sats.num_sats};
00950 memcpy(prns.old_prns, old_prns, amb_test->sats.num_sats * sizeof(u8));
00951 memcpy(prns.new_prns, new_prns, amb_test->sats.num_sats * sizeof(u8));
00952 memory_pool_map(amb_test->pool, &prns, &rebase_hypothesis);
00953 }
00954 if (DEBUG_AMBIGUITY_TEST) {
00955 printf("</AMBIGUITY_UPDATE_REFERENCE>\n");
00956 }
00957 return changed_ref;
00958 }
00959
00960 typedef struct {
00961 u8 num_ndxs;
00962 u8 intersection_ndxs[MAX_CHANNELS-1];
00963 } intersection_ndxs_t;
00964
00965 s32 projection_comparator(void *arg, element_t *a, element_t *b)
00966 {
00967 intersection_ndxs_t *intersection_struct = (intersection_ndxs_t *) arg;
00968 u8 num_ndxs = intersection_struct->num_ndxs;
00969 u8 *intersection_ndxs = intersection_struct->intersection_ndxs;
00970
00971 hypothesis_t *hyp_a = (hypothesis_t *) a;
00972 hypothesis_t *hyp_b = (hypothesis_t *) b;
00973
00974 for (u8 i=0; i<num_ndxs; i++) {
00975 u8 ndxi = intersection_ndxs[i];
00976 s32 ai = hyp_a->N[ndxi];
00977 s32 bi = hyp_b->N[ndxi];
00978 if (ai == bi) {
00979 continue;
00980 }
00981 if (ai < bi) {
00982 return -1;
00983 }
00984 if (ai > bi) {
00985 return 1;
00986 }
00987 }
00988 return 0;
00989 }
00990
00991 void projection_aggregator(element_t *new_, void *x_, u32 n, element_t *elem_)
00992 {
00993 intersection_ndxs_t *x = (intersection_ndxs_t *)x_;
00994 hypothesis_t *new = (hypothesis_t *)new_;
00995 hypothesis_t *elem = (hypothesis_t *)elem_;
00996
00997 if (n == 0) {
00998 for (u8 i=0; i<x->num_ndxs; i++) {
00999 u8 ndxi = x->intersection_ndxs[i];
01000 new->N[i] = elem->N[ndxi];
01001 }
01002 new->ll = elem->ll;
01003 }
01004 else {
01005 new->ll += log(1 + exp(elem->ll - new->ll));
01006
01007 }
01008
01009 }
01010
01011 u8 ambiguity_sat_projection(ambiguity_test_t *amb_test, u8 num_dds_in_intersection, u8 *dd_intersection_ndxs)
01012 {
01013 if (DEBUG_AMBIGUITY_TEST) {
01014 printf("<AMBIGUITY_SAT_PROJECTION>\n");
01015 }
01016 u8 num_dds_before_proj = MAX(1, amb_test->sats.num_sats) - 1;
01017 if (num_dds_before_proj == num_dds_in_intersection) {
01018 if (DEBUG_AMBIGUITY_TEST) {
01019 printf("no need for projection\n</AMBIGUITY_SAT_PROJECTION>\n");
01020 }
01021 return 0;
01022 }
01023
01024 intersection_ndxs_t intersection = {.num_ndxs = num_dds_in_intersection};
01025 memcpy(intersection.intersection_ndxs, dd_intersection_ndxs, num_dds_in_intersection * sizeof(u8));
01026
01027
01028 printf("IAR: %"PRIu32" hypotheses before projection\n", memory_pool_n_allocated(amb_test->pool));
01029
01030 memory_pool_group_by(amb_test->pool,
01031 &intersection, &projection_comparator,
01032 &intersection, sizeof(intersection),
01033 &projection_aggregator);
01034 printf("IAR: updates to %"PRIu32"\n", memory_pool_n_allocated(amb_test->pool));
01035
01036 u8 work_prns[MAX_CHANNELS];
01037 memcpy(work_prns, amb_test->sats.prns, amb_test->sats.num_sats * sizeof(u8));
01038 for (u8 i=0; i<num_dds_in_intersection; i++) {
01039 amb_test->sats.prns[i+1] = work_prns[dd_intersection_ndxs[i]+1];
01040 }
01041 amb_test->sats.num_sats = num_dds_in_intersection+1;
01042 if (DEBUG_AMBIGUITY_TEST) {
01043 printf("</AMBIGUITY_SAT_PROJECTION>\n");
01044 }
01045 return 1;
01046 }
01047
01048
01049 u8 ambiguity_sat_inclusion(ambiguity_test_t *amb_test, u8 num_dds_in_intersection,
01050 sats_management_t *float_sats, double *float_mean, double *float_cov_U, double *float_cov_D)
01051 {
01052 if (DEBUG_AMBIGUITY_TEST) {
01053 printf("<AMBIGUITY_SAT_INCLUSION>\n");
01054 }
01055 if (float_sats->num_sats <= num_dds_in_intersection + 1 || float_sats->num_sats < 2) {
01056 if (DEBUG_AMBIGUITY_TEST) {
01057 printf("no need for inclusion\n</AMBIGUITY_SAT_INCLUSION>\n");
01058 }
01059 return 0;
01060 }
01061
01062 u32 state_dim = float_sats->num_sats-1;
01063 double float_cov[state_dim * state_dim];
01064 matrix_reconstruct_udu(state_dim, float_cov_U, float_cov_D, float_cov);
01065 u8 float_prns[float_sats->num_sats];
01066 memcpy(float_prns, float_sats->prns, float_sats->num_sats * sizeof(u8));
01067 double N_mean[float_sats->num_sats-1];
01068 memcpy(N_mean, float_mean, (float_sats->num_sats-1) * sizeof(double));
01069 if (amb_test->sats.num_sats >= 2 && amb_test->sats.prns[0] != float_sats->prns[0]) {
01070 u8 old_prns[float_sats->num_sats];
01071 memcpy(old_prns, float_sats->prns, float_sats->num_sats * sizeof(u8));
01072
01073 set_reference_sat_of_prns(amb_test->sats.prns[0], float_sats->num_sats, float_prns);
01074 rebase_mean_N(N_mean, float_sats->num_sats, old_prns, float_prns);
01075 rebase_covariance_sigma(float_cov, float_sats->num_sats, old_prns, float_prns);
01076 }
01077 double N_cov[(float_sats->num_sats-1) * (float_sats->num_sats-1)];
01078 memcpy(N_cov, float_cov, state_dim * state_dim * sizeof(double));
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 u8 i = 1;
01108 u8 j = 1;
01109 u8 num_addible_dds = 0;
01110 u8 ndxs_of_new_dds_in_float[MAX_CHANNELS-1];
01111 u8 new_dd_prns[MAX_CHANNELS-1];
01112 while (j < float_sats->num_sats) {
01113 if (i < amb_test->sats.num_sats && amb_test->sats.prns[i] == float_prns[j]) {
01114 i++;
01115 j++;
01116 } else {
01117 ndxs_of_new_dds_in_float[num_addible_dds] = j-1;
01118 new_dd_prns[num_addible_dds] = float_prns[j];
01119 num_addible_dds++;
01120 j++;
01121 }
01122 }
01123
01124 double addible_float_cov[num_addible_dds * num_addible_dds];
01125 double addible_float_mean[num_addible_dds];
01126 for (i=0; i < num_addible_dds; i++) {
01127 for (j=0; j < num_addible_dds; j++) {
01128 addible_float_cov[i*num_addible_dds + j] = N_cov[ndxs_of_new_dds_in_float[i]*(float_sats->num_sats-1) + ndxs_of_new_dds_in_float[j]];
01129 }
01130 addible_float_mean[i] = N_mean[ndxs_of_new_dds_in_float[i]];
01131 }
01132
01133
01134
01135 s32 Z_inv[num_addible_dds * num_addible_dds];
01136 s32 lower_bounds[num_addible_dds];
01137 s32 upper_bounds[num_addible_dds];
01138 u8 num_dds_to_add;
01139 s8 add_any_sats = determine_sats_addition(amb_test,
01140 addible_float_cov, num_addible_dds, addible_float_mean,
01141 lower_bounds, upper_bounds, &num_dds_to_add,
01142 Z_inv);
01143
01144 if (add_any_sats == 1) {
01145 add_sats(amb_test, float_prns[0], num_dds_to_add, new_dd_prns, lower_bounds, upper_bounds, Z_inv);
01146 if (DEBUG_AMBIGUITY_TEST) {
01147 printf("adding sats\n<AMBIGUITY_SAT_INCLUSION>\n");
01148 }
01149 return 1;
01150 } else {
01151 if (DEBUG_AMBIGUITY_TEST) {
01152 printf("not adding sats\n<AMBIGUITY_SAT_INCLUSION>\n");
01153 }
01154 return 0;
01155 }
01156
01157 }
01158
01159 u32 float_to_decor(ambiguity_test_t *amb_test,
01160 double *addible_float_cov, u8 num_addible_dds,
01161 double *addible_float_mean,
01162 u8 num_dds_to_add,
01163 s32 *lower_bounds, s32 *upper_bounds, double *Z)
01164 {
01165 (void) amb_test;
01166 double added_float_cov[num_dds_to_add * num_dds_to_add];
01167 for (u8 i=0; i<num_dds_to_add; i++) {
01168 for (u8 j=0; j<num_dds_to_add; j++) {
01169 added_float_cov[i*num_dds_to_add + j] = addible_float_cov[i*num_addible_dds + j];
01170 #if RAW_PHASE_BIAS_VAR != 0
01171 if (i == j) {
01172 added_float_cov[i*num_dds_to_add + j] += RAW_PHASE_BIAS_VAR;
01173 }
01174 #endif
01175 }
01176 }
01177
01178
01179 lambda_reduction(num_dds_to_add, added_float_cov, Z);
01180
01181 double decor_float_cov_diag[num_dds_to_add];
01182
01183 memset(decor_float_cov_diag, 0, num_dds_to_add * sizeof(double));
01184
01185 for (u8 i=0; i < num_dds_to_add; i++) {
01186 for (u8 j=0; j < num_dds_to_add; j++) {
01187 for (u8 k=0; k < num_dds_to_add; k++) {
01188 decor_float_cov_diag[i] += Z[i*num_dds_to_add + j] * added_float_cov[j * num_dds_to_add + k] * Z[i*num_dds_to_add + k];
01189 }
01190 }
01191 #if DECORRELATED_PHASE_BIAS_VAR != 0
01192 decor_float_cov_diag[i] += DECORRELATED_PHASE_BIAS_VAR;
01193 #endif
01194 }
01195
01196 double decor_float_mean[num_dds_to_add];
01197 memset(decor_float_mean, 0, num_dds_to_add * sizeof(double));
01198 for (u8 i=0; i < num_dds_to_add; i++) {
01199 for (u8 j=0; j < num_dds_to_add; j++) {
01200 decor_float_mean[i] += Z[i*num_dds_to_add + j] * addible_float_mean[j];
01201 }
01202
01203 }
01204
01205 u32 new_hyp_set_cardinality = 1;
01206
01207
01208 for (u8 i=0; i<num_dds_to_add; i++) {
01209 double search_distance = NUM_SEARCH_STDS * sqrt(decor_float_cov_diag[i]);
01210
01211
01212 upper_bounds[i] = lround(ceil(decor_float_mean[i] + search_distance));
01213 lower_bounds[i] = lround(floor(decor_float_mean[i] - search_distance));
01214 new_hyp_set_cardinality *= upper_bounds[i] - lower_bounds[i] + 1;
01215 }
01216 return new_hyp_set_cardinality;
01217 }
01218
01219 s8 determine_sats_addition(ambiguity_test_t *amb_test,
01220 double *float_N_cov, u8 num_float_dds, double *float_N_mean,
01221 s32 *lower_bounds, s32 *upper_bounds, u8 *num_dds_to_add,
01222 s32 *Z_inv)
01223 {
01224 u8 num_current_dds = MAX(1, amb_test->sats.num_sats) - 1;
01225 u8 min_dds_to_add = MAX(1, 4 - num_current_dds);
01226
01227 u32 max_new_hyps_cardinality;
01228 s32 current_num_hyps = memory_pool_n_allocated(amb_test->pool);
01229 u32 max_num_hyps = memory_pool_n_elements(amb_test->pool);
01230 if (current_num_hyps <= 0) {
01231 max_new_hyps_cardinality = max_num_hyps;
01232 } else {
01233 max_new_hyps_cardinality = max_num_hyps / current_num_hyps;
01234 }
01235
01236
01237
01238
01239
01240 *num_dds_to_add = num_float_dds;
01241 double Z[num_float_dds * num_float_dds];
01242 while (*num_dds_to_add >= min_dds_to_add) {
01243 u32 new_hyp_set_cardinality = float_to_decor(amb_test,
01244 float_N_cov, num_float_dds,
01245 float_N_mean,
01246 *num_dds_to_add,
01247 lower_bounds, upper_bounds, Z);
01248 if (new_hyp_set_cardinality <= max_new_hyps_cardinality) {
01249 double Z_inv_[*num_dds_to_add * *num_dds_to_add];
01250 matrix_inverse(*num_dds_to_add, Z, Z_inv_);
01251
01252 for (u8 i=0; i < *num_dds_to_add; i++) {
01253 for (u8 j=0; j < *num_dds_to_add; j++) {
01254 Z_inv[i* *num_dds_to_add + j] = lround(Z_inv_[i* *num_dds_to_add + j]);
01255 }
01256 }
01257 return 1;
01258 }
01259 else {
01260 *num_dds_to_add -= 1;
01261 }
01262 }
01263 return -1;
01264 }
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275 u8 ambiguity_update_sats(ambiguity_test_t *amb_test, u8 num_sdiffs, sdiff_t *sdiffs,
01276 sats_management_t *float_sats, double *float_mean, double *float_cov_U, double *float_cov_D)
01277 {
01278 if (DEBUG_AMBIGUITY_TEST) {
01279 printf("<AMBIGUITY_UPDATE_SATS>\n");
01280 }
01281 if (num_sdiffs < 2) {
01282 create_ambiguity_test(amb_test);
01283 if (DEBUG_AMBIGUITY_TEST) {
01284 printf("< 2 sdiffs, starting over\n</AMBIGUITY_UPDATE_SATS>\n");
01285 }
01286 return 0;
01287 }
01288
01289 u8 changed_sats = 0;
01290 if (!sats_match(amb_test, num_sdiffs, sdiffs)) {
01291 sdiff_t sdiffs_with_ref_first[num_sdiffs];
01292 if (amb_test->sats.num_sats >= 2) {
01293 if (ambiguity_update_reference(amb_test, num_sdiffs, sdiffs, sdiffs_with_ref_first)) {
01294 changed_sats=1;
01295 }
01296 } else {
01297 create_ambiguity_test(amb_test);
01298 }
01299
01300 u8 intersection_ndxs[num_sdiffs];
01301 u8 num_dds_in_intersection = find_indices_of_intersection_sats(amb_test, num_sdiffs, sdiffs_with_ref_first, intersection_ndxs);
01302
01303 if (amb_test->sats.num_sats > 1 && num_dds_in_intersection == 0) {
01304 create_ambiguity_test(amb_test);
01305 }
01306
01307
01308 if (ambiguity_sat_projection(amb_test, num_dds_in_intersection, intersection_ndxs)) {
01309 changed_sats = 1;
01310 }
01311 if (ambiguity_sat_inclusion(amb_test, num_dds_in_intersection,
01312 float_sats, float_mean, float_cov_U, float_cov_D)) {
01313 changed_sats = 1;
01314 }
01315 }
01316 if (DEBUG_AMBIGUITY_TEST) {
01317 printf("changed_sats = %u\n</AMBIGUITY_UPDATE_SATS>\n", changed_sats);
01318 }
01319
01320 return changed_sats;
01321
01322 }
01323
01324 u8 find_indices_of_intersection_sats(ambiguity_test_t *amb_test, u8 num_sdiffs, sdiff_t *sdiffs_with_ref_first, u8 *intersection_ndxs)
01325 {
01326 if (DEBUG_AMBIGUITY_TEST) {
01327 printf("<FIND_INDICES_OF_INTERSECTION_SATS>\n");
01328 printf("amb_test->sats.prns = {");
01329 for (u8 i = 0; i < amb_test->sats.num_sats; i++) {
01330 printf("%u, ", amb_test->sats.prns[i]);
01331 }
01332 if (amb_test->sats.num_sats < 2) {
01333 printf("}\nsdiffs_with_ref_first not populated\n");
01334 }
01335 else {
01336 printf("}\nsdiffs_with_ref_first[*].prn = {");
01337 for (u8 i = 0; i < num_sdiffs; i++) {
01338 printf("%u, ", sdiffs_with_ref_first[i].prn);
01339 }
01340 printf("}\n");
01341 }
01342 printf("(i, j, k, amb_test->sats.prns[i], sdiffs_with_ref_first[j].prn)\n");
01343 }
01344 u8 i = 1;
01345 u8 j = 1;
01346 u8 k = 0;
01347 while (i < amb_test->sats.num_sats && j < num_sdiffs) {
01348 if (amb_test->sats.prns[i] == sdiffs_with_ref_first[j].prn) {
01349 if (DEBUG_AMBIGUITY_TEST) {
01350 printf("(%u, \t%u, \t%u, \t%u, \t%u)\t\t\tamb_test->sats.prns[i] == sdiffs_with_ref_first[j].prn; i,j,k++\n",
01351 i, j, k, amb_test->sats.prns[i], sdiffs_with_ref_first[j].prn);
01352 }
01353 intersection_ndxs[k] = i-1;
01354 i++;
01355 j++;
01356 k++;
01357 }
01358 else if (amb_test->sats.prns[i] < sdiffs_with_ref_first[j].prn) {
01359 if (DEBUG_AMBIGUITY_TEST) {
01360 printf("(%u, \t%u, \t%u, \t%u, \t%u)\t\t\tamb_test->sats.prns[i] < sdiffs_with_ref_first[j].prn; i++\n",
01361 i, j, k, amb_test->sats.prns[i], sdiffs_with_ref_first[j].prn);
01362 }
01363 i++;
01364 }
01365 else {
01366 if (DEBUG_AMBIGUITY_TEST) {
01367 printf("(%u, \t%u, \t%u, \t%u, \t%u)\t\t\tamb_test->sats.prns[i] > sdiffs_with_ref_first[j].prn; j++\n",
01368 i, j, k, amb_test->sats.prns[i], sdiffs_with_ref_first[j].prn);
01369 }
01370 j++;
01371 }
01372 }
01373 if (DEBUG_AMBIGUITY_TEST) {
01374 printf("</FIND_INDICES_OF_INTERSECTION_SATS>\n");
01375 }
01376 return k;
01377 }
01378
01379 typedef struct {
01380 s32 upper_bounds[MAX_CHANNELS-1];
01381 s32 lower_bounds[MAX_CHANNELS-1];
01382 s32 counter[MAX_CHANNELS-1];
01383 u8 ndxs_of_old_in_new[MAX_CHANNELS-1];
01384 u8 ndxs_of_added_in_new[MAX_CHANNELS-1];
01385 u8 num_added_dds;
01386 u8 num_old_dds;
01387 s32 Z_inv[(MAX_CHANNELS-1) * (MAX_CHANNELS-1)];
01388 } generate_hypothesis_state_t;
01389
01390 s8 generate_next_hypothesis(void *x_, u32 n)
01391 {
01392 (void) n;
01393 generate_hypothesis_state_t *x = (generate_hypothesis_state_t *)x_;
01394
01395
01396 if (memcmp(x->upper_bounds, x->counter, x->num_added_dds * sizeof(s32)) == 0) {
01397
01398 return 0;
01399 }
01400
01401 for (u8 i=0; i<x->num_added_dds; i++) {
01402 x->counter[i]++;
01403 if (x->counter[i] > x->upper_bounds[i]) {
01404
01405
01406 x->counter[i] = x->lower_bounds[i];
01407 } else {
01408
01409 break;
01410 }
01411 }
01412
01413
01414
01415
01416
01417
01418
01419 return 1;
01420 }
01421
01422 void hypothesis_prod(element_t *new_, void *x_, u32 n, element_t *elem_)
01423 {
01424 (void) elem_;
01425 (void) n;
01426 generate_hypothesis_state_t *x = (generate_hypothesis_state_t *)x_;
01427 hypothesis_t *new = (hypothesis_t *) new_;
01428
01429 u8 *ndxs_of_old_in_new = x->ndxs_of_old_in_new;
01430 u8 *ndxs_of_added_in_new = x->ndxs_of_added_in_new;
01431
01432 s32 old_N[MAX_CHANNELS-1];
01433 memcpy(old_N, new->N, x->num_old_dds * sizeof(s32));
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463 for (u8 i=0; i < x->num_old_dds; i++) {
01464 new->N[ndxs_of_old_in_new[i]] = old_N[i];
01465 }
01466 for (u8 i=0; i<x->num_added_dds; i++) {
01467 new->N[ndxs_of_added_in_new[i]] = 0;
01468 for (u8 j=0; j<x->num_added_dds; j++) {
01469 new->N[ndxs_of_added_in_new[i]] += x->Z_inv[i*x->num_added_dds + j] * x->counter[j];
01470
01471
01472 }
01473 }
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485 }
01486
01487 typedef struct {
01488 u8 num_added_dds;
01489 u8 num_old_dds;
01490 s32 Z_inv[(MAX_CHANNELS-1)*(MAX_CHANNELS-1)];
01491 } recorrelation_params_t;
01492
01493 void recorrelate_added_sats(void *arg, element_t *elem_)
01494 {
01495 hypothesis_t *elem = (hypothesis_t *) elem_;
01496 recorrelation_params_t *params = (recorrelation_params_t *)arg;
01497
01498
01499
01500
01501
01502
01503 s32 recorrelated_N[params->num_added_dds];
01504 memset(recorrelated_N, 0, params->num_added_dds * sizeof(s32));
01505 for (u8 i=0; i<params->num_added_dds; i++) {
01506 for (u8 j=0; j<params->num_added_dds; j++) {
01507 recorrelated_N[i] += params->Z_inv[i*params->num_added_dds + j] * elem->N[params->num_old_dds + j];
01508 }
01509 }
01510 memcpy(&elem->N[params->num_old_dds], recorrelated_N, params->num_added_dds * sizeof(s32));
01511 }
01512
01513 void print_hyp(void *arg, element_t *elem)
01514 {
01515 u8 num_dds = *( (u8 *) arg );
01516
01517 hypothesis_t *hyp = (hypothesis_t *)elem;
01518 printf("[");
01519 for (u8 i=0; i< num_dds; i++) {
01520 printf("%"PRId32", ", hyp->N[i]);
01521 }
01522 printf("]: %f\n", hyp->ll);
01523 }
01524
01525 void add_sats(ambiguity_test_t *amb_test,
01526 u8 ref_prn,
01527 u32 num_added_dds, u8 *added_prns,
01528 s32 *lower_bounds, s32 *upper_bounds,
01529 s32 *Z_inv)
01530 {
01531
01532 generate_hypothesis_state_t x0;
01533 memcpy(x0.upper_bounds, upper_bounds, num_added_dds * sizeof(s32));
01534 memcpy(x0.lower_bounds, lower_bounds, num_added_dds * sizeof(s32));
01535 memcpy(x0.counter, lower_bounds, num_added_dds * sizeof(s32));
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547 x0.num_added_dds = num_added_dds;
01548 x0.num_old_dds = MAX(1,amb_test->sats.num_sats)-1;
01549
01550
01551 u8 i = 0;
01552 u8 j = 0;
01553 u8 k = 0;
01554 u8 old_prns[x0.num_old_dds];
01555 memcpy(old_prns, &amb_test->sats.prns[1], x0.num_old_dds * sizeof(u8));
01556 while (k < x0.num_old_dds + num_added_dds) {
01557 if (j == x0.num_added_dds || (old_prns[i] < added_prns[j] && i != x0.num_old_dds)) {
01558 x0.ndxs_of_old_in_new[i] = k;
01559 amb_test->sats.prns[k+1] = old_prns[i];
01560 i++;
01561 k++;
01562 } else if (i == x0.num_old_dds || old_prns[i] > added_prns[j]) {
01563 x0.ndxs_of_added_in_new[j] = k;
01564 amb_test->sats.prns[k+1] = added_prns[j];
01565 j++;
01566 k++;
01567 } else {
01568 printf("This method is being used improperly. This shouldn't happen.\n");
01569 printf("old_prns = [");
01570 for (u8 ii=0; ii < x0.num_old_dds; ii++) {
01571 printf("%d, ",old_prns[ii]);
01572 }
01573 printf("]\n");
01574 printf("added_prns = [");
01575 for (u8 jj=0; jj < x0.num_old_dds; jj++) {
01576 printf("%d, ", added_prns[jj]);
01577 }
01578 printf("]\n");
01579 break;
01580 }
01581 }
01582 amb_test->sats.prns[0] = ref_prn;
01583 amb_test->sats.num_sats = k+1;
01584
01585 if (x0.num_old_dds == 0 && memory_pool_n_allocated(amb_test->pool) == 0) {
01586 hypothesis_t *empty_element = (hypothesis_t *)memory_pool_add(amb_test->pool);
01587
01588 empty_element->ll = 0;
01589 }
01590
01591 printf("IAR: %"PRIu32" hypotheses before inclusion\n", memory_pool_n_allocated(amb_test->pool));
01592 if (DEBUG_AMBIGUITY_TEST) {
01593 memory_pool_map(amb_test->pool, &x0.num_old_dds, &print_hyp);
01594 }
01595 memcpy(x0.Z_inv, Z_inv, num_added_dds * num_added_dds * sizeof(s32));
01596
01597 memory_pool_product_generator(amb_test->pool, &x0, MAX_HYPOTHESES, sizeof(x0),
01598 &generate_next_hypothesis, &hypothesis_prod);
01599 printf("IAR: updates to %"PRIu32"\n", memory_pool_n_allocated(amb_test->pool));
01600 if (DEBUG_AMBIGUITY_TEST) {
01601 memory_pool_map(amb_test->pool, &k, &print_hyp);
01602 }
01603 }
01604
01605 void init_residual_matrices(residual_mtxs_t *res_mtxs, u8 num_dds, double *DE_mtx, double *obs_cov)
01606 {
01607 res_mtxs->res_dim = num_dds + MAX(3, num_dds) - 3;
01608 res_mtxs->null_space_dim = MAX(3, num_dds) - 3;
01609 assign_phase_obs_null_basis(num_dds, DE_mtx, res_mtxs->null_projector);
01610 assign_residual_covariance_inverse(num_dds, obs_cov, res_mtxs->null_projector, res_mtxs->half_res_cov_inv);
01611
01612
01613 }
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678 void assign_residual_covariance_inverse(u8 num_dds, double *obs_cov, double *q, double *r_cov_inv)
01679 {
01680 integer dd_dim = 2*num_dds;
01681 integer res_dim = num_dds + MAX(3, num_dds) - 3;
01682 u32 nullspace_dim = MAX(3, num_dds) - 3;
01683 double q_tilde[res_dim * dd_dim];
01684 memset(q_tilde, 0, res_dim * dd_dim * sizeof(double));
01685
01686
01687
01688 for (u8 i=0; i<nullspace_dim; i++) {
01689 memcpy(&q_tilde[i*dd_dim], &q[i*num_dds], num_dds * sizeof(double));
01690 }
01691
01692 for (u8 i=0; i<num_dds; i++) {
01693 q_tilde[(i+nullspace_dim)*dd_dim + i] = 1;
01694 q_tilde[(i+nullspace_dim)*dd_dim + i+num_dds] = -1 / GPS_L1_LAMBDA_NO_VAC;
01695 }
01696
01697
01698
01699 double QC[res_dim * dd_dim];
01700 cblas_dsymm(CblasRowMajor, CblasRight, CblasUpper,
01701 res_dim, dd_dim,
01702 1, obs_cov, dd_dim,
01703 q_tilde, dd_dim,
01704 0, QC, dd_dim);
01705
01706
01707
01708 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasTrans,
01709 res_dim, res_dim, dd_dim,
01710 2, QC, dd_dim,
01711 q_tilde, dd_dim,
01712 0, r_cov_inv, res_dim);
01713
01714
01715
01716
01717
01718
01719 char uplo = 'L';
01720 integer info;
01721 dpotrf_(&uplo, &res_dim, r_cov_inv, &res_dim, &info);
01722
01723
01724 dpotri_(&uplo, &res_dim, r_cov_inv, &res_dim, &info);
01725 for (u8 i=0; i < res_dim; i++) {
01726 for (u8 j=0; j < i; j++) {
01727 r_cov_inv[i*res_dim + j] = r_cov_inv[j*res_dim + i];
01728 }
01729 }
01730
01731
01732 }
01733
01734 void assign_r_vec(residual_mtxs_t *res_mtxs, u8 num_dds, double *dd_measurements, double *r_vec)
01735 {
01736 cblas_dgemv(CblasRowMajor, CblasNoTrans,
01737 res_mtxs->null_space_dim, num_dds,
01738 1, res_mtxs->null_projector, num_dds,
01739 dd_measurements, 1,
01740 0, r_vec, 1);
01741 for (u8 i=0; i< num_dds; i++) {
01742 r_vec[i + res_mtxs->null_space_dim] = dd_measurements[i] - dd_measurements[i+num_dds] / GPS_L1_LAMBDA_NO_VAC;
01743 }
01744 }
01745
01746 void assign_r_mean(residual_mtxs_t *res_mtxs, u8 num_dds, double *hypothesis, double *r_mean)
01747 {
01748 cblas_dgemv(CblasRowMajor, CblasNoTrans,
01749 res_mtxs->null_space_dim, num_dds,
01750 1, res_mtxs->null_projector, num_dds,
01751 hypothesis, 1,
01752 0, r_mean, 1);
01753 memcpy(&r_mean[res_mtxs->null_space_dim], hypothesis, num_dds * sizeof(double));
01754 }
01755
01756 double get_quadratic_term(residual_mtxs_t *res_mtxs, u8 num_dds, double *hypothesis, double *r_vec)
01757 {
01758
01759 double r[res_mtxs->res_dim];
01760 assign_r_mean(res_mtxs, num_dds, hypothesis, r);
01761
01762 for (u32 i=0; i<res_mtxs->res_dim; i++) {
01763 r[i] = r_vec[i] - r[i];
01764 }
01765
01766 double half_sig_dot_r[res_mtxs->res_dim];
01767 cblas_dsymv(CblasRowMajor, CblasUpper,
01768 res_mtxs->res_dim,
01769 1, res_mtxs->half_res_cov_inv, res_mtxs->res_dim,
01770 r, 1,
01771 0, half_sig_dot_r, 1);
01772
01773 double quad_term = 0;
01774 for (u32 i=0; i<res_mtxs->res_dim; i++) {
01775 quad_term -= half_sig_dot_r[i] * r[i];
01776 }
01777 return quad_term;
01778 }
01779