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.
@@ -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