gps_pvt 0.8.0 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -201,6 +201,11 @@ template <class InputT> \
201
201
  static u ## bits ## _t name(const InputT *buf){ \
202
202
  return parser_t::template bits2num<u ## bits ## _t, InputT>( \
203
203
  buf, offset_bits, length); \
204
+ } \
205
+ template <class BufferT> \
206
+ static void name ## _set(BufferT *dest, const u ## bits ## _t &src){ \
207
+ parser_t::template num2bits<u ## bits ## _t, BufferT>( \
208
+ dest, src, offset_bits, length); \
204
209
  }
205
210
  #define convert_s(bits, offset_bits, length, name) \
206
211
  template <class InputT> \
@@ -208,12 +213,22 @@ static s ## bits ## _t name(const InputT *buf){ \
208
213
  return (s ## bits ## _t)parser_t::template bits2num<u ## bits ## _t, InputT>( \
209
214
  buf, offset_bits) \
210
215
  >> (bits - length); \
216
+ } \
217
+ template <class BufferT> \
218
+ static void name ## _set(BufferT *dest, const s ## bits ## _t &src){ \
219
+ parser_t::template num2bits<u ## bits ## _t, BufferT>( \
220
+ dest, *(u ## bits ## _t *)(&src), offset_bits, length); \
211
221
  }
212
222
  #define convert_u_ch(bits, offset_bits, length, bits_per_ch, name) \
213
223
  template <class InputT> \
214
224
  static u ## bits ## _t name(const InputT *buf, const uint_t &ch){ \
215
225
  return parser_t::template bits2num<u ## bits ## _t>( \
216
226
  buf, offset_bits + (bits_per_ch * ch), length); \
227
+ } \
228
+ template <class BufferT> \
229
+ static void name ## _set(BufferT *dest, const uint_t &ch, const u ## bits ## _t &src){ \
230
+ parser_t::template num2bits<u ## bits ## _t, BufferT>( \
231
+ dest, src, offset_bits + (bits_per_ch * ch), length); \
217
232
  }
218
233
  #define convert_s_ch(bits, offset_bits, length, bits_per_ch, name) \
219
234
  template <class InputT> \
@@ -221,6 +236,11 @@ static s ## bits ## _t name(const InputT *buf, const uint_t &ch){ \
221
236
  return (s ## bits ## _t)parser_t::template bits2num<u ## bits ## _t>( \
222
237
  buf, offset_bits + (bits_per_ch * ch)) \
223
238
  >> (bits - length); \
239
+ } \
240
+ template <class BufferT> \
241
+ static void name ## _set(BufferT *dest, const uint_t &ch, const s ## bits ## _t &src){ \
242
+ parser_t::template num2bits<u ## bits ## _t, BufferT>( \
243
+ dest, *(u ## bits ## _t *)(&src), offset_bits + (bits_per_ch * ch), length); \
224
244
  }
225
245
 
226
246
  /**
@@ -254,8 +274,55 @@ static s ## bits ## _t name(const InputT *buf, const uint_t &ch){ \
254
274
  }
255
275
 
256
276
  convert_u(8, 0, 8, preamble);
277
+ template <class BufferT>
278
+ static void preamble_set2(BufferT *dest, const unsigned int &index = 0){
279
+ static const u8_t preamble_list[] = {0x53, 0x9A, 0xC6};
280
+ preamble_set(dest, preamble_list[index % 3]);
281
+ }
257
282
  convert_u(8, 8, 6, message_type);
258
283
 
284
+ convert_u(32, 226, 24, parity);
285
+ /**
286
+ * update parity bits based on current buffer
287
+ * @param buf buffer
288
+ * @see SBAS MOPS (DO-229) A.4.3.3
289
+ */
290
+ template <class BufferT>
291
+ static void parity_set(BufferT *dst){
292
+ // CRC-24Q
293
+ static const u32_t poly(0x1864CFBu);
294
+ static const struct tbl_t {
295
+ u32_t fw[0x100];
296
+ tbl_t() {
297
+ for(int i(0); i < 0x100; ++i){
298
+ fw[i] = i << 16;
299
+ for(int j(0); j < 8; ++j){
300
+ fw[i] <<= 1;
301
+ if(fw[i] & 0x1000000u){fw[i] ^= poly;}
302
+ }
303
+ }
304
+ }
305
+ } tbl;
306
+ u32_t crc(0);
307
+ u8_t buf;
308
+ int bit_idx(0);
309
+ for(int bytes(226 / 8); bytes > 0; bytes--, bit_idx += 8){
310
+ buf = parser_t::template bits2num<u8_t, BufferT>(dst, bit_idx, 8);
311
+ crc = (((crc << 8) & 0xFFFF00) | buf) ^ tbl.fw[(crc >> 16) & 0xFF];
312
+ }
313
+ buf = parser_t::template bits2num<u8_t, BufferT>(dst, bit_idx, 8);
314
+ for(unsigned char mask(0x80); bit_idx < 226; bit_idx++, mask >>= 1){
315
+ crc <<= 1;
316
+ if(buf & mask){crc |= 1;}
317
+ if(crc & 0x1000000u){crc ^= poly;}
318
+ }
319
+ for(int i(0); i < 3; i++){ // forward operation for padding
320
+ unsigned int cache(tbl.fw[(crc >> 16) & 0xFF]);
321
+ crc = (((crc << 8) ^ cache) & 0xFFFF00) | (cache & 0xFF);
322
+ }
323
+ parity_set(dst, crc);
324
+ }
325
+
259
326
  struct Type1 { ///< @see Fig. A-6 PRN_MASK
260
327
  struct mask_t {
261
328
  u8_t valid;
@@ -1838,6 +1905,18 @@ sf[SF_ ## TARGET] * msg_t::TARGET(buf)
1838
1905
  };
1839
1906
  return res;
1840
1907
  }
1908
+ template <class BufferT>
1909
+ void dump(BufferT *dst){
1910
+ typedef typename DataBlock::Type9 msg_t;
1911
+ #define dump_item(name) msg_t:: name ## _set(dst, name)
1912
+ DataBlock::message_type_set(dst, 9);
1913
+ msg_t::t0_set(dst, t_0); msg_t::ura_set(dst, URA);
1914
+ dump_item(x); dump_item(y); dump_item(z);
1915
+ dump_item(dx); dump_item(dy); dump_item(dz);
1916
+ dump_item(ddx); dump_item(ddy); dump_item(ddz);
1917
+ dump_item(a_Gf0); dump_item(a_Gf1);
1918
+ #undef dump_item
1919
+ }
1841
1920
 
1842
1921
  enum {
1843
1922
  SF_t_0,
@@ -1873,13 +1952,13 @@ sf[SF_ ## TARGET] * msg_t::TARGET(buf)
1873
1952
 
1874
1953
  raw_t &operator=(const Ephemeris &eph){
1875
1954
  #define CONVERT3(TARGET_DST, TARGET_SRC, TARGET_SF) \
1876
- {TARGET_DST = (s32_t)((TARGET_SRC + 0.5 * sf[SF_ ## TARGET_SF]) / sf[SF_ ## TARGET_SF]);}
1877
- #define CONVERT2(TARGET, TARGET_SF) CONVERT3(eph.TARGET, eph.TARGET, TARGET_SF)
1955
+ {TARGET_DST = std::floor((TARGET_SRC / sf[SF_ ## TARGET_SF]) + 0.5);}
1956
+ #define CONVERT2(TARGET, TARGET_SF) CONVERT3(TARGET, eph.TARGET, TARGET_SF)
1878
1957
  #define CONVERT(TARGET) CONVERT2(TARGET, TARGET)
1879
1958
  svid = eph.svid;
1880
1959
 
1881
1960
  URA = URA_index(eph.URA);
1882
- CONVERT3(t_0, std::fmod(t_0, gps_time_t::seconds_day), t_0);
1961
+ CONVERT3(t_0, std::fmod(eph.t_0, gps_time_t::seconds_day), t_0);
1883
1962
  CONVERT2(x, xy); CONVERT2(y, xy); CONVERT(z);
1884
1963
  CONVERT2(dx, dxy); CONVERT2(dy, dxy); CONVERT(dz);
1885
1964
  CONVERT2(ddx, ddxy); CONVERT2(ddy, ddxy); CONVERT(ddz);
@@ -1992,7 +2071,7 @@ if(std::abs(TARGET - eph.TARGET) > raw_t::sf[raw_t::SF_ ## TARGET_SF]){break;}
1992
2071
  float_t dx, dy, dz; ///< ECEF velocity (m/s)
1993
2072
  float_t t_0; ///< Time of applicability (s)
1994
2073
 
1995
- ///< Up-cast to ephemeris
2074
+ ///< Upgrade to ephemeris
1996
2075
  operator Ephemeris() const {
1997
2076
  Ephemeris converted = {
1998
2077
  prn, // Satellite number
@@ -2006,6 +2085,14 @@ if(std::abs(TARGET - eph.TARGET) > raw_t::sf[raw_t::SF_ ## TARGET_SF]){break;}
2006
2085
  };
2007
2086
  return converted;
2008
2087
  }
2088
+ ///< Downgrade from ephemeris
2089
+ Almanac &operator=(const Ephemeris &eph) {
2090
+ prn = eph.svid;
2091
+ t_0 = eph.t_0;
2092
+ x = eph.x; y = eph.y; z = eph.z;
2093
+ dx = eph.dx; dy = eph.dy; dz = eph.dz;
2094
+ return *this;
2095
+ }
2009
2096
 
2010
2097
  struct raw_t {
2011
2098
  u8_t data_id;
@@ -2028,6 +2115,21 @@ if(std::abs(TARGET - eph.TARGET) > raw_t::sf[raw_t::SF_ ## TARGET_SF]){break;}
2028
2115
  };
2029
2116
  return res;
2030
2117
  }
2118
+ template <class BufferT>
2119
+ void dump(BufferT *dst, const uint_t &ch = 0){
2120
+ typedef typename DataBlock::Type17 msg_t;
2121
+ #define dump_item(name) msg_t:: name ## _set(dst, ch, name)
2122
+ if(ch == 0){
2123
+ DataBlock::message_type_set(dst, 17);
2124
+ msg_t::t0_set(dst, t_0);
2125
+ }
2126
+ msg_t::id_set(dst, ch, data_id);
2127
+ dump_item(prn);
2128
+ msg_t::health_status_set(dst, ch, SV_health);
2129
+ dump_item(x); dump_item(y); dump_item(z);
2130
+ dump_item(dx); dump_item(dy); dump_item(dz);
2131
+ #undef dump_item
2132
+ }
2031
2133
 
2032
2134
  enum {
2033
2135
  SF_xy, SF_z,
@@ -56,12 +56,14 @@ struct SBAS_SinglePositioning_Options : public GPS_Solver_GeneralOptions<FloatT>
56
56
 
57
57
  template <class FloatT, class SolverBaseT = GPS_Solver_Base<FloatT> >
58
58
  class SBAS_SinglePositioning : public SolverBaseT {
59
- private:
60
- SBAS_SinglePositioning<FloatT> &operator=(const SBAS_SinglePositioning<FloatT> &);
61
59
  public:
62
- typedef SBAS_SinglePositioning<FloatT> self_t;
60
+ typedef SBAS_SinglePositioning<FloatT, SolverBaseT> self_t;
63
61
  typedef SolverBaseT base_t;
62
+ private:
63
+ self_t &operator=(const self_t &);
64
+ SBAS_SinglePositioning(const self_t &);
64
65
 
66
+ public:
65
67
  #if defined(__GNUC__) && (__GNUC__ < 5)
66
68
  #define inheritate_type(x) typedef typename base_t::x x;
67
69
  #else
@@ -43,25 +43,31 @@
43
43
 
44
44
  #include <vector>
45
45
 
46
- template <int denom, int pow2 = 1, int log2 = 0, int rem2 = denom % pow2>
47
- struct const_div_t : public std::div_t {
48
- const_div_t(const int &num) : std::div_t(std::div(num, denom)) {}
49
- };
50
- template <int denom, int pow2, int log2>
51
- struct const_div_t<denom, pow2, log2, 0> : public const_div_t<denom, (pow2 << 1), log2 + 1> {
52
- const_div_t(const int &num) : const_div_t<denom, (pow2 << 1), log2 + 1>(num) {}
53
- };
54
- template <int denom, int log2>
55
- struct const_div_t<denom, denom, log2, 0> {
56
- int quot, rem;
57
- const_div_t(const int &num) : quot(num >> log2), rem(num & (denom - 1)) {}
58
- };
46
+ #include "util/bit_counter.h"
59
47
 
60
48
  template <int MAX_SIZE, class ContainerT = unsigned char>
61
49
  struct BitArray {
50
+
51
+ template <int denom, int pow2 = 1, int log2 = 0, int rem2 = denom % pow2>
52
+ struct const_div_t : public std::div_t {
53
+ const_div_t(const int &num) : std::div_t(std::div(num, denom)) {}
54
+ };
55
+ template <int denom, int pow2, int log2>
56
+ struct const_div_t<denom, pow2, log2, 0> : public const_div_t<denom, (pow2 << 1), log2 + 1> {
57
+ const_div_t(const int &num) : const_div_t<denom, (pow2 << 1), log2 + 1>(num) {}
58
+ };
59
+ template <int denom, int log2>
60
+ struct const_div_t<denom, denom, log2, 0> {
61
+ int quot, rem;
62
+ const_div_t(const int &num) : quot(num >> log2), rem(num & (denom - 1)) {}
63
+ };
64
+
62
65
  static const int bits_per_addr = (int)sizeof(ContainerT) * CHAR_BIT;
63
66
  static const int max_size = MAX_SIZE;
67
+ static const const_div_t<bits_per_addr> prop;
64
68
  ContainerT buf[(MAX_SIZE + bits_per_addr - 1) / bits_per_addr];
69
+ static const ContainerT mask_rem;
70
+
65
71
  void set(const bool &new_bit = false) {
66
72
  std::memset(buf, (new_bit ? (~0) : 0), sizeof(buf));
67
73
  }
@@ -125,12 +131,35 @@ struct BitArray {
125
131
  return (unsigned int)res;
126
132
  }
127
133
  }
134
+ int ones() const {
135
+ int res(0);
136
+ for(int i(0); i < prop.quot; ++i){
137
+ res += BitCounter<ContainerT>::count(buf[i]);
138
+ }
139
+ if(prop.rem){
140
+ res += BitCounter<ContainerT>::count(
141
+ buf[(sizeof(buf) / sizeof(buf[0])) - 1] & mask_rem);
142
+ }
143
+ return res;
144
+ }
145
+ int least_index_one() const {
146
+ int res(0);
147
+ for(int i(0); prop.quot; ++i){
148
+ int ntz(BitCounter<ContainerT>::ntz(buf[i]));
149
+ res += ntz;
150
+ if(ntz < bits_per_addr){return res;}
151
+ }
152
+ if(prop.rem){
153
+ res += BitCounter<ContainerT>::ntz(
154
+ buf[(sizeof(buf) / sizeof(buf[0])) - 1] & mask_rem);
155
+ }
156
+ return res;
157
+ }
128
158
  std::vector<int> indices_one(const int &offset = 0) const {
129
159
  std::vector<int> res;
130
160
  int idx(offset);
131
- static const const_div_t<bits_per_addr> qr(MAX_SIZE);
132
- int rem(qr.rem), i(0);
133
- for(; i < qr.quot; ++i, idx += bits_per_addr){
161
+ int rem(prop.rem), i(0);
162
+ for(; i < prop.quot; ++i, idx += bits_per_addr){
134
163
  int idx2(idx);
135
164
  for(ContainerT temp(buf[i]); temp > 0; temp >>= 1, ++idx2){
136
165
  if(temp & 0x1){res.push_back(idx2);}
@@ -143,4 +172,12 @@ struct BitArray {
143
172
  }
144
173
  };
145
174
 
175
+ template <int MAX_SIZE, class ContainerT>
176
+ const typename BitArray<MAX_SIZE, ContainerT>::template const_div_t<BitArray<MAX_SIZE, ContainerT>::bits_per_addr>
177
+ BitArray<MAX_SIZE, ContainerT>::prop
178
+ = typename BitArray<MAX_SIZE, ContainerT>::template const_div_t<BitArray<MAX_SIZE, ContainerT>::bits_per_addr>(MAX_SIZE);
179
+
180
+ template <int MAX_SIZE, class ContainerT>
181
+ const ContainerT BitArray<MAX_SIZE, ContainerT>::mask_rem = ((ContainerT)0x1 << prop.rem) - 1;
182
+
146
183
  #endif /* __BIT_ARRAY_H__ */