Skip to content
This repository was archived by the owner on Apr 13, 2021. It is now read-only.

Commit 80dbe54

Browse files
committed
Generalisation of almanac for SBAS support.
1 parent 044af42 commit 80dbe54

File tree

2 files changed

+91
-5
lines changed

2 files changed

+91
-5
lines changed

include/libswiftnav/almanac.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#define LIBSWIFTNAV_ALMANAC_H
1515

1616
#include "common.h"
17-
#include "almanac.h"
17+
#include "signal.h"
1818

1919
/** \addtogroup almanac
2020
* \{ */
@@ -32,9 +32,31 @@ typedef struct {
3232
double af0; /**< 0-order clock correction in seconds. */
3333
double af1; /**< 1-order clock correction in seconds/second. */
3434
u16 week; /**< GPS week number, modulo 1024. */
35-
u8 prn; /**< PRN number of the satellite. */
35+
} almanac_gps_t;
36+
37+
/** Structure containing the SBAS almanac for one satellite. */
38+
typedef struct {
39+
u8 data_id; /**< Data ID. */
40+
41+
u16 x; /**< X coordinate ECEF. */
42+
u16 y; /**< Y coordinate ECEF. */
43+
u16 z; /**< Z coordinate ECEF. */
44+
45+
u8 x_rate; /**< X coordinate rate of change [m/s]. */
46+
u8 y_rate; /**< Y coordinate rate of change [m/s]. */
47+
u8 z_rate; /**< Z coordinate rate of change [m/s]. */
48+
49+
u16 t0; /**< Time of day [seconds]. */
50+
} almanac_sbas_t;
51+
52+
typedef struct {
53+
gnss_signal_t sid; /**< Signal ID. */
3654
u8 healthy; /**< Satellite health status. */
3755
u8 valid; /**< Almanac is valid. */
56+
union {
57+
almanac_gps_t gps;
58+
almanac_sbas_t sbas;
59+
};
3860
} almanac_t;
3961

4062
/** \} */

src/almanac.c

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*/
1212

1313
#include <math.h>
14+
#include <assert.h>
1415

1516
#include "constants.h"
1617
#include "linear_algebra.h"
@@ -24,7 +25,42 @@
2425
* \see coord_system
2526
* \{ */
2627

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.
2864
*
2965
* \param alm Pointer to an almanac structure for the satellite of interest.
3066
* \param t GPS time of week at which to calculate the satellite state in
@@ -36,9 +72,10 @@
3672
* \param vel The satellite velocity in ECEF coordinates is returned in this
3773
* vector. Ignored if NULL.
3874
*/
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])
4177
{
78+
const almanac_gps_t *alm = &alm_->gps;
4279
/* Seconds since the almanac reference epoch. */
4380
double dt = t - alm->toa;
4481

@@ -122,6 +159,33 @@ void calc_sat_state_almanac(const almanac_t* alm, double t, s16 week,
122159

123160
}
124161

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+
125189
/** Calculate the azimuth and elevation of a satellite from a reference
126190
* position given the satellite almanac.
127191
*

0 commit comments

Comments
 (0)