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.
@@ -3002,7 +3002,6 @@ struct MatrixUtil {
3002
3002
  }
3003
3003
  static VALUE read(
3004
3004
  const VALUE &v, const unsigned int &row = 0, const unsigned int &column = 0) {
3005
- int state;
3006
3005
  VALUE values[3] = {v, UINT2NUM(row), UINT2NUM(column)};
3007
3006
  return funcall_throw_if_error(run, reinterpret_cast<VALUE>(values));
3008
3007
  }
@@ -3355,7 +3354,7 @@ SWIGINTERN std::string Matrix_Frozen_Sl_double_Sc_Array2D_Dense_Sl_double_Sg__Sc
3355
3354
  static const ID with_index[] = {
3356
3355
  rb_intern("map_with_index"), rb_intern("map_with_index!"),
3357
3356
  rb_intern("collect_with_index"), rb_intern("collect_with_index!")};
3358
- for(int i(0); i < sizeof(with_index) / sizeof(with_index[0]); ++i){
3357
+ for(std::size_t i(0); i < sizeof(with_index) / sizeof(with_index[0]); ++i){
3359
3358
  if(id_callee == with_index[i]){
3360
3359
  return matrix_yield_get_with_index;
3361
3360
  }
@@ -3829,7 +3828,7 @@ SWIGINTERN std::string Matrix_Frozen_Sl_Complex_Sl_double_Sg__Sc_Array2D_Dense_S
3829
3828
  static const ID with_index[] = {
3830
3829
  rb_intern("map_with_index"), rb_intern("map_with_index!"),
3831
3830
  rb_intern("collect_with_index"), rb_intern("collect_with_index!")};
3832
- for(int i(0); i < sizeof(with_index) / sizeof(with_index[0]); ++i){
3831
+ for(std::size_t i(0); i < sizeof(with_index) / sizeof(with_index[0]); ++i){
3833
3832
  if(id_callee == with_index[i]){
3834
3833
  return matrix_yield_get_with_index;
3835
3834
  }
@@ -34,6 +34,9 @@
34
34
 
35
35
  #include <cstddef>
36
36
  #include <vector>
37
+ #include <map>
38
+ #include <algorithm>
39
+ #include <stdexcept>
37
40
 
38
41
  /*
39
42
  * perform Neville's interpolation (with derivative)
@@ -118,4 +121,107 @@ Ty interpolate_Neville(
118
121
  return interpolate_Neville(x_given, y_given, x, y_buf, n)[0];
119
122
  }
120
123
 
124
+ template <class Tx, class Ty, class Tx_delta = Tx>
125
+ struct InterpolatableSet {
126
+ struct condition_t {
127
+ std::size_t max_x_size; ///< maximum number of data used for interpolation
128
+ Tx_delta max_dx_range; ///< maximum acceptable absolute difference between x and x0
129
+ };
130
+
131
+ typedef typename std::vector<std::pair<Tx, Ty> > buffer_t;
132
+ buffer_t buf;
133
+ Tx x0, x_lower, x_upper;
134
+ std::vector<Tx_delta> dx;
135
+ bool ready;
136
+
137
+ InterpolatableSet() : x0(), dx(), ready(false) {}
138
+
139
+ /**
140
+ * update interpolation source
141
+ * @param force_update If true, update is forcibly performed irrespective of current state
142
+ * @param cnd condition for source data selection
143
+ */
144
+ InterpolatableSet &update(
145
+ const Tx &x, const std::map<Tx, Ty> &xy_table,
146
+ const condition_t &cnd,
147
+ const bool &force_update = false){
148
+
149
+ do{
150
+ if(force_update){break;}
151
+ if(dx.size() <= 2){break;}
152
+ if(x < x_lower){break;}
153
+ if(x > x_upper){break;}
154
+ return *this;
155
+ }while(false);
156
+
157
+ // If the 1st and 2nd nearest items are changed, then recalculate interpolation targets.
158
+ struct {
159
+ const Tx &x_base;
160
+ bool operator()(
161
+ const typename std::map<Tx, Ty>::value_type &rhs,
162
+ const typename std::map<Tx, Ty>::value_type &lhs) const {
163
+ return std::abs(rhs.first - x_base) < std::abs(lhs.first - x_base);
164
+ }
165
+ } cmp = {(x0 = x)};
166
+
167
+ buf.resize(cnd.max_x_size);
168
+ dx.clear();
169
+ // extract x where x0-dx_range <= x <= x0+dx_range, then sort by ascending order of |x-x0|
170
+ for(typename buffer_t::const_iterator
171
+ it(buf.begin()),
172
+ it_end(std::partial_sort_copy(
173
+ xy_table.lower_bound(x - cnd.max_dx_range),
174
+ xy_table.upper_bound(x + cnd.max_dx_range),
175
+ buf.begin(), buf.end(), cmp));
176
+ it != it_end; ++it){
177
+ dx.push_back(it->first - x0);
178
+ }
179
+ if(dx.size() >= 2){ // calculate a necessary condition to update samples for new x
180
+ // According to Nth nearest points, x range in which the order of extracted samples
181
+ // is retained can be calculated.
182
+ bool ascending(buf[0].first <= buf[1].first);
183
+ Tx &xa(ascending ? x_lower : x_upper), &xb(ascending ? x_upper : x_lower);
184
+ xa = x0;
185
+ for(std::size_t i(2); i < buf.size(); ++i){
186
+ if(ascending ? (dx[1] <= dx[i]) : (dx[1] >= dx[i])){continue;}
187
+ xa = x0 + (dx[1] + dx[i]) / 2;
188
+ break;
189
+ }
190
+ xb = x0 + (dx[0] + dx[1]) / 2;
191
+ }
192
+ ready = (dx.size() >= cnd.max_x_size);
193
+
194
+ return *this;
195
+ }
196
+
197
+ template <class Ty2, class Ty2_Iterator>
198
+ Ty2 interpolate2(
199
+ const Tx &x, const Ty2_Iterator &y,
200
+ Ty2 *derivative = NULL) const {
201
+ int order(dx.size() - 1);
202
+ do{
203
+ if(order > 0){break;}
204
+ if((order == 0) && (!derivative)){return y[0];}
205
+ throw std::range_error("Insufficient records for interpolation");
206
+ }while(false);
207
+ std::vector<Ty2> y_buf(order), dy_buf(order);
208
+ interpolate_Neville(
209
+ dx, y, x - x0, y_buf, order,
210
+ &dy_buf, derivative ? 1 : 0);
211
+ if(derivative){*derivative = dy_buf[0];}
212
+ return y_buf[0];
213
+ }
214
+
215
+ Ty interpolate(const Tx &x, Ty *derivative = NULL) const {
216
+ struct second_iterator : public buffer_t::const_iterator {
217
+ second_iterator(const typename buffer_t::const_iterator &it)
218
+ : buffer_t::const_iterator(it) {}
219
+ const Ty &operator[](const int &n) const {
220
+ return buffer_t::const_iterator::operator[](n).second;
221
+ }
222
+ } y_it(buf.begin());
223
+ return interpolate2(x, y_it, derivative);
224
+ }
225
+ };
226
+
121
227
  #endif /* __INTERPOLATE_H__ */
@@ -604,7 +604,7 @@ class ANTEX_Reader {
604
604
  typedef typename ANTEX_Product<FloatT>::antenna_t antenna_t;
605
605
  antenna_t *antenna;
606
606
  typedef typename ANTEX_Product<FloatT>::per_freq_t per_freq_t;
607
- per_freq_t *per_freq;
607
+ per_freq_t *per_freq(NULL); // NULL fot suppression of GCC uninitialized variable warning
608
608
 
609
609
  while(src.has_next()){
610
610
  parsed_t parsed(src.parse_line());
@@ -133,7 +133,7 @@ class GLONASS_SinglePositioning : public SolverBaseT {
133
133
  }
134
134
  };
135
135
  satellite_t res = {
136
- &(it_sat->second),
136
+ &(it_sat->second), &(it_sat->second),
137
137
  impl_t::position, impl_t::velocity,
138
138
  impl_t::clock_error, impl_t::clock_error_dot};
139
139
  return res;
@@ -157,7 +157,7 @@ class GPS_SinglePositioning : public SolverBaseT {
157
157
  }
158
158
  };
159
159
  satellite_t res = {
160
- &(it_sat->second),
160
+ &(it_sat->second), &(it_sat->second),
161
161
  impl_t::position, impl_t::velocity,
162
162
  impl_t::clock_error, impl_t::clock_error_dot};
163
163
  return res;
@@ -227,13 +227,13 @@ struct GPS_Solver_Base {
227
227
  }
228
228
 
229
229
  struct satellite_t {
230
- const void *impl;
230
+ const void *impl_xyz, *impl_t; ///< pointer to actual implementation to return position and clock error
231
231
  xyz_t (*impl_position)(const void *, const gps_time_t &, const float_t &);
232
232
  xyz_t (*impl_velocity)(const void *, const gps_time_t &, const float_t &);
233
233
  float_t (*impl_clock_error)(const void *, const gps_time_t &);
234
234
  float_t (*impl_clock_error_dot)(const void *, const gps_time_t &);
235
235
  inline bool is_available() const {
236
- return impl != NULL;
236
+ return (impl_xyz != NULL) && (impl_t != NULL);
237
237
  }
238
238
  /**
239
239
  * Return satellite position at the transmission time in EFEC.
@@ -244,28 +244,28 @@ struct GPS_Solver_Base {
244
244
  * that is, the transmission time added by the transit time.
245
245
  */
246
246
  inline xyz_t position(const gps_time_t &t_tx, const float_t &dt_transit = 0) const {
247
- return impl_position(impl, t_tx, dt_transit);
247
+ return impl_position(impl_xyz, t_tx, dt_transit);
248
248
  }
249
249
  /**
250
250
  * Return satellite velocity at the transmission time in EFEC.
251
251
  * @see position
252
252
  */
253
253
  inline xyz_t velocity(const gps_time_t &t_tx, const float_t &dt_transit = 0) const {
254
- return impl_velocity(impl, t_tx, dt_transit);
254
+ return impl_velocity(impl_xyz, t_tx, dt_transit);
255
255
  }
256
256
  /**
257
257
  * Return satellite clock error [s] at the transmission time.
258
258
  * @param t_tx transmission time
259
259
  */
260
260
  inline float_t clock_error(const gps_time_t &t_tx) const {
261
- return impl_clock_error(impl, t_tx);
261
+ return impl_clock_error(impl_t, t_tx);
262
262
  }
263
263
  /**
264
264
  * Return satellite clock error derivative [s/s] at the transmission time.
265
265
  * @param t_tx transmission time
266
266
  */
267
267
  inline float_t clock_error_dot(const gps_time_t &t_tx) const {
268
- return impl_clock_error_dot(impl, t_tx);
268
+ return impl_clock_error_dot(impl_t, t_tx);
269
269
  }
270
270
  static const satellite_t &unavailable() {
271
271
  struct impl_t {
@@ -276,7 +276,7 @@ struct GPS_Solver_Base {
276
276
  return float_t(0);
277
277
  }
278
278
  };
279
- static const satellite_t res = {NULL, impl_t::v3, impl_t::v3, impl_t::v, impl_t::v};
279
+ static const satellite_t res = {NULL, NULL, impl_t::v3, impl_t::v3, impl_t::v, impl_t::v};
280
280
  return res;
281
281
  }
282
282
  };
@@ -143,16 +143,17 @@ class MagneticFieldGeneric {
143
143
  field_components_res_t res;
144
144
 
145
145
  // @see http://mooring.ucsd.edu/software/matlab/mfiles/toolbox/geo/IGRF/geomag60.c
146
+ // @see https://web.archive.org/web/20171008182325/http://mooring.ucsd.edu/software/matlab/mfiles/toolbox/geo/IGRF/geomag60.c
146
147
 
147
- const FloatT slat(sin_geocentric_latitude);
148
- const FloatT clat(cos_geocentric_latitude);
148
+ const FloatT &slat(sin_geocentric_latitude);
149
+ const FloatT &clat(cos_geocentric_latitude);
149
150
 
150
151
  FloatT sl[13] = {sin(longitude_rad)};
151
152
  FloatT cl[13] = {cos(longitude_rad)};
152
153
 
153
154
  res.north = res.east = res.down = 0;
154
155
 
155
- FloatT aa, bb, cc, rr;
156
+ FloatT aa, bb, cc, rr(0); // rr(0) for suppression of warning of use of uninitialized variable
156
157
 
157
158
  aa = sqrt(3.0);
158
159
  FloatT p[118] = {
@@ -66,7 +66,7 @@ class NTCM_GL_Generic {
66
66
  return cos_Chi_star3
67
67
  + (C[0] * std::cos(v_D)
68
68
  + C[1] * std::cos(v_SD) + C[2] * std::sin(v_SD)
69
- + C[3] * std::cos(v_TD) + C[4] * std::sin(v_TD)) * cos_Chi_star;
69
+ + C[3] * std::cos(v_TD) + C[4] * std::sin(v_TD)) * cos_Chi_star2;
70
70
  }
71
71
 
72
72
  static const float_t doy_A, doy_SA;
@@ -76,6 +76,7 @@ class RINEX_Reader {
76
76
  FTYPE_OBSERVATION,
77
77
  FTYPE_NAVIGATION,
78
78
  FTYPE_METEOROLOGICAL,
79
+ FTYPE_CLOCK,
79
80
  } file_type;
80
81
  enum sat_system_t {
81
82
  SYS_UNKNOWN = 0,
@@ -89,6 +90,19 @@ class RINEX_Reader {
89
90
  SYS_TRANSIT,
90
91
  SYS_MIXED,
91
92
  } sat_system;
93
+ static sat_system_t char2sys_v3(const char &c){
94
+ switch(c){
95
+ case 'G': return SYS_GPS;
96
+ case 'R': return SYS_GLONASS;
97
+ case 'E': return SYS_GALILEO;
98
+ case 'J': return SYS_QZSS;
99
+ case 'C': return SYS_BDS;
100
+ case 'I': return SYS_IRNSS;
101
+ case 'S': return SYS_SBAS;
102
+ case 'M': return SYS_MIXED;
103
+ }
104
+ return SYS_UNKNOWN;
105
+ }
92
106
  version_type_t(
93
107
  const int &ver = 0, const file_type_t &ftype = FTYPE_UNKNOWN, const sat_system_t &sys = SYS_UNKNOWN)
94
108
  : version(ver), file_type(ftype), sat_system(sys) {}
@@ -105,7 +119,7 @@ class RINEX_Reader {
105
119
  : src(in), _has_next(false),
106
120
  version_type() {
107
121
  if(src.fail()){return;}
108
-
122
+
109
123
  char buf[256];
110
124
 
111
125
  // Read header
@@ -135,7 +149,13 @@ class RINEX_Reader {
135
149
  version_type.parse(it->second.front());
136
150
  break;
137
151
  }
138
-
152
+ }
153
+ RINEX_Reader(
154
+ std::istream &in,
155
+ void (RINEX_Reader::*read_header)())
156
+ : src(in), _has_next(false),
157
+ version_type() {
158
+ (this->*read_header)();
139
159
  }
140
160
  virtual ~RINEX_Reader(){_header.clear();}
141
161
  header_t &header() {return _header;}
@@ -235,6 +255,7 @@ void RINEX_Reader<U>::version_type_t::parse(const std::string &buf){
235
255
  case 'H': file_type = FTYPE_NAVIGATION;
236
256
  sat_system = SYS_SBAS; // TODO: Is geostational as SBAS?
237
257
  break;
258
+ case 'C': file_type = FTYPE_CLOCK; break;
238
259
  }
239
260
  break;
240
261
  case 3:
@@ -242,18 +263,12 @@ void RINEX_Reader<U>::version_type_t::parse(const std::string &buf){
242
263
  case 'O': file_type = FTYPE_OBSERVATION; break;
243
264
  case 'N': file_type = FTYPE_NAVIGATION; break;
244
265
  case 'M': file_type = FTYPE_METEOROLOGICAL; break;
266
+ case 'C': file_type = FTYPE_CLOCK; break;
245
267
  }
246
- if((file_type == FTYPE_OBSERVATION) || (file_type == FTYPE_NAVIGATION)){
247
- switch(buf[40]){
248
- case 'G': sat_system = SYS_GPS; break;
249
- case 'R': sat_system = SYS_GLONASS; break;
250
- case 'E': sat_system = SYS_GALILEO; break;
251
- case 'J': sat_system = SYS_QZSS; break;
252
- case 'C': sat_system = SYS_BDS; break;
253
- case 'I': sat_system = SYS_IRNSS; break;
254
- case 'S': sat_system = SYS_SBAS; break;
255
- case 'M': sat_system = SYS_MIXED; break;
256
- }
268
+ if((file_type == FTYPE_OBSERVATION)
269
+ || (file_type == FTYPE_NAVIGATION)
270
+ || (file_type == FTYPE_CLOCK)){
271
+ sat_system = char2sys_v3(buf[40]);
257
272
  }
258
273
  break;
259
274
  }
@@ -306,7 +321,7 @@ void RINEX_Reader<U>::version_type_t::dump(std::string &buf) const {
306
321
  switch(sat_system){
307
322
  case SYS_GPS: sys_str = "G: GPS"; break;
308
323
  case SYS_GLONASS: sys_str = "R: GLONASS"; break;
309
- case SYS_GALILEO: sys_str = "G: GALILEO"; break;
324
+ case SYS_GALILEO: sys_str = "E: GALILEO"; break;
310
325
  case SYS_QZSS: sys_str = "Q: QZSS"; break;
311
326
  case SYS_BDS: sys_str = "B: BDS"; break;
312
327
  case SYS_IRNSS: sys_str = "I: IRNSS"; break;