gps_pvt 0.6.2 → 0.7.0
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/README.md +1 -0
- data/Rakefile +1 -0
- data/exe/gps_pvt +3 -1
- data/exe/to_ubx +214 -0
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +787 -205
- data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +2 -3
- data/ext/ninja-scan-light/tool/algorithm/interpolate.h +106 -0
- data/ext/ninja-scan-light/tool/navigation/ANTEX.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/GLONASS_Solver.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +7 -7
- data/ext/ninja-scan-light/tool/navigation/MagneticField.h +4 -3
- data/ext/ninja-scan-light/tool/navigation/NTCM.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +29 -14
- data/ext/ninja-scan-light/tool/navigation/RINEX_Clock.h +458 -0
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +3 -3
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/SP3.h +69 -112
- data/ext/ninja-scan-light/tool/param/quaternion.h +2 -2
- data/ext/ninja-scan-light/tool/param/vector3.h +2 -2
- data/ext/ninja-scan-light/tool/swig/GPS.i +95 -51
- data/ext/ninja-scan-light/tool/swig/SylphideMath.i +1 -2
- data/gps_pvt.gemspec +3 -0
- data/lib/gps_pvt/receiver.rb +19 -3
- data/lib/gps_pvt/version.rb +5 -5
- metadata +7 -3
@@ -41,7 +41,6 @@
|
|
41
41
|
#include <cstring>
|
42
42
|
#include <map>
|
43
43
|
#include <set>
|
44
|
-
#include <algorithm>
|
45
44
|
#include <stdexcept>
|
46
45
|
|
47
46
|
#include "util/text_helper.h"
|
@@ -61,22 +60,15 @@ struct SP3_Product {
|
|
61
60
|
typedef std::map<GPS_Time<FloatT>, prop_t> history_t;
|
62
61
|
history_t pos_history;
|
63
62
|
history_t vel_history;
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
} interpolate_cnd_default;
|
63
|
+
|
64
|
+
typedef InterpolatableSet<GPS_Time<FloatT>, prop_t, FloatT> interpolator_t;
|
65
|
+
typedef typename interpolator_t::condition_t interpolate_cnd_t;
|
66
|
+
static const interpolate_cnd_t interpolate_cnd_default;
|
69
67
|
|
70
68
|
mutable struct {
|
71
|
-
struct target_t {
|
72
|
-
|
73
|
-
typedef typename std::vector<std::pair<GPS_Time<FloatT>, prop_t> > buf_t;
|
74
|
-
buf_t buf;
|
75
|
-
GPS_Time<FloatT> t0;
|
76
|
-
std::vector<FloatT> dt;
|
77
|
-
bool updated_full_cnd;
|
69
|
+
struct target_t : public interpolator_t {
|
78
70
|
|
79
|
-
target_t() :
|
71
|
+
target_t() : interpolator_t() {}
|
80
72
|
|
81
73
|
/**
|
82
74
|
* update interpolation source
|
@@ -88,58 +80,13 @@ struct SP3_Product {
|
|
88
80
|
const bool &force_update = false,
|
89
81
|
const interpolate_cnd_t &cnd = interpolate_cnd_default){
|
90
82
|
|
91
|
-
|
92
|
-
|
93
|
-
&& ((std::abs(t_diff) <= 10)
|
94
|
-
|| ((dt.size() >= 2)
|
95
|
-
&& (std::abs(t_diff + dt[0]) <= std::abs(t_diff + dt[1])))) ){
|
96
|
-
return *this;
|
97
|
-
}
|
98
|
-
|
99
|
-
// If the 1st and 2nd nearest epochs are changed, then recalculate interpolation targets.
|
100
|
-
struct {
|
101
|
-
const GPS_Time<FloatT> &t_base;
|
102
|
-
bool operator()(
|
103
|
-
const typename history_t::value_type &rhs,
|
104
|
-
const typename history_t::value_type &lhs) const {
|
105
|
-
return std::abs(rhs.first - t_base) < std::abs(lhs.first - t_base);
|
106
|
-
}
|
107
|
-
} cmp = {(t0 = t)};
|
108
|
-
|
109
|
-
buf.resize(cnd.max_epochs);
|
110
|
-
dt.clear();
|
111
|
-
// extract t where t0-dt <= t <= t0+dt, then sort by ascending order of |t-t0|
|
112
|
-
for(typename buf_t::const_iterator
|
113
|
-
it(buf.begin()),
|
114
|
-
it_end(std::partial_sort_copy(
|
115
|
-
history.lower_bound(t - cnd.max_delta_t),
|
116
|
-
history.upper_bound(t + cnd.max_delta_t),
|
117
|
-
buf.begin(), buf.end(), cmp));
|
118
|
-
it != it_end; ++it){
|
119
|
-
dt.push_back(it->first - t0);
|
120
|
-
}
|
121
|
-
updated_full_cnd = (dt.size() >= cnd.max_epochs);
|
122
|
-
|
83
|
+
if((!force_update) && (std::abs(t - interpolator_t::x0) <= 10)){return *this;}
|
84
|
+
interpolator_t::update(t, history, cnd, force_update);
|
123
85
|
return *this;
|
124
86
|
}
|
125
87
|
|
126
|
-
|
127
|
-
|
128
|
-
const GPS_Time<FloatT> &t, const Ty_Array &y,
|
129
|
-
Ty *derivative = NULL) const {
|
130
|
-
int order(dt.size() - 1);
|
131
|
-
do{
|
132
|
-
if(order > 0){break;}
|
133
|
-
if((order == 0) && (!derivative)){return y[0];}
|
134
|
-
throw std::range_error("Insufficient records for interpolation");
|
135
|
-
}while(false);
|
136
|
-
std::vector<Ty> y_buf(order), dy_buf(order);
|
137
|
-
interpolate_Neville(
|
138
|
-
dt, y, t - t0, y_buf, order,
|
139
|
-
&dy_buf, derivative ? 1 : 0);
|
140
|
-
if(derivative){*derivative = dy_buf[0];}
|
141
|
-
return y_buf[0];
|
142
|
-
}
|
88
|
+
typedef typename interpolator_t::buffer_t buf_t;
|
89
|
+
|
143
90
|
Vector3<FloatT> interpolate_xyz(
|
144
91
|
const GPS_Time<FloatT> &t,
|
145
92
|
Vector3<FloatT> *derivative = NULL) const {
|
@@ -149,8 +96,8 @@ struct SP3_Product {
|
|
149
96
|
const Vector3<FloatT> &operator[](const int &n) const {
|
150
97
|
return buf_t::const_iterator::operator[](n).second.xyz;
|
151
98
|
}
|
152
|
-
} xyz(buf.begin());
|
153
|
-
return
|
99
|
+
} xyz(interpolator_t::buf.begin());
|
100
|
+
return interpolator_t::interpolate2(t, xyz, derivative);
|
154
101
|
}
|
155
102
|
FloatT interpolate_clk(
|
156
103
|
const GPS_Time<FloatT> &t,
|
@@ -161,8 +108,8 @@ struct SP3_Product {
|
|
161
108
|
const FloatT &operator[](const int &n) const {
|
162
109
|
return buf_t::const_iterator::operator[](n).second.clk;
|
163
110
|
}
|
164
|
-
} clk(buf.begin());
|
165
|
-
return
|
111
|
+
} clk(interpolator_t::buf.begin());
|
112
|
+
return interpolator_t::interpolate2(t, clk, derivative);
|
166
113
|
}
|
167
114
|
} pos_clk, vel_rate;
|
168
115
|
} subset;
|
@@ -175,7 +122,7 @@ struct SP3_Product {
|
|
175
122
|
bool precheck(const GPS_Time<FloatT> &t) const {
|
176
123
|
// Only position/clock is checked, because velocity/rate can be calculated based on pos/clk.
|
177
124
|
subset.pos_clk.update(t, pos_history);
|
178
|
-
return subset.pos_clk.
|
125
|
+
return subset.pos_clk.ready;
|
179
126
|
}
|
180
127
|
|
181
128
|
typename GPS_SpaceNode<FloatT>::SatelliteProperties::constellation_t
|
@@ -238,7 +185,7 @@ struct SP3_Product {
|
|
238
185
|
}
|
239
186
|
};
|
240
187
|
typename GPS_Solver_Base<FloatT>::satellite_t res = {
|
241
|
-
this,
|
188
|
+
this, this,
|
242
189
|
impl_t::position, impl_t::velocity,
|
243
190
|
impl_t::clock_error, impl_t::clock_error_dot
|
244
191
|
};
|
@@ -301,29 +248,33 @@ struct SP3_Product {
|
|
301
248
|
}
|
302
249
|
|
303
250
|
enum system_t {
|
304
|
-
SYSTEM_GPS
|
305
|
-
SYSTEM_SBAS
|
306
|
-
SYSTEM_QZSS
|
307
|
-
SYSTEM_GLONASS
|
308
|
-
SYSTEM_LEO
|
309
|
-
SYSTEM_GALILEO
|
310
|
-
SYSTEM_BEIDOU
|
311
|
-
SYSTEM_IRNSS
|
251
|
+
SYSTEM_GPS,
|
252
|
+
SYSTEM_SBAS,
|
253
|
+
SYSTEM_QZSS,
|
254
|
+
SYSTEM_GLONASS,
|
255
|
+
SYSTEM_LEO,
|
256
|
+
SYSTEM_GALILEO,
|
257
|
+
SYSTEM_BEIDOU,
|
258
|
+
SYSTEM_IRNSS,
|
259
|
+
NUM_OF_SYSTEMS,
|
312
260
|
};
|
313
261
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
262
|
+
static const int offset_list[NUM_OF_SYSTEMS];
|
263
|
+
|
264
|
+
protected:
|
265
|
+
|
266
|
+
mutable struct per_system_t {
|
267
|
+
const SP3_Product<FloatT> *product;
|
268
|
+
system_t sys;
|
269
|
+
} per_system[NUM_OF_SYSTEMS];
|
270
|
+
|
271
|
+
static typename GPS_Solver_Base<FloatT>::satellite_t select(
|
272
|
+
const void *ptr, const int &prn, const GPS_Time<FloatT> &receiver_time){
|
273
|
+
const per_system_t *ptr_impl(reinterpret_cast<const per_system_t *>(ptr));
|
274
|
+
return ptr_impl->product->select((prn & 0xFF) + offset_list[ptr_impl->sys], receiver_time);
|
275
|
+
}
|
276
|
+
|
277
|
+
public:
|
327
278
|
|
328
279
|
/**
|
329
280
|
* push SP3 product to satellite selector
|
@@ -334,19 +285,11 @@ static typename GPS_Solver_Base<FloatT>::satellite_t select_ ## sys( \
|
|
334
285
|
*/
|
335
286
|
template <class SelectorT>
|
336
287
|
bool push(SelectorT &slct, const system_t &sys = SYSTEM_GPS) const {
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
case SYSTEM_GLONASS: slct.impl_select = select_GLONASS; break;
|
343
|
-
case SYSTEM_LEO: slct.impl_select = select_LEO; break;
|
344
|
-
case SYSTEM_GALILEO: slct.impl_select = select_GALILEO; break;
|
345
|
-
case SYSTEM_BEIDOU: slct.impl_select = select_BEIDOU; break;
|
346
|
-
case SYSTEM_IRNSS: slct.impl_select = select_IRNSS; break;
|
347
|
-
default: return false;
|
348
|
-
}
|
349
|
-
slct.impl = this;
|
288
|
+
if(sys >= NUM_OF_SYSTEMS){return false;}
|
289
|
+
per_system[sys].product = this;
|
290
|
+
per_system[sys].sys = sys;
|
291
|
+
slct.impl_select = select;
|
292
|
+
slct.impl = &per_system[sys];
|
350
293
|
return true;
|
351
294
|
}
|
352
295
|
|
@@ -358,19 +301,19 @@ static typename GPS_Solver_Base<FloatT>::satellite_t select_ ## sys( \
|
|
358
301
|
for(typename satellites_t::const_iterator
|
359
302
|
it(satellites.begin()), it_end(satellites.end());
|
360
303
|
it != it_end; ++it){
|
361
|
-
switch(it->first
|
362
|
-
case
|
304
|
+
switch((char)(it->first >> 8)){
|
305
|
+
case '\0': {
|
363
306
|
int id(it->first & 0xFF);
|
364
307
|
if(id < 100){++res.gps;}
|
365
308
|
else if(id < 192){++res.sbas;}
|
366
309
|
else{++res.qzss;}
|
367
310
|
break;
|
368
311
|
}
|
369
|
-
case
|
370
|
-
case
|
371
|
-
case
|
372
|
-
case
|
373
|
-
case
|
312
|
+
case 'R': ++res.glonass; break;
|
313
|
+
case 'L': ++res.leo; break;
|
314
|
+
case 'E': ++res.galileo; break;
|
315
|
+
case 'C': ++res.beidou; break;
|
316
|
+
case 'I': ++res.irnss; break;
|
374
317
|
default: ++res.unknown; break;
|
375
318
|
}
|
376
319
|
}
|
@@ -381,10 +324,24 @@ static typename GPS_Solver_Base<FloatT>::satellite_t select_ ## sys( \
|
|
381
324
|
template <class FloatT>
|
382
325
|
const typename SP3_Product<FloatT>::per_satellite_t::interpolate_cnd_t
|
383
326
|
SP3_Product<FloatT>::per_satellite_t::interpolate_cnd_default = {
|
384
|
-
9, //
|
385
|
-
|
327
|
+
9, // maximum number of epochs used for interpolation
|
328
|
+
/* maximum acceptable absolute time difference between t and epoch,
|
329
|
+
* default is 2 hr = 15 min interval records; (2 hr * 2 / (9 - 1) = 15 min)
|
330
|
+
*/
|
331
|
+
60 * 60 * 2,
|
332
|
+
};
|
333
|
+
|
334
|
+
template <class FloatT>
|
335
|
+
const int SP3_Product<FloatT>::offset_list[NUM_OF_SYSTEMS] = {
|
336
|
+
0, 0, 0, // GPS, SBAS, QZSS
|
337
|
+
((int)'R' << 8), // GLONASS
|
338
|
+
((int)'L' << 8), // LEO
|
339
|
+
((int)'E' << 8), // GALILEO
|
340
|
+
((int)'C' << 8), // BEIDOU
|
341
|
+
((int)'I' << 8), // IRNSS
|
386
342
|
};
|
387
343
|
|
344
|
+
|
388
345
|
template <class FloatT>
|
389
346
|
class SP3_Reader {
|
390
347
|
protected:
|
@@ -130,7 +130,7 @@ class QuaternionData : public QuaternionDataProperty<FloatT> {
|
|
130
130
|
* @param q �R�s�[��
|
131
131
|
*/
|
132
132
|
QuaternionData(const self_t &q){
|
133
|
-
if(storage = q.storage){(storage->ref)++;}
|
133
|
+
if((storage = q.storage)){(storage->ref)++;}
|
134
134
|
}
|
135
135
|
|
136
136
|
/**
|
@@ -143,7 +143,7 @@ class QuaternionData : public QuaternionDataProperty<FloatT> {
|
|
143
143
|
self_t &operator=(const self_t &q){
|
144
144
|
if(this == &q){return *this;}
|
145
145
|
if(storage && ((--(storage->ref)) <= 0)){delete storage;}
|
146
|
-
if(storage = q.storage){(storage->ref)++;}
|
146
|
+
if((storage = q.storage)){(storage->ref)++;}
|
147
147
|
return *this;
|
148
148
|
}
|
149
149
|
|
@@ -133,7 +133,7 @@ class Vector3Data : public Vector3DataProperty<FloatT> {
|
|
133
133
|
* @param v �R�s�[��
|
134
134
|
*/
|
135
135
|
Vector3Data(const self_t &v){
|
136
|
-
if(storage = v.storage){(storage->ref)++;}
|
136
|
+
if((storage = v.storage)){(storage->ref)++;}
|
137
137
|
}
|
138
138
|
|
139
139
|
/**
|
@@ -146,7 +146,7 @@ class Vector3Data : public Vector3DataProperty<FloatT> {
|
|
146
146
|
self_t &operator=(const self_t &v){
|
147
147
|
if(this == &v){return *this;}
|
148
148
|
if(storage && ((--(storage->ref)) <= 0)){delete storage;}
|
149
|
-
if(storage = v.storage){(storage->ref)++;}
|
149
|
+
if((storage = v.storage)){(storage->ref)++;}
|
150
150
|
return *this;
|
151
151
|
}
|
152
152
|
|
@@ -22,6 +22,7 @@
|
|
22
22
|
#include "navigation/QZSS.h"
|
23
23
|
#include "navigation/GLONASS.h"
|
24
24
|
#include "navigation/RINEX.h"
|
25
|
+
#include "navigation/RINEX_Clock.h"
|
25
26
|
#include "navigation/SP3.h"
|
26
27
|
#include "navigation/ANTEX.h"
|
27
28
|
|
@@ -228,12 +229,10 @@ struct GPS_Ionospheric_UTC_Parameters : public GPS_SpaceNode<FloatT>::Ionospheri
|
|
228
229
|
%}
|
229
230
|
%extend GPS_Ionospheric_UTC_Parameters {
|
230
231
|
%fragment(SWIG_Traits_frag(FloatT));
|
231
|
-
%typemap(in,numinputs=0) FloatT values[4] (FloatT temp
|
232
|
-
|
233
|
-
%}
|
234
|
-
%typemap(argout) FloatT values[4] {
|
232
|
+
%typemap(in,numinputs=0) const FloatT *values[4] (FloatT *temp) "$1 = &temp;"
|
233
|
+
%typemap(argout) const FloatT *values[4] {
|
235
234
|
for(int i(0); i < 4; ++i){
|
236
|
-
%append_output(swig::from(
|
235
|
+
%append_output(swig::from((*$1)[i]));
|
237
236
|
}
|
238
237
|
}
|
239
238
|
MAKE_ARRAY_INPUT(const FloatT, values, swig::asval);
|
@@ -245,11 +244,7 @@ struct GPS_Ionospheric_UTC_Parameters : public GPS_SpaceNode<FloatT>::Ionospheri
|
|
245
244
|
}
|
246
245
|
}
|
247
246
|
%rename("alpha") get_alpha;
|
248
|
-
void get_alpha(FloatT values[4]) const {
|
249
|
-
for(int i(0); i < 4; ++i){
|
250
|
-
values[i] = self->alpha[i];
|
251
|
-
}
|
252
|
-
}
|
247
|
+
void get_alpha(const FloatT *values[4]) const {*values = self->alpha;}
|
253
248
|
%rename("beta=") set_beta;
|
254
249
|
void set_beta(const FloatT values[4]){
|
255
250
|
for(int i(0); i < 4; ++i){
|
@@ -257,11 +252,7 @@ struct GPS_Ionospheric_UTC_Parameters : public GPS_SpaceNode<FloatT>::Ionospheri
|
|
257
252
|
}
|
258
253
|
}
|
259
254
|
%rename("beta") get_beta;
|
260
|
-
void get_beta(FloatT values[4]) const {
|
261
|
-
for(int i(0); i < 4; ++i){
|
262
|
-
values[i] = self->beta[i];
|
263
|
-
}
|
264
|
-
}
|
255
|
+
void get_beta(const FloatT *values[4]) const {*values = self->beta;}
|
265
256
|
MAKE_ACCESSOR(A1, FloatT);
|
266
257
|
MAKE_ACCESSOR(A0, FloatT);
|
267
258
|
MAKE_ACCESSOR(t_ot, unsigned int);
|
@@ -1006,6 +997,7 @@ const type &get_ ## name () const {
|
|
1006
997
|
%inline %{
|
1007
998
|
template <class FloatT>
|
1008
999
|
struct GPS_SolverOptions_Common {
|
1000
|
+
virtual ~GPS_SolverOptions_Common() {}
|
1009
1001
|
virtual GPS_Solver_GeneralOptions<FloatT> *cast_general() = 0;
|
1010
1002
|
virtual const GPS_Solver_GeneralOptions<FloatT> *cast_general() const = 0;
|
1011
1003
|
};
|
@@ -1206,7 +1198,10 @@ struct GPS_RangeCorrector
|
|
1206
1198
|
if(!res.is_available()){
|
1207
1199
|
static const VALUE key(ID2SYM(rb_intern("relative_property")));
|
1208
1200
|
VALUE hook(rb_hash_lookup(hooks, key));
|
1209
|
-
if(!NIL_P(hook)){
|
1201
|
+
if(!NIL_P(hook)){
|
1202
|
+
if(!res.impl_xyz){res.impl_xyz = this;}
|
1203
|
+
if(!res.impl_t){res.impl_t = this;}
|
1204
|
+
}
|
1210
1205
|
}
|
1211
1206
|
#endif
|
1212
1207
|
return res;
|
@@ -1653,31 +1648,8 @@ template <class FloatT>
|
|
1653
1648
|
struct RINEX_Observation {};
|
1654
1649
|
}
|
1655
1650
|
|
1656
|
-
%extend SP3 {
|
1657
|
-
%typemap(in,numinputs=0) int count[ANY] (int temp[$1_dim0]) "$1 = temp;"
|
1658
|
-
%typemap(argout) int count[ANY] {
|
1659
|
-
for(int i(0); i < $1_dim0; ++i){
|
1660
|
-
%append_output(SWIG_From(int)($1[i]));
|
1661
|
-
}
|
1662
|
-
}
|
1663
|
-
void satellites(int count[SP3::SYS_SYSTEMS]) const {
|
1664
|
-
typename SP3_Product<FloatT>::satellite_count_t x(self->satellite_count());
|
1665
|
-
count[SP3<FloatT>::SYS_GPS] = x.gps;
|
1666
|
-
count[SP3<FloatT>::SYS_SBAS] = x.sbas;
|
1667
|
-
count[SP3<FloatT>::SYS_QZSS] = x.qzss;
|
1668
|
-
count[SP3<FloatT>::SYS_GLONASS] = x.glonass;
|
1669
|
-
count[SP3<FloatT>::SYS_GALILEO] = x.galileo;
|
1670
|
-
count[SP3<FloatT>::SYS_BEIDOU] = x.beidou;
|
1671
|
-
}
|
1672
|
-
|
1673
|
-
}
|
1674
1651
|
%inline {
|
1675
|
-
|
1676
|
-
struct SP3 : public SP3_Product<FloatT> {
|
1677
|
-
int read(const char *fname) {
|
1678
|
-
std::fstream fin(fname, std::ios::in | std::ios::binary);
|
1679
|
-
return SP3_Reader<FloatT>::read_all(fin, *this);
|
1680
|
-
}
|
1652
|
+
struct PushableData {
|
1681
1653
|
enum system_t {
|
1682
1654
|
SYS_GPS,
|
1683
1655
|
SYS_SBAS,
|
@@ -1687,20 +1659,21 @@ struct SP3 : public SP3_Product<FloatT> {
|
|
1687
1659
|
SYS_BEIDOU,
|
1688
1660
|
SYS_SYSTEMS,
|
1689
1661
|
};
|
1690
|
-
|
1662
|
+
template <class DataT, class FloatT>
|
1663
|
+
static bool push(DataT &data, GPS_Solver<FloatT> &solver, const system_t &sys){
|
1691
1664
|
switch(sys){
|
1692
1665
|
case SYS_GPS:
|
1693
|
-
return
|
1694
|
-
solver.gps.ephemeris_proxy.gps,
|
1666
|
+
return data.push(
|
1667
|
+
solver.gps.ephemeris_proxy.gps, DataT::SYSTEM_GPS);
|
1695
1668
|
case SYS_SBAS:
|
1696
|
-
return
|
1697
|
-
solver.sbas.solver.satellites,
|
1669
|
+
return data.push(
|
1670
|
+
solver.sbas.solver.satellites, DataT::SYSTEM_SBAS);
|
1698
1671
|
case SYS_QZSS:
|
1699
|
-
return
|
1700
|
-
solver.gps.ephemeris_proxy.qzss,
|
1672
|
+
return data.push(
|
1673
|
+
solver.gps.ephemeris_proxy.qzss, DataT::SYSTEM_QZSS);
|
1701
1674
|
case SYS_GLONASS:
|
1702
|
-
return
|
1703
|
-
solver.glonass.solver.satellites,
|
1675
|
+
return data.push(
|
1676
|
+
solver.glonass.solver.satellites, DataT::SYSTEM_GLONASS);
|
1704
1677
|
case SYS_GALILEO:
|
1705
1678
|
case SYS_BEIDOU:
|
1706
1679
|
default:
|
@@ -1708,7 +1681,8 @@ struct SP3 : public SP3_Product<FloatT> {
|
|
1708
1681
|
}
|
1709
1682
|
return false;
|
1710
1683
|
}
|
1711
|
-
|
1684
|
+
template <class DataT, class FloatT>
|
1685
|
+
static bool push(DataT &data, GPS_Solver<FloatT> &solver){
|
1712
1686
|
system_t target[] = {
|
1713
1687
|
SYS_GPS,
|
1714
1688
|
SYS_SBAS,
|
@@ -1718,10 +1692,39 @@ struct SP3 : public SP3_Product<FloatT> {
|
|
1718
1692
|
//SYS_BEIDOU,
|
1719
1693
|
};
|
1720
1694
|
for(std::size_t i(0); i < sizeof(target) / sizeof(target[0]); ++i){
|
1721
|
-
if(!push(solver, target[i])){return false;}
|
1695
|
+
if(!push(data, solver, target[i])){return false;}
|
1722
1696
|
}
|
1723
1697
|
return true;
|
1724
1698
|
}
|
1699
|
+
};
|
1700
|
+
}
|
1701
|
+
|
1702
|
+
%extend SP3 {
|
1703
|
+
%typemap(out) typename SP3_Product<FloatT>::satellite_count_t {
|
1704
|
+
%append_output(SWIG_From(int)($1.gps));
|
1705
|
+
%append_output(SWIG_From(int)($1.sbas));
|
1706
|
+
%append_output(SWIG_From(int)($1.qzss));
|
1707
|
+
%append_output(SWIG_From(int)($1.glonass));
|
1708
|
+
%append_output(SWIG_From(int)($1.galileo));
|
1709
|
+
%append_output(SWIG_From(int)($1.beidou));
|
1710
|
+
}
|
1711
|
+
}
|
1712
|
+
%inline {
|
1713
|
+
template <class FloatT>
|
1714
|
+
struct SP3 : public SP3_Product<FloatT>, PushableData {
|
1715
|
+
int read(const char *fname) {
|
1716
|
+
std::fstream fin(fname, std::ios::in | std::ios::binary);
|
1717
|
+
return SP3_Reader<FloatT>::read_all(fin, *this);
|
1718
|
+
}
|
1719
|
+
typename SP3_Product<FloatT>::satellite_count_t satellites() const {
|
1720
|
+
return SP3_Product<FloatT>::satellite_count();
|
1721
|
+
}
|
1722
|
+
bool push(GPS_Solver<FloatT> &solver, const PushableData::system_t &sys) const {
|
1723
|
+
return PushableData::push((SP3_Product<FloatT> &)*this, solver, sys);
|
1724
|
+
}
|
1725
|
+
bool push(GPS_Solver<FloatT> &solver) const {
|
1726
|
+
return PushableData::push((SP3_Product<FloatT> &)*this, solver);
|
1727
|
+
}
|
1725
1728
|
System_XYZ<FloatT, WGS84> position(
|
1726
1729
|
const int &sat_id, const GPS_Time<FloatT> &t) const {
|
1727
1730
|
return SP3_Product<FloatT>::select(sat_id, t).position(t);
|
@@ -1748,6 +1751,46 @@ struct SP3 : public SP3_Product<FloatT> {
|
|
1748
1751
|
};
|
1749
1752
|
}
|
1750
1753
|
|
1754
|
+
%extend RINEX_Clock {
|
1755
|
+
%typemap(out) typename RINEX_CLK<FloatT>::satellites_t::count_t {
|
1756
|
+
%append_output(SWIG_From(int)($1.gps));
|
1757
|
+
%append_output(SWIG_From(int)($1.sbas));
|
1758
|
+
%append_output(SWIG_From(int)($1.qzss));
|
1759
|
+
%append_output(SWIG_From(int)($1.glonass));
|
1760
|
+
%append_output(SWIG_From(int)($1.galileo));
|
1761
|
+
%append_output(SWIG_From(int)($1.beidou));
|
1762
|
+
}
|
1763
|
+
}
|
1764
|
+
%inline {
|
1765
|
+
template <class FloatT>
|
1766
|
+
struct RINEX_Clock : public RINEX_CLK<FloatT>::satellites_t, PushableData {
|
1767
|
+
typedef typename RINEX_CLK<FloatT>::satellites_t super_t;
|
1768
|
+
int read(const char *fname) {
|
1769
|
+
std::fstream fin(fname, std::ios::in | std::ios::binary);
|
1770
|
+
return RINEX_CLK_Reader<FloatT>::read_all(fin, *this);
|
1771
|
+
}
|
1772
|
+
typename RINEX_CLK<FloatT>::satellites_t::count_t satellites() const {
|
1773
|
+
return RINEX_CLK<FloatT>::satellites_t::count();
|
1774
|
+
}
|
1775
|
+
bool push(GPS_Solver<FloatT> &solver, const PushableData::system_t &sys) const {
|
1776
|
+
return PushableData::push((typename RINEX_CLK<FloatT>::satellites_t &)*this, solver, sys);
|
1777
|
+
}
|
1778
|
+
bool push(GPS_Solver<FloatT> &solver) const {
|
1779
|
+
return PushableData::push((typename RINEX_CLK<FloatT>::satellites_t &)*this, solver);
|
1780
|
+
}
|
1781
|
+
FloatT clock_error(const int &sat_id, const GPS_Time<FloatT> &t) const {
|
1782
|
+
typename super_t::buf_t::const_iterator it(this->buf.find(sat_id));
|
1783
|
+
if(it == this->buf.end()){return super_t::sat_t::unavailable().clock_error(t);}
|
1784
|
+
return it->second.clock_error(t);
|
1785
|
+
}
|
1786
|
+
FloatT clock_error_dot(const int &sat_id, const GPS_Time<FloatT> &t) const {
|
1787
|
+
typename super_t::buf_t::const_iterator it(this->buf.find(sat_id));
|
1788
|
+
if(it == this->buf.end()){return super_t::sat_t::unavailable().clock_error(t);}
|
1789
|
+
return it->second.clock_error_dot(t);
|
1790
|
+
}
|
1791
|
+
};
|
1792
|
+
}
|
1793
|
+
|
1751
1794
|
#undef MAKE_ACCESSOR
|
1752
1795
|
#undef MAKE_VECTOR2ARRAY
|
1753
1796
|
#undef MAKE_ARRAY_INPUT
|
@@ -1776,6 +1819,7 @@ struct SP3 : public SP3_Product<FloatT> {
|
|
1776
1819
|
|
1777
1820
|
%template(RINEX_Observation) RINEX_Observation<type>;
|
1778
1821
|
%template(SP3) SP3<type>;
|
1822
|
+
%template(RINEX_Clock) RINEX_Clock<type>;
|
1779
1823
|
%enddef
|
1780
1824
|
|
1781
1825
|
CONCRETIZE(double);
|
@@ -592,7 +592,6 @@ struct MatrixUtil {
|
|
592
592
|
}
|
593
593
|
static VALUE read(
|
594
594
|
const VALUE &v, const unsigned int &row = 0, const unsigned int &column = 0) {
|
595
|
-
int state;
|
596
595
|
VALUE values[3] = {v, UINT2NUM(row), UINT2NUM(column)};
|
597
596
|
return funcall_throw_if_error(run, reinterpret_cast<VALUE>(values));
|
598
597
|
}
|
@@ -865,7 +864,7 @@ struct MatrixUtil {
|
|
865
864
|
static const ID with_index[] = {
|
866
865
|
rb_intern("map_with_index"), rb_intern("map_with_index!"),
|
867
866
|
rb_intern("collect_with_index"), rb_intern("collect_with_index!")};
|
868
|
-
for(
|
867
|
+
for(std::size_t i(0); i < sizeof(with_index) / sizeof(with_index[0]); ++i){
|
869
868
|
if(id_callee == with_index[i]){
|
870
869
|
return matrix_yield_get_with_index;
|
871
870
|
}
|
data/gps_pvt.gemspec
CHANGED
@@ -53,6 +53,9 @@ Gem::Specification.new do |spec|
|
|
53
53
|
}.flatten
|
54
54
|
}.call
|
55
55
|
|
56
|
+
spec.rdoc_options << '--exclude=ext/ninja-scan-light'
|
57
|
+
spec.extra_rdoc_files = []
|
58
|
+
|
56
59
|
# Uncomment to register a new dependency of your gem
|
57
60
|
# spec.add_dependency "example-gem", "~> 1.0"
|
58
61
|
spec.add_development_dependency "rake"
|
data/lib/gps_pvt/receiver.rb
CHANGED
@@ -410,7 +410,7 @@ class Receiver
|
|
410
410
|
@solver.sbas_space_node.ionospheric_grid_points(prn)].each{|str|
|
411
411
|
$stderr.puts str
|
412
412
|
} if @debug[:SBAS_IGP]
|
413
|
-
end
|
413
|
+
end if t_meas
|
414
414
|
when :GLONASS
|
415
415
|
next unless eph = eph_glonass_list[prn]
|
416
416
|
leap_sec = @solver.gps_space_node.is_valid_utc ?
|
@@ -508,10 +508,10 @@ class Receiver
|
|
508
508
|
{
|
509
509
|
:L1_PSEUDORANGE => [16, 8, "E", proc{|v| (trk_stat & 0x1 == 0x1) ? v : nil}],
|
510
510
|
:L1_PSEUDORANGE_SIGMA => [43, 1, nil, proc{|v|
|
511
|
-
(trk_stat & 0x1 == 0x1) ? (1E-2 * (v[0] & 0xF)) : nil
|
511
|
+
(trk_stat & 0x1 == 0x1) ? (1E-2 * (1 << (v[0] & 0xF))) : nil
|
512
512
|
}],
|
513
513
|
:L1_DOPPLER => [32, 4, "e"],
|
514
|
-
:L1_DOPPLER_SIGMA => [45, 1, nil, proc{|v| 2E-3 * (v[0] & 0xF)}],
|
514
|
+
:L1_DOPPLER_SIGMA => [45, 1, nil, proc{|v| 2E-3 * (1 << (v[0] & 0xF))}],
|
515
515
|
:L1_CARRIER_PHASE => [24, 8, "E", proc{|v| (trk_stat & 0x2 == 0x2) ? v : nil}],
|
516
516
|
:L1_CARRIER_PHASE_SIGMA => [44, 1, nil, proc{|v|
|
517
517
|
(trk_stat & 0x2 == 0x2) ? (0.004 * (v[0] & 0xF)) : nil
|
@@ -651,5 +651,21 @@ class Receiver
|
|
651
651
|
raise "Format error! (Not ANTEX) #{src}" unless applied_items >= 0
|
652
652
|
$stderr.puts "SP3 correction with ANTEX file (%s): %d items have been processed."%[src, applied_items]
|
653
653
|
end
|
654
|
+
|
655
|
+
def attach_rinex_clk(src)
|
656
|
+
fname = Util::get_txt(src)
|
657
|
+
@clk ||= GPS::RINEX_Clock::new
|
658
|
+
read_items = @clk.read(fname)
|
659
|
+
raise "Format error! (Not RINEX clock) #{src}" if read_items < 0
|
660
|
+
$stderr.puts "Read RINEX clock file (%s): %d items."%[src, read_items]
|
661
|
+
sats = @clk.satellites
|
662
|
+
@clk.class.constants.each{|sys|
|
663
|
+
next unless /^SYS_(?!SYSTEMS)(.*)/ =~ sys.to_s
|
664
|
+
idx, sys_name = [@clk.class.const_get(sys), $1]
|
665
|
+
next unless sats[idx] > 0
|
666
|
+
next unless @clk.push(@solver, idx)
|
667
|
+
$stderr.puts "Change clock error source of #{sys_name} to RINEX clock"
|
668
|
+
}
|
669
|
+
end
|
654
670
|
end
|
655
671
|
end
|
data/lib/gps_pvt/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module GPS_PVT
|
4
|
-
VERSION = "0.
|
5
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GPS_PVT
|
4
|
+
VERSION = "0.7.0"
|
5
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gps_pvt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fenrir(M.Naruoka)
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -44,6 +44,7 @@ email:
|
|
44
44
|
- fenrir.naru@gmail.com
|
45
45
|
executables:
|
46
46
|
- gps_pvt
|
47
|
+
- to_ubx
|
47
48
|
extensions:
|
48
49
|
- ext/gps_pvt/extconf.rb
|
49
50
|
extra_rdoc_files: []
|
@@ -57,6 +58,7 @@ files:
|
|
57
58
|
- bin/console
|
58
59
|
- bin/setup
|
59
60
|
- exe/gps_pvt
|
61
|
+
- exe/to_ubx
|
60
62
|
- ext/gps_pvt/Coordinate/Coordinate_wrap.cxx
|
61
63
|
- ext/gps_pvt/GPS/GPS_wrap.cxx
|
62
64
|
- ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx
|
@@ -76,6 +78,7 @@ files:
|
|
76
78
|
- ext/ninja-scan-light/tool/navigation/NTCM.h
|
77
79
|
- ext/ninja-scan-light/tool/navigation/QZSS.h
|
78
80
|
- ext/ninja-scan-light/tool/navigation/RINEX.h
|
81
|
+
- ext/ninja-scan-light/tool/navigation/RINEX_Clock.h
|
79
82
|
- ext/ninja-scan-light/tool/navigation/SBAS.h
|
80
83
|
- ext/ninja-scan-light/tool/navigation/SBAS_Solver.h
|
81
84
|
- ext/ninja-scan-light/tool/navigation/SP3.h
|
@@ -109,7 +112,8 @@ metadata:
|
|
109
112
|
homepage_uri: https://github.com/fenrir-naru/gps_pvt
|
110
113
|
source_code_uri: https://github.com/fenrir-naru/gps_pvt
|
111
114
|
post_install_message:
|
112
|
-
rdoc_options:
|
115
|
+
rdoc_options:
|
116
|
+
- "--exclude=ext/ninja-scan-light"
|
113
117
|
require_paths:
|
114
118
|
- lib
|
115
119
|
required_ruby_version: !ruby/object:Gem::Requirement
|