00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdio.h>
00014 #include <string.h>
00015
00016 #include "linear_algebra.h"
00017 #include "single_diff.h"
00018 #include "ephemeris.h"
00019 #include "constants.h"
00020 #include "sats_management.h"
00021
00026 #define GPS_L1_LAMBDA (GPS_C / GPS_L1_HZ)
00027
00028 u8 propagate(u8 n, double ref_ecef[3],
00029 navigation_measurement_t *m_in_base, gps_time_t *t_base,
00030 navigation_measurement_t *m_in_rover, gps_time_t *t_rover,
00031 navigation_measurement_t *m_out_base)
00032 {
00033 double dt = gpsdifftime(*t_rover, *t_base);
00034 (void)dt;
00035
00036 double dr_[n];
00037
00038 for (u8 i=0; i<n; i++) {
00039 m_out_base[i].prn = m_in_base[i].prn;
00040 m_out_base[i].snr = m_in_base[i].snr;
00041 m_out_base[i].lock_time = m_in_base[i].lock_time;
00042
00043
00044 double dr[3];
00045 vector_subtract(3, m_in_rover[i].sat_pos, m_in_base[i].sat_pos, dr);
00046
00047
00048
00049
00050
00051
00052
00053 double e[3];
00054 vector_subtract(3, m_in_rover[i].sat_pos, ref_ecef, e);
00055 vector_normalize(3, e);
00056
00057
00058 dr_[i] = vector_dot(3, dr, e);
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 m_out_base[i].raw_pseudorange = m_in_base[i].raw_pseudorange + dr_[i];
00075 m_out_base[i].pseudorange = m_in_base[i].pseudorange;
00076 m_out_base[i].carrier_phase = m_in_base[i].carrier_phase - dr_[i] / GPS_L1_LAMBDA;
00077 m_out_base[i].raw_doppler = m_in_base[i].raw_doppler;
00078 m_out_base[i].doppler = m_in_base[i].doppler;
00079
00080 }
00081 return 0;
00082 }
00083
00099 u8 single_diff(u8 n_a, navigation_measurement_t *m_a,
00100 u8 n_b, navigation_measurement_t *m_b,
00101 sdiff_t *sds)
00102 {
00103 u8 i, j, n = 0;
00104
00105
00106 for (i=0, j=0; i<n_a && j<n_b; i++, j++) {
00107 if (m_a[i].prn < m_b[j].prn)
00108 j--;
00109 else if (m_a[i].prn > m_b[j].prn)
00110 i--;
00111 else {
00112 sds[n].prn = m_a[i].prn;
00113 sds[n].pseudorange = m_a[i].raw_pseudorange - m_b[j].raw_pseudorange;
00114 sds[n].carrier_phase = m_a[i].carrier_phase - m_b[j].carrier_phase;
00115 sds[n].doppler = m_a[i].raw_doppler - m_b[j].raw_doppler;
00116 sds[n].snr = MIN(m_a[i].snr, m_b[j].snr);
00117
00118 memcpy(&(sds[n].sat_pos), &(m_a[i].sat_pos), 3*sizeof(double));
00119 memcpy(&(sds[n].sat_vel), &(m_a[i].sat_vel), 3*sizeof(double));
00120
00121 n++;
00122 }
00123 }
00124
00125 return n;
00126 }
00127
00128 int sdiff_search_prn(const void *a, const void *b)
00129 {
00130 return (*(u8*)a - ((sdiff_t *)b)->prn);
00131 }
00132
00162 u8 make_propagated_sdiffs(u8 n_local, navigation_measurement_t *m_local,
00163 u8 n_remote, navigation_measurement_t *m_remote,
00164 double *remote_dists, double remote_pos_ecef[3],
00165 ephemeris_t *es, gps_time_t t,
00166 sdiff_t *sds)
00167 {
00168 u8 i, j, n = 0;
00169
00170
00171 for (i=0, j=0; i<n_local && j<n_remote; i++, j++) {
00172 if (m_local[i].prn < m_remote[j].prn)
00173 j--;
00174 else if (m_local[i].prn > m_remote[j].prn)
00175 i--;
00176 else if (ephemeris_good(es[m_local[i].prn], t)) {
00177 double clock_err;
00178 double clock_rate_err;
00179 double local_sat_pos[3];
00180 double local_sat_vel[3];
00181 calc_sat_pos(&local_sat_pos[0],
00182 &local_sat_vel[0],
00183 &clock_err, &clock_rate_err, &es[m_local[i].prn], t);
00184 sds[n].prn = m_local[i].prn;
00185 double dx = local_sat_pos[0] - remote_pos_ecef[0];
00186 double dy = local_sat_pos[1] - remote_pos_ecef[1];
00187 double dz = local_sat_pos[2] - remote_pos_ecef[2];
00188 double new_dist = sqrt( dx * dx + dy * dy + dz * dz);
00189 double dist_diff = new_dist - remote_dists[j];
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 sds[n].pseudorange = m_local[i].raw_pseudorange
00203 - (m_remote[j].raw_pseudorange
00204 + dist_diff);
00205 sds[n].carrier_phase = m_local[i].carrier_phase
00206 - (m_remote[j].carrier_phase
00207 - dist_diff / GPS_L1_LAMBDA);
00208
00209
00210
00211 sds[n].snr = MIN(m_local[i].snr, m_remote[j].snr);
00212 memcpy(&(sds[n].sat_pos), &(local_sat_pos[0]), 3*sizeof(double));
00213 memcpy(&(sds[n].sat_vel), &(local_sat_vel[0]), 3*sizeof(double));
00214
00215 n++;
00216 }
00217 }
00218
00219 return n;
00220 }
00221
00222
00228 void almanacs_to_single_diffs(u8 n, almanac_t *alms, gps_time_t timestamp, sdiff_t *sdiffs)
00229 {
00230 for (u8 i=0; i<n; i++) {
00231 double p[3];
00232 double v[3];
00233 calc_sat_state_almanac(&alms[i], timestamp.tow, timestamp.wn, p, v);
00234 memcpy(sdiffs[i].sat_pos, &p[0], 3 * sizeof(double));
00235 memcpy(sdiffs[i].sat_vel, &v[0], 3 * sizeof(double));
00236 sdiffs[i].prn = alms[i].prn;
00237 if (i==0) {
00238 sdiffs[i].snr = 1;
00239
00240 }
00241 else {
00242 sdiffs[i].snr = 0;
00243 }
00244
00245
00246
00247 }
00248 }
00249
00250 void double_diff(u8 n, sdiff_t *sds, sdiff_t *dds, u8 ref_idx)
00251 {
00252 for (u8 i=0; i<n; i++) {
00253 dds[i].prn = sds[i].prn;
00254 dds[i].pseudorange = sds[i].pseudorange - sds[ref_idx].pseudorange;
00255 dds[i].carrier_phase = sds[i].carrier_phase - sds[ref_idx].carrier_phase;
00256 dds[i].doppler = sds[i].doppler - sds[ref_idx].doppler;
00257 dds[i].snr = MIN(sds[i].snr, sds[ref_idx].snr);
00258
00259 memcpy(&(dds[i].sat_pos), &(sds[i].sat_pos), 3*sizeof(double));
00260 memcpy(&(dds[i].sat_vel), &(sds[i].sat_vel), 3*sizeof(double));
00261 }
00262 }
00263
00264 s8 copy_sdiffs_put_ref_first(u8 ref_prn, u8 num_sdiffs, sdiff_t *sdiffs, sdiff_t *sdiffs_with_ref_first)
00265 {
00266 s8 not_found = -1;
00267 u8 j = 1;
00268 for (u8 i=0; i<num_sdiffs; i++) {
00269 if (sdiffs[i].prn == ref_prn) {
00270 memcpy(sdiffs_with_ref_first, &sdiffs[i], sizeof(sdiff_t));
00271 not_found = 0;
00272 }
00273 else {
00274 if (j == num_sdiffs) {
00275 return not_found;
00276 }
00277 memcpy(&sdiffs_with_ref_first[j], &sdiffs[i], sizeof(sdiff_t));
00278 j++;
00279 }
00280 }
00281 return not_found;
00282 }
00283
00284 bool _contains_prn(u8 len, u8 *prns, u8 prn)
00285 {
00286 for (u8 i = 0; i < len; i++) {
00287 if (prns[i] == prn) {
00288 return true;
00289 }
00290 }
00291 return false;
00292 }
00293
00294 u8 filter_sdiffs(u8 num_sdiffs, sdiff_t *sdiffs, u8 num_sats_to_drop, u8 *sats_to_drop)
00295 {
00296 u8 new_num_sdiffs = 0;
00297 for (u8 i = 0; i < num_sdiffs; i++) {
00298 if (!_contains_prn(num_sats_to_drop, sats_to_drop, sdiffs[i].prn)) {
00299 if (new_num_sdiffs != i) {
00300 memcpy(&sdiffs[new_num_sdiffs], &sdiffs[i], sizeof(sdiff_t));
00301 }
00302 new_num_sdiffs++;
00303 }
00304 }
00305 return new_num_sdiffs;
00306 }
00307