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.
- checksums.yaml +4 -4
- data/Rakefile +1 -0
- data/exe/gps_pvt +1 -17
- data/exe/to_ubx +162 -32
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +1677 -399
- data/ext/ninja-scan-light/tool/navigation/GLONASS.h +137 -9
- data/ext/ninja-scan-light/tool/navigation/GLONASS_Solver.h +5 -3
- data/ext/ninja-scan-light/tool/navigation/GPS.h +301 -50
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +5 -3
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_MultiFrequency.h +1 -0
- data/ext/ninja-scan-light/tool/navigation/QZSS.h +48 -15
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +106 -4
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +5 -3
- data/ext/ninja-scan-light/tool/param/bit_array.h +53 -16
- data/ext/ninja-scan-light/tool/swig/GPS.i +265 -25
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +64 -0
- data/ext/ninja-scan-light/tool/util/bit_counter.h +84 -0
- data/lib/gps_pvt/receiver/extension.rb +51 -0
- data/lib/gps_pvt/receiver.rb +49 -32
- data/lib/gps_pvt/version.rb +1 -1
- metadata +4 -2
@@ -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 = (
|
1877
|
-
#define CONVERT2(TARGET, TARGET_SF) CONVERT3(
|
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
|
-
///<
|
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
|
-
|
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
|
-
|
132
|
-
|
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__ */
|