gps_pvt 0.2.0 → 0.3.0

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.
@@ -49,11 +49,7 @@ struct SBAS_SinglePositioning_Options : public GPS_Solver_GeneralOptions<FloatT>
49
49
 
50
50
  typename GPS_Solver_Base<FloatT>::options_t::template exclude_prn_t<120, 158> exclude_prn; // SBAS PRN ranges from 120 to 158
51
51
  SBAS_SinglePositioning_Options()
52
- : super_t() {
53
- // default: SBAS IGP, then broadcasted Klobuchar.
54
- super_t::ionospheric_models[0] = super_t::IONOSPHERIC_SBAS;
55
- super_t::ionospheric_models[1] = super_t::IONOSPHERIC_KLOBUCHAR;
56
-
52
+ : super_t(), exclude_prn() {
57
53
  exclude_prn.set(true); // SBAS ranging is default off.
58
54
  }
59
55
  };
@@ -86,6 +82,8 @@ class SBAS_SinglePositioning : public SolverBaseT {
86
82
 
87
83
  typedef typename base_t::measurement_t measurement_t;
88
84
  typedef typename base_t::range_error_t range_error_t;
85
+ typedef typename base_t::range_corrector_t range_corrector_t;
86
+ typedef typename base_t::range_correction_t range_correction_t;
89
87
 
90
88
  inheritate_type(relative_property_t);
91
89
  #undef inheritate_type
@@ -93,8 +91,6 @@ class SBAS_SinglePositioning : public SolverBaseT {
93
91
  typedef typename GPS_Solver_Base<float_t>::options_t::template merge_t<
94
92
  SBAS_SinglePositioning_Options<float_t>, base_t> options_t;
95
93
 
96
- typedef GPS_SpaceNode<float_t> gps_space_node_t;
97
- const gps_space_node_t *space_node_gps; ///< optional
98
94
  protected:
99
95
  const space_node_t &_space_node;
100
96
  SBAS_SinglePositioning_Options<float_t> _options;
@@ -102,40 +98,47 @@ class SBAS_SinglePositioning : public SolverBaseT {
102
98
  public:
103
99
  const space_node_t &space_node() const {return _space_node;}
104
100
 
105
- /**
106
- * Check availability of ionospheric models
107
- * If a model is completely unavailable, it will be replaced to IONOSPHERIC_SKIP.
108
- * It implies that when a model has conditional applicability (such as SBAS), it will be retained.
109
- *
110
- * @return (int) number of (possibly) available models
111
- */
112
- int filter_ionospheric_models(SBAS_SinglePositioning_Options<float_t> &opt) const {
113
- int available_models(0);
114
- for(std::size_t i(0); i < sizeof(opt.ionospheric_models) / sizeof(opt.ionospheric_models[0]); ++i){
115
- bool usable(false);
116
- switch(opt.ionospheric_models[i]){
117
- case options_t::IONOSPHERIC_KLOBUCHAR:
118
- // check whether Klobuchar parameters alpha and beta have been already received
119
- if(space_node_gps && space_node_gps->is_valid_iono()){usable = true;}
120
- break;
121
- case options_t::IONOSPHERIC_SBAS:
122
- usable = true;
123
- break;
124
- case options_t::IONOSPHERIC_NTCM_GL:
125
- if(opt.f_10_7 >= 0){usable = true;}
126
- // check F10.7 has been already configured
127
- break;
128
- default:
129
- break;
130
- }
131
- if(usable){
132
- available_models++;
133
- }else{
134
- opt.ionospheric_models[i] = options_t::IONOSPHERIC_SKIP;
101
+ struct ionospheric_sbas_t : public range_corrector_t {
102
+ const space_node_t &space_node;
103
+ ionospheric_sbas_t(const space_node_t &sn) : range_corrector_t(), space_node(sn) {}
104
+ bool is_available(const gps_time_t &t) const {
105
+ return true;
106
+ }
107
+ float_t *calculate(
108
+ const gps_time_t &t, const pos_t &usr_pos, const enu_t &sat_rel_pos,
109
+ float_t &buf) const {
110
+
111
+ // placeholder of checking availability and performing correction
112
+ typedef typename space_node_t::available_satellites_t sats_t;
113
+ sats_t sats(space_node.available_satellites(usr_pos.llh.longitude()));
114
+
115
+ typename space_node_t::IonosphericGridPoints::PointProperty prop;
116
+ for(typename sats_t::const_iterator it(sats.begin()); it != sats.end(); ++it){
117
+ prop = it->second
118
+ ->ionospheric_grid_points().iono_correction(sat_rel_pos, usr_pos.llh);
119
+ if(prop.is_available()){
120
+ return &(buf = prop.delay);
121
+ }
122
+ break; // TODO The nearest satellite is only checked
135
123
  }
124
+ return NULL;
136
125
  }
137
- return available_models;
138
- }
126
+ } ionospheric_sbas;
127
+
128
+ struct tropospheric_sbas_t : public range_corrector_t {
129
+ tropospheric_sbas_t() : range_corrector_t() {}
130
+ bool is_available(const gps_time_t &t) const {
131
+ return true;
132
+ }
133
+ float_t *calculate(
134
+ const gps_time_t &t, const pos_t &usr_pos, const enu_t &sat_rel_pos,
135
+ float_t &buf) const {
136
+ return &(buf = space_node_t::tropo_correction(
137
+ t.year(), sat_rel_pos, usr_pos.llh));
138
+ }
139
+ } tropospheric_sbas;
140
+
141
+ range_correction_t ionospheric_correction, tropospheric_correction;
139
142
 
140
143
  options_t available_options() const {
141
144
  return options_t(base_t::available_options(), _options);
@@ -143,19 +146,24 @@ class SBAS_SinglePositioning : public SolverBaseT {
143
146
 
144
147
  options_t available_options(const options_t &opt_wish) const {
145
148
  SBAS_SinglePositioning_Options<float_t> opt(opt_wish);
146
- filter_ionospheric_models(opt);
147
149
  return options_t(base_t::available_options(opt_wish), opt);
148
150
  }
149
151
 
150
152
  options_t update_options(const options_t &opt_wish){
151
- filter_ionospheric_models(_options = opt_wish);
153
+ _options = opt_wish;
152
154
  return options_t(base_t::update_options(opt_wish), _options);
153
155
  }
154
156
 
155
- SBAS_SinglePositioning(const space_node_t &sn, const options_t &opt_wish = options_t())
156
- : base_t(),
157
- _space_node(sn), space_node_gps(NULL),
158
- _options(available_options(opt_wish)) {}
157
+ SBAS_SinglePositioning(const space_node_t &sn)
158
+ : base_t(), _space_node(sn), _options(available_options(options_t())),
159
+ ionospheric_sbas(sn), tropospheric_sbas() {
160
+
161
+ // default ionospheric correction: Broadcasted IGP.
162
+ ionospheric_correction.push_front(&ionospheric_sbas);
163
+
164
+ // default troposheric correction: SBAS
165
+ tropospheric_correction.push_front(&tropospheric_sbas);
166
+ }
159
167
 
160
168
  ~SBAS_SinglePositioning(){}
161
169
 
@@ -245,43 +253,12 @@ class SBAS_SinglePositioning : public SolverBaseT {
245
253
 
246
254
  // Tropospheric (2.1.4.10.3, A.4.2.4)
247
255
  res.range_residual += (range_error.unknown_flag & range_error_t::MASK_TROPOSPHERIC)
248
- ? _space_node.tropo_correction(time_arrival.year(), relative_pos, usr_pos.llh)
256
+ ? tropospheric_correction(time_arrival, usr_pos, relative_pos)
249
257
  : range_error.value[range_error_t::TROPOSPHERIC];
250
258
 
251
259
  // Ionospheric (2.1.4.10.2, A.4.4.10.4)
252
260
  if(range_error.unknown_flag & range_error_t::MASK_IONOSPHERIC){
253
- // Ionospheric model selection, the fall back is no correction
254
- bool iono_model_hit(false);
255
- for(std::size_t i(0); i < sizeof(_options.ionospheric_models) / sizeof(_options.ionospheric_models[0]); ++i){
256
- switch(_options.ionospheric_models[i]){
257
- case options_t::IONOSPHERIC_KLOBUCHAR: // 20.3.3.5.2.5
258
- res.range_residual += space_node_gps->iono_correction(relative_pos, usr_pos.llh, time_arrival);
259
- break;
260
- case options_t::IONOSPHERIC_SBAS: { // 2.1.4.10.2, A.4.4.10.4
261
- typename space_node_t::IonosphericGridPoints::PointProperty prop(
262
- sat->ionospheric_grid_points().iono_correction(relative_pos, usr_pos.llh));
263
- if(!prop.is_available()){continue;}
264
- res.range_residual += prop.delay;
265
- break;
266
- }
267
- case options_t::IONOSPHERIC_NTCM_GL: {
268
- // TODO f_10_7 setup, optimization (mag_model etc.)
269
- typename gps_space_node_t::pierce_point_res_t pp(gps_space_node_t::pierce_point(relative_pos, usr_pos.llh));
270
- res.range_residual -= gps_space_node_t::tec2delay(
271
- gps_space_node_t::slant_factor(relative_pos)
272
- * NTCM_GL_Generic<float_t>::tec_vert(
273
- pp.latitude, pp.longitude,
274
- time_arrival.year(), _options.f_10_7));
275
- break;
276
- }
277
- case options_t::IONOSPHERIC_NONE:
278
- break;
279
- default:
280
- continue;
281
- }
282
- iono_model_hit = true;
283
- break;
284
- }
261
+ res.range_residual += ionospheric_correction(time_arrival, usr_pos, relative_pos);
285
262
  }else{
286
263
  res.range_residual += range_error.value[range_error_t::IONOSPHERIC];
287
264
  }
@@ -60,6 +60,7 @@ struct const_div_t<denom, denom, log2, 0> {
60
60
  template <int MAX_SIZE, class ContainerT = unsigned char>
61
61
  struct BitArray {
62
62
  static const int bits_per_addr = (int)sizeof(ContainerT) * CHAR_BIT;
63
+ static const int max_size = MAX_SIZE;
63
64
  ContainerT buf[(MAX_SIZE + bits_per_addr - 1) / bits_per_addr];
64
65
  void set(const bool &new_bit = false) {
65
66
  std::memset(buf, (new_bit ? (~0) : 0), sizeof(buf));
@@ -128,14 +129,14 @@ struct BitArray {
128
129
  std::vector<int> res;
129
130
  int idx(0);
130
131
  static const const_div_t<bits_per_addr> qr(MAX_SIZE);
131
- int rem(qr.rem);
132
- for(int i(0); i < qr.quot; ++i, idx += bits_per_addr){
132
+ int rem(qr.rem), i(0);
133
+ for(; i < qr.quot; ++i, idx += bits_per_addr){
133
134
  int idx2(idx);
134
135
  for(ContainerT temp(buf[i]); temp > 0; temp >>= 1, ++idx2){
135
136
  if(temp & 0x1){res.push_back(idx2);}
136
137
  }
137
138
  }
138
- for(ContainerT temp(buf[qr.quot + 1]); (temp > 0) && (rem > 0); --rem, ++idx, temp >>= 1){
139
+ for(ContainerT temp(buf[i]); (temp > 0) && (rem > 0); --rem, ++idx, temp >>= 1){
139
140
  if(temp & 0x1){res.push_back(idx);}
140
141
  }
141
142
  return res;