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

Commit f4e5dc8

Browse files
author
Dmitry Tatarinov
committed
Add GLO string parser
1 parent dc9e29e commit f4e5dc8

File tree

6 files changed

+248
-146
lines changed

6 files changed

+248
-146
lines changed

include/libswiftnav/nav_msg_glo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define LIBSWIFTNAV_NAV_MSG_GLO_H
1515

1616
#include <libswiftnav/common.h>
17+
#include <libswiftnav/ephemeris.h>
1718

1819
#define NAV_MSG_GLO_STRING_BITS_LEN 3 /* Buffer 96 nav bits. */
1920

@@ -23,6 +24,7 @@ typedef struct {
2324
} nav_msg_glo_t;
2425

2526
void nav_msg_init_glo(nav_msg_glo_t *n);
26-
u32 extract_word_glo(nav_msg_glo_t *n, u16 bit_index, u8 n_bits); //TODO: this will be static so remove after test
27+
s8 process_string_glo(nav_msg_glo_t *n, ephemeris_t *e);
28+
u32 extract_word_glo(const nav_msg_glo_t *n, u16 bit_index, u8 n_bits); //TODO: remove after tests
2729

2830
#endif /* LIBSWIFTNAV_NAV_MSG_GLO_H */

include/libswiftnav/time.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,6 @@ static inline bool is_leap_year(s32 year)
9797
return ((year%4==0) && (year%100!=0)) || (year%400==0);
9898
}
9999

100-
gps_time_t glo_time2gps_time(u16 nt, u8 n4, s8 h, s8 m, s8 s);
100+
gps_time_t glo_time2gps_time(u16 nt, u8 n4, u8 h, u8 m, u8 s);
101101

102102
#endif /* LIBSWIFTNAV_TIME_H */

src/ephemeris.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -763,23 +763,7 @@ void decode_ephemeris(u32 frame_words[3][8], ephemeris_t *e)
763763
log_warn_sid(e->sid, "Latest ephemeris had IODC/IODE mismatch. Ignoring ephemeris.");
764764
}
765765
}
766-
#if 0
767-
/** Decode ephemeris from L1 GLO navigation message frames.
768-
*
769-
* \note This function does not check for parity errors. You should check the
770-
* subframes for parity errors before calling this function.
771-
*
772-
* References:
773-
* TODO -# IS-GPS-200D, Section 20.3.2 and Figure 20-1
774-
*
775-
* \param string Array containing 85 bits strings 1 through 3 of any GLO frames
776-
* \param e Pointer to an ephemeris struct to fill in.
777-
*/
778-
void decode_glo_ephemeris(u32 strigs[3][4], ephemeris_t *e)
779-
{
780766

781-
}
782-
#endif
783767
static bool ephemeris_xyz_equal(const ephemeris_xyz_t *a,
784768
const ephemeris_xyz_t *b)
785769
{

src/nav_msg_glo.c

Lines changed: 169 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,56 @@
1212
#include <assert.h>
1313
#include <string.h>
1414
#include <stdio.h>
15+
#include <math.h>
1516
#include <libswiftnav/nav_msg_glo.h>
17+
#include <libswiftnav/time.h>
18+
19+
/* local containers for parsing GLO ephemeris*/
20+
static ephemeris_t g_e;
21+
static bool done_flag = false;
22+
static u16 nt;
23+
static u8 n4;
24+
static u8 hrs;
25+
static u8 min;
26+
static u8 sec;
27+
28+
/* Word Ft (accuracy of measurements), refer to GLO ICD, Table 4.4 */
29+
const float f_t[] = {1.0f,
30+
2.0f,
31+
2.5f,
32+
4.0f,
33+
5.0f,
34+
7.0f,
35+
10.0f,
36+
12.0f,
37+
14.0f,
38+
16.0f,
39+
32.0f,
40+
64.0f,
41+
128.0f,
42+
256.0f,
43+
512.0f,
44+
-1.0f};
45+
46+
/* Word P1 (Time interval between adjacent values of tb, minutes), refer Table 4.3 */
47+
const u8 p1[] = {0, 30, 45, 60}; /* min */
1648

1749
void nav_msg_init_glo(nav_msg_glo_t *n)
1850
{
1951
/* Initialize the necessary parts of the nav message state structure. */
2052
memset(n, 0, sizeof(nav_msg_glo_t));
21-
n->next_string_id = 1;
53+
n->next_string_id = 1; /* start parsing from string 1 */
54+
done_flag = false;
2255
}
2356

2457
/** Extract a word of n_bits length (n_bits <= 32) at position bit_index into
25-
* the subframe. Takes account of the offset stored in n, and the circular
26-
* nature of the n->subframe_bits buffer.
27-
* Refer to bit index to Table 4.6 in GLO ICD 5.1 (pg. 34)
58+
* the subframe. Refer to bit index to Table 4.6 and 4.11 in GLO ICD 5.1 (pg. 34)
2859
* \param n pointer to GLO nav message structure to be parsed
29-
* \param bit_index number of bit to the extract process start with. Range [1..85]
30-
* \param n_bits how many bits should be extract [1..32]
31-
* \return word extracted from navigation string */
32-
u32 extract_word_glo(nav_msg_glo_t *n, u16 bit_index, u8 n_bits)
60+
* \param bit_index number of bit the extract process start with. Range [1..85]
61+
* \param n_bits how many bits should be extracted [1..32]
62+
* \return word extracted from navigation string
63+
*/
64+
/*static*/ u32 extract_word_glo(const nav_msg_glo_t *n, u16 bit_index, u8 n_bits)
3365
{
3466
assert(n_bits <= 32 && n_bits > 0);
3567
assert(bit_index <= 85 && bit_index > 0);
@@ -51,22 +83,138 @@ u32 extract_word_glo(nav_msg_glo_t *n, u16 bit_index, u8 n_bits)
5183

5284
return word;
5385
}
54-
#if 0
55-
static s8 process_string_glo(nav_msg_t *n, ephemeris_t *e)
86+
87+
/** The function deccodes a GLO navigation string
88+
* \param n Pointer to nav_msg_glo_t structure which contains GLO string
89+
* \param e Pointer to Ephemeris to store
90+
* \return 0 - decode not completed,
91+
* 1 -- decode completed, all ephemeris data stored
92+
* <0 -- in case of an error.
93+
*/
94+
s8 process_string_glo(nav_msg_glo_t *n, ephemeris_t *e)
5695
{
57-
/* Extract dummy bit from string */
58-
/* sanity check dummy bit */
59-
/* Extract string number */
96+
/* Extract and check dummy bit from GLO string, bit 85 in GLO string */
97+
if (extract_word_glo(n, 85, 1) != 0) {
98+
log_error("GLO dummy bit is not 0.");
99+
return -1;
100+
} else {
101+
/* Extract string number */
102+
u8 m = extract_word_glo(n, 81, 4);
103+
u32 ret;
104+
u8 sign;
105+
/* is the string we need? */
106+
if (n->next_string_id == m) {
107+
switch (m) {
108+
case 1: /* string 1 */
109+
/* extract x */
110+
ret = extract_word_glo(n, 9, 26);
111+
sign = extract_word_glo(n, 9 + 26, 1);
112+
g_e.glo.pos[0] = sign ? -1.0 * ret * pow(2, -11) * 1000.0 :
113+
ret * pow(2, -11) * 1000.0;
114+
/* extract Vx */
115+
ret = extract_word_glo(n, 41, 23);
116+
sign = extract_word_glo(n, 41 + 23, 1);
117+
g_e.glo.vel[0] = sign ? -1.0 * ret * pow(2, -20) * 1000.0 :
118+
ret * pow(2, -20) * 1000.0;
119+
/* extract Ax */
120+
ret = extract_word_glo(n, 36, 4);
121+
sign = extract_word_glo(n, 36 + 4, 1);
122+
g_e.glo.acc[0] = sign ? -1.0 * ret * pow(2, -30) * 1000.0 :
123+
ret * pow(2, -30) * 1000.0;
124+
/* extract tk */
125+
hrs = (u8)extract_word_glo(n,65,5);
126+
min = (u8)extract_word_glo(n,70,6);
127+
sec = (u8)extract_word_glo(n,76,1);
128+
129+
n->next_string_id = 2;
130+
break;
131+
case 2: /* string 2 */
132+
/* extract y */
133+
ret = extract_word_glo(n, 9, 26);
134+
sign = extract_word_glo(n, 9 + 26, 1);
135+
g_e.glo.pos[1] = sign ? -1.0 * ret * pow(2, -11) * 1000.0 :
136+
ret * pow(2, -11) * 1000.0;
137+
/* extract Vy */
138+
ret = extract_word_glo(n, 41, 23);
139+
sign = extract_word_glo(n, 41 + 23, 1);
140+
g_e.glo.vel[1] = sign ? -1.0 * ret * pow(2, -20) * 1000.0 :
141+
ret * pow(2, -20) * 1000.0;
142+
/* extract Ay */
143+
ret = extract_word_glo(n, 36, 4);
144+
sign = extract_word_glo(n, 36 + 4, 1);
145+
g_e.glo.acc[1] = sign ? -1.0 * ret * pow(2, -30) * 1000.0 :
146+
ret * pow(2, -30) * 1000.0;
147+
/* extract MSB of B */
148+
g_e.healthy = extract_word_glo(n, 80, 1);
149+
/* extract P1 */
150+
g_e.fit_interval = p1[extract_word_glo(n, 77, 2)];
151+
152+
n->next_string_id = 3;
153+
break;
154+
case 3: /* string 3 */
155+
/* extract z */
156+
ret = extract_word_glo(n, 9, 26);
157+
sign = extract_word_glo(n, 9 + 26, 1);
158+
g_e.glo.pos[2] = sign ? -1.0 * ret * pow(2, -11) * 1000.0 :
159+
ret * pow(2, -11) * 1000.0;
160+
/* extract Vz */
161+
ret = extract_word_glo(n, 41, 23);
162+
sign = extract_word_glo(n, 41 + 23, 1);
163+
g_e.glo.vel[2] = sign ? -1.0 * ret * pow(2, -20) * 1000.0 :
164+
ret * pow(2, -20) * 1000.0;
165+
/* extract Az */
166+
ret = extract_word_glo(n, 36, 4);
167+
sign = extract_word_glo(n, 36 + 4, 1);
168+
g_e.glo.acc[2] = sign ? -1.0 * ret * pow(2, -30) * 1000.0 :
169+
ret * pow(2, -30) * 1000.0;
170+
/* extract gamma */
171+
ret = extract_word_glo(n, 69, 10);
172+
sign = extract_word_glo(n, 69 + 10, 1);
173+
g_e.glo.gamma = sign ? -1.0 * ret * pow(2, -40) :
174+
ret * pow(2, -40);
175+
/* extract l and add B */
176+
g_e.healthy |= extract_word_glo(n, 65, 1);
60177

61-
/* Extract time stamp from a sting */
62-
u32 ts = extract_word(n, 0, 30, 0);
63-
if (nav_parity(&sf_word2)) {
64-
log_info_sid(e->sid, "subframe parity mismatch (word 2)");
65-
n->gps.subframe_start_index = 0; // Mark the subframe as processed
66-
n->gps.next_subframe_id = 1; // Make sure we start again next time
67-
return -2;
178+
n->next_string_id = 4;
179+
break;
180+
case 4: /* string 4 */
181+
/* extract tau */
182+
ret = extract_word_glo(n, 59, 21);
183+
sign = extract_word_glo(n, 59 + 21, 1);
184+
g_e.glo.tau = sign ? -1.0 * ret * pow(2, -30) :
185+
ret * pow(2, -30);
186+
/* extract n */
187+
g_e.sid.sat = extract_word_glo(n, 11, 5);
188+
/* extract Ft (URA) */
189+
g_e.ura = f_t[extract_word_glo(n, 30, 4)];
190+
/*extract Nt*/
191+
nt = (u16)extract_word_glo(n, 16, 11);
192+
193+
n->next_string_id = 5;
194+
break;
195+
case 5: /* string 5 */
196+
/* extract N4 */
197+
n4 = (u8)extract_word_glo(n, 32, 5);
198+
199+
n->next_string_id = 1;
200+
done_flag = true;
201+
break;
202+
default:
203+
break;
204+
}
205+
}
206+
if (done_flag)
207+
{
208+
g_e.sid.code = CODE_GLO_L1CA;
209+
/* convert GLO TOE to GPS TOE */
210+
g_e.toe = glo_time2gps_time(nt, n4, hrs, min, sec);
211+
g_e.valid = g_e.healthy; //NOTE: probably Valid needs to be defined by other way
212+
memcpy(e, &g_e, sizeof(g_e));
213+
done_flag = false;
214+
return 1;
215+
}
68216
}
69217

70218
return 0;
71219
}
72-
#endif
220+

src/time.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ u16 gps_adjust_week_cycle(u16 wn_raw, u16 wn_ref)
139139
* |return converted gps time
140140
*/
141141

142-
gps_time_t glo_time2gps_time(u16 nt, u8 n4, s8 h, s8 m, s8 s)
142+
gps_time_t glo_time2gps_time(u16 nt, u8 n4, u8 h, u8 m, u8 s)
143143
{
144144
u8 j = 0;
145145
u16 day_of_year = 0;

0 commit comments

Comments
 (0)