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
1749void 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+
0 commit comments