gps_pvt 0.6.4 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -126,11 +126,15 @@ class SBAS_SinglePositioning : public SolverBaseT {
126
126
  static float_t clock_error_dot(const void *ptr, const gps_time_t &t_tx) {
127
127
  return sat(ptr).ephemeris().clock_error_dot(t_tx);
128
128
  }
129
+ static float_t range_sigma(const void *ptr, const gps_time_t &t_tx) {
130
+ return sat(ptr).ephemeris().URA;
131
+ }
129
132
  };
130
133
  satellite_t res = {
131
- &(it_sat->second),
134
+ &(it_sat->second), &(it_sat->second), // position, time
132
135
  impl_t::position, impl_t::velocity,
133
- impl_t::clock_error, impl_t::clock_error_dot};
136
+ impl_t::clock_error, impl_t::clock_error_dot,
137
+ &(it_sat->second), impl_t::range_sigma, NULL}; // error model
134
138
  return res;
135
139
  }
136
140
  satellites_t(const space_node_t &sn)
@@ -245,7 +249,7 @@ class SBAS_SinglePositioning : public SolverBaseT {
245
249
  float_t range;
246
250
  range_error_t range_error;
247
251
  if(!this->range(measurement, range, &range_error)){
248
- return res; // If no range entry, return with weight = 0
252
+ return res; // If no range entry, return with sigma = 0
249
253
  }
250
254
 
251
255
  satellite_t sat(select_satellite(prn, time_arrival));
@@ -297,21 +301,29 @@ class SBAS_SinglePositioning : public SolverBaseT {
297
301
 
298
302
  // TODO Fast corrections (2.1.1.4.12)
299
303
 
300
- // TODO Setup weight
301
- if(std::abs(res.range_residual) > _options.residual_mask){
302
- // If residual is too big, gently exclude it by decreasing its weight.
303
- res.weight = 1E-8;
304
- }else{
304
+ // Setup weight
305
+ res.range_sigma = 1E+4; // sufficiently big value, 1E4 [m]
306
+ do{
307
+ // If residual is too big, gently exclude it.
308
+ if(std::abs(res.range_residual) > _options.residual_mask){break;}
305
309
 
306
310
  float_t elv(relative_pos.elevation());
307
311
  if(elv < _options.elevation_mask){
308
- res.weight = 0; // exclude it when elevation is less than threshold
309
- }else{
310
- // elevation weight based on "GPS���p�v���O���~���O" @see GPS_Solver.h
311
- res.weight = std::pow(sin(elv)/0.8, 2);
312
- if(res.weight < 1E-3){res.weight = 1E-3;}
312
+ res.range_sigma = 0; // exclude it when elevation is less than threshold
313
+ break;
313
314
  }
314
- }
315
+
316
+ res.range_sigma = sat.range_sigma(t_tx);
317
+
318
+ /* elevation weight based on "GPS���p�v���O���~���O"
319
+ * elevation[deg] : 90 53 45 30 15 10 5
320
+ * sf_sigma(k) : 0.80 1.00 1.13 1.60 3.09 4.61 9.18
321
+ * weight(k^-2) : 1.56 1.00 0.78 0.39 0.10 0.05 0.01
322
+ */
323
+ static const float_t max_sf(10);
324
+ static const float_t elv_limit(std::asin(0.8/max_sf)); // limit
325
+ res.range_sigma *= (elv > elv_limit) ? (0.8 / sin(elv)) : max_sf;
326
+ }while(false);
315
327
 
316
328
  res.range_corrected = range;
317
329
 
@@ -185,9 +185,10 @@ struct SP3_Product {
185
185
  }
186
186
  };
187
187
  typename GPS_Solver_Base<FloatT>::satellite_t res = {
188
- this,
188
+ this, this, // position, time
189
189
  impl_t::position, impl_t::velocity,
190
- impl_t::clock_error, impl_t::clock_error_dot
190
+ impl_t::clock_error, impl_t::clock_error_dot,
191
+ NULL, NULL, NULL, // TODO error model
191
192
  };
192
193
  return res;
193
194
  }
@@ -248,29 +249,33 @@ struct SP3_Product {
248
249
  }
249
250
 
250
251
  enum system_t {
251
- SYSTEM_GPS = (int)'\0' << 8,
252
- SYSTEM_SBAS = SYSTEM_GPS,
253
- SYSTEM_QZSS = SYSTEM_GPS,
254
- SYSTEM_GLONASS = (int)'R' << 8,
255
- SYSTEM_LEO = (int)'L' << 8,
256
- SYSTEM_GALILEO = (int)'E' << 8,
257
- SYSTEM_BEIDOU = (int)'C' << 8,
258
- SYSTEM_IRNSS = (int)'I' << 8,
252
+ SYSTEM_GPS,
253
+ SYSTEM_SBAS,
254
+ SYSTEM_QZSS,
255
+ SYSTEM_GLONASS,
256
+ SYSTEM_LEO,
257
+ SYSTEM_GALILEO,
258
+ SYSTEM_BEIDOU,
259
+ SYSTEM_IRNSS,
260
+ NUM_OF_SYSTEMS,
259
261
  };
260
262
 
261
- #define gen_func(sys) \
262
- static typename GPS_Solver_Base<FloatT>::satellite_t select_ ## sys( \
263
- const void *ptr, const int &prn, const GPS_Time<FloatT> &receiver_time){ \
264
- return reinterpret_cast<const SP3_Product<FloatT> *>(ptr) \
265
- ->select(prn + SYSTEM_ ## sys, receiver_time); \
266
- }
267
- gen_func(GPS);
268
- gen_func(GLONASS);
269
- gen_func(LEO);
270
- gen_func(GALILEO);
271
- gen_func(BEIDOU);
272
- gen_func(IRNSS);
273
- #undef gen_fun
263
+ static const int offset_list[NUM_OF_SYSTEMS];
264
+
265
+ protected:
266
+
267
+ mutable struct per_system_t {
268
+ const SP3_Product<FloatT> *product;
269
+ system_t sys;
270
+ } per_system[NUM_OF_SYSTEMS];
271
+
272
+ static typename GPS_Solver_Base<FloatT>::satellite_t select(
273
+ const void *ptr, const int &prn, const GPS_Time<FloatT> &receiver_time){
274
+ const per_system_t *ptr_impl(reinterpret_cast<const per_system_t *>(ptr));
275
+ return ptr_impl->product->select((prn & 0xFF) + offset_list[ptr_impl->sys], receiver_time);
276
+ }
277
+
278
+ public:
274
279
 
275
280
  /**
276
281
  * push SP3 product to satellite selector
@@ -281,19 +286,11 @@ static typename GPS_Solver_Base<FloatT>::satellite_t select_ ## sys( \
281
286
  */
282
287
  template <class SelectorT>
283
288
  bool push(SelectorT &slct, const system_t &sys = SYSTEM_GPS) const {
284
- switch(sys){
285
- case SYSTEM_GPS: // SBAS and QZSS are identically treated as GPS.
286
- //case SYSTEM_SBAS:
287
- //case SYSTEM_QZSS:
288
- slct.impl_select = select_GPS; break;
289
- case SYSTEM_GLONASS: slct.impl_select = select_GLONASS; break;
290
- case SYSTEM_LEO: slct.impl_select = select_LEO; break;
291
- case SYSTEM_GALILEO: slct.impl_select = select_GALILEO; break;
292
- case SYSTEM_BEIDOU: slct.impl_select = select_BEIDOU; break;
293
- case SYSTEM_IRNSS: slct.impl_select = select_IRNSS; break;
294
- default: return false;
295
- }
296
- slct.impl = this;
289
+ if(sys >= NUM_OF_SYSTEMS){return false;}
290
+ per_system[sys].product = this;
291
+ per_system[sys].sys = sys;
292
+ slct.impl_select = select;
293
+ slct.impl = &per_system[sys];
297
294
  return true;
298
295
  }
299
296
 
@@ -305,19 +302,19 @@ static typename GPS_Solver_Base<FloatT>::satellite_t select_ ## sys( \
305
302
  for(typename satellites_t::const_iterator
306
303
  it(satellites.begin()), it_end(satellites.end());
307
304
  it != it_end; ++it){
308
- switch(it->first & 0xFF00){
309
- case SYSTEM_GPS: {
305
+ switch((char)(it->first >> 8)){
306
+ case '\0': {
310
307
  int id(it->first & 0xFF);
311
308
  if(id < 100){++res.gps;}
312
309
  else if(id < 192){++res.sbas;}
313
310
  else{++res.qzss;}
314
311
  break;
315
312
  }
316
- case SYSTEM_GLONASS: ++res.glonass; break;
317
- case SYSTEM_LEO: ++res.leo; break;
318
- case SYSTEM_GALILEO: ++res.galileo; break;
319
- case SYSTEM_BEIDOU: ++res.beidou; break;
320
- case SYSTEM_IRNSS: ++res.irnss; break;
313
+ case 'R': ++res.glonass; break;
314
+ case 'L': ++res.leo; break;
315
+ case 'E': ++res.galileo; break;
316
+ case 'C': ++res.beidou; break;
317
+ case 'I': ++res.irnss; break;
321
318
  default: ++res.unknown; break;
322
319
  }
323
320
  }
@@ -335,6 +332,17 @@ const typename SP3_Product<FloatT>::per_satellite_t::interpolate_cnd_t
335
332
  60 * 60 * 2,
336
333
  };
337
334
 
335
+ template <class FloatT>
336
+ const int SP3_Product<FloatT>::offset_list[NUM_OF_SYSTEMS] = {
337
+ 0, 0, 0, // GPS, SBAS, QZSS
338
+ ((int)'R' << 8), // GLONASS
339
+ ((int)'L' << 8), // LEO
340
+ ((int)'E' << 8), // GALILEO
341
+ ((int)'C' << 8), // BEIDOU
342
+ ((int)'I' << 8), // IRNSS
343
+ };
344
+
345
+
338
346
  template <class FloatT>
339
347
  class SP3_Reader {
340
348
  protected:
@@ -125,9 +125,9 @@ struct BitArray {
125
125
  return (unsigned int)res;
126
126
  }
127
127
  }
128
- std::vector<int> indices_one() const {
128
+ std::vector<int> indices_one(const int &offset = 0) const {
129
129
  std::vector<int> res;
130
- int idx(0);
130
+ int idx(offset);
131
131
  static const const_div_t<bits_per_addr> qr(MAX_SIZE);
132
132
  int rem(qr.rem), i(0);
133
133
  for(; i < qr.quot; ++i, idx += bits_per_addr){
@@ -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
  };
@@ -1132,10 +1124,13 @@ struct GPS_RangeCorrector
1132
1124
  static const int prop_items(sizeof(res.values) / sizeof(res.values[0]));
1133
1125
  VALUE hook(rb_hash_lookup(hooks, key));
1134
1126
  if(NIL_P(hook)){break;}
1127
+ FloatT weight((res.prop.range_sigma > 0)
1128
+ ? (1. / std::pow(res.prop.range_sigma, 2)) // weight=1/(sigma^2)
1129
+ : res.prop.range_sigma);
1135
1130
  VALUE values[] = {
1136
1131
  SWIG_From(int)(prn), // prn
1137
1132
  rb_ary_new_from_args(prop_items, // relative_property
1138
- swig::from(res.prop.weight),
1133
+ swig::from(weight),
1139
1134
  swig::from(res.prop.range_corrected),
1140
1135
  swig::from(res.prop.range_residual),
1141
1136
  swig::from(res.prop.rate_relative_neg),
@@ -1167,6 +1162,9 @@ struct GPS_RangeCorrector
1167
1162
  .append(" @ [").append(std::to_string(i)).append("]"));
1168
1163
  }
1169
1164
  }
1165
+ if(res.values[0] > 0){
1166
+ res.values[0] = std::pow(1. / res.values[0], 0.5); // sigma=(1/weight)^0.5
1167
+ }
1170
1168
  }while(false);
1171
1169
  #endif
1172
1170
  return res.prop;
@@ -1206,7 +1204,10 @@ struct GPS_RangeCorrector
1206
1204
  if(!res.is_available()){
1207
1205
  static const VALUE key(ID2SYM(rb_intern("relative_property")));
1208
1206
  VALUE hook(rb_hash_lookup(hooks, key));
1209
- if(!NIL_P(hook)){res.impl = this;}
1207
+ if(!NIL_P(hook)){
1208
+ if(!res.impl_xyz){res.impl_xyz = this;}
1209
+ if(!res.impl_t){res.impl_t = this;}
1210
+ }
1210
1211
  }
1211
1212
  #endif
1212
1213
  return res;
@@ -1361,6 +1362,28 @@ struct GPS_RangeCorrector
1361
1362
  return self->update_correction(true, hash);
1362
1363
  }
1363
1364
  #endif
1365
+ #ifdef SWIGRUBY
1366
+ %typemap(out) typename super_t::options_t {
1367
+ VALUE res(rb_hash_new());
1368
+ rb_hash_aset(res, ID2SYM(rb_intern("skip_exclusion")), SWIG_From(bool)($1.skip_exclusion));
1369
+ %set_output(res);
1370
+ }
1371
+ #endif
1372
+ %rename("options") get_options;
1373
+ typename super_t::options_t get_options() const {
1374
+ return self->available_options();
1375
+ }
1376
+ %rename("options=") set_options;
1377
+ typename super_t::options_t set_options(SWIG_Object obj) {
1378
+ GPS_Solver<FloatT>::super_t::options_t opt(self->available_options());
1379
+ #ifdef SWIGRUBY
1380
+ if(!RB_TYPE_P(obj, T_HASH)){SWIG_exception(SWIG_TypeError, "Hash is expected");}
1381
+ SWIG_AsVal(bool)(
1382
+ rb_hash_lookup(obj, ID2SYM(rb_intern("skip_exclusion"))),
1383
+ &opt.skip_exclusion);
1384
+ #endif
1385
+ return self->update_options(opt);
1386
+ }
1364
1387
  }
1365
1388
  %inline {
1366
1389
  template <class FloatT>
@@ -1653,31 +1676,8 @@ template <class FloatT>
1653
1676
  struct RINEX_Observation {};
1654
1677
  }
1655
1678
 
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
1679
  %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
- }
1680
+ struct PushableData {
1681
1681
  enum system_t {
1682
1682
  SYS_GPS,
1683
1683
  SYS_SBAS,
@@ -1687,20 +1687,21 @@ struct SP3 : public SP3_Product<FloatT> {
1687
1687
  SYS_BEIDOU,
1688
1688
  SYS_SYSTEMS,
1689
1689
  };
1690
- bool push(GPS_Solver<FloatT> &solver, const system_t &sys) const {
1690
+ template <class DataT, class FloatT>
1691
+ static bool push(DataT &data, GPS_Solver<FloatT> &solver, const system_t &sys){
1691
1692
  switch(sys){
1692
1693
  case SYS_GPS:
1693
- return SP3_Product<FloatT>::push(
1694
- solver.gps.ephemeris_proxy.gps, SP3_Product<FloatT>::SYSTEM_GPS);
1694
+ return data.push(
1695
+ solver.gps.ephemeris_proxy.gps, DataT::SYSTEM_GPS);
1695
1696
  case SYS_SBAS:
1696
- return SP3_Product<FloatT>::push(
1697
- solver.sbas.solver.satellites, SP3_Product<FloatT>::SYSTEM_SBAS);
1697
+ return data.push(
1698
+ solver.sbas.solver.satellites, DataT::SYSTEM_SBAS);
1698
1699
  case SYS_QZSS:
1699
- return SP3_Product<FloatT>::push(
1700
- solver.gps.ephemeris_proxy.qzss, SP3_Product<FloatT>::SYSTEM_QZSS);
1700
+ return data.push(
1701
+ solver.gps.ephemeris_proxy.qzss, DataT::SYSTEM_QZSS);
1701
1702
  case SYS_GLONASS:
1702
- return SP3_Product<FloatT>::push(
1703
- solver.glonass.solver.satellites, SP3_Product<FloatT>::SYSTEM_GLONASS);
1703
+ return data.push(
1704
+ solver.glonass.solver.satellites, DataT::SYSTEM_GLONASS);
1704
1705
  case SYS_GALILEO:
1705
1706
  case SYS_BEIDOU:
1706
1707
  default:
@@ -1708,7 +1709,8 @@ struct SP3 : public SP3_Product<FloatT> {
1708
1709
  }
1709
1710
  return false;
1710
1711
  }
1711
- bool push(GPS_Solver<FloatT> &solver) const {
1712
+ template <class DataT, class FloatT>
1713
+ static bool push(DataT &data, GPS_Solver<FloatT> &solver){
1712
1714
  system_t target[] = {
1713
1715
  SYS_GPS,
1714
1716
  SYS_SBAS,
@@ -1718,10 +1720,39 @@ struct SP3 : public SP3_Product<FloatT> {
1718
1720
  //SYS_BEIDOU,
1719
1721
  };
1720
1722
  for(std::size_t i(0); i < sizeof(target) / sizeof(target[0]); ++i){
1721
- if(!push(solver, target[i])){return false;}
1723
+ if(!push(data, solver, target[i])){return false;}
1722
1724
  }
1723
1725
  return true;
1724
1726
  }
1727
+ };
1728
+ }
1729
+
1730
+ %extend SP3 {
1731
+ %typemap(out) typename SP3_Product<FloatT>::satellite_count_t {
1732
+ %append_output(SWIG_From(int)($1.gps));
1733
+ %append_output(SWIG_From(int)($1.sbas));
1734
+ %append_output(SWIG_From(int)($1.qzss));
1735
+ %append_output(SWIG_From(int)($1.glonass));
1736
+ %append_output(SWIG_From(int)($1.galileo));
1737
+ %append_output(SWIG_From(int)($1.beidou));
1738
+ }
1739
+ }
1740
+ %inline {
1741
+ template <class FloatT>
1742
+ struct SP3 : public SP3_Product<FloatT>, PushableData {
1743
+ int read(const char *fname) {
1744
+ std::fstream fin(fname, std::ios::in | std::ios::binary);
1745
+ return SP3_Reader<FloatT>::read_all(fin, *this);
1746
+ }
1747
+ typename SP3_Product<FloatT>::satellite_count_t satellites() const {
1748
+ return SP3_Product<FloatT>::satellite_count();
1749
+ }
1750
+ bool push(GPS_Solver<FloatT> &solver, const PushableData::system_t &sys) const {
1751
+ return PushableData::push((SP3_Product<FloatT> &)*this, solver, sys);
1752
+ }
1753
+ bool push(GPS_Solver<FloatT> &solver) const {
1754
+ return PushableData::push((SP3_Product<FloatT> &)*this, solver);
1755
+ }
1725
1756
  System_XYZ<FloatT, WGS84> position(
1726
1757
  const int &sat_id, const GPS_Time<FloatT> &t) const {
1727
1758
  return SP3_Product<FloatT>::select(sat_id, t).position(t);
@@ -1748,6 +1779,46 @@ struct SP3 : public SP3_Product<FloatT> {
1748
1779
  };
1749
1780
  }
1750
1781
 
1782
+ %extend RINEX_Clock {
1783
+ %typemap(out) typename RINEX_CLK<FloatT>::satellites_t::count_t {
1784
+ %append_output(SWIG_From(int)($1.gps));
1785
+ %append_output(SWIG_From(int)($1.sbas));
1786
+ %append_output(SWIG_From(int)($1.qzss));
1787
+ %append_output(SWIG_From(int)($1.glonass));
1788
+ %append_output(SWIG_From(int)($1.galileo));
1789
+ %append_output(SWIG_From(int)($1.beidou));
1790
+ }
1791
+ }
1792
+ %inline {
1793
+ template <class FloatT>
1794
+ struct RINEX_Clock : public RINEX_CLK<FloatT>::satellites_t, PushableData {
1795
+ typedef typename RINEX_CLK<FloatT>::satellites_t super_t;
1796
+ int read(const char *fname) {
1797
+ std::fstream fin(fname, std::ios::in | std::ios::binary);
1798
+ return RINEX_CLK_Reader<FloatT>::read_all(fin, *this);
1799
+ }
1800
+ typename RINEX_CLK<FloatT>::satellites_t::count_t satellites() const {
1801
+ return RINEX_CLK<FloatT>::satellites_t::count();
1802
+ }
1803
+ bool push(GPS_Solver<FloatT> &solver, const PushableData::system_t &sys) const {
1804
+ return PushableData::push((typename RINEX_CLK<FloatT>::satellites_t &)*this, solver, sys);
1805
+ }
1806
+ bool push(GPS_Solver<FloatT> &solver) const {
1807
+ return PushableData::push((typename RINEX_CLK<FloatT>::satellites_t &)*this, solver);
1808
+ }
1809
+ FloatT clock_error(const int &sat_id, const GPS_Time<FloatT> &t) const {
1810
+ typename super_t::buf_t::const_iterator it(this->buf.find(sat_id));
1811
+ if(it == this->buf.end()){return super_t::sat_t::unavailable().clock_error(t);}
1812
+ return it->second.clock_error(t);
1813
+ }
1814
+ FloatT clock_error_dot(const int &sat_id, const GPS_Time<FloatT> &t) const {
1815
+ typename super_t::buf_t::const_iterator it(this->buf.find(sat_id));
1816
+ if(it == this->buf.end()){return super_t::sat_t::unavailable().clock_error(t);}
1817
+ return it->second.clock_error_dot(t);
1818
+ }
1819
+ };
1820
+ }
1821
+
1751
1822
  #undef MAKE_ACCESSOR
1752
1823
  #undef MAKE_VECTOR2ARRAY
1753
1824
  #undef MAKE_ARRAY_INPUT
@@ -1776,6 +1847,7 @@ struct SP3 : public SP3_Product<FloatT> {
1776
1847
 
1777
1848
  %template(RINEX_Observation) RINEX_Observation<type>;
1778
1849
  %template(SP3) SP3<type>;
1850
+ %template(RINEX_Clock) RINEX_Clock<type>;
1779
1851
  %enddef
1780
1852
 
1781
1853
  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
  }