gps_pvt 0.6.4 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }