00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <math.h>
00014 #include <string.h>
00015 #include <cblas.h>
00016 #include <stdio.h>
00017
00018 #include "constants.h"
00019 #include "stupid_filter.h"
00020 #include "amb_kf.h"
00021 #include "linear_algebra.h"
00022
00023 #include <lapacke.h>
00024
00054 void amb_from_baseline(u8 num_sats, double *DE, double *dd_meas,
00055 double b[3], s32 *N)
00056 {
00057 double N_float[num_sats-1];
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 memcpy(N_float, dd_meas, (num_sats-1) * sizeof(double));
00068 cblas_dgemv(
00069 CblasRowMajor, CblasNoTrans, num_sats-1, 3,
00070 -1.0 / GPS_L1_LAMBDA_NO_VAC, DE, 3, b, 1,
00071 1.0, N_float, 1
00072 );
00073
00074
00075 for (u8 i=0; i<num_sats-1; i++) {
00076 N[i] = (s32)lround(N_float[i]);
00077 }
00078 }
00079
00080 void init_stupid_filter(stupid_filter_state_t *s, u8 num_sats, sdiff_t *sdiffs,
00081 double *dd_meas, double b[3], double ref_ecef[3])
00082 {
00083 double DE[(num_sats-1)*3];
00084
00085
00086 assign_de_mtx(num_sats, sdiffs, ref_ecef, DE);
00087
00088 amb_from_baseline(num_sats, DE, dd_meas, b, s->N);
00089 }
00090
00091
00092 static void rebase_N(s32 *N, u8 num_sats, u8 *old_prns, u8 *new_prns)
00093 {
00094 u8 old_ref = old_prns[0];
00095 u8 new_ref = new_prns[0];
00096
00097 s32 new_N[num_sats-1];
00098 s32 index_of_new_ref_in_old = find_index_of_element_in_u8s(num_sats, new_ref, &old_prns[1]);
00099 s32 val_for_new_ref_in_old_basis = N[index_of_new_ref_in_old];
00100 for (u8 i=0; i<num_sats-1; i++) {
00101 u8 new_prn = new_prns[1+i];
00102 if (new_prn == old_ref) {
00103 new_N[i] = - val_for_new_ref_in_old_basis;
00104 }
00105 else {
00106 s32 index_of_this_sat_in_old_basis = find_index_of_element_in_u8s(num_sats, new_prn, &old_prns[1]);
00107 new_N[i] = N[index_of_this_sat_in_old_basis] - val_for_new_ref_in_old_basis;
00108 }
00109 }
00110 memcpy(N, new_N, (num_sats-1) * sizeof(s32));
00111 }
00112
00113 void rebase_stupid_filter(stupid_filter_state_t *s, u8 num_sats, u8 *old_prns, u8 *new_prns)
00114 {
00115 rebase_N(&(s->N[0]), num_sats, old_prns, new_prns);
00116 }
00117
00118
00119 u8 intersect_o_tron(u8 num_sats1, u8 num_sats2, u8 *sats1, sdiff_t *sdiffs, double *dd_meas,
00120 sdiff_t *intersection_sats, double *intersection_dd_meas,
00121 s32* N, s32 *intersection_N)
00122 {
00123 u8 i, j, n = 0;
00124
00125
00126 for (i=0, j=0; i<num_sats1 && j<num_sats2; i++, j++) {
00127 if (sats1[i] < sdiffs[j].prn)
00128 j--;
00129 else if (sats1[i] > sdiffs[j].prn)
00130 i--;
00131 else {
00132 memcpy(&intersection_sats[n], &sdiffs[j], sizeof(sdiff_t));
00133 intersection_dd_meas[n] = dd_meas[j];
00134 intersection_N[n] = N[i];
00135 n++;
00136 }
00137 }
00138 return n;
00139 }
00140
00141 void update_sats_stupid_filter(stupid_filter_state_t *s, u8 num_old, u8 *old_prns, u8 num_new,
00142 sdiff_t *sdiffs, double *dd_meas, double ref_ecef[3])
00143 {
00144
00145
00146 double intersection_dd_meas[num_new];
00147 sdiff_t intersection_sats[num_new];
00148 memcpy(&intersection_sats[0], &sdiffs[0], sizeof(sdiff_t));
00149 s32 intersection_N[MAX_CHANNELS];
00150 u8 n_intersection = intersect_o_tron(num_old-1, num_new-1, &old_prns[1], &sdiffs[1], dd_meas, &intersection_sats[1], intersection_dd_meas, s->N, intersection_N);
00151
00152 if ((num_old-1) == (num_new-1) && (num_old-1) == n_intersection) {
00153 u8 flag = 0;
00154 for (u8 i=0; i<n_intersection+1; i++) {
00155 if (intersection_sats[i].prn != old_prns[i])
00156 flag = 1;
00157 }
00158 if (flag == 0)
00159
00160 return;
00161 }
00162
00163 printf("====== UPDATE =======\n");
00164
00165
00166 memcpy(&(s->N), intersection_N, n_intersection*sizeof(s32));
00167
00168 double b[3];
00169 update_stupid_filter(s, n_intersection, intersection_sats, intersection_dd_meas, b, ref_ecef);
00170
00171
00172 init_stupid_filter(s, num_new, sdiffs, dd_meas, b, ref_ecef);
00173 }
00174
00175 void lesq_solution(u8 num_dds, double *dd_meas, s32 *N, double *DE, double b[3], double *resid)
00176 {
00177 double DE_work[num_dds*3];
00178 memcpy(DE_work, DE, num_dds * 3 * sizeof(double));
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 double rhs[MAX(num_dds, 3)];
00190 for (u8 i=0; i<num_dds; i++) {
00191 rhs[i] = (dd_meas[i] - N[i]) * GPS_L1_LAMBDA_NO_VAC;
00192 }
00193
00194 int jpvt[3] = {0, 0, 0};
00195 int rank;
00196
00197
00198 LAPACKE_dgelsy(
00199 LAPACK_ROW_MAJOR, num_dds, 3,
00200 1, DE_work, 3,
00201 rhs, 1, jpvt,
00202 -1, &rank
00203 );
00204 memcpy(b, rhs, 3*sizeof(double));
00205
00206 if (resid) {
00207
00208
00209 memcpy(DE_work, DE, num_dds * 3 * sizeof(double));
00210
00211
00212
00213
00214
00215
00216 for (u8 i=0; i<num_dds; i++) {
00217 resid[i] = dd_meas[i] - N[i];
00218 }
00219 cblas_dgemv(
00220 CblasRowMajor, CblasNoTrans, num_dds, 3,
00221 -1.0 / GPS_L1_LAMBDA_NO_VAC, DE_work, 3, b, 1,
00222 1.0, resid, 1
00223 );
00224 }
00225 }
00226
00227
00228
00229 void update_stupid_filter(stupid_filter_state_t *s, u8 num_sats, sdiff_t *sdiffs,
00230 double *dd_meas, double b[3], double ref_ecef[3])
00231 {
00232 double DE[(num_sats-1)*3];
00233
00234
00235 assign_de_mtx(num_sats, sdiffs, ref_ecef, DE);
00236 lesq_solution(num_sats-1, dd_meas, s->N, DE, b, 0);
00237
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249