gps_pvt 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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__ */
|