dgnss_management.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2014 Swift Navigation Inc.
00003  * Contact: Ian Horn <ian@swift-nav.com>
00004  *
00005  * This source is subject to the license found in the file 'LICENSE' which must
00006  * be be distributed together with this source. All other rights reserved.
00007  *
00008  * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
00009  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
00010  * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
00011  */
00012 
00013 #include <string.h>
00014 #include <stdio.h>
00015 #include "amb_kf.h"
00016 #include "stupid_filter.h"
00017 #include "single_diff.h"
00018 #include "dgnss_management.h"
00019 #include "linear_algebra.h"
00020 #include "ambiguity_test.h"
00021 
00022 #define DEBUG_DGNSS_MANAGEMENT 0
00023 
00024 nkf_t nkf;
00025 stupid_filter_state_t stupid_state;
00026 sats_management_t sats_management;
00027 ambiguity_test_t ambiguity_test;
00028 
00029 dgnss_settings_t dgnss_settings = {
00030   .phase_var_test = DEFAULT_PHASE_VAR_TEST,
00031   .code_var_test = DEFAULT_CODE_VAR_TEST,
00032   .phase_var_kf = DEFAULT_PHASE_VAR_KF,
00033   .code_var_kf = DEFAULT_CODE_VAR_KF,
00034   .amb_drift_var = DEFAULT_AMB_DRIFT_VAR,
00035   .amb_init_var = DEFAULT_AMB_INIT_VAR,
00036   .new_int_var = DEFAULT_NEW_INT_VAR,
00037 };
00038 
00039 void dgnss_set_settings(double phase_var_test, double code_var_test,
00040                         double phase_var_kf, double code_var_kf,
00041                         double amb_drift_var, double amb_init_var,
00042                         double new_int_var)
00043 {
00044   dgnss_settings.phase_var_test = phase_var_test;
00045   dgnss_settings.code_var_test  = code_var_test;
00046   dgnss_settings.phase_var_kf   = phase_var_kf;
00047   dgnss_settings.code_var_kf    = code_var_kf;
00048   dgnss_settings.amb_drift_var  = amb_drift_var;
00049   dgnss_settings.amb_init_var   = amb_init_var;
00050   dgnss_settings.new_int_var    = new_int_var;
00051 }
00052 
00053 void make_measurements(u8 num_double_diffs, sdiff_t *sdiffs, double *raw_measurements)
00054 {
00055   if (DEBUG_DGNSS_MANAGEMENT) {
00056       printf("<MAKE_MEASUREMENTS>\n");
00057   }
00058   double phase0 = sdiffs[0].carrier_phase;
00059   double code0 = sdiffs[0].pseudorange;
00060   for (u8 i=0; i<num_double_diffs; i++) {
00061     raw_measurements[i] = sdiffs[i+1].carrier_phase - phase0;
00062     raw_measurements[i+num_double_diffs] = sdiffs[i+1].pseudorange - code0;
00063   }
00064   if (DEBUG_DGNSS_MANAGEMENT) {
00065       printf("</MAKE_MEASUREMENTS>\n");
00066   }
00067 }
00068 
00069 bool prns_match(u8 *old_non_ref_prns, u8 num_non_ref_sdiffs, sdiff_t *non_ref_sdiffs)
00070 {
00071   if (sats_management.num_sats-1 != num_non_ref_sdiffs) {
00072     /* lengths don't match */
00073     return false;
00074   }
00075   for (u8 i=0; i<num_non_ref_sdiffs; i++) {
00076     /* iterate through the non-reference_sats, checking they match. */
00077     if (old_non_ref_prns[i] != non_ref_sdiffs[i].prn) {
00078       return false;
00079     }
00080   }
00081   return true;
00082 }
00083 
00087 u8 dgnss_intersect_sats(u8 num_old_prns, u8 *old_prns,
00088                   u8 num_sdiffs, sdiff_t *sdiffs,
00089                   u8 *ndx_of_intersection_in_old,
00090                   u8 *ndx_of_intersection_in_new)
00091 {
00092   u8 i, j, n = 0;
00093   /* Loop over old_prns and sdiffs and check if a PRN is present in both. */
00094   for (i=0, j=0; i<num_old_prns && j<num_sdiffs; i++, j++) {
00095     if (old_prns[i] < sdiffs[j].prn)
00096       j--;
00097     else if (old_prns[i] > sdiffs[j].prn)
00098       i--;
00099     else {
00100       ndx_of_intersection_in_old[n] = i;
00101       ndx_of_intersection_in_new[n] = j;
00102       n++;
00103     }
00104   }
00105   return n;
00106 }
00107 
00108 void dgnss_init(u8 num_sats, sdiff_t *sdiffs, double reciever_ecef[3])
00109 {
00110   if (DEBUG_DGNSS_MANAGEMENT) {
00111       printf("<DGNSS_INIT>\n");
00112   }
00113   sdiff_t corrected_sdiffs[num_sats];
00114   init_sats_management(&sats_management, num_sats, sdiffs, corrected_sdiffs);
00115 
00116   create_ambiguity_test(&ambiguity_test);
00117 
00118   if (num_sats <= 1) {
00119     if (DEBUG_DGNSS_MANAGEMENT) {
00120       printf("</DGNSS_INIT>\n");
00121     }
00122     return;
00123   }
00124 
00125   double dd_measurements[2*(num_sats-1)];
00126   make_measurements(num_sats-1, corrected_sdiffs, dd_measurements);
00127 
00128   set_nkf(
00129     &nkf,
00130     dgnss_settings.amb_drift_var,
00131     dgnss_settings.phase_var_kf, dgnss_settings.code_var_kf,
00132     dgnss_settings.amb_init_var,
00133     num_sats, corrected_sdiffs, dd_measurements, reciever_ecef
00134   );
00135 
00136   if (DEBUG_DGNSS_MANAGEMENT) {
00137       printf("</DGNSS_INIT>\n");
00138   }
00139 }
00140 
00141 void dgnss_start_over(u8 num_sats, sdiff_t *sdiffs, double reciever_ecef[3])
00142 {
00143   if (DEBUG_DGNSS_MANAGEMENT) {
00144       printf("<DGNSS_START_OVER>\n");
00145   }
00146   sdiff_t corrected_sdiffs[num_sats];
00147   init_sats_management(&sats_management, num_sats, sdiffs, corrected_sdiffs);
00148 
00149   reset_ambiguity_test(&ambiguity_test);
00150 
00151   if (num_sats <= 1) {
00152     if (DEBUG_DGNSS_MANAGEMENT) {
00153       printf("</DGNSS_START_OVER>\n");
00154     }
00155     return;
00156   }
00157   double dd_measurements[2*(num_sats-1)];
00158   make_measurements(num_sats-1, corrected_sdiffs, dd_measurements);
00159 
00160   set_nkf(
00161     &nkf,
00162     dgnss_settings.amb_drift_var,
00163     dgnss_settings.phase_var_kf, dgnss_settings.code_var_kf,
00164     dgnss_settings.amb_init_var,
00165     num_sats, corrected_sdiffs, dd_measurements, reciever_ecef
00166   );
00167 
00168   if (DEBUG_DGNSS_MANAGEMENT) {
00169       printf("</DGNSS_START_OVER>\n");
00170   }
00171 }
00172 
00173 
00174 void dgnss_rebase_ref(u8 num_sdiffs, sdiff_t *sdiffs, double reciever_ecef[3], u8 old_prns[MAX_CHANNELS], sdiff_t *corrected_sdiffs)
00175 {
00176   (void)reciever_ecef;
00177   /* all the ref sat stuff */
00178   s8 sats_management_code = rebase_sats_management(&sats_management, num_sdiffs, sdiffs, corrected_sdiffs);
00179   if (sats_management_code == NEW_REF_START_OVER) {
00180     printf("====== START OVER =======\n");
00181     dgnss_start_over(num_sdiffs, sdiffs, reciever_ecef);
00182     memcpy(old_prns, sats_management.prns, sats_management.num_sats * sizeof(u8));
00183     if (num_sdiffs >= 1) {
00184       copy_sdiffs_put_ref_first(old_prns[0], num_sdiffs, sdiffs, corrected_sdiffs);
00185     }
00186     /*dgnss_init(num_sdiffs, sdiffs, reciever_ecef); //TODO use current baseline state*/
00187     return;
00188   }
00189   else if (sats_management_code == NEW_REF) {
00190     /* do everything related to changing the reference sat here */
00191     rebase_nkf(&nkf, sats_management.num_sats, &old_prns[0], &sats_management.prns[0]);
00192   }
00193 }
00194 
00195 
00196 void sdiffs_to_prns(u8 n, sdiff_t *sdiffs, u8 *prns)
00197 {
00198   for (u8 i=0; i<n; i++) {
00199     prns[i] = sdiffs[i].prn;
00200   }
00201 }
00202 
00203 void dgnss_update_sats(u8 num_sdiffs, double reciever_ecef[3], sdiff_t *sdiffs_with_ref_first,
00204                        double *dd_measurements)
00205 {
00206   if (DEBUG_DGNSS_MANAGEMENT) {
00207     printf("<DGNSS_UPDATE_SATS>\n");
00208   }
00209   (void)dd_measurements;
00210   u8 new_prns[num_sdiffs];
00211   sdiffs_to_prns(num_sdiffs, sdiffs_with_ref_first, new_prns);
00212 
00213   u8 old_prns[MAX_CHANNELS];
00214   memcpy(old_prns, sats_management.prns, sats_management.num_sats * sizeof(u8));
00215 
00216   if (!prns_match(&old_prns[1], num_sdiffs-1, &sdiffs_with_ref_first[1])) {
00217     u8 ndx_of_intersection_in_old[sats_management.num_sats];
00218     u8 ndx_of_intersection_in_new[sats_management.num_sats];
00219     ndx_of_intersection_in_old[0] = 0;
00220     ndx_of_intersection_in_new[0] = 0;
00221     u8 num_intersection_sats = dgnss_intersect_sats(
00222         sats_management.num_sats-1, &old_prns[1],
00223         num_sdiffs-1, &sdiffs_with_ref_first[1],
00224         &ndx_of_intersection_in_old[1],
00225         &ndx_of_intersection_in_new[1]) + 1;
00226 
00227     set_nkf_matrices(
00228       &nkf,
00229       dgnss_settings.phase_var_kf, dgnss_settings.code_var_kf,
00230       num_sdiffs, sdiffs_with_ref_first, reciever_ecef
00231     );
00232 
00233     if (num_intersection_sats < sats_management.num_sats) { /* we lost sats */
00234       nkf_state_projection(&nkf,
00235                            sats_management.num_sats-1,
00236                            num_intersection_sats-1,
00237                            &ndx_of_intersection_in_old[1]);
00238     }
00239     if (num_intersection_sats < num_sdiffs) { /* we gained sats */
00240       nkf_state_inclusion(&nkf,
00241                           num_intersection_sats-1,
00242                           num_sdiffs-1,
00243                           &ndx_of_intersection_in_new[1],
00244                           dgnss_settings.new_int_var);
00245     }
00246 
00247     update_sats_sats_management(&sats_management, num_sdiffs-1, &sdiffs_with_ref_first[1]);
00248   }
00249   else {
00250     set_nkf_matrices(
00251       &nkf,
00252       dgnss_settings.phase_var_kf, dgnss_settings.code_var_kf,
00253       num_sdiffs, sdiffs_with_ref_first, reciever_ecef
00254     );
00255   }
00256   if (DEBUG_DGNSS_MANAGEMENT) {
00257     printf("</DGNSS_UPDATE_SATS>\n");
00258   }
00259 }
00260 
00261 void dgnss_incorporate_observation(sdiff_t *sdiffs, double * dd_measurements,
00262                                    double *reciever_ecef)
00263 {
00264   if (DEBUG_DGNSS_MANAGEMENT) {
00265     printf("<DGNSS_INCORPORATE_OBSERVATION>\n");
00266   }
00267 
00268   double b2[3];
00269   least_squares_solve_b(&nkf, sdiffs, dd_measurements, reciever_ecef, b2);
00270 
00271   double ref_ecef[3];
00272 
00273   ref_ecef[0] = reciever_ecef[0] + 0.5 * b2[0];
00274   ref_ecef[1] = reciever_ecef[1] + 0.5 * b2[0];
00275   ref_ecef[2] = reciever_ecef[2] + 0.5 * b2[0];
00276 
00277   /* TODO: make a common DE and use it instead. */
00278 
00279   set_nkf_matrices(&nkf,
00280                    dgnss_settings.phase_var_kf, dgnss_settings.code_var_kf,
00281                    sats_management.num_sats, sdiffs, ref_ecef);
00282 
00283   nkf_update(&nkf, dd_measurements);
00284   if (DEBUG_DGNSS_MANAGEMENT) {
00285     printf("</DGNSS_INCORPORATE_OBSERVATION>\n");
00286   }
00287 }
00288 
00289 void dvec_printf(double *v, u32 n)
00290 {
00291   for (u32 i = 0; i < n; i++)
00292     printf(", %f", v[i]);
00293 }
00294 
00295 void dgnss_update(u8 num_sats, sdiff_t *sdiffs, double reciever_ecef[3])
00296 {
00297   if (DEBUG_DGNSS_MANAGEMENT) {
00298     printf("<DGNSS_UPDATE>\nsdiff[*].prn = {");
00299     for (u8 i=0; i < num_sats; i++) {
00300       printf("%u, ",sdiffs[i].prn);
00301     }
00302     printf("}\n");
00303   }
00304 
00305   if (num_sats <= 1) {
00306     sats_management.num_sats = num_sats;
00307     if (num_sats == 1) {
00308       sats_management.prns[0] = sdiffs[0].prn;
00309     }
00310     return;
00311     if (DEBUG_DGNSS_MANAGEMENT) {
00312       printf("<DGNSS_UPDATE>\n");
00313     }
00314   }
00315 
00316   if (sats_management.num_sats <= 1) {
00317     dgnss_start_over(num_sats, sdiffs, reciever_ecef);
00318   }
00319 
00320   sdiff_t sdiffs_with_ref_first[num_sats];
00321 
00322   u8 old_prns[MAX_CHANNELS];
00323   memcpy(old_prns, sats_management.prns, sats_management.num_sats * sizeof(u8));
00324 
00325   /* rebase globals to a new reference sat
00326    * (permutes sdiffs_with_ref_first accordingly) */
00327   dgnss_rebase_ref(num_sats, sdiffs, reciever_ecef, old_prns, sdiffs_with_ref_first);
00328 
00329   double dd_measurements[2*(num_sats-1)];
00330   make_measurements(num_sats-1, sdiffs_with_ref_first, dd_measurements);
00331 
00332   /* all the added/dropped sat stuff */
00333   dgnss_update_sats(num_sats, reciever_ecef, sdiffs_with_ref_first, dd_measurements);
00334 
00335   double ref_ecef[3];
00336   if (num_sats >= 5) {
00337     dgnss_incorporate_observation(sdiffs_with_ref_first, dd_measurements, reciever_ecef);
00338 
00339     double b2[3];
00340     least_squares_solve_b(&nkf, sdiffs_with_ref_first, dd_measurements, reciever_ecef, b2);
00341 
00342     ref_ecef[0] = reciever_ecef[0] + 0.5 * b2[0];
00343     ref_ecef[1] = reciever_ecef[1] + 0.5 * b2[1];
00344     ref_ecef[2] = reciever_ecef[2] + 0.5 * b2[2];
00345   }
00346 
00347   u8 changed_sats = ambiguity_update_sats(&ambiguity_test, num_sats, sdiffs,
00348                                           &sats_management, nkf.state_mean,
00349                                           nkf.state_cov_U, nkf.state_cov_D);
00350 
00351   update_ambiguity_test(ref_ecef,
00352                         dgnss_settings.phase_var_test,
00353                         dgnss_settings.code_var_test,
00354                         &ambiguity_test, nkf.state_dim,
00355                         sdiffs, changed_sats);
00356 
00357   update_unanimous_ambiguities(&ambiguity_test);
00358 
00359   if (DEBUG_DGNSS_MANAGEMENT) {
00360     if (num_sats >=4) {
00361       double bb[3];
00362       u8 num_used;
00363       dgnss_fixed_baseline(num_sats, sdiffs, ref_ecef,
00364                            &num_used, bb);
00365       printf("\n\nold dgnss_fixed_baseline:\nb = %f, \t%f, \t%f\nnum_used/num_sats = %u/%u\nusing_iar = %u\n\n",
00366              bb[0], bb[1], bb[2],
00367              num_used, num_sats,
00368              dgnss_iar_resolved());
00369       dgnss_fixed_baseline2(num_sats, sdiffs, ref_ecef,
00370                             &num_used, bb);
00371       printf("\n\nnew dgnss_fixed_baseline:\nb = %f, \t%f, \t%f\nnum_used/num_sats = %u/%u\nusing_iar = %u\n\n",
00372              bb[0], bb[1], bb[2],
00373              num_used, num_sats,
00374              ambiguity_iar_can_solve(&ambiguity_test));
00375     }
00376     printf("</DGNSS_UPDATE>\n");
00377   }
00378 }
00379 
00380 u32 dgnss_iar_num_hyps(void)
00381 {
00382   if (ambiguity_test.pool == NULL) {
00383     return 0;
00384   } else {
00385     return ambiguity_test_n_hypotheses(&ambiguity_test);
00386   }
00387 }
00388 
00389 u32 dgnss_iar_num_sats(void)
00390 {
00391   return ambiguity_test.sats.num_sats;
00392 }
00393 
00394 s8 dgnss_iar_get_single_hyp(double *dhyp)
00395 {
00396   u8 num_dds = ambiguity_test.sats.num_sats;
00397   s32 hyp[num_dds];
00398   s8 ret = get_single_hypothesis(&ambiguity_test, hyp);
00399   for (u8 i=0; i<num_dds; i++) {
00400     dhyp[i] = hyp[i];
00401   }
00402   return ret;
00403 }
00404 
00405 void dgnss_new_float_baseline(u8 num_sats, sdiff_t *sdiffs, double receiver_ecef[3], u8 *num_used, double b[3])
00406 {
00407   if (DEBUG_DGNSS_MANAGEMENT) {
00408     printf("<DGNSS_NEW_FLOAT_BASELINE>\n");
00409   }
00410   sdiff_t corrected_sdiffs[num_sats];
00411 
00412   u8 old_prns[MAX_CHANNELS];
00413   memcpy(old_prns, sats_management.prns, sats_management.num_sats * sizeof(u8));
00414   /* rebase globals to a new reference sat
00415    * (permutes corrected_sdiffs accordingly) */
00416   dgnss_rebase_ref(num_sats, sdiffs, receiver_ecef, old_prns, corrected_sdiffs);
00417 
00418   double dd_measurements[2*(num_sats-1)];
00419   make_measurements(num_sats-1, corrected_sdiffs, dd_measurements);
00420 
00421   least_squares_solve_b(&nkf, corrected_sdiffs, dd_measurements, receiver_ecef, b);
00422   *num_used = sats_management.num_sats;
00423   if (DEBUG_DGNSS_MANAGEMENT) {
00424     printf("</DGNSS_NEW_FLOAT_BASELINE>\n");
00425   }
00426 }
00427 
00428 void dgnss_fixed_baseline(u8 n, sdiff_t *sdiffs, double ref_ecef[3],
00429                           u8 *num_used, double b[3])
00430 {
00431   if (dgnss_iar_resolved()) {
00432     sdiff_t ambiguity_sdiffs[ambiguity_test.sats.num_sats];
00433     double dd_meas[2*(ambiguity_test.sats.num_sats-1)];
00434     make_ambiguity_dd_measurements_and_sdiffs(&ambiguity_test, n, sdiffs,
00435         dd_meas, ambiguity_sdiffs);
00436     double DE[(ambiguity_test.sats.num_sats-1) * 3];
00437     assign_de_mtx(ambiguity_test.sats.num_sats, ambiguity_sdiffs, ref_ecef, DE);
00438     hypothesis_t *hyp = (hypothesis_t*)ambiguity_test.pool->allocated_nodes_head->elem;
00439     *num_used = ambiguity_test.sats.num_sats;
00440     lesq_solution(ambiguity_test.sats.num_sats-1, dd_meas, hyp->N, DE, b, 0);
00441   } else {
00442     dgnss_new_float_baseline(n, sdiffs, ref_ecef, num_used, b);
00443   }
00444 }
00445 
00446 /* this version returns the fixed baseline iff there are at least 3 dd ambs unanimously agreed upon in the ambiguity_test
00447  * \return 1 if fixed baseline calculation succeeds
00448  *         0 if iar cannot solve or an error occurs. Signals that float baseline is needed instead.
00449  */
00450 s8 dgnss_fixed_baseline2(u8 num_sdiffs, sdiff_t *sdiffs, double ref_ecef[3],
00451                          u8 *num_used, double b[3])
00452 {
00453   if (ambiguity_iar_can_solve(&ambiguity_test)) {
00454     sdiff_t ambiguity_sdiffs[ambiguity_test.amb_check.num_matching_ndxs+1];
00455     double dd_meas[2 * ambiguity_test.amb_check.num_matching_ndxs];
00456     s8 valid_sdiffs = make_ambiguity_resolved_dd_measurements_and_sdiffs(&ambiguity_test, num_sdiffs, sdiffs,
00457         dd_meas, ambiguity_sdiffs);
00458     /* At this point, sdiffs should be valid due to dgnss_update
00459      * Return code not equal to 0 signals an error. */
00460     if (valid_sdiffs == 0) {
00461       double DE[ambiguity_test.amb_check.num_matching_ndxs * 3];
00462       assign_de_mtx(ambiguity_test.amb_check.num_matching_ndxs + 1, ambiguity_sdiffs, ref_ecef, DE);
00463       *num_used = ambiguity_test.amb_check.num_matching_ndxs + 1;
00464       lesq_solution(ambiguity_test.amb_check.num_matching_ndxs, dd_meas, ambiguity_test.amb_check.ambs, DE, b, 0);
00465       return 1;
00466     } else {
00467       if (valid_sdiffs == -2) {
00468         printf("dngss_fixed_baseline2: Invalid sdiffs.\n");
00469         for (u8 k=0; k < num_sdiffs; k++) {
00470           printf("%u, ", sdiffs[k].prn);
00471         }
00472         printf("}\n");
00473       }
00474     }
00475   }
00476   return 0;
00477 }
00478 
00479 
00493 s8 make_float_dd_measurements_and_sdiffs(
00494             u8 num_sdiffs, sdiff_t *sdiffs,
00495             double *float_dd_measurements, sdiff_t *float_sdiffs)
00496 {
00497   u8 ref_prn = sats_management.prns[0];
00498   u8 num_dds = sats_management.num_sats - 1;
00499   u8 *non_ref_prns = &sats_management.prns[1];
00500   s8 valid_sdiffs =
00501         make_dd_measurements_and_sdiffs(ref_prn, non_ref_prns, num_dds,
00502                                         num_sdiffs, sdiffs,
00503                                         float_dd_measurements, float_sdiffs);
00504   return valid_sdiffs;
00505 }
00506 
00507 
00532 s8 _dgnss_low_latency_float_baseline(u8 num_sdiffs, sdiff_t *sdiffs,
00533                                  double ref_ecef[3], u8 *num_used, double b[3])
00534 {
00535   if (DEBUG_DGNSS_MANAGEMENT) {
00536     printf("<DGNSS_LOW_LATENCY_FLOAT_BASELINE>\n");
00537   }
00538   if (num_sdiffs <= 1 || sats_management.num_sats <= 1) {
00539     if (DEBUG_DGNSS_MANAGEMENT) {
00540       printf("too few sats or too few sdiffs\n</DGNSS_LOW_LATENCY_FLOAT_BASELINE>\n");
00541     }
00542     return -1;
00543   }
00544   double float_dd_measurements[2 * (sats_management.num_sats - 1)];
00545   sdiff_t float_sdiffs[sats_management.num_sats];
00546   s8 can_make_obs = make_dd_measurements_and_sdiffs(sats_management.prns[0],
00547              &sats_management.prns[1], sats_management.num_sats - 1,
00548              num_sdiffs, sdiffs,
00549              float_dd_measurements, float_sdiffs);
00550   if (can_make_obs == -1) {
00551     if (DEBUG_DGNSS_MANAGEMENT) {
00552       printf("make_float_dd_measurements_and_sdiffs has error code -1\n</DGNSS_LOW_LATENCY_FLOAT_BASELINE>\n");
00553     }
00554     return -1;
00555   }
00556   least_squares_solve_b(&nkf, float_sdiffs, float_dd_measurements,
00557                         ref_ecef, b);
00558   *num_used = sats_management.num_sats;
00559   if (DEBUG_DGNSS_MANAGEMENT) {
00560     printf("</DGNSS_LOW_LATENCY_FLOAT_BASELINE>\n");
00561   }
00562   return 0;
00563 }
00564 
00589 s8 _dgnss_low_latency_IAR_baseline(u8 num_sdiffs, sdiff_t *sdiffs,
00590                                   double ref_ecef[3], u8 *num_used, double b[3])
00591 {
00592   if (DEBUG_DGNSS_MANAGEMENT) {
00593     printf("<DGNSS_LOW_LATENCY_IAR_BASELINE>\n");
00594   }
00595   if (ambiguity_iar_can_solve(&ambiguity_test)) {
00596     sdiff_t ambiguity_sdiffs[ambiguity_test.amb_check.num_matching_ndxs+1];
00597     double dd_meas[2 * ambiguity_test.amb_check.num_matching_ndxs];
00598     s8 valid_sdiffs = make_ambiguity_resolved_dd_measurements_and_sdiffs(
00599         &ambiguity_test, num_sdiffs, sdiffs, dd_meas, ambiguity_sdiffs);
00600     if (valid_sdiffs == 0) {
00601       //TODO: check internals of this if's content and abstract it from the KF
00602       double DE[ambiguity_test.amb_check.num_matching_ndxs * 3];
00603       assign_de_mtx(ambiguity_test.amb_check.num_matching_ndxs + 1,
00604                     ambiguity_sdiffs, ref_ecef, DE);
00605       *num_used = ambiguity_test.amb_check.num_matching_ndxs + 1;
00606       lesq_solution(ambiguity_test.amb_check.num_matching_ndxs,
00607                     dd_meas, ambiguity_test.amb_check.ambs, DE, b, 0);
00608       if (DEBUG_DGNSS_MANAGEMENT) {
00609         printf("</DGNSS_LOW_LATENCY_IAR_BASELINE>\n");
00610       }
00611       return 0;
00612     } else if (valid_sdiffs == -2) {
00613       printf("_dgnss_low_latency_IAR_baseline: Invalid sdiffs: {\n");
00614       for (u8 i = 0; i < num_sdiffs; i++) {
00615         printf("%u, ", sdiffs[i].prn);
00616       }
00617       printf("}\n");
00618       print_sats_management_short(&ambiguity_test.sats);
00619     }
00620   }
00621   if (DEBUG_DGNSS_MANAGEMENT) {
00622     printf("</DGNSS_LOW_LATENCY_IAR_BASELINE>\n");
00623   }
00624   return -1;
00625 }
00626 
00643 s8 dgnss_low_latency_baseline(u8 num_sdiffs, sdiff_t *sdiffs,
00644                                double ref_ecef[3], u8 *num_used, double b[3])
00645 {
00646   if (DEBUG_DGNSS_MANAGEMENT) {
00647     printf("<DGNSS_LOW_LATENCY_BASELINE>\n");
00648   }
00649   if (0 == _dgnss_low_latency_IAR_baseline(num_sdiffs, sdiffs,
00650                                   ref_ecef, num_used, b)) {
00651     if (DEBUG_DGNSS_MANAGEMENT) {
00652       printf("low latency IAR solution\n<DGNSS_LOW_LATENCY_BASELINE>\n");
00653     }
00654     return 1;
00655   }
00656   /* if we get here, we weren't able to get an IAR resolved baseline.
00657    * Check if we can get a float baseline. */
00658   s8 float_ret_code = _dgnss_low_latency_float_baseline(num_sdiffs, sdiffs,
00659                                               ref_ecef, num_used, b);
00660   if (float_ret_code == 0) {
00661     if (DEBUG_DGNSS_MANAGEMENT) {
00662       printf("low latency float solution\n<DGNSS_LOW_LATENCY_BASELINE>\n");
00663     }
00664     return 2;
00665   }
00666   if (DEBUG_DGNSS_MANAGEMENT) {
00667     printf("no low latency solution\n</DGNSS_LOW_LATENCY_BASELINE>\n");
00668   }
00669   return -1;
00670 }
00671 
00672 
00673 void dgnss_reset_iar()
00674 {
00675   create_ambiguity_test(&ambiguity_test);
00676 }
00677 
00678 
00679 void dgnss_init_known_baseline(u8 num_sats, sdiff_t *sdiffs, double receiver_ecef[3], double b[3])
00680 {
00681   double ref_ecef[3];
00682   ref_ecef[0] = receiver_ecef[0] + 0.5 * b[0];
00683   ref_ecef[1] = receiver_ecef[1] + 0.5 * b[1];
00684   ref_ecef[2] = receiver_ecef[2] + 0.5 * b[2];
00685 
00686   sdiff_t corrected_sdiffs[num_sats];
00687 
00688   u8 old_prns[MAX_CHANNELS];
00689   memcpy(old_prns, sats_management.prns, sats_management.num_sats * sizeof(u8));
00690   /* rebase globals to a new reference sat
00691    * (permutes corrected_sdiffs accordingly) */
00692   dgnss_rebase_ref(num_sats, sdiffs, ref_ecef, old_prns, corrected_sdiffs);
00693 
00694   double dds[2*(num_sats-1)];
00695   make_measurements(num_sats-1, corrected_sdiffs, dds);
00696 
00697   double DE[(num_sats-1)*3];
00698   assign_de_mtx(num_sats, corrected_sdiffs, ref_ecef, DE);
00699 
00700   dgnss_reset_iar();
00701 
00702   memcpy(&ambiguity_test.sats, &sats_management, sizeof(sats_management));
00703   hypothesis_t *hyp = (hypothesis_t *)memory_pool_add(ambiguity_test.pool);
00704   hyp->ll = 0;
00705   amb_from_baseline(num_sats, DE, dds, b, hyp->N);
00706 
00707   double obs_cov[(num_sats-1) * (num_sats-1) * 4];
00708   memset(obs_cov, 0, (num_sats-1) * (num_sats-1) * 4 * sizeof(double));
00709   u8 num_dds = num_sats-1;
00710   for (u8 i=0; i<num_dds; i++) {
00711     for (u8 j=0; j<num_dds; j++) {
00712       u8 i_ = i+num_dds;
00713       u8 j_ = j+num_dds;
00714       if (i==j) {
00715         obs_cov[i*2*num_dds + j] = dgnss_settings.phase_var_test * 2;
00716         obs_cov[i_*2*num_dds + j_] = dgnss_settings.code_var_test * 2;
00717       }
00718       else {
00719         obs_cov[i*2*num_dds + j] = dgnss_settings.phase_var_test;
00720         obs_cov[i_*2*num_dds + j_] = dgnss_settings.code_var_test;
00721       }
00722     }
00723   }
00724 
00725   init_residual_matrices(&ambiguity_test.res_mtxs, num_sats-1, DE, obs_cov);
00726 
00727   /*printf("Known Base: [");*/
00728   /*for (u8 i=0; i<num_sats-1; i++)*/
00729     /*printf("%d, ", hyp->N[i]);*/
00730   /*printf("]\n");*/
00731 }
00732 
00733 void dgnss_init_known_baseline2(u8 num_sats, sdiff_t *sdiffs, double receiver_ecef[3], double b[3])
00734 {
00735   double ref_ecef[3];
00736   ref_ecef[0] = receiver_ecef[0] + 0.5 * b[0];
00737   ref_ecef[1] = receiver_ecef[1] + 0.5 * b[1];
00738   ref_ecef[2] = receiver_ecef[2] + 0.5 * b[2];
00739 
00740   sdiff_t corrected_sdiffs[num_sats];
00741 
00742   u8 old_prns[MAX_CHANNELS];
00743   memcpy(old_prns, sats_management.prns, sats_management.num_sats * sizeof(u8));
00744   /* rebase globals to a new reference sat
00745    * (permutes corrected_sdiffs accordingly) */
00746   dgnss_rebase_ref(num_sats, sdiffs, ref_ecef, old_prns, corrected_sdiffs);
00747 
00748   double dds[2*(num_sats-1)];
00749   make_measurements(num_sats-1, corrected_sdiffs, dds);
00750 
00751   double DE[(num_sats-1)*3];
00752   s32 N[num_sats-1];
00753   assign_de_mtx(num_sats, corrected_sdiffs, ref_ecef, DE);
00754   amb_from_baseline(num_sats, DE, dds, b, N);
00755 
00756   printf("Known Base: [");
00757   for (u8 i=0; i<num_sats-1; i++)
00758     printf("%"PRId32", ", N[i]);
00759   printf("]\n");
00760 
00761   /* Construct fake state means. */
00762   double state_mean[num_sats-1+6];
00763   memcpy(&state_mean[0], b, 3 * sizeof(double));
00764   memset(&state_mean[3], 0, 3 * sizeof(double));
00765   for (u8 i=0; i<num_sats-1; i++) {
00766     state_mean[i+6] = N[i];
00767   }
00768 
00769   /* Construct fake covariance U factor (just identity). */
00770   double state_cov_U[(num_sats-1+6)*(num_sats-1+6)];
00771   matrix_eye(num_sats-1+6, state_cov_U);
00772 
00773   double state_cov_D[num_sats-1+6];
00774   memset(state_cov_D, 0, 6 * sizeof(double));
00775   for (u8 i=0; i<num_sats-1; i++) {
00776     state_cov_D[i+6] = 1.0 / 64.0;
00777   }
00778 
00779   dgnss_reset_iar();
00780 
00781   u8 changed_sats = ambiguity_update_sats(&ambiguity_test, num_sats, sdiffs,
00782                                           &sats_management, nkf.state_mean,
00783                                           nkf.state_cov_U, nkf.state_cov_D);
00784   update_ambiguity_test(ref_ecef,
00785                         dgnss_settings.phase_var_test,
00786                         dgnss_settings.code_var_test,
00787                         &ambiguity_test, nkf.state_dim,
00788                         sdiffs, changed_sats);
00789   update_unanimous_ambiguities(&ambiguity_test);
00790 }
00791 
00792 double l2_dist(double x1[3], double x2[3])
00793 {
00794   double d0 = x2[0] - x1[0];
00795   double d1 = x2[1] - x1[1];
00796   double d2 = x2[2] - x1[2];
00797   return sqrt(d0 * d0 +
00798               d1 * d1 +
00799               d2 * d2);
00800 }
00801 
00802 void normalize(double x[3])
00803 {
00804   double l2_norm = sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
00805   x[0] = x[0] / l2_norm;
00806   x[1] = x[1] / l2_norm;
00807   x[2] = x[2] / l2_norm;
00808 }
00809 
00810 void measure_amb_kf_b(double reciever_ecef[3],
00811                       u8 num_sdiffs, sdiff_t *sdiffs,
00812                       double *b)
00813 {
00814   if (DEBUG_DGNSS_MANAGEMENT) {
00815     printf("<MEASURE_AMB_KF_B>\n");
00816   }
00817   sdiff_t sdiffs_with_ref_first[num_sdiffs];
00818   /* We require the sats updating has already been done with these sdiffs */
00819   u8 ref_prn = sats_management.prns[0];
00820   copy_sdiffs_put_ref_first(ref_prn, num_sdiffs, sdiffs, sdiffs_with_ref_first);
00821   double dd_measurements[2*(num_sdiffs-1)];
00822   make_measurements(num_sdiffs - 1, sdiffs_with_ref_first, dd_measurements);
00823   double b_old[3] = {0, 0, 0};
00824   double ref_ecef[3];
00825   ref_ecef[0] = reciever_ecef[0];
00826   ref_ecef[1] = reciever_ecef[1];
00827   ref_ecef[2] = reciever_ecef[2];
00828 
00829   least_squares_solve_b(&nkf, sdiffs_with_ref_first, dd_measurements, ref_ecef, b);
00830 
00831   while (l2_dist(b_old, b) > 1e-4) {
00832     memcpy(b_old, b, sizeof(double)*3);
00833     ref_ecef[0] = reciever_ecef[0] + 0.5 * b_old[0];
00834     ref_ecef[1] = reciever_ecef[1] + 0.5 * b_old[1];
00835     ref_ecef[2] = reciever_ecef[2] + 0.5 * b_old[2];
00836     least_squares_solve_b(&nkf, sdiffs_with_ref_first, dd_measurements, ref_ecef, b);
00837   }
00838   if (DEBUG_DGNSS_MANAGEMENT) {
00839     printf("</MEASURE_AMB_KF_B>\n");
00840   }
00841 }
00842 
00843 /*TODO consolidate this with the similar one above*/
00844 void measure_b_with_external_ambs(double reciever_ecef[3],
00845                                   u8 num_sdiffs, sdiff_t *sdiffs,
00846                                   double *ambs,
00847                                   double *b)
00848 {
00849   if (DEBUG_DGNSS_MANAGEMENT) {
00850     printf("<MEASURE_B_WITH_EXTERNAL_AMBS>\n");
00851   }
00852   sdiff_t sdiffs_with_ref_first[num_sdiffs];
00853   /* We assume the sats updating has already been done with these sdiffs */
00854   u8 ref_prn = sats_management.prns[0];
00855   copy_sdiffs_put_ref_first(ref_prn, num_sdiffs, sdiffs, sdiffs_with_ref_first);
00856   double dd_measurements[2*(num_sdiffs-1)];
00857   make_measurements(num_sdiffs - 1, sdiffs_with_ref_first, dd_measurements);
00858   double b_old[3] = {0, 0, 0};
00859   double ref_ecef[3];
00860   ref_ecef[0] = reciever_ecef[0];
00861   ref_ecef[1] = reciever_ecef[1];
00862   ref_ecef[2] = reciever_ecef[2];
00863   least_squares_solve_b_external_ambs(nkf.state_dim, ambs, sdiffs_with_ref_first, dd_measurements, ref_ecef, b);
00864 
00865   while (l2_dist(b_old, b) > 1e-4) {
00866     memcpy(b_old, b, sizeof(double)*3);
00867     ref_ecef[0] = reciever_ecef[0] + 0.5 * b_old[0];
00868     ref_ecef[1] = reciever_ecef[1] + 0.5 * b_old[1];
00869     ref_ecef[2] = reciever_ecef[2] + 0.5 * b_old[2];
00870     least_squares_solve_b_external_ambs(nkf.state_dim, ambs, sdiffs_with_ref_first, dd_measurements, ref_ecef, b);
00871   }
00872   if (DEBUG_DGNSS_MANAGEMENT) {
00873     printf("</MEASURE_B_WITH_EXTERNAL_AMBS>\n");
00874   }
00875 }
00876 
00877 /*TODO consolidate this with the similar ones above*/
00878 void measure_iar_b_with_external_ambs(double reciever_ecef[3],
00879                                       u8 num_sdiffs, sdiff_t *sdiffs,
00880                                       double *ambs,
00881                                       double *b)
00882 {
00883   if (DEBUG_DGNSS_MANAGEMENT) {
00884       printf("<MEASURE_IAR_B_WITH_EXTERNAL_AMBS>\n");
00885   }
00886   sdiff_t sdiffs_with_ref_first[num_sdiffs];
00887   match_sdiffs_to_sats_man(&ambiguity_test.sats, num_sdiffs, sdiffs, sdiffs_with_ref_first);
00888   double dd_measurements[2*(num_sdiffs-1)];
00889   make_measurements(num_sdiffs - 1, sdiffs_with_ref_first, dd_measurements);
00890   double b_old[3] = {0, 0, 0};
00891   double ref_ecef[3];
00892   ref_ecef[0] = reciever_ecef[0];
00893   ref_ecef[1] = reciever_ecef[1];
00894   ref_ecef[2] = reciever_ecef[2];
00895   least_squares_solve_b_external_ambs(MAX(1,ambiguity_test.sats.num_sats)-1, ambs, sdiffs_with_ref_first, dd_measurements, ref_ecef, b);
00896   while (l2_dist(b_old, b) > 1e-4) {
00897     memcpy(b_old, b, sizeof(double)*3);
00898     ref_ecef[0] = reciever_ecef[0] + 0.5 * b_old[0];
00899     ref_ecef[1] = reciever_ecef[1] + 0.5 * b_old[1];
00900     ref_ecef[2] = reciever_ecef[2] + 0.5 * b_old[2];
00901     least_squares_solve_b_external_ambs(MAX(1,ambiguity_test.sats.num_sats)-1, ambs, sdiffs_with_ref_first, dd_measurements, ref_ecef, b);
00902   }
00903   if (DEBUG_DGNSS_MANAGEMENT) {
00904       printf("</MEASURE_IAR_B_WITH_EXTERNAL_AMBS>\n");
00905   }
00906 }
00907 
00908 
00909 u8 get_de_and_phase(sats_management_t *sats_man,
00910                     u8 num_sdiffs, sdiff_t *sdiffs,
00911                     double ref_ecef[3],
00912                     double *de, double *phase)
00913 {
00914   u8 ref_prn = sats_man->prns[0];
00915   u8 num_sats = sats_man->num_sats;
00916   double e0[3];
00917   double phi0 = 0;
00918   /* TODO: Detect if ref_prn is not in prns and return error? */
00919   u8 i;
00920   for (i=0; i<num_sdiffs; i++) {
00921     if (sdiffs[i].prn == ref_prn) {
00922       e0[0] = sdiffs[i].sat_pos[0] - ref_ecef[0];
00923       e0[1] = sdiffs[i].sat_pos[1] - ref_ecef[1];
00924       e0[2] = sdiffs[i].sat_pos[2] - ref_ecef[2];
00925       normalize(e0);
00926       phi0 = sdiffs[i].carrier_phase;
00927       break;
00928     }
00929   }
00930   i=1;
00931   u8 j = 0;
00932   while (i < num_sats) {
00933     if (sdiffs[j].prn < sats_man->prns[i]) {
00934       j++;
00935     }
00936     else if (sdiffs[j].prn > sats_man->prns[i]) {
00937       i++;
00938       printf("probable error. sdiffs should be a super set of sats_man prns\n");
00939     }
00940     else {  /* else they match */
00941       double e[3];
00942       e[0] = sdiffs[j].sat_pos[0] - ref_ecef[0];
00943       e[1] = sdiffs[j].sat_pos[1] - ref_ecef[1];
00944       e[2] = sdiffs[j].sat_pos[2] - ref_ecef[2];
00945       normalize(e);
00946       de[(i-1)*3    ] = e[0] - e0[0];
00947       de[(i-1)*3 + 1] = e[1] - e0[1];
00948       de[(i-1)*3 + 2] = e[2] - e0[2];
00949       phase[i-1] = sdiffs[j].carrier_phase - phi0;
00950       i++;
00951       j++;
00952     }
00953   }
00954   return num_sats;
00955 }
00956 
00957 u8 get_amb_kf_de_and_phase(u8 num_sdiffs, sdiff_t *sdiffs,
00958                            double ref_ecef[3],
00959                            double *de, double *phase)
00960 {
00961   return get_de_and_phase(&sats_management,
00962                           num_sdiffs, sdiffs,
00963                           ref_ecef,
00964                           de, phase);
00965 }
00966 
00967 u8 get_iar_de_and_phase(u8 num_sdiffs, sdiff_t *sdiffs,
00968                         double ref_ecef[3],
00969                         double *de, double *phase)
00970 {
00971   return get_de_and_phase(&ambiguity_test.sats,
00972                           num_sdiffs, sdiffs,
00973                           ref_ecef,
00974                           de, phase);
00975 }
00976 
00977 u8 get_amb_kf_mean(double *ambs)
00978 {
00979   u8 num_dds = MAX(1, sats_management.num_sats) - 1;
00980   memcpy(ambs, nkf.state_mean, num_dds * sizeof(double));
00981   return num_dds;
00982 }
00983 
00984 u8 get_amb_kf_cov(double *cov)
00985 {
00986   u8 num_dds = MAX(1, sats_management.num_sats) - 1;
00987   matrix_reconstruct_udu(num_dds, nkf.state_cov_U, nkf.state_cov_D, cov);
00988   return num_dds;
00989 }
00990 
00991 u8 get_amb_kf_prns(u8 *prns)
00992 {
00993   memcpy(prns, sats_management.prns, sats_management.num_sats * sizeof(u8));
00994   return sats_management.num_sats;
00995 }
00996 
00997 u8 get_amb_test_prns(u8 *prns)
00998 {
00999   memcpy(prns, ambiguity_test.sats.prns, ambiguity_test.sats.num_sats * sizeof(u8));
01000   return ambiguity_test.sats.num_sats;
01001 }
01002 
01003 s8 dgnss_iar_resolved()
01004 {
01005   return ambiguity_iar_can_solve(&ambiguity_test);
01006 }
01007 
01008 u8 dgnss_iar_pool_contains(double *ambs)
01009 {
01010   return ambiguity_test_pool_contains(&ambiguity_test, ambs);
01011 }
01012 
01013 u8 dgnss_iar_MLE_ambs(s32 *ambs)
01014 {
01015   ambiguity_test_MLE_ambs(&ambiguity_test, ambs);
01016   return MAX(1, ambiguity_test.sats.num_sats) - 1;
01017 }
01018 
01019 nkf_t* get_dgnss_nkf()
01020 {
01021   return &nkf;
01022 }
01023 
01024 s32* get_stupid_filter_ints()
01025 {
01026   return stupid_state.N;
01027 }
01028 
01029 sats_management_t* get_sats_management()
01030 {
01031   return &sats_management;
01032 }
01033 
01034 


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:45