|
11 | 11 | */ |
12 | 12 |
|
13 | 13 | #include <math.h> |
| 14 | +#include <assert.h> |
14 | 15 |
|
15 | 16 | #include "constants.h" |
16 | 17 | #include "linear_algebra.h" |
|
24 | 25 | * \see coord_system |
25 | 26 | * \{ */ |
26 | 27 |
|
27 | | -/** Calculate the position / velocity state of a satellite from the almanac. |
| 28 | +/** Calculate the position / velocity state of a satellite from the SBAS |
| 29 | + * almanac. |
| 30 | + * |
| 31 | + * \param alm Pointer to an almanac structure for the satellite of interest. |
| 32 | + * \param t GPS time of week at which to calculate the satellite state in |
| 33 | + * seconds since Sunday. |
| 34 | + * \param pos The satellite position in ECEF coordinates is returned in this |
| 35 | + * vector. |
| 36 | + * \param vel The satellite velocity in ECEF coordinates is returned in this |
| 37 | + * vector. Ignored if NULL. |
| 38 | + */ |
| 39 | +static void sbas_calc_sat_state_almanac(const almanac_t* alm_, double t, |
| 40 | + double pos[3], double vel[3]) |
| 41 | +{ |
| 42 | + const almanac_sbas_t *alm = &alm_->sbas; |
| 43 | + |
| 44 | + u8 days = t / DAY_SECS; |
| 45 | + double tod = t - (days * DAY_SECS); |
| 46 | + double dt = tod - alm->t0; |
| 47 | + |
| 48 | + if (dt > DAY_SECS/2) |
| 49 | + dt -= DAY_SECS; |
| 50 | + else if (dt < -DAY_SECS/2) |
| 51 | + dt += DAY_SECS; |
| 52 | + |
| 53 | + vel[0] = alm->x_rate; |
| 54 | + vel[1] = alm->y_rate; |
| 55 | + vel[2] = alm->z_rate; |
| 56 | + |
| 57 | + pos[0] = alm->x + alm->x_rate * dt; |
| 58 | + pos[1] = alm->y + alm->y_rate * dt; |
| 59 | + pos[2] = alm->z + alm->z_rate * dt; |
| 60 | +} |
| 61 | + |
| 62 | +/** Calculate the position / velocity state of a satellite from the GPS |
| 63 | + * almanac. |
28 | 64 | * |
29 | 65 | * \param alm Pointer to an almanac structure for the satellite of interest. |
30 | 66 | * \param t GPS time of week at which to calculate the satellite state in |
|
36 | 72 | * \param vel The satellite velocity in ECEF coordinates is returned in this |
37 | 73 | * vector. Ignored if NULL. |
38 | 74 | */ |
39 | | -void calc_sat_state_almanac(const almanac_t* alm, double t, s16 week, |
40 | | - double pos[3], double vel[3]) |
| 75 | +static void gps_calc_sat_state_almanac(const almanac_t* alm_, double t, s16 week, |
| 76 | + double pos[3], double vel[3]) |
41 | 77 | { |
| 78 | + const almanac_gps_t *alm = &alm_->gps; |
42 | 79 | /* Seconds since the almanac reference epoch. */ |
43 | 80 | double dt = t - alm->toa; |
44 | 81 |
|
@@ -122,6 +159,33 @@ void calc_sat_state_almanac(const almanac_t* alm, double t, s16 week, |
122 | 159 |
|
123 | 160 | } |
124 | 161 |
|
| 162 | +/** Calculate the position / velocity state of a satellite from the almanac. |
| 163 | + * |
| 164 | + * \param alm Pointer to an almanac structure for the satellite of interest. |
| 165 | + * \param t GPS time of week at which to calculate the satellite state in |
| 166 | + * seconds since Sunday. |
| 167 | + * \param week GPS week number modulo 1024 or pass -1 to assume within one |
| 168 | + * half-week of the almanac time of applicability. |
| 169 | + * \param pos The satellite position in ECEF coordinates is returned in this |
| 170 | + * vector. |
| 171 | + * \param vel The satellite velocity in ECEF coordinates is returned in this |
| 172 | + * vector. Ignored if NULL. |
| 173 | + */ |
| 174 | +void calc_sat_state_almanac(const almanac_t* alm, double t, s16 week, |
| 175 | + double pos[3], double vel[3]) |
| 176 | +{ |
| 177 | + switch(alm->sid.constellation) { |
| 178 | + case CONSTELLATION_GPS: |
| 179 | + gps_calc_sat_state_almanac(alm, t, week, pos, vel); |
| 180 | + break; |
| 181 | + case CONSTELLATION_SBAS: |
| 182 | + sbas_calc_sat_state_almanac(alm, t, pos, vel); |
| 183 | + break; |
| 184 | + default: |
| 185 | + assert("unsupported constellation"); |
| 186 | + } |
| 187 | +} |
| 188 | + |
125 | 189 | /** Calculate the azimuth and elevation of a satellite from a reference |
126 | 190 | * position given the satellite almanac. |
127 | 191 | * |
|
0 commit comments