Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "linear_algebra.h"
00014 #include "ephemeris.h"
00015 #include <math.h>
00016 #include <stdlib.h>
00017 #include <stdio.h>
00018
00019 #define NAV_OMEGAE_DOT 7.2921151467e-005
00020 #define NAV_GM 3.986005e14
00021
00022 int calc_sat_pos(double pos[3], double vel[3],
00023 double *clock_err, double *clock_rate_err,
00024 const ephemeris_t *ephemeris,
00025 gps_time_t tot)
00026 {
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 double tempd1 = 0, tempd2, tempd3;
00040 double tdiff;
00041 double a;
00042 double ma, ma_dot;
00043 double ea, ea_dot, ea_old;
00044 double einstein;
00045 double al, al_dot;
00046 double cal, cal_dot;
00047 double r, r_dot;
00048 double inc, inc_dot;
00049 double x, x_dot, y, y_dot;
00050 double om, om_dot;
00051
00052
00053
00054
00055 tdiff = gpsdifftime(tot, ephemeris->toc);
00056
00057 *clock_err = ephemeris->af0 + tdiff * (ephemeris->af1 + tdiff * ephemeris->af2) - ephemeris->tgd;
00058 *clock_rate_err = ephemeris->af1 + 2.0 * tdiff * ephemeris->af2;
00059
00060
00061 tdiff = gpsdifftime(tot, ephemeris->toe);
00062
00063
00064
00065
00066 if (fabs(tdiff) > 4*3600)
00067 printf(" WARNING: using ephemeris older (or newer!) than 4 hours.\n");
00068
00069
00070 a = ephemeris->sqrta * ephemeris->sqrta;
00071 ma_dot = sqrt (NAV_GM / (a * a * a)) + ephemeris->dn;
00072 ma = ephemeris->m0 + ma_dot * tdiff;
00073
00074
00075 ea = ma;
00076 double ecc = ephemeris->ecc;
00077 u32 count = 0;
00078
00079
00080
00081 do {
00082 ea_old = ea;
00083 tempd1 = 1.0 - ecc * cos (ea_old);
00084 ea = ea + (ma - ea_old + ecc * sin (ea_old)) / tempd1;
00085 count++;
00086 if (count > 5)
00087 break;
00088 } while (fabs (ea - ea_old) > 1.0E-14);
00089 ea_dot = ma_dot / tempd1;
00090
00091
00092 einstein = -4.442807633E-10 * ecc * ephemeris->sqrta * sin (ea);
00093
00094
00095 tempd2 = sqrt (1.0 - ecc * ecc);
00096 al = atan2 (tempd2 * sin (ea), cos (ea) - ecc) + ephemeris->w;
00097 al_dot = tempd2 * ea_dot / tempd1;
00098
00099
00100 cal = al + ephemeris->cus * sin (2.0 * al) + ephemeris->cuc * cos (2.0 * al);
00101 cal_dot =
00102 al_dot * (1.0 +
00103 2.0 * (ephemeris->cus * cos (2.0 * al) -
00104 ephemeris->cuc * sin (2.0 * al)));
00105
00106
00107 r =
00108 a * tempd1 + ephemeris->crc * cos (2.0 * al) +
00109 ephemeris->crs * sin (2.0 * al);
00110 r_dot =
00111 a * ecc * sin (ea) * ea_dot +
00112 2.0 * al_dot * (ephemeris->crs * cos (2.0 * al) -
00113 ephemeris->crc * sin (2.0 * al));
00114
00115
00116 inc =
00117 ephemeris->inc + ephemeris->inc_dot * tdiff +
00118 ephemeris->cic * cos (2.0 * al) + ephemeris->cis * sin (2.0 * al);
00119 inc_dot =
00120 ephemeris->inc_dot + 2.0 * al_dot * (ephemeris->cis * cos (2.0 * al) -
00121 ephemeris->cic * sin (2.0 * al));
00122
00123
00124 x = r * cos (cal);
00125 y = r * sin (cal);
00126 x_dot = r_dot * cos (cal) - y * cal_dot;
00127 y_dot = r_dot * sin (cal) + x * cal_dot;
00128
00129
00130 om_dot = ephemeris->omegadot - NAV_OMEGAE_DOT;
00131 om = ephemeris->omega0 + tdiff * om_dot - NAV_OMEGAE_DOT * ephemeris->toe.tow;
00132
00133
00134 pos[0] = x * cos (om) - y * cos (inc) * sin (om);
00135 pos[1] = x * sin (om) + y * cos (inc) * cos (om);
00136 pos[2] = y * sin (inc);
00137
00138 tempd3 = y_dot * cos (inc) - y * sin (inc) * inc_dot;
00139
00140
00141 vel[0] = -om_dot * pos[1] + x_dot * cos (om) - tempd3 * sin (om);
00142 vel[1] = om_dot * pos[0] + x_dot * sin (om) + tempd3 * cos (om);
00143 vel[2] = y * cos (inc) * inc_dot + y_dot * sin (inc);
00144
00145 *clock_err += einstein;
00146
00147 return 0;
00148 }
00149
00150 double predict_range(double rx_pos[3],
00151 gps_time_t tot,
00152 ephemeris_t *ephemeris)
00153 {
00154 double sat_pos[3];
00155 double sat_vel[3];
00156 double temp[3];
00157 double clock_err, clock_rate_err;
00158
00159 calc_sat_pos(sat_pos, sat_vel, &clock_err, &clock_rate_err, ephemeris, tot);
00160
00161 vector_subtract(3, sat_pos, rx_pos, temp);
00162 return vector_norm(3, temp);
00163 }
00164
00174 u8 ephemeris_good(ephemeris_t eph, gps_time_t t)
00175 {
00176
00177
00178 double tdiff = gpsdifftime(t, eph.toe);
00179
00180
00181 return (eph.valid && fabs(tdiff) < 4*3600);
00182 }