gps_pvt 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  /* ----------------------------------------------------------------------------
2
2
  * This file was automatically generated by SWIG (http://www.swig.org).
3
- * Version 4.0.1
3
+ * Version 4.0.2
4
4
  *
5
5
  * This file is not intended to be easily readable and contains a number of
6
6
  * coding conventions designed to improve portability and efficiency. Do not make
@@ -1612,6 +1612,8 @@ SWIGRUNTIMEINLINE char *
1612
1612
  SWIG_Ruby_MangleStr(VALUE obj)
1613
1613
  {
1614
1614
  VALUE stype = rb_iv_get(obj, "@__swigtype__");
1615
+ if (NIL_P(stype))
1616
+ return NULL;
1615
1617
  return StringValuePtr(stype);
1616
1618
  }
1617
1619
 
@@ -1876,7 +1878,7 @@ static VALUE mSylphideMath;
1876
1878
  #define SWIG_RUBY_THREAD_END_BLOCK
1877
1879
 
1878
1880
 
1879
- #define SWIGVERSION 0x040001
1881
+ #define SWIGVERSION 0x040002
1880
1882
  #define SWIG_VERSION SWIGVERSION
1881
1883
 
1882
1884
 
@@ -2259,7 +2261,7 @@ SWIG_ruby_failed(VALUE SWIGUNUSEDPARM(arg1), VALUE SWIGUNUSEDPARM(arg2))
2259
2261
  }
2260
2262
 
2261
2263
 
2262
- /*@SWIG:/usr/share/swig4.0/ruby/rubyprimtypes.swg,19,%ruby_aux_method@*/
2264
+ /*@SWIG:/usr/local/share/swig/4.0.2/ruby/rubyprimtypes.swg,19,%ruby_aux_method@*/
2263
2265
  SWIGINTERN VALUE SWIG_AUX_NUM2DBL(VALUE arg)
2264
2266
  {
2265
2267
  VALUE *args = (VALUE *)arg;
@@ -3089,7 +3091,7 @@ SWIG_From_unsigned_SS_int (unsigned int value)
3089
3091
  }
3090
3092
 
3091
3093
 
3092
- /*@SWIG:/usr/share/swig4.0/ruby/rubyprimtypes.swg,19,%ruby_aux_method@*/
3094
+ /*@SWIG:/usr/local/share/swig/4.0.2/ruby/rubyprimtypes.swg,19,%ruby_aux_method@*/
3093
3095
  SWIGINTERN VALUE SWIG_AUX_NUM2LONG(VALUE arg)
3094
3096
  {
3095
3097
  VALUE *args = (VALUE *)arg;
@@ -3155,7 +3157,7 @@ SWIG_AsVal_bool (VALUE obj, bool *val)
3155
3157
  }
3156
3158
 
3157
3159
 
3158
- /*@SWIG:/usr/share/swig4.0/ruby/rubyprimtypes.swg,19,%ruby_aux_method@*/
3160
+ /*@SWIG:/usr/local/share/swig/4.0.2/ruby/rubyprimtypes.swg,19,%ruby_aux_method@*/
3159
3161
  SWIGINTERN VALUE SWIG_AUX_NUM2ULONG(VALUE arg)
3160
3162
  {
3161
3163
  VALUE *args = (VALUE *)arg;
@@ -405,11 +405,12 @@ struct GPS_Time {
405
405
  }
406
406
 
407
407
  // process remaining 4 years
408
- int doy_i(0), doy[] = {
408
+ int doy[] = {
409
409
  leap_year ? 366 : 365,
410
410
  365, 365, 365,
411
411
  is_leap_year(year + 4) ? 366 : 365,
412
412
  };
413
+ std::size_t doy_i(0);
413
414
  for(; doy_i < sizeof(doy) / sizeof(doy[0]); ++doy_i){
414
415
  if(days <= doy[doy_i]){break;}
415
416
  days -= doy[doy_i];
@@ -2051,6 +2052,7 @@ if(std::abs(TARGET - eph.TARGET) > raw_t::sf[raw_t::SF_ ## TARGET]){break;}
2051
2052
  * @param height_over_ellipsoid
2052
2053
  * @see spherically single layer approach, for example,
2053
2054
  * Eq.(3) of "Ionospheric Range Error Correction Models" by N. Jakowski
2055
+ * @see DO-229D A4.4.10.4 Eq.(A-42) is equivalent
2054
2056
  */
2055
2057
  static float_t slant_factor(
2056
2058
  const enu_t &relative_pos,
@@ -2089,8 +2091,7 @@ if(std::abs(TARGET - eph.TARGET) > raw_t::sf[raw_t::SF_ ## TARGET]){break;}
2089
2091
  // Elevation and azimuth
2090
2092
  float_t el(relative_pos.elevation()),
2091
2093
  az(relative_pos.azimuth());
2092
- float_t sc_el(rad2sc(el)),
2093
- sc_az(rad2sc(az));
2094
+ float_t sc_el(rad2sc(el));
2094
2095
 
2095
2096
  // Pierce point (PP stands for the earth projection of the Pierce point)
2096
2097
  // (the following equation is based on GPS ICD)
@@ -43,11 +43,13 @@
43
43
  #include <exception>
44
44
 
45
45
  #include <cmath>
46
+ #include <cstddef>
46
47
 
47
48
  #include "param/bit_array.h"
48
49
 
49
50
  #include "GPS.h"
50
51
  #include "GPS_Solver_Base.h"
52
+ #include "SBAS.h"
51
53
  #include "NTCM.h"
52
54
 
53
55
  template <class FloatT>
@@ -57,6 +59,7 @@ struct GPS_Solver_GeneralOptions {
57
59
 
58
60
  enum ionospheric_model_t {
59
61
  IONOSPHERIC_KLOBUCHAR,
62
+ IONOSPHERIC_SBAS,
60
63
  IONOSPHERIC_NTCM_GL,
61
64
  IONOSPHERIC_NONE, // which allows no correction
62
65
  IONOSPHERIC_MODELS,
@@ -66,7 +69,7 @@ struct GPS_Solver_GeneralOptions {
66
69
 
67
70
  int count_ionospheric_models() const {
68
71
  int res(0);
69
- for(int i(0); i < sizeof(ionospheric_models) / sizeof(ionospheric_models[0]); ++i){
72
+ for(std::size_t i(0); i < sizeof(ionospheric_models) / sizeof(ionospheric_models[0]); ++i){
70
73
  if(ionospheric_models[i] != IONOSPHERIC_SKIP){res++;}
71
74
  }
72
75
  return res;
@@ -78,7 +81,7 @@ struct GPS_Solver_GeneralOptions {
78
81
  : elevation_mask(0), // elevation mask default is 0 [deg]
79
82
  residual_mask(30), // range residual mask is 30 [m]
80
83
  f_10_7(-1) {
81
- for(int i(0); i < sizeof(ionospheric_models) / sizeof(ionospheric_models[0]); ++i){
84
+ for(std::size_t i(0); i < sizeof(ionospheric_models) / sizeof(ionospheric_models[0]); ++i){
82
85
  ionospheric_models[i] = IONOSPHERIC_SKIP;
83
86
  }
84
87
  // default: broadcasted Klobuchar parameters are at least required for solution.
@@ -97,6 +100,22 @@ struct GPS_Solver_GeneralOptions {
97
100
  }
98
101
  ionospheric_models[index] = model;
99
102
 
103
+ return true;
104
+ }
105
+ bool remove_ionospheric_model(const ionospheric_model_t &model) {
106
+ // shift, then replace
107
+ int j(0);
108
+ for(int i(0); i < sizeof(ionospheric_models) / sizeof(ionospheric_models[0]); ++i){
109
+ if(ionospheric_models[i] == model){continue;}
110
+ ionospheric_models[j++] = ionospheric_models[i];
111
+ }
112
+ if(j == (sizeof(ionospheric_models) / sizeof(ionospheric_models[0]))){
113
+ return false;
114
+ }
115
+ do{
116
+ ionospheric_models[j++] = IONOSPHERIC_SKIP;
117
+ }while(j < sizeof(ionospheric_models) / sizeof(ionospheric_models[0]));
118
+
100
119
  return true;
101
120
  }
102
121
  };
@@ -139,6 +158,8 @@ class GPS_SinglePositioning : public SolverBaseT {
139
158
  inheritate_type(llh_t);
140
159
  inheritate_type(enu_t);
141
160
 
161
+ typedef SBAS_SpaceNode<float_t> sbas_space_node_t;
162
+
142
163
  inheritate_type(pos_t);
143
164
 
144
165
  inheritate_type(prn_obs_t);
@@ -151,9 +172,10 @@ class GPS_SinglePositioning : public SolverBaseT {
151
172
  inheritate_type(user_pvt_t);
152
173
  #undef inheritate_type
153
174
 
175
+ const sbas_space_node_t *space_node_sbas; ///< optional
176
+
154
177
  typedef typename GPS_Solver_Base<float_t>::options_t::template merge_t<
155
178
  GPS_SinglePositioning_Options<float_t>, base_t> options_t;
156
-
157
179
  protected:
158
180
  const space_node_t &_space_node;
159
181
  GPS_SinglePositioning_Options<float_t> _options;
@@ -172,22 +194,28 @@ class GPS_SinglePositioning : public SolverBaseT {
172
194
 
173
195
  int available_models(0);
174
196
 
175
- for(int i(0); i < sizeof(opt.ionospheric_models) / sizeof(opt.ionospheric_models[0]); ++i){
197
+ for(std::size_t i(0);
198
+ i < sizeof(opt.ionospheric_models) / sizeof(opt.ionospheric_models[0]); ++i){
199
+ bool usable(false);
176
200
  switch(opt.ionospheric_models[i]){
177
201
  case options_t::IONOSPHERIC_KLOBUCHAR:
178
202
  // check whether Klobuchar parameters alpha and beta have been already received
179
- if(_space_node.is_valid_iono()){break;}
180
- opt.ionospheric_models[i] = options_t::IONOSPHERIC_SKIP;
181
- continue;
203
+ if(_space_node.is_valid_iono()){usable = true;}
204
+ break;
205
+ case options_t::IONOSPHERIC_SBAS:
206
+ if(space_node_sbas){usable = true;}
207
+ break;
182
208
  case options_t::IONOSPHERIC_NTCM_GL:
183
- if(opt.f_10_7 >= 0){break;}
209
+ if(opt.f_10_7 >= 0){usable = true;}
184
210
  // check F10.7 has been already configured
185
- opt.ionospheric_models[i] = options_t::IONOSPHERIC_SKIP;
186
- continue;
187
- case options_t::IONOSPHERIC_SKIP:
188
- continue;
211
+ break;
212
+ default: break;
213
+ }
214
+ if(usable){
215
+ available_models++;
216
+ }else{
217
+ opt.ionospheric_models[i] = options_t::IONOSPHERIC_SKIP;
189
218
  }
190
- available_models++;
191
219
  }
192
220
 
193
221
  return available_models;
@@ -209,7 +237,9 @@ class GPS_SinglePositioning : public SolverBaseT {
209
237
  }
210
238
 
211
239
  GPS_SinglePositioning(const space_node_t &sn)
212
- : base_t(), _space_node(sn), _options() {
240
+ : base_t(),
241
+ _space_node(sn), space_node_sbas(NULL),
242
+ _options() {
213
243
  filter_ionospheric_models(_options);
214
244
  }
215
245
 
@@ -266,11 +296,28 @@ class GPS_SinglePositioning : public SolverBaseT {
266
296
  if(error.unknown_flag & range_error_t::MASK_IONOSPHERIC){
267
297
  // Ionospheric model selection, the fall back is no correction
268
298
  bool iono_model_hit(false);
269
- for(int i(0); i < sizeof(_options.ionospheric_models) / sizeof(_options.ionospheric_models[0]); ++i){
299
+ for(std::size_t i(0);
300
+ i < sizeof(_options.ionospheric_models) / sizeof(_options.ionospheric_models[0]);
301
+ ++i){
270
302
  switch(_options.ionospheric_models[i]){
271
303
  case options_t::IONOSPHERIC_KLOBUCHAR:
272
304
  residual.residual += _space_node.iono_correction(relative_pos, usr_pos.llh, time_arrival);
273
305
  break;
306
+ case options_t::IONOSPHERIC_SBAS: {
307
+ // placeholder of checking availability and performing correction
308
+ typedef typename SBAS_SpaceNode<float_t>::available_satellites_t sats_t;
309
+ sats_t sats(space_node_sbas->available_satellites(usr_pos.llh.longitude()));
310
+
311
+ typename SBAS_SpaceNode<float_t>::IonosphericGridPoints::PointProperty prop;
312
+ for(typename sats_t::const_iterator it(sats.begin()); it != sats.end(); ++it){
313
+ prop = it->second
314
+ ->ionospheric_grid_points().iono_correction(relative_pos, usr_pos.llh);
315
+ break; // TODO The nearest satellite is only checked
316
+ }
317
+ if(!prop.is_available()){continue;}
318
+ residual.residual += prop.delay;
319
+ break;
320
+ }
274
321
  case options_t::IONOSPHERIC_NTCM_GL: {
275
322
  // TODO f_10_7 setup, optimization (mag_model etc.)
276
323
  typename space_node_t::pierce_point_res_t pp(_space_node.pierce_point(relative_pos, usr_pos.llh));
@@ -202,9 +202,9 @@ struct GPS_Solver_Base {
202
202
  virtual const float_t *rate(
203
203
  const typename measurement_t::mapped_type &values, float_t &buf) const {
204
204
  const float_t *res;
205
- if(res = find_value(values, measurement_items_t::L1_RANGE_RATE, buf)){
205
+ if((res = find_value(values, measurement_items_t::L1_RANGE_RATE, buf))){
206
206
 
207
- }else if(res = find_value(values, measurement_items_t::L1_DOPPLER, buf)){
207
+ }else if((res = find_value(values, measurement_items_t::L1_DOPPLER, buf))){
208
208
  // Fall back to doppler
209
209
  buf *= -space_node_t::L1_WaveLength();
210
210
  }
@@ -214,9 +214,9 @@ struct GPS_Solver_Base {
214
214
  virtual const float_t *rate_sigma(
215
215
  const typename measurement_t::mapped_type &values, float_t &buf) const {
216
216
  const float_t *res;
217
- if(res = find_value(values, measurement_items_t::L1_RANGE_RATE_SIGMA, buf)){
217
+ if((res = find_value(values, measurement_items_t::L1_RANGE_RATE_SIGMA, buf))){
218
218
 
219
- }else if(res = find_value(values, measurement_items_t::L1_DOPPLER_SIGMA, buf)){
219
+ }else if((res = find_value(values, measurement_items_t::L1_DOPPLER_SIGMA, buf))){
220
220
  // Fall back to doppler
221
221
  buf *= space_node_t::L1_WaveLength();
222
222
  }
@@ -308,8 +308,9 @@ struct GPS_Solver_Base {
308
308
  case ERROR_VELOCITY_INSUFFICIENT_SATELLITES:
309
309
  case ERROR_VELOCITY_LS:
310
310
  return true;
311
+ default:
312
+ return false;
311
313
  }
312
- return false;
313
314
  }
314
315
  bool velocity_solved() const {
315
316
  return error_code == ERROR_NO;
@@ -0,0 +1,62 @@
1
+ /*
2
+ * Copyright (c) 2021, M.Naruoka (fenrir)
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without modification,
6
+ * are permitted provided that the following conditions are met:
7
+ *
8
+ * - Redistributions of source code must retain the above copyright notice,
9
+ * this list of conditions and the following disclaimer.
10
+ * - Redistributions in binary form must reproduce the above copyright notice,
11
+ * this list of conditions and the following disclaimer in the documentation
12
+ * and/or other materials provided with the distribution.
13
+ * - Neither the name of the naruoka.org nor the names of its contributors
14
+ * may be used to endorse or promote products derived from this software
15
+ * without specific prior written permission.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
21
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
22
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ *
30
+ */
31
+
32
+ #ifndef __QZSS_H__
33
+ #define __QZSS_H__
34
+
35
+ /** @file
36
+ * @brief QZSS ICD definitions
37
+ */
38
+
39
+ #include "GPS.h"
40
+ #include <limits>
41
+
42
+ template <class FloatT>
43
+ struct QZSS_LNAV_Ephemeris_Raw : public GPS_SpaceNode<FloatT>::Satellite::Ephemeris::raw_t {
44
+ typedef typename GPS_SpaceNode<FloatT>::Satellite::Ephemeris eph_t;
45
+ typedef typename eph_t::raw_t super_t;
46
+
47
+ operator eph_t() const {
48
+ eph_t res(super_t::operator eph_t());
49
+ res.fit_interval = super_t::fit_interval_flag
50
+ ? (std::numeric_limits<FloatT>::max)()
51
+ : (2 * 60 * 60); // Fit interval (ICD:4.1.2.4 Subframe 2); should be zero
52
+ return res;
53
+ };
54
+
55
+ QZSS_LNAV_Ephemeris_Raw &operator=(const eph_t &eph){
56
+ super_t::operator=(eph);
57
+ super_t::fit_interval_flag = (eph.fit_interval > 2 * 60 * 60);
58
+ return *this;
59
+ }
60
+ };
61
+
62
+ #endif /* __QZSS_H__ */