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.
@@ -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
- static const struct interpolate_cnd_t {
66
- std::size_t max_epochs; ///< maximum number of epochs used for interpolation
67
- FloatT max_delta_t; ///< maximum acceptable absolute time difference between t and epoch
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() : t0(0, 0), updated_full_cnd(false) {}
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
- FloatT t_diff(t0 - t);
92
- if((!force_update)
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
- template <class Ty, class Ty_Array>
127
- Ty interpolate(
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 interpolate(t, xyz, derivative);
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 interpolate(t, clk, derivative);
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.updated_full_cnd;
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 = (int)'\0' << 8,
305
- SYSTEM_SBAS = SYSTEM_GPS,
306
- SYSTEM_QZSS = SYSTEM_GPS,
307
- SYSTEM_GLONASS = (int)'R' << 8,
308
- SYSTEM_LEO = (int)'L' << 8,
309
- SYSTEM_GALILEO = (int)'E' << 8,
310
- SYSTEM_BEIDOU = (int)'C' << 8,
311
- SYSTEM_IRNSS = (int)'I' << 8,
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
- #define gen_func(sys) \
315
- static typename GPS_Solver_Base<FloatT>::satellite_t select_ ## sys( \
316
- const void *ptr, const int &prn, const GPS_Time<FloatT> &receiver_time){ \
317
- return reinterpret_cast<const SP3_Product<FloatT> *>(ptr) \
318
- ->select(prn + SYSTEM_ ## sys, receiver_time); \
319
- }
320
- gen_func(GPS);
321
- gen_func(GLONASS);
322
- gen_func(LEO);
323
- gen_func(GALILEO);
324
- gen_func(BEIDOU);
325
- gen_func(IRNSS);
326
- #undef gen_fun
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
- switch(sys){
338
- case SYSTEM_GPS: // SBAS and QZSS are identically treated as GPS.
339
- //case SYSTEM_SBAS:
340
- //case SYSTEM_QZSS:
341
- slct.impl_select = select_GPS; break;
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 & 0xFF00){
362
- case SYSTEM_GPS: {
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 SYSTEM_GLONASS: ++res.glonass; break;
370
- case SYSTEM_LEO: ++res.leo; break;
371
- case SYSTEM_GALILEO: ++res.galileo; break;
372
- case SYSTEM_BEIDOU: ++res.beidou; break;
373
- case SYSTEM_IRNSS: ++res.irnss; break;
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, // max_epochs
385
- 60 * 60 * 2, // max_delta_t, default is 2 hr = 15 min interval records; (2 hr * 2 / (9 - 1) = 15 min)
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[4]) %{
232
- $1 = temp;
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($1[i]));
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)){res.impl = this;}
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
- template <class FloatT>
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
- bool push(GPS_Solver<FloatT> &solver, const system_t &sys) const {
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 SP3_Product<FloatT>::push(
1694
- solver.gps.ephemeris_proxy.gps, SP3_Product<FloatT>::SYSTEM_GPS);
1666
+ return data.push(
1667
+ solver.gps.ephemeris_proxy.gps, DataT::SYSTEM_GPS);
1695
1668
  case SYS_SBAS:
1696
- return SP3_Product<FloatT>::push(
1697
- solver.sbas.solver.satellites, SP3_Product<FloatT>::SYSTEM_SBAS);
1669
+ return data.push(
1670
+ solver.sbas.solver.satellites, DataT::SYSTEM_SBAS);
1698
1671
  case SYS_QZSS:
1699
- return SP3_Product<FloatT>::push(
1700
- solver.gps.ephemeris_proxy.qzss, SP3_Product<FloatT>::SYSTEM_QZSS);
1672
+ return data.push(
1673
+ solver.gps.ephemeris_proxy.qzss, DataT::SYSTEM_QZSS);
1701
1674
  case SYS_GLONASS:
1702
- return SP3_Product<FloatT>::push(
1703
- solver.glonass.solver.satellites, SP3_Product<FloatT>::SYSTEM_GLONASS);
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
- bool push(GPS_Solver<FloatT> &solver) const {
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(int i(0); i < sizeof(with_index) / sizeof(with_index[0]); ++i){
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"
@@ -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
@@ -1,5 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
- module GPS_PVT
4
- VERSION = "0.6.2"
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.6.2
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-03 00:00:00.000000000 Z
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