gps_pvt 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -46,6 +46,7 @@
46
46
 
47
47
  #include "GPS.h"
48
48
  #include "algorithm/integral.h"
49
+ #include "util/bit_counter.h"
49
50
 
50
51
  template <class FloatT = double>
51
52
  class GLONASS_SpaceNode {
@@ -89,17 +90,79 @@ static u ## bits ## _t name(const InputT *buf){ \
89
90
  return \
90
91
  DataParser::template bits2num<u ## bits ## _t, EffectiveBits, PaddingBits_MSB>( \
91
92
  buf, offset_bits, length); \
93
+ } \
94
+ static void name ## _set(InputT *dest, const u ## bits ## _t &src){ \
95
+ DataParser::template num2bits<u ## bits ## _t, InputT>( \
96
+ dest, src, offset_bits, length, EffectiveBits, PaddingBits_MSB); \
92
97
  }
93
98
  #define convert_s(bits, offset_bits, length, name) \
94
99
  static s ## bits ## _t name(const InputT *buf){ \
95
100
  u ## bits ## _t temp( \
96
101
  DataParser::template bits2num<u ## bits ## _t, EffectiveBits, PaddingBits_MSB>( \
97
102
  buf, offset_bits, length)); \
98
- static const u ## bits ## _t mask((u ## bits ## _t)1 << (length - 1)); /* MSB is sign bit */ \
103
+ /* MSB is sign bit (Not equal to two's complement?) */ \
104
+ static const u ## bits ## _t mask((u ## bits ## _t)1 << (length - 1)); \
99
105
  return (temp & mask) ? ((s ## bits ## _t)-1 * (temp & (mask - 1))) : temp; \
106
+ } \
107
+ static void name ## _set(InputT *dest, const s ## bits ## _t &src){ \
108
+ static const u ## bits ## _t mask((u ## bits ## _t)1 << (length - 1)); \
109
+ u ## bits ## _t src2((src < 0) ? ((-src) | mask) : src); \
110
+ DataParser::template num2bits<u ## bits ## _t, InputT>( \
111
+ dest, src2, offset_bits, length, EffectiveBits, PaddingBits_MSB); \
100
112
  }
113
+ convert_u( 8, 0, 1, idle);
114
+ static void idle_set(InputT *dest){idle_set(dest, 0);}
101
115
  convert_u( 8, 1, 4, m);
102
116
  convert_u( 8, 77, 8, KX);
117
+ static void KX_set(InputT *dest){
118
+ #if 0
119
+ // mask generation with Ruby
120
+ mask_bits = 32
121
+ mask_str = "0x%0#{mask_bits / 4}X"
122
+ [
123
+ [9, 10, 12, 13, 15, 17, 19, 20, 22, 24, 26, 28, 30, 32, 34, 35, 37, 39, 41, 43,
124
+ 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84],
125
+ [9, 11, 12, 14, 15, 18, 19, 21, 22, 25, 26, 29, 30, 33, 34, 36, 37, 40, 41, 44,
126
+ 45, 48, 49, 52, 53, 56, 57, 60, 61, 64, 65, 67, 68, 71, 72, 75, 76, 79, 80, 83, 84],
127
+ [10..12, 16..19, 23..26, 31..34, 38..41, 46..49, 54..57, 62..65, 69..72, 77..80, 85],
128
+ [13..19, 27..34, 42..49, 58..65, 73..80],
129
+ [20..34, 50..65, 81..85],
130
+ [35..65],
131
+ [66..85],
132
+ ].collect{|pat|
133
+ pat.collect{|idx| idx.to_a rescue idx}.flatten \
134
+ .collect{|i| 85 - i}.sort.chunk{|i| i / mask_bits} \
135
+ .collect{|quot, i_s|
136
+ mask = eval("0b#{i_s.inject("0" * mask_bits){|res, i| res[i % mask_bits] = '1'; res}}")
137
+ #mask = [mask_be].pack("N").unpack("L")[0] # endianess correction
138
+ [quot, mask] # endianess correction
139
+ }.inject([mask_str % [0]] * (77.0 / mask_bits).ceil){|res, (i, mask)|
140
+ res[i] = (mask_str % [mask]); res
141
+ }
142
+ }.transpose
143
+ #endif
144
+ u8_t hamming(0);
145
+ static const struct {
146
+ uint_t idx, len;
147
+ u32_t mask[8];
148
+ } prop[] = {
149
+ { 0, 32, {0x55555AAAu, 0x66666CCCu, 0x87878F0Fu, 0x07F80FF0u, 0xF8000FFFu, 0x00000FFFu, 0xFFFFF000u, ~0u}},
150
+ {32, 32, {0xAAAAB555u, 0xCCCCD999u, 0x0F0F1E1Eu, 0x0FF01FE0u, 0xF0001FFFu, 0xFFFFE000u, 0, ~0u}},
151
+ {64, 13, {0x6AD80000u >> 19, 0xB3680000u >> 19, 0x3C700000u >> 19, 0x3F800000u >> 19, 0xC0000000u >> 19, 0, 0, ~0u}},
152
+ };
153
+ for(std::size_t j(0); j < sizeof(prop) / sizeof(prop[0]); ++j){
154
+ u8_t check_bit(1);
155
+ u32_t v(DataParser::template bits2num<u32_t, EffectiveBits, PaddingBits_MSB>(dest, prop[j].idx, prop[j].len));
156
+ for(int i(0); i < 8; ++i, check_bit <<= 1){
157
+ if(BitCounter<u32_t>::count(v & prop[j].mask[i]) % 2 == 0){continue;}
158
+ hamming ^= check_bit;
159
+ }
160
+ }
161
+ if(BitCounter<u8_t>::count(hamming & 0x7F) % 2 == 1){
162
+ hamming ^= 0x80;
163
+ }
164
+ KX_set(dest, hamming);
165
+ }
103
166
 
104
167
  struct String1 {
105
168
  convert_u( 8, 7, 2, P1);
@@ -135,7 +198,7 @@ static s ## bits ## _t name(const InputT *buf){ \
135
198
  convert_u( 8, 70, 5, n);
136
199
  convert_u( 8, 75, 2, M);
137
200
  };
138
- struct String5_Alnamac {
201
+ struct String5_Almanac {
139
202
  convert_u(16, 5, 11, NA);
140
203
  convert_s(32, 16, 32, tau_c);
141
204
  convert_u( 8, 49, 5, N_4);
@@ -143,7 +206,7 @@ static s ## bits ## _t name(const InputT *buf){ \
143
206
  convert_u( 8, 76, 1, l_n);
144
207
  };
145
208
 
146
- struct String6_Alnamac { // String 6; same as 8, 10, 12, 14
209
+ struct String6_Almanac { // String 6; same as 8, 10, 12, 14
147
210
  convert_u( 8, 5, 1, C_n);
148
211
  convert_u( 8, 6, 2, M_n);
149
212
  convert_u( 8, 8, 5, nA);
@@ -152,7 +215,7 @@ static s ## bits ## _t name(const InputT *buf){ \
152
215
  convert_s(32, 44, 18, delta_iA_n);
153
216
  convert_u(16, 62, 15, epsilonA_n);
154
217
  };
155
- struct String7_Alnamac { // String 7; same as 9, 11, 13, 15
218
+ struct String7_Almanac { // String 7; same as 9, 11, 13, 15
156
219
  convert_s(16, 5, 16, omegaA_n);
157
220
  convert_u(32, 21, 21, tA_lambda_n);
158
221
  convert_s(32, 42, 22, delta_TA_n);
@@ -257,7 +320,7 @@ static s ## bits ## _t name(const InputT *buf){ \
257
320
  bool l_n;
258
321
  #define fetch_item(name) name = BroadcastedMessage< \
259
322
  InputT, (int)sizeof(InputT) * CHAR_BIT - PaddingBits_MSB - PaddingBits_LSB, PaddingBits_MSB> \
260
- :: String5_Alnamac :: name (src)
323
+ :: String5_Almanac :: name (src)
261
324
  template <int PaddingBits_MSB, int PaddingBits_LSB, class InputT>
262
325
  void update_string5(const InputT *src){
263
326
  fetch_item(tau_c);
@@ -267,6 +330,22 @@ static s ## bits ## _t name(const InputT *buf){ \
267
330
  fetch_item(l_n);
268
331
  }
269
332
  #undef fetch_item
333
+ template <int PaddingBits_MSB, int PaddingBits_LSB, class BufferT>
334
+ void dump(BufferT *dst){
335
+ typedef BroadcastedMessage<
336
+ BufferT, (int)sizeof(BufferT) * CHAR_BIT - PaddingBits_MSB - PaddingBits_LSB, PaddingBits_MSB>
337
+ deparse_t;
338
+ #define dump_item(name) deparse_t::String5_Almanac:: name ## _set(dst, name)
339
+ dump_item(tau_c);
340
+ dump_item(tau_GPS);
341
+ dump_item(N_4);
342
+ dump_item(NA);
343
+ dump_item(l_n);
344
+ #undef dump_item
345
+ deparse_t::m_set(dst, 5);
346
+ deparse_t::idle_set(dst);
347
+ deparse_t::KX_set(dst);
348
+ }
270
349
 
271
350
  enum {
272
351
  SF_tau_c, SF_tau_GPS,
@@ -307,7 +386,7 @@ static s ## bits ## _t name(const InputT *buf){ \
307
386
 
308
387
  raw_t &operator=(const TimeProperties &t){
309
388
  #define CONVERT(TARGET) \
310
- {TARGET = (s32_t)((t.TARGET + 0.5 * sf[SF_ ## TARGET]) / sf[SF_ ## TARGET]);}
389
+ {TARGET = (s32_t)std::floor(t.TARGET / sf[SF_ ## TARGET] + 0.5);}
311
390
  CONVERT(tau_c);
312
391
  CONVERT(tau_GPS);
313
392
  std::div_t divmod(std::div(t.date.year - 1996, 4));
@@ -364,7 +443,7 @@ if(std::abs(TARGET - t.TARGET) > raw_t::sf[raw_t::SF_ ## TARGET]){break;}
364
443
  uint_t E_n; // [days]
365
444
  uint_t P1; // [s] time interval of two adjacent t_b; 0 - 0, 1 - 30, 2 - 45, 3 - 60 mins
366
445
  bool P2;
367
- //bool P3; // flag for alnamac; 1 - five, 0 - four
446
+ //bool P3; // flag for almanac; 1 - five, 0 - four
368
447
  bool P4; // flag for ephemeris; 1 - uploaded by the control segment
369
448
  bool l_n; // health flag; 0 - healthy, 1 - malfunction
370
449
 
@@ -798,6 +877,56 @@ if(std::abs(TARGET - t.TARGET) > raw_t::sf[raw_t::SF_ ## TARGET]){break;}
798
877
  fetch_item(4, M);
799
878
  }
800
879
  #undef fetch_item
880
+ template <int PaddingBits_MSB, int PaddingBits_LSB, class BufferT>
881
+ void dump(BufferT *dst, const unsigned int &str){
882
+ typedef BroadcastedMessage<
883
+ BufferT, (int)sizeof(BufferT) * CHAR_BIT - PaddingBits_MSB - PaddingBits_LSB, PaddingBits_MSB>
884
+ deparse_t;
885
+ #define dump_item(num, name) deparse_t::String ## num :: name ## _set(dst, name)
886
+ switch(str){
887
+ case 1:
888
+ dump_item(1, P1);
889
+ dump_item(1, t_k);
890
+ dump_item(1, xn_dot);
891
+ dump_item(1, xn_ddot);
892
+ dump_item(1, xn);
893
+ break;
894
+ case 2: {
895
+ dump_item(2, B_n);
896
+ dump_item(2, P2);
897
+ dump_item(2, t_b);
898
+ dump_item(2, yn_dot);
899
+ dump_item(2, yn_ddot);
900
+ dump_item(2, yn);
901
+ break;
902
+ }
903
+ case 3:
904
+ dump_item(3, P3);
905
+ dump_item(3, gamma_n);
906
+ dump_item(3, p);
907
+ dump_item(3, l_n);
908
+ dump_item(3, zn_dot);
909
+ dump_item(3, zn_ddot);
910
+ dump_item(3, zn);
911
+ break;
912
+ case 4:
913
+ dump_item(4, tau_n);
914
+ dump_item(4, delta_tau_n);
915
+ dump_item(4, E_n);
916
+ dump_item(4, P4);
917
+ dump_item(4, F_T);
918
+ dump_item(4, N_T);
919
+ dump_item(4, n);
920
+ dump_item(4, M);
921
+ break;
922
+ default:
923
+ return;
924
+ }
925
+ #undef dump_item
926
+ deparse_t::m_set(dst, str);
927
+ deparse_t::idle_set(dst);
928
+ deparse_t::KX_set(dst);
929
+ }
801
930
 
802
931
  enum {
803
932
  SF_xn, SF_yn = SF_xn, SF_zn = SF_xn,
@@ -859,9 +988,8 @@ if(std::abs(TARGET - t.TARGET) > raw_t::sf[raw_t::SF_ ## TARGET]){break;}
859
988
  return res;
860
989
  }
861
990
  raw_t &operator=(const Ephemeris &eph){
862
- // TODO: m?
863
991
  #define CONVERT(TARGET) \
864
- {TARGET = (s32_t)((eph.TARGET + 0.5 * sf[SF_ ## TARGET]) / sf[SF_ ## TARGET]);}
992
+ {TARGET = (s32_t)std::floor(eph.TARGET / sf[SF_ ## TARGET] + 0.5);}
865
993
  svid = eph.svid;
866
994
  { // t_k
867
995
  std::div_t minutes(div(eph.t_k, 60));