gps_pvt 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|