gps_pvt 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +10 -41
- data/ext/ninja-scan-light/tool/navigation/GLONASS_Solver.h +63 -43
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +58 -34
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +42 -17
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +28 -10
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +19 -4
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +63 -43
- data/ext/ninja-scan-light/tool/swig/GPS.i +11 -42
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +0 -16
- data/lib/gps_pvt/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b4f5df780c4ff0977b025fab381c327b04a3e8fae742cc6ff672e08839d9c51
|
4
|
+
data.tar.gz: cbbb233acbe548944d9b317449160465ec04d2041e56f54decc286a900503723
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a724b51f5fe55fe9c0d74d02176c26dbad63bcc1fc1fbd477c7a0707e06f832df5110f4a80c5c2807ac5e1ae2d0717846858a30365eec874847c96fb11e12b5e
|
7
|
+
data.tar.gz: 97b3670fd401bc860d9f16ab473fe4c6c33ee87fcf6855757490ec724d8405a6aeb7df22aabaf7e37f559d80ce9b4ce1c764c550acccf591bb940805b3c660a6
|
@@ -2671,10 +2671,9 @@ struct GPS_Solver
|
|
2671
2671
|
const typename base_t::gps_time_t &time_arrival,
|
2672
2672
|
const typename base_t::pos_t &usr_pos,
|
2673
2673
|
const typename base_t::xyz_t &usr_vel) const;
|
2674
|
-
virtual typename base_t::
|
2674
|
+
virtual typename base_t::satellite_t select_satellite(
|
2675
2675
|
const typename base_t::prn_t &prn,
|
2676
|
-
const typename base_t::gps_time_t &time
|
2677
|
-
typename base_t::xyz_t &res) const;
|
2676
|
+
const typename base_t::gps_time_t &time) const;
|
2678
2677
|
virtual bool update_position_solution(
|
2679
2678
|
const typename base_t::geometric_matrices_t &geomat,
|
2680
2679
|
typename base_t::user_pvt_t &res) const;
|
@@ -3867,47 +3866,17 @@ SWIGINTERN double const &GPS_SolverOptions_Common_Sl_double_Sg__get_residual_mas
|
|
3867
3866
|
return super_t::update_position_solution(geomat, res);
|
3868
3867
|
}
|
3869
3868
|
template <>
|
3870
|
-
GPS_Solver<double>::base_t::
|
3869
|
+
GPS_Solver<double>::base_t::satellite_t GPS_Solver<double>::select_satellite(
|
3871
3870
|
const GPS_Solver<double>::base_t::prn_t &prn,
|
3872
|
-
const GPS_Solver<double>::base_t::gps_time_t &time
|
3873
|
-
|
3874
|
-
|
3875
|
-
select_solver(prn).satellite_position(prn, time, buf));
|
3871
|
+
const GPS_Solver<double>::base_t::gps_time_t &time) const {
|
3872
|
+
GPS_Solver<double>::base_t::satellite_t res(
|
3873
|
+
select_solver(prn).select_satellite(prn, time));
|
3876
3874
|
|
3877
|
-
|
3878
|
-
static const VALUE key(ID2SYM(rb_intern("
|
3875
|
+
if(!res.is_available()){
|
3876
|
+
static const VALUE key(ID2SYM(rb_intern("relative_property")));
|
3879
3877
|
VALUE hook(rb_hash_lookup(hooks, key));
|
3880
|
-
if(NIL_P(hook)){
|
3881
|
-
|
3882
|
-
SWIG_From_int (prn), // prn
|
3883
|
-
SWIG_NewPointerObj( // time
|
3884
|
-
new base_t::gps_time_t(time), SWIGTYPE_p_GPS_TimeT_double_t, SWIG_POINTER_OWN),
|
3885
|
-
(res // position (internally calculated)
|
3886
|
-
? SWIG_NewPointerObj(res, SWIGTYPE_p_System_XYZT_double_WGS84_t, 0)
|
3887
|
-
: Qnil)};
|
3888
|
-
VALUE res_hook(proc_call_throw_if_error(hook, sizeof(values) / sizeof(values[0]), values));
|
3889
|
-
if(NIL_P(res_hook)){ // unknown position
|
3890
|
-
res = NULL;
|
3891
|
-
break;
|
3892
|
-
}else if(RB_TYPE_P(res_hook, T_ARRAY) && (RARRAY_LEN(res_hook) == 3)){
|
3893
|
-
int i(0);
|
3894
|
-
for(; i < 3; ++i){
|
3895
|
-
VALUE v(RARRAY_AREF(res_hook, i));
|
3896
|
-
if(!SWIG_IsOK(swig::asval(v, &buf[i]))){break;}
|
3897
|
-
}
|
3898
|
-
if(i == 3){
|
3899
|
-
res = &buf;
|
3900
|
-
break;
|
3901
|
-
}
|
3902
|
-
}else if(SWIG_IsOK(SWIG_ConvertPtr(
|
3903
|
-
res_hook, (void **)&res, SWIGTYPE_p_System_XYZT_double_WGS84_t, 0))){
|
3904
|
-
res = &(buf = *res);
|
3905
|
-
break;
|
3906
|
-
}
|
3907
|
-
throw std::runtime_error(
|
3908
|
-
std::string("System_XYZ or [d * 3] is expected (d: " "double" "), however ")
|
3909
|
-
.append(inspect_str(res_hook)));
|
3910
|
-
}while(false);
|
3878
|
+
if(!NIL_P(hook)){res.impl = this;}
|
3879
|
+
}
|
3911
3880
|
|
3912
3881
|
return res;
|
3913
3882
|
}
|
@@ -75,7 +75,6 @@ class GLONASS_SinglePositioning : public SolverBaseT {
|
|
75
75
|
|
76
76
|
typedef GLONASS_SpaceNode<float_t> space_node_t;
|
77
77
|
inheritate_type(gps_time_t);
|
78
|
-
typedef typename space_node_t::Satellite satellite_t;
|
79
78
|
|
80
79
|
inheritate_type(xyz_t);
|
81
80
|
inheritate_type(enu_t);
|
@@ -83,9 +82,10 @@ class GLONASS_SinglePositioning : public SolverBaseT {
|
|
83
82
|
inheritate_type(pos_t);
|
84
83
|
|
85
84
|
typedef typename base_t::measurement_t measurement_t;
|
86
|
-
|
87
|
-
|
88
|
-
|
85
|
+
typedef typename base_t::satellite_t satellite_t;
|
86
|
+
typedef typename base_t::range_error_t range_error_t;
|
87
|
+
typedef typename base_t::range_corrector_t range_corrector_t;
|
88
|
+
typedef typename base_t::range_correction_t range_correction_t;
|
89
89
|
|
90
90
|
inheritate_type(relative_property_t);
|
91
91
|
typedef typename super_t::measurement_items_t measurement_items_t;
|
@@ -97,11 +97,51 @@ class GLONASS_SinglePositioning : public SolverBaseT {
|
|
97
97
|
GLONASS_SinglePositioning_Options<float_t>, base_t> options_t;
|
98
98
|
|
99
99
|
protected:
|
100
|
-
const space_node_t &_space_node;
|
101
100
|
GLONASS_SinglePositioning_Options<float_t> _options;
|
102
101
|
|
103
102
|
public:
|
104
|
-
|
103
|
+
struct satellites_t {
|
104
|
+
const void *impl;
|
105
|
+
satellite_t (*impl_select)(const void *, const prn_t &, const gps_time_t &);
|
106
|
+
inline satellite_t select(const prn_t &prn, const gps_time_t &receiver_time) const {
|
107
|
+
return impl_select(impl, prn, receiver_time);
|
108
|
+
}
|
109
|
+
static satellite_t select_broadcast(
|
110
|
+
const void *ptr, const prn_t &prn, const gps_time_t &receiver_time){
|
111
|
+
const typename space_node_t::satellites_t &sats(
|
112
|
+
reinterpret_cast<const space_node_t *>(ptr)->satellites());
|
113
|
+
const typename space_node_t::satellites_t::const_iterator it_sat(sats.find(prn));
|
114
|
+
if((it_sat == sats.end()) // has ephemeris?
|
115
|
+
|| (!it_sat->second.ephemeris().is_valid(receiver_time))){ // valid ephemeris?
|
116
|
+
return satellite_t::unavailable();
|
117
|
+
}
|
118
|
+
struct impl_t {
|
119
|
+
static inline const typename space_node_t::Satellite &sat(const void *ptr) {
|
120
|
+
return *reinterpret_cast<const typename space_node_t::Satellite *>(ptr);
|
121
|
+
}
|
122
|
+
static xyz_t position(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
123
|
+
return sat(ptr).constellation(t, pseudo_range).position;
|
124
|
+
}
|
125
|
+
static xyz_t velocity(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
126
|
+
return sat(ptr).constellation(t, pseudo_range).velocity;
|
127
|
+
}
|
128
|
+
static float_t clock_error(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
129
|
+
return sat(ptr).clock_error(t, pseudo_range);
|
130
|
+
}
|
131
|
+
static float_t clock_error_dot(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
132
|
+
// Clock rate error is already taken into account in constellation()
|
133
|
+
return 0;
|
134
|
+
}
|
135
|
+
};
|
136
|
+
satellite_t res = {
|
137
|
+
&(it_sat->second),
|
138
|
+
impl_t::position, impl_t::velocity,
|
139
|
+
impl_t::clock_error, impl_t::clock_error_dot};
|
140
|
+
return res;
|
141
|
+
}
|
142
|
+
satellites_t(const space_node_t &sn)
|
143
|
+
: impl(&sn), impl_select(select_broadcast) {}
|
144
|
+
} satellites;
|
105
145
|
|
106
146
|
range_correction_t ionospheric_correction, tropospheric_correction;
|
107
147
|
|
@@ -120,7 +160,8 @@ class GLONASS_SinglePositioning : public SolverBaseT {
|
|
120
160
|
}
|
121
161
|
|
122
162
|
GLONASS_SinglePositioning(const space_node_t &sn, const options_t &opt_wish = options_t())
|
123
|
-
: base_t(),
|
163
|
+
: base_t(), _options(available_options(opt_wish)),
|
164
|
+
satellites(sn),
|
124
165
|
ionospheric_correction(), tropospheric_correction() {
|
125
166
|
|
126
167
|
// default ionospheric correction: no correction
|
@@ -163,25 +204,18 @@ class GLONASS_SinglePositioning : public SolverBaseT {
|
|
163
204
|
}
|
164
205
|
|
165
206
|
/**
|
166
|
-
*
|
207
|
+
* Select satellite by using PRN and time
|
167
208
|
*
|
168
209
|
* @param prn satellite number
|
169
210
|
* @param receiver_time receiver time
|
170
|
-
* @return (
|
171
|
-
* otherwise NULL.
|
211
|
+
* @return (satellite_t) If available, satellite.is_available() returning true is returned.
|
172
212
|
*/
|
173
|
-
|
174
|
-
const
|
213
|
+
satellite_t select_satellite(
|
214
|
+
const prn_t &prn,
|
175
215
|
const gps_time_t &receiver_time) const {
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
if((it_sat == sats.end()) // has ephemeris?
|
180
|
-
|| (!it_sat->second.ephemeris().is_valid(receiver_time))){ // valid ephemeris?
|
181
|
-
return NULL;
|
182
|
-
}
|
183
|
-
|
184
|
-
return &(it_sat->second);
|
216
|
+
prn_t prn_(prn & 0xFF);
|
217
|
+
if(_options.exclude_prn[prn_]){return satellite_t::unavailable();}
|
218
|
+
return satellites.select(prn_, receiver_time);
|
185
219
|
}
|
186
220
|
|
187
221
|
/**
|
@@ -205,32 +239,27 @@ class GLONASS_SinglePositioning : public SolverBaseT {
|
|
205
239
|
|
206
240
|
relative_property_t res = {0};
|
207
241
|
|
208
|
-
if(_options.exclude_prn[prn & 0xFF]){return res;}
|
209
|
-
|
210
242
|
float_t range;
|
211
243
|
range_error_t range_error;
|
212
244
|
if(!this->range(measurement, range, &range_error)){
|
213
245
|
return res; // If no range entry, return with weight = 0
|
214
246
|
}
|
215
247
|
|
216
|
-
|
217
|
-
if(!sat){return res;} // If satellite is unavailable, return with weight = 0
|
248
|
+
satellite_t sat(select_satellite(prn, time_arrival));
|
249
|
+
if(!sat.is_available()){return res;} // If satellite is unavailable, return with weight = 0
|
218
250
|
|
219
251
|
range -= receiver_error;
|
220
252
|
|
221
253
|
// Clock correction, which will be considered in the next constellation()
|
222
254
|
// as extra transmission time by using extra psuedo range.
|
223
255
|
if(range_error.unknown_flag & range_error_t::SATELLITE_CLOCK){
|
224
|
-
range += (sat
|
256
|
+
range += (sat.clock_error(time_arrival, range) * space_node_t::light_speed);
|
225
257
|
}else{
|
226
258
|
range += range_error.value[range_error_t::SATELLITE_CLOCK];
|
227
259
|
}
|
228
260
|
|
229
|
-
// Calculate satellite position
|
230
|
-
|
231
|
-
sat->constellation(time_arrival, range));
|
232
|
-
|
233
|
-
const xyz_t &sat_pos(sat_pos_vel.position);
|
261
|
+
// Calculate satellite position
|
262
|
+
xyz_t sat_pos(sat.position(time_arrival, range));
|
234
263
|
float_t geometric_range(usr_pos.xyz.dist(sat_pos));
|
235
264
|
|
236
265
|
// Calculate residual
|
@@ -278,24 +307,15 @@ class GLONASS_SinglePositioning : public SolverBaseT {
|
|
278
307
|
|
279
308
|
res.range_corrected = range;
|
280
309
|
|
281
|
-
xyz_t rel_vel(
|
310
|
+
xyz_t rel_vel(sat.velocity(time_arrival, range) - usr_vel); // Calculate velocity
|
282
311
|
|
283
|
-
// Note: clock rate error is already accounted for in constellation()
|
284
312
|
res.rate_relative_neg = res.los_neg[0] * rel_vel.x()
|
285
313
|
+ res.los_neg[1] * rel_vel.y()
|
286
|
-
+ res.los_neg[2] * rel_vel.z()
|
314
|
+
+ res.los_neg[2] * rel_vel.z()
|
315
|
+
+ sat.clock_error_dot(time_arrival, range) * space_node_t::light_speed;
|
287
316
|
|
288
317
|
return res;
|
289
318
|
}
|
290
|
-
|
291
|
-
xyz_t *satellite_position(
|
292
|
-
const prn_t &prn,
|
293
|
-
const gps_time_t &time,
|
294
|
-
xyz_t &res) const {
|
295
|
-
|
296
|
-
const satellite_t *sat(is_available(prn, time));
|
297
|
-
return sat ? &(res = sat->position(time)) : NULL;
|
298
|
-
}
|
299
319
|
};
|
300
320
|
|
301
321
|
template <class FloatT, class SolverBaseT>
|
@@ -95,7 +95,6 @@ class GPS_SinglePositioning : public SolverBaseT {
|
|
95
95
|
|
96
96
|
typedef typename base_t::space_node_t space_node_t;
|
97
97
|
inheritate_type(gps_time_t);
|
98
|
-
typedef typename space_node_t::Satellite satellite_t;
|
99
98
|
|
100
99
|
inheritate_type(xyz_t);
|
101
100
|
inheritate_type(llh_t);
|
@@ -106,6 +105,7 @@ class GPS_SinglePositioning : public SolverBaseT {
|
|
106
105
|
inheritate_type(prn_obs_t);
|
107
106
|
typedef typename base_t::measurement_t measurement_t;
|
108
107
|
inheritate_type(measurement_items_t);
|
108
|
+
typedef typename base_t::satellite_t satellite_t;
|
109
109
|
typedef typename base_t::range_error_t range_error_t;
|
110
110
|
typedef typename base_t::range_corrector_t range_corrector_t;
|
111
111
|
typedef typename base_t::range_correction_t range_correction_t;
|
@@ -119,11 +119,52 @@ class GPS_SinglePositioning : public SolverBaseT {
|
|
119
119
|
GPS_SinglePositioning_Options<float_t>, base_t> options_t;
|
120
120
|
|
121
121
|
protected:
|
122
|
-
const space_node_t &_space_node;
|
123
122
|
GPS_SinglePositioning_Options<float_t> _options;
|
124
123
|
|
125
124
|
public:
|
126
|
-
|
125
|
+
struct satellites_t {
|
126
|
+
const void *impl;
|
127
|
+
satellite_t (*impl_select)(const void *, const prn_t &, const gps_time_t &);
|
128
|
+
inline satellite_t select(const prn_t &prn, const gps_time_t &receiver_time) const {
|
129
|
+
return impl_select(impl, prn, receiver_time);
|
130
|
+
}
|
131
|
+
static satellite_t select_broadcast(
|
132
|
+
const void *ptr, const prn_t &prn, const gps_time_t &receiver_time){
|
133
|
+
// If this static function is defined in inner struct,
|
134
|
+
// C2440 error raises with VC2010
|
135
|
+
const typename space_node_t::satellites_t &sats(
|
136
|
+
reinterpret_cast<const space_node_t *>(ptr)->satellites());
|
137
|
+
const typename space_node_t::satellites_t::const_iterator it_sat(sats.find(prn));
|
138
|
+
if((it_sat == sats.end()) // has ephemeris?
|
139
|
+
|| (!it_sat->second.ephemeris().is_valid(receiver_time))){ // valid ephemeris?
|
140
|
+
return satellite_t::unavailable();
|
141
|
+
}
|
142
|
+
struct impl_t {
|
143
|
+
static inline const typename space_node_t::Satellite &sat(const void *ptr) {
|
144
|
+
return *reinterpret_cast<const typename space_node_t::Satellite *>(ptr);
|
145
|
+
}
|
146
|
+
static xyz_t position(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
147
|
+
return sat(ptr).position(t, pseudo_range);
|
148
|
+
}
|
149
|
+
static xyz_t velocity(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
150
|
+
return sat(ptr).velocity(t, pseudo_range);
|
151
|
+
}
|
152
|
+
static float_t clock_error(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
153
|
+
return sat(ptr).clock_error(t, pseudo_range);
|
154
|
+
}
|
155
|
+
static float_t clock_error_dot(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
156
|
+
return sat(ptr).clock_error_dot(t, pseudo_range);
|
157
|
+
}
|
158
|
+
};
|
159
|
+
satellite_t res = {
|
160
|
+
&(it_sat->second),
|
161
|
+
impl_t::position, impl_t::velocity,
|
162
|
+
impl_t::clock_error, impl_t::clock_error_dot};
|
163
|
+
return res;
|
164
|
+
}
|
165
|
+
satellites_t(const space_node_t &sn)
|
166
|
+
: impl(&sn), impl_select(select_broadcast) {}
|
167
|
+
} satellites;
|
127
168
|
|
128
169
|
struct klobuchar_t : public range_corrector_t {
|
129
170
|
const space_node_t &space_node;
|
@@ -134,6 +175,7 @@ class GPS_SinglePositioning : public SolverBaseT {
|
|
134
175
|
float_t *calculate(
|
135
176
|
const gps_time_t &t, const pos_t &usr_pos, const enu_t &sat_rel_pos,
|
136
177
|
float_t &buf) const {
|
178
|
+
if(!is_available(t)){return NULL;}
|
137
179
|
return &(buf = space_node.iono_correction(sat_rel_pos, usr_pos.llh, t));
|
138
180
|
}
|
139
181
|
} ionospheric_klobuchar;
|
@@ -185,7 +227,8 @@ class GPS_SinglePositioning : public SolverBaseT {
|
|
185
227
|
}
|
186
228
|
|
187
229
|
GPS_SinglePositioning(const space_node_t &sn)
|
188
|
-
: base_t(),
|
230
|
+
: base_t(), _options(available_options(options_t())),
|
231
|
+
satellites(sn),
|
189
232
|
ionospheric_klobuchar(sn), ionospheric_ntcm_gl(),
|
190
233
|
tropospheric_simplified(),
|
191
234
|
ionospheric_correction(), tropospheric_correction() {
|
@@ -309,27 +352,17 @@ class GPS_SinglePositioning : public SolverBaseT {
|
|
309
352
|
}
|
310
353
|
|
311
354
|
/**
|
312
|
-
*
|
355
|
+
* Select satellite by using PRN and time
|
313
356
|
*
|
314
357
|
* @param prn satellite number
|
315
358
|
* @param receiver_time receiver time
|
316
|
-
* @return (
|
317
|
-
* otherwise NULL.
|
359
|
+
* @return (satellite_t) If available, satellite.is_available() returning true is returned.
|
318
360
|
*/
|
319
|
-
|
320
|
-
const
|
361
|
+
satellite_t select_satellite(
|
362
|
+
const prn_t &prn,
|
321
363
|
const gps_time_t &receiver_time) const {
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
const typename space_node_t::satellites_t &sats(_space_node.satellites());
|
326
|
-
const typename space_node_t::satellites_t::const_iterator it_sat(sats.find(prn));
|
327
|
-
if((it_sat == sats.end()) // has ephemeris?
|
328
|
-
|| (!it_sat->second.ephemeris().is_valid(receiver_time))){ // valid ephemeris?
|
329
|
-
return NULL;
|
330
|
-
}
|
331
|
-
|
332
|
-
return &(it_sat->second);
|
364
|
+
if(_options.exclude_prn[prn]){return satellite_t::unavailable();}
|
365
|
+
return satellites.select(prn, receiver_time);
|
333
366
|
}
|
334
367
|
|
335
368
|
/**
|
@@ -359,8 +392,8 @@ class GPS_SinglePositioning : public SolverBaseT {
|
|
359
392
|
return res; // If no range entry, return with weight = 0
|
360
393
|
}
|
361
394
|
|
362
|
-
|
363
|
-
if(!sat){return res;} // If satellite is unavailable, return with weight = 0
|
395
|
+
satellite_t sat(select_satellite(prn, time_arrival));
|
396
|
+
if(!sat.is_available()){return res;} // If satellite is unavailable, return with weight = 0
|
364
397
|
|
365
398
|
residual_t residual = {
|
366
399
|
res.range_residual,
|
@@ -369,9 +402,9 @@ class GPS_SinglePositioning : public SolverBaseT {
|
|
369
402
|
};
|
370
403
|
|
371
404
|
res.range_corrected = range_corrected(
|
372
|
-
|
405
|
+
sat, range - receiver_error, time_arrival,
|
373
406
|
usr_pos, residual, range_error);
|
374
|
-
res.rate_relative_neg = rate_relative_neg(
|
407
|
+
res.rate_relative_neg = rate_relative_neg(sat, res.range_corrected, time_arrival, usr_vel,
|
375
408
|
res.los_neg[0], res.los_neg[1], res.los_neg[2]);
|
376
409
|
|
377
410
|
return res;
|
@@ -415,7 +448,7 @@ class GPS_SinglePositioning : public SolverBaseT {
|
|
415
448
|
float_t range;
|
416
449
|
if(!this->range(it->second, range)){continue;} // No range entry
|
417
450
|
|
418
|
-
if(!
|
451
|
+
if(!(select_satellite(it->first, receiver_time).is_available())){continue;} // No satellite
|
419
452
|
|
420
453
|
typename base_t::measurement2_t::value_type v = {
|
421
454
|
it->first, &(it->second), this}; // prn, measurement, solver
|
@@ -426,15 +459,6 @@ class GPS_SinglePositioning : public SolverBaseT {
|
|
426
459
|
measurement2, receiver_time, user_position_init, receiver_error_init,
|
427
460
|
typename base_t::user_pvt_opt_t(good_init, with_velocity));
|
428
461
|
}
|
429
|
-
|
430
|
-
xyz_t *satellite_position(
|
431
|
-
const prn_t &prn,
|
432
|
-
const gps_time_t &time,
|
433
|
-
xyz_t &res) const {
|
434
|
-
|
435
|
-
const satellite_t *sat(is_available(prn, time));
|
436
|
-
return sat ? &(res = sat->position(time)) : NULL;
|
437
|
-
}
|
438
462
|
};
|
439
463
|
|
440
464
|
#endif /* __GPS_SOLVER_H__ */
|
@@ -226,6 +226,47 @@ struct GPS_Solver_Base {
|
|
226
226
|
return res;
|
227
227
|
}
|
228
228
|
|
229
|
+
struct satellite_t {
|
230
|
+
const void *impl;
|
231
|
+
xyz_t (*impl_position)(const void *, const gps_time_t &, const float_t &);
|
232
|
+
xyz_t (*impl_velocity)(const void *, const gps_time_t &, const float_t &);
|
233
|
+
float_t (*impl_clock_error)(const void *, const gps_time_t &, const float_t &);
|
234
|
+
float_t (*impl_clock_error_dot)(const void *, const gps_time_t &, const float_t &);
|
235
|
+
inline bool is_available() const {
|
236
|
+
return impl != NULL;
|
237
|
+
}
|
238
|
+
inline xyz_t position(const gps_time_t &t, const float_t &pseudo_range = 0) const {
|
239
|
+
return impl_position(impl, t, pseudo_range);
|
240
|
+
}
|
241
|
+
inline xyz_t velocity(const gps_time_t &t, const float_t &pseudo_range = 0) const {
|
242
|
+
return impl_velocity(impl, t, pseudo_range);
|
243
|
+
}
|
244
|
+
inline float_t clock_error(const gps_time_t &t, const float_t &pseudo_range = 0) const {
|
245
|
+
return impl_clock_error(impl, t, pseudo_range);
|
246
|
+
}
|
247
|
+
inline float_t clock_error_dot(const gps_time_t &t, const float_t &pseudo_range = 0) const {
|
248
|
+
return impl_clock_error_dot(impl, t, pseudo_range);
|
249
|
+
}
|
250
|
+
static const satellite_t &unavailable() {
|
251
|
+
static const satellite_t res = {NULL};
|
252
|
+
return res;
|
253
|
+
}
|
254
|
+
};
|
255
|
+
|
256
|
+
/**
|
257
|
+
* Select satellite by using PRN and time
|
258
|
+
* This function should be overridden.
|
259
|
+
*
|
260
|
+
* @param prn satellite number
|
261
|
+
* @param receiver_time receiver time
|
262
|
+
* @return (satellite_t) If available, satellite.is_available() returning true is returned.
|
263
|
+
*/
|
264
|
+
virtual satellite_t select_satellite(
|
265
|
+
const prn_t &prn,
|
266
|
+
const gps_time_t &receiver_time) const {
|
267
|
+
return satellite_t::unavailable();
|
268
|
+
}
|
269
|
+
|
229
270
|
struct range_corrector_t {
|
230
271
|
virtual ~range_corrector_t() {}
|
231
272
|
virtual bool is_available(const gps_time_t &t) const {
|
@@ -838,21 +879,6 @@ protected:
|
|
838
879
|
}
|
839
880
|
|
840
881
|
public:
|
841
|
-
/**
|
842
|
-
* Calculate satellite position
|
843
|
-
*
|
844
|
-
* @param prn satellite number
|
845
|
-
* @param time GPS time
|
846
|
-
* @param res object to which results are stored
|
847
|
-
* @return If position is available, &res will be returned, otherwise NULL.
|
848
|
-
*/
|
849
|
-
virtual xyz_t *satellite_position(
|
850
|
-
const prn_t &prn,
|
851
|
-
const gps_time_t &time,
|
852
|
-
xyz_t &res) const {
|
853
|
-
return NULL;
|
854
|
-
}
|
855
|
-
|
856
882
|
/**
|
857
883
|
* Calculate User position/velocity with hint
|
858
884
|
* This is multi-constellation version,
|
@@ -882,8 +908,7 @@ public:
|
|
882
908
|
it != it_end; ++it){
|
883
909
|
typename measurement2_t::value_type v = {
|
884
910
|
it->first, &(it->second), &select(it->first)}; // prn, measurement, solver
|
885
|
-
|
886
|
-
if(!v.solver->satellite_position(v.prn, receiver_time, sat)){
|
911
|
+
if(!v.solver->select_satellite(v.prn, receiver_time).is_available()){
|
887
912
|
// pre-check satellite availability; remove it when its position is unknown
|
888
913
|
continue;
|
889
914
|
}
|
@@ -62,8 +62,6 @@ class RINEX_Reader {
|
|
62
62
|
typedef RINEX_Reader<U> self_t;
|
63
63
|
typedef std::map<std::string, std::vector<std::string> > header_t;
|
64
64
|
|
65
|
-
protected:
|
66
|
-
header_t _header;
|
67
65
|
struct src_stream_t : public std::istream {
|
68
66
|
src_stream_t(std::istream &is) : std::istream(is.rdbuf()) {}
|
69
67
|
/**
|
@@ -106,7 +104,11 @@ class RINEX_Reader {
|
|
106
104
|
}
|
107
105
|
return *this;
|
108
106
|
}
|
109
|
-
}
|
107
|
+
};
|
108
|
+
|
109
|
+
protected:
|
110
|
+
header_t _header;
|
111
|
+
src_stream_t src;
|
110
112
|
bool _has_next;
|
111
113
|
|
112
114
|
public:
|
@@ -198,7 +200,7 @@ class RINEX_Reader {
|
|
198
200
|
return true;
|
199
201
|
}
|
200
202
|
}
|
201
|
-
static bool
|
203
|
+
static bool f_pure(
|
202
204
|
std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
|
203
205
|
if(str2val){
|
204
206
|
std::stringstream ss(buf.substr(offset, length));
|
@@ -209,22 +211,30 @@ class RINEX_Reader {
|
|
209
211
|
ss << std::setfill(' ') << std::right << std::setw(length)
|
210
212
|
<< std::setprecision(precision) << std::fixed
|
211
213
|
<< *(T *)value;
|
212
|
-
|
214
|
+
buf.replace(offset, length, ss.str());
|
215
|
+
return true;
|
216
|
+
}
|
217
|
+
}
|
218
|
+
static bool f(
|
219
|
+
std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
|
220
|
+
bool res(f_pure(buf, offset, length, value, precision, str2val));
|
221
|
+
if((!str2val) && res){
|
213
222
|
if((*(T *)value) >= 0){
|
214
223
|
if((*(T *)value) < 1){
|
215
224
|
int i(length - precision - 2);
|
216
|
-
|
225
|
+
// 0.12345 => .12345
|
226
|
+
if(i >= 0){buf[i + offset] = ' ';}
|
217
227
|
}
|
218
228
|
}else{
|
219
229
|
if((*(T *)value) > -1){
|
220
230
|
int i(length - precision - 2);
|
221
|
-
|
222
|
-
if(
|
231
|
+
// -0.12345 => -.12345
|
232
|
+
if(i >= 0){buf[i + offset] = '-';}
|
233
|
+
if(--i >= 0){buf[i + offset] = ' ';}
|
223
234
|
}
|
224
235
|
}
|
225
|
-
buf.replace(offset, length, s);
|
226
|
-
return true;
|
227
236
|
}
|
237
|
+
return res;
|
228
238
|
}
|
229
239
|
static bool e(
|
230
240
|
std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
|
@@ -268,6 +278,14 @@ class RINEX_Reader {
|
|
268
278
|
std::string &buf, const int &offset, const int &length, void *value, const int &opt = 0, const bool &str2val = true){
|
269
279
|
return conv_t<T, false>::d(buf, offset, length, value, opt, str2val);
|
270
280
|
}
|
281
|
+
static bool f_pure(
|
282
|
+
std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
|
283
|
+
double v(*(T *)value);
|
284
|
+
bool res(
|
285
|
+
conv_t<double, false>::f_pure(buf, offset, length, &v, precision, str2val));
|
286
|
+
*(T *)value = static_cast<T>(v);
|
287
|
+
return res;
|
288
|
+
}
|
271
289
|
static bool f(
|
272
290
|
std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
|
273
291
|
double v(*(T *)value);
|
@@ -2183,10 +2183,11 @@ template <typename T>
|
|
2183
2183
|
typename SBAS_SpaceNode<FloatT>::KnownSatellites::list_t
|
2184
2184
|
SBAS_SpaceNode<FloatT>::KnownSatellites::sort(T sorter){
|
2185
2185
|
static const typename SBAS_SpaceNode<FloatT>::RangingCode codes[] = {
|
2186
|
+
{120, 145, 01106, 5, "ASECNA (A-SBAS)"},
|
2186
2187
|
{121, 175, 01241, 5, "EGNOS (Eutelsat 5WB)"},
|
2187
2188
|
{122, 52, 00267, 143.5, "SPAN (INMARSAT 4F1)"},
|
2188
2189
|
{123, 21, 00232, 31.5, "EGNOS (ASTRA 5B)"},
|
2189
|
-
{124, 237, 01617, 0, "
|
2190
|
+
//{124, 237, 01617, 0, "(Reserved)"},
|
2190
2191
|
{125, 235, 01076, -16, "SDCM (Luch-5A)"},
|
2191
2192
|
{126, 886, 01764, 63.9, "EGNOS (INMARSAT 4F2)"},
|
2192
2193
|
{127, 657, 00717, 55, "GAGAN (GSAT-8)"},
|
@@ -2198,16 +2199,30 @@ typename SBAS_SpaceNode<FloatT>::KnownSatellites::list_t
|
|
2198
2199
|
{133, 603, 01731, -129, "WAAS (SES-15)"},
|
2199
2200
|
{134, 130, 00706, 91.5, "KASS (MEASAT-3D)"},
|
2200
2201
|
{135, 359, 01216, -125, "WAAS (Intelsat Galaxy 30)"},
|
2201
|
-
{136, 595, 00740, 5, "EGNOS (
|
2202
|
+
{136, 595, 00740, 5, "EGNOS (HOTBIRD 13G)"},
|
2202
2203
|
{137, 68, 01007, 127, "MSAS (QZS-3)"},
|
2203
2204
|
{138, 386, 00450, 107.3, "WAAS (ANIK F1R)"},
|
2205
|
+
//{139, 797, 00305, 0, "MSAS (QZS-7)"},
|
2204
2206
|
{140, 456, 01653, 95, "SDCM (Luch-5V)"},
|
2205
2207
|
{141, 499, 01411, 167, "SDCM (Luch-5A)"},
|
2208
|
+
//{142, 883, 01644, 0, "(Unallocated)"},
|
2206
2209
|
{143, 307, 01312, 110.5, "BDSBAS (G3)"},
|
2207
2210
|
{144, 127, 01060, 80, "BDSBAS (G2)"},
|
2208
|
-
{
|
2211
|
+
//{145, 211, 01560, 0, "(Unallocated)"},
|
2212
|
+
//{146, 121, 00035, 0, "(Unallocated)"},
|
2213
|
+
{147, 118, 00355, 5, "ASECNA (A-SBAS)"},
|
2209
2214
|
{148, 163, 00335, -24.8, "ASAL (ALCOMSAT-1)"},
|
2210
|
-
}
|
2215
|
+
//{149, 628, 01254, 0, "(Unallocated)"},
|
2216
|
+
//{150, 853, 01041, 0, "EGNOS"},
|
2217
|
+
//{151, 484, 00142, 0, "(Unallocated)"},
|
2218
|
+
//{152, 289, 01641, 0, "(Unallocated)"},
|
2219
|
+
//{153, 811, 01504, 0, "(Unallocated)"},
|
2220
|
+
//{154, 202, 00751, 0, "(Unallocated)"},
|
2221
|
+
//{155, 1021, 01774, 0, "(Unallocated)"},
|
2222
|
+
//{156, 463, 00107, 0, "(Unallocated)"},
|
2223
|
+
//{157, 568, 01153, 0, "(Unallocated)"},
|
2224
|
+
//{158, 904, 01542, 0, "(Unallocated)"},
|
2225
|
+
}; ///< @see https://www.gps.gov/technical/prn-codes/L1-CA-PRN-code-assignments-2021-Jun.pdf
|
2211
2226
|
list_t res;
|
2212
2227
|
res.reserve(sizeof(codes) / sizeof(codes[0]));
|
2213
2228
|
for(unsigned int i(0); i < sizeof(codes) / sizeof(codes[0]); ++i){
|
@@ -73,7 +73,6 @@ class SBAS_SinglePositioning : public SolverBaseT {
|
|
73
73
|
|
74
74
|
typedef SBAS_SpaceNode<float_t> space_node_t;
|
75
75
|
inheritate_type(gps_time_t);
|
76
|
-
typedef typename space_node_t::Satellite satellite_t;
|
77
76
|
|
78
77
|
inheritate_type(xyz_t);
|
79
78
|
inheritate_type(enu_t);
|
@@ -81,6 +80,7 @@ class SBAS_SinglePositioning : public SolverBaseT {
|
|
81
80
|
inheritate_type(pos_t);
|
82
81
|
|
83
82
|
typedef typename base_t::measurement_t measurement_t;
|
83
|
+
typedef typename base_t::satellite_t satellite_t;
|
84
84
|
typedef typename base_t::range_error_t range_error_t;
|
85
85
|
typedef typename base_t::range_corrector_t range_corrector_t;
|
86
86
|
typedef typename base_t::range_correction_t range_correction_t;
|
@@ -92,11 +92,52 @@ class SBAS_SinglePositioning : public SolverBaseT {
|
|
92
92
|
SBAS_SinglePositioning_Options<float_t>, base_t> options_t;
|
93
93
|
|
94
94
|
protected:
|
95
|
-
const space_node_t &_space_node;
|
96
95
|
SBAS_SinglePositioning_Options<float_t> _options;
|
97
96
|
|
98
97
|
public:
|
99
|
-
|
98
|
+
struct satellites_t {
|
99
|
+
const void *impl;
|
100
|
+
satellite_t (*impl_select)(const void *, const prn_t &, const gps_time_t &);
|
101
|
+
inline satellite_t select(const prn_t &prn, const gps_time_t &receiver_time) const {
|
102
|
+
return impl_select(impl, prn, receiver_time);
|
103
|
+
}
|
104
|
+
static satellite_t select_broadcast(
|
105
|
+
const void *ptr, const prn_t &prn, const gps_time_t &receiver_time){
|
106
|
+
const typename space_node_t::satellites_t &sats(
|
107
|
+
reinterpret_cast<const space_node_t *>(ptr)->satellites());
|
108
|
+
const typename space_node_t::satellites_t::const_iterator it_sat(sats.find(prn));
|
109
|
+
if((it_sat == sats.end()) // has ephemeris?
|
110
|
+
|| (!it_sat->second.ephemeris().is_valid(receiver_time))){ // valid ephemeris?
|
111
|
+
return satellite_t::unavailable();
|
112
|
+
}
|
113
|
+
struct impl_t {
|
114
|
+
static inline const typename space_node_t::Satellite &sat(const void *ptr) {
|
115
|
+
return *reinterpret_cast<const typename space_node_t::Satellite *>(ptr);
|
116
|
+
}
|
117
|
+
static xyz_t position(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
118
|
+
return sat(ptr).ephemeris().constellation(t, pseudo_range, false).position;
|
119
|
+
}
|
120
|
+
static xyz_t velocity(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
121
|
+
return sat(ptr).ephemeris().constellation(t, pseudo_range, true).velocity;
|
122
|
+
}
|
123
|
+
static float_t clock_error(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
124
|
+
// Clock correction is taken into account in position()
|
125
|
+
return 0;
|
126
|
+
}
|
127
|
+
static float_t clock_error_dot(const void *ptr, const gps_time_t &t, const float_t &pseudo_range) {
|
128
|
+
// Clock rate error is taken in account in velocity()
|
129
|
+
return 0;
|
130
|
+
}
|
131
|
+
};
|
132
|
+
satellite_t res = {
|
133
|
+
&(it_sat->second),
|
134
|
+
impl_t::position, impl_t::velocity,
|
135
|
+
impl_t::clock_error, impl_t::clock_error_dot};
|
136
|
+
return res;
|
137
|
+
}
|
138
|
+
satellites_t(const space_node_t &sn)
|
139
|
+
: impl(&sn), impl_select(select_broadcast) {}
|
140
|
+
} satellites;
|
100
141
|
|
101
142
|
struct ionospheric_sbas_t : public range_corrector_t {
|
102
143
|
const space_node_t &space_node;
|
@@ -155,7 +196,8 @@ class SBAS_SinglePositioning : public SolverBaseT {
|
|
155
196
|
}
|
156
197
|
|
157
198
|
SBAS_SinglePositioning(const space_node_t &sn)
|
158
|
-
: base_t(),
|
199
|
+
: base_t(), _options(available_options(options_t())),
|
200
|
+
satellites(sn),
|
159
201
|
ionospheric_sbas(sn), tropospheric_sbas() {
|
160
202
|
|
161
203
|
// default ionospheric correction: Broadcasted IGP.
|
@@ -168,25 +210,17 @@ class SBAS_SinglePositioning : public SolverBaseT {
|
|
168
210
|
~SBAS_SinglePositioning(){}
|
169
211
|
|
170
212
|
/**
|
171
|
-
*
|
213
|
+
* Select satellite by using PRN and time
|
172
214
|
*
|
173
215
|
* @param prn satellite number
|
174
216
|
* @param receiver_time receiver time
|
175
|
-
* @return (
|
176
|
-
* otherwise NULL.
|
217
|
+
* @return (satellite_t) If available, satellite.is_available() returning true is returned.
|
177
218
|
*/
|
178
|
-
|
179
|
-
const
|
219
|
+
satellite_t select_satellite(
|
220
|
+
const prn_t &prn,
|
180
221
|
const gps_time_t &receiver_time) const {
|
181
|
-
|
182
|
-
|
183
|
-
const typename space_node_t::satellites_t::const_iterator it_sat(sats.find(prn));
|
184
|
-
if((it_sat == sats.end()) // has ephemeris?
|
185
|
-
|| (!it_sat->second.ephemeris().is_valid(receiver_time))){ // valid ephemeris?
|
186
|
-
return NULL;
|
187
|
-
}
|
188
|
-
|
189
|
-
return &(it_sat->second);
|
222
|
+
if(_options.exclude_prn[prn]){return satellite_t::unavailable();}
|
223
|
+
return satellites.select(prn, receiver_time);
|
190
224
|
}
|
191
225
|
|
192
226
|
/**
|
@@ -210,33 +244,28 @@ class SBAS_SinglePositioning : public SolverBaseT {
|
|
210
244
|
|
211
245
|
relative_property_t res = {0};
|
212
246
|
|
213
|
-
if(_options.exclude_prn[prn]){return res;}
|
214
|
-
|
215
247
|
float_t range;
|
216
248
|
range_error_t range_error;
|
217
249
|
if(!this->range(measurement, range, &range_error)){
|
218
250
|
return res; // If no range entry, return with weight = 0
|
219
251
|
}
|
220
252
|
|
221
|
-
|
222
|
-
if(!sat){return res;} // If satellite is unavailable, return with weight = 0
|
253
|
+
satellite_t sat(select_satellite(prn, time_arrival));
|
254
|
+
if(!sat.is_available()){return res;} // If satellite is unavailable, return with weight = 0
|
223
255
|
|
224
256
|
///< The following procedure is based on Appendix.S with modification
|
225
257
|
|
226
258
|
range -= receiver_error;
|
227
259
|
|
228
|
-
// Clock correction
|
229
|
-
|
230
|
-
|
231
|
-
|
260
|
+
// Clock error correction
|
261
|
+
range += ((range_error.unknown_flag & range_error_t::SATELLITE_CLOCK)
|
262
|
+
? (sat.clock_error(time_arrival, range) * GPS_SpaceNode<float_t>::light_speed)
|
263
|
+
: range_error.value[range_error_t::SATELLITE_CLOCK]);
|
232
264
|
|
233
265
|
// TODO WAAS long term clock correction (2.1.1.4.11)
|
234
266
|
|
235
|
-
// Calculate satellite position
|
236
|
-
|
237
|
-
sat->ephemeris().constellation(time_arrival, range));
|
238
|
-
|
239
|
-
const xyz_t &sat_pos(sat_pos_vel.position);
|
267
|
+
// Calculate satellite position
|
268
|
+
xyz_t sat_pos(sat.position(time_arrival, range));
|
240
269
|
float_t geometric_range(usr_pos.xyz.dist(sat_pos));
|
241
270
|
|
242
271
|
// Calculate residual with Sagnac correction (A.4.4.11)
|
@@ -283,24 +312,15 @@ class SBAS_SinglePositioning : public SolverBaseT {
|
|
283
312
|
|
284
313
|
res.range_corrected = range;
|
285
314
|
|
286
|
-
xyz_t rel_vel(
|
315
|
+
xyz_t rel_vel(sat.velocity(time_arrival, range) - usr_vel); // Calculate velocity
|
287
316
|
|
288
|
-
// Note: clock rate error is already accounted for in constellation()
|
289
317
|
res.rate_relative_neg = res.los_neg[0] * rel_vel.x()
|
290
318
|
+ res.los_neg[1] * rel_vel.y()
|
291
|
-
+ res.los_neg[2] * rel_vel.z()
|
319
|
+
+ res.los_neg[2] * rel_vel.z()
|
320
|
+
+ sat.clock_error_dot(time_arrival, range) * GPS_SpaceNode<float_t>::light_speed;
|
292
321
|
|
293
322
|
return res;
|
294
323
|
}
|
295
|
-
|
296
|
-
xyz_t *satellite_position(
|
297
|
-
const prn_t &prn,
|
298
|
-
const gps_time_t &time,
|
299
|
-
xyz_t &res) const {
|
300
|
-
|
301
|
-
const satellite_t *sat(is_available(prn, time));
|
302
|
-
return sat ? &(res = sat->ephemeris().constellation(time).position) : NULL;
|
303
|
-
}
|
304
324
|
};
|
305
325
|
|
306
326
|
#endif /* __SBAS_SOLVER_H__ */
|
@@ -1104,7 +1104,7 @@ struct GPS_RangeCorrector
|
|
1104
1104
|
%ignore glonass;
|
1105
1105
|
%ignore select_solver;
|
1106
1106
|
%ignore relative_property;
|
1107
|
-
%ignore
|
1107
|
+
%ignore select_satellite;
|
1108
1108
|
%ignore update_position_solution;
|
1109
1109
|
%ignore user_correctors_t;
|
1110
1110
|
%ignore user_correctors;
|
@@ -1201,47 +1201,17 @@ struct GPS_RangeCorrector
|
|
1201
1201
|
return super_t::update_position_solution(geomat, res);
|
1202
1202
|
}
|
1203
1203
|
template <>
|
1204
|
-
GPS_Solver<FloatT>::base_t::
|
1204
|
+
GPS_Solver<FloatT>::base_t::satellite_t GPS_Solver<FloatT>::select_satellite(
|
1205
1205
|
const GPS_Solver<FloatT>::base_t::prn_t &prn,
|
1206
|
-
const GPS_Solver<FloatT>::base_t::gps_time_t &time
|
1207
|
-
|
1208
|
-
|
1209
|
-
select_solver(prn).satellite_position(prn, time, buf));
|
1206
|
+
const GPS_Solver<FloatT>::base_t::gps_time_t &time) const {
|
1207
|
+
GPS_Solver<FloatT>::base_t::satellite_t res(
|
1208
|
+
select_solver(prn).select_satellite(prn, time));
|
1210
1209
|
#ifdef SWIGRUBY
|
1211
|
-
|
1212
|
-
static const VALUE key(ID2SYM(rb_intern("
|
1210
|
+
if(!res.is_available()){
|
1211
|
+
static const VALUE key(ID2SYM(rb_intern("relative_property")));
|
1213
1212
|
VALUE hook(rb_hash_lookup(hooks, key));
|
1214
|
-
if(NIL_P(hook)){
|
1215
|
-
|
1216
|
-
SWIG_From(int)(prn), // prn
|
1217
|
-
SWIG_NewPointerObj( // time
|
1218
|
-
new base_t::gps_time_t(time), $descriptor(GPS_Time<FloatT> *), SWIG_POINTER_OWN),
|
1219
|
-
(res // position (internally calculated)
|
1220
|
-
? SWIG_NewPointerObj(res, $descriptor(System_XYZ<FloatT, WGS84> *), 0)
|
1221
|
-
: Qnil)};
|
1222
|
-
VALUE res_hook(proc_call_throw_if_error(hook, sizeof(values) / sizeof(values[0]), values));
|
1223
|
-
if(NIL_P(res_hook)){ // unknown position
|
1224
|
-
res = NULL;
|
1225
|
-
break;
|
1226
|
-
}else if(RB_TYPE_P(res_hook, T_ARRAY) && (RARRAY_LEN(res_hook) == 3)){
|
1227
|
-
int i(0);
|
1228
|
-
for(; i < 3; ++i){
|
1229
|
-
VALUE v(RARRAY_AREF(res_hook, i));
|
1230
|
-
if(!SWIG_IsOK(swig::asval(v, &buf[i]))){break;}
|
1231
|
-
}
|
1232
|
-
if(i == 3){
|
1233
|
-
res = &buf;
|
1234
|
-
break;
|
1235
|
-
}
|
1236
|
-
}else if(SWIG_IsOK(SWIG_ConvertPtr(
|
1237
|
-
res_hook, (void **)&res, $descriptor(System_XYZ<FloatT, WGS84> *), 0))){
|
1238
|
-
res = &(buf = *res);
|
1239
|
-
break;
|
1240
|
-
}
|
1241
|
-
throw std::runtime_error(
|
1242
|
-
std::string("System_XYZ or [d * 3] is expected (d: " %str(FloatT) "), however ")
|
1243
|
-
.append(inspect_str(res_hook)));
|
1244
|
-
}while(false);
|
1213
|
+
if(!NIL_P(hook)){res.impl = this;}
|
1214
|
+
}
|
1245
1215
|
#endif
|
1246
1216
|
return res;
|
1247
1217
|
}
|
@@ -1481,10 +1451,9 @@ struct GPS_Solver
|
|
1481
1451
|
const typename base_t::gps_time_t &time_arrival,
|
1482
1452
|
const typename base_t::pos_t &usr_pos,
|
1483
1453
|
const typename base_t::xyz_t &usr_vel) const;
|
1484
|
-
virtual typename base_t::
|
1454
|
+
virtual typename base_t::satellite_t select_satellite(
|
1485
1455
|
const typename base_t::prn_t &prn,
|
1486
|
-
const typename base_t::gps_time_t &time
|
1487
|
-
typename base_t::xyz_t &res) const;
|
1456
|
+
const typename base_t::gps_time_t &time) const;
|
1488
1457
|
virtual bool update_position_solution(
|
1489
1458
|
const typename base_t::geometric_matrices_t &geomat,
|
1490
1459
|
typename base_t::user_pvt_t &res) const;
|
@@ -375,22 +375,6 @@ __RINEX_OBS_TEXT__
|
|
375
375
|
expect(mat).to respond_to(:resize!)
|
376
376
|
}
|
377
377
|
}
|
378
|
-
solver.hooks[:satellite_position] = proc{
|
379
|
-
i = 0
|
380
|
-
proc{|prn, time, pos|
|
381
|
-
expect(input[:measurement]).to include(prn)
|
382
|
-
expect(pos).to be_a_kind_of(Coordinate::XYZ).or eq(nil)
|
383
|
-
# System_XYZ or [x,y,z] or nil(= unknown position) are acceptable
|
384
|
-
case (i += 1) % 5
|
385
|
-
when 0
|
386
|
-
nil
|
387
|
-
when 1
|
388
|
-
pos.to_a
|
389
|
-
else
|
390
|
-
pos
|
391
|
-
end
|
392
|
-
}
|
393
|
-
}.call
|
394
378
|
pvt = solver.solve(
|
395
379
|
input[:measurement].collect{|prn, items|
|
396
380
|
items.collect{|k, v| [prn, k, v]}
|
data/lib/gps_pvt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gps_pvt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fenrir(M.Naruoka)
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|