gps_pvt 0.1.1

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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/CHANGELOG.md +5 -0
  4. data/CODE_OF_CONDUCT.md +84 -0
  5. data/Gemfile +10 -0
  6. data/README.md +86 -0
  7. data/Rakefile +86 -0
  8. data/bin/console +15 -0
  9. data/bin/setup +8 -0
  10. data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +6613 -0
  11. data/ext/gps_pvt/GPS/GPS_wrap.cxx +16019 -0
  12. data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +21050 -0
  13. data/ext/gps_pvt/extconf.rb +70 -0
  14. data/ext/ninja-scan-light/tool/navigation/EGM.h +2971 -0
  15. data/ext/ninja-scan-light/tool/navigation/GPS.h +2432 -0
  16. data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +479 -0
  17. data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +1081 -0
  18. data/ext/ninja-scan-light/tool/navigation/GPS_Solver_MultiFrequency.h +199 -0
  19. data/ext/ninja-scan-light/tool/navigation/GPS_Solver_RAIM.h +210 -0
  20. data/ext/ninja-scan-light/tool/navigation/MagneticField.h +928 -0
  21. data/ext/ninja-scan-light/tool/navigation/NTCM.h +211 -0
  22. data/ext/ninja-scan-light/tool/navigation/RINEX.h +1781 -0
  23. data/ext/ninja-scan-light/tool/navigation/WGS84.h +186 -0
  24. data/ext/ninja-scan-light/tool/navigation/coordinate.h +406 -0
  25. data/ext/ninja-scan-light/tool/param/bit_array.h +145 -0
  26. data/ext/ninja-scan-light/tool/param/complex.h +558 -0
  27. data/ext/ninja-scan-light/tool/param/matrix.h +4049 -0
  28. data/ext/ninja-scan-light/tool/param/matrix_fixed.h +665 -0
  29. data/ext/ninja-scan-light/tool/param/matrix_special.h +562 -0
  30. data/ext/ninja-scan-light/tool/param/quaternion.h +765 -0
  31. data/ext/ninja-scan-light/tool/param/vector3.h +651 -0
  32. data/ext/ninja-scan-light/tool/swig/Coordinate.i +177 -0
  33. data/ext/ninja-scan-light/tool/swig/GPS.i +1102 -0
  34. data/ext/ninja-scan-light/tool/swig/SylphideMath.i +1234 -0
  35. data/ext/ninja-scan-light/tool/swig/extconf.rb +5 -0
  36. data/ext/ninja-scan-light/tool/swig/makefile +53 -0
  37. data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +417 -0
  38. data/ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb +489 -0
  39. data/gps_pvt.gemspec +57 -0
  40. data/lib/gps_pvt/receiver.rb +375 -0
  41. data/lib/gps_pvt/ubx.rb +148 -0
  42. data/lib/gps_pvt/version.rb +5 -0
  43. data/lib/gps_pvt.rb +9 -0
  44. data/sig/gps_pvt.rbs +4 -0
  45. metadata +117 -0
@@ -0,0 +1,1102 @@
1
+ /**
2
+ * @file SWIG interface file for GPS related classes
3
+ *
4
+ */
5
+
6
+ %module GPS
7
+
8
+ %{
9
+ #if defined(SWIGRUBY)
10
+ #undef isfinite
11
+ #endif
12
+
13
+ #include <string>
14
+ #include <vector>
15
+ #include <iostream>
16
+ #include <fstream>
17
+ #include <exception>
18
+
19
+ #include "navigation/GPS.h"
20
+ #include "navigation/RINEX.h"
21
+
22
+ #include "navigation/GPS_Solver_Base.h"
23
+ #include "navigation/GPS_Solver.h"
24
+ #include "navigation/GPS_Solver_RAIM.h"
25
+ %}
26
+
27
+ %include typemaps.i
28
+ %include std_common.i
29
+ %include std_string.i
30
+ %include exception.i
31
+
32
+ #if !defined(SWIGIMPORTED)
33
+ %header {
34
+ struct native_exception : public std::exception {
35
+ #if defined(SWIGRUBY)
36
+ int state;
37
+ native_exception(const int &state_) : std::exception(), state(state_) {}
38
+ void regenerate() const {rb_jump_tag(state);}
39
+ #else
40
+ void regenerate() const {}
41
+ #endif
42
+ };
43
+ }
44
+ %exception {
45
+ try {
46
+ $action
47
+ } catch (const native_exception &e) {
48
+ e.regenerate();
49
+ SWIG_fail;
50
+ } catch (const std::exception& e) {
51
+ SWIG_exception_fail(SWIG_RuntimeError, e.what());
52
+ }
53
+ }
54
+ #endif
55
+
56
+ #ifdef SWIGRUBY
57
+ %header {
58
+ static VALUE yield_throw_if_error(const int &argc, const VALUE *argv) {
59
+ struct yield_t {
60
+ const int &argc;
61
+ const VALUE *argv;
62
+ static VALUE run(VALUE v){
63
+ yield_t *arg(reinterpret_cast<yield_t *>(v));
64
+ return rb_yield_values2(arg->argc, arg->argv);
65
+ }
66
+ } arg = {argc, argv};
67
+ int state;
68
+ VALUE res(rb_protect(yield_t::run, reinterpret_cast<VALUE>(&arg), &state));
69
+ if(state != 0){throw native_exception(state);}
70
+ return res;
71
+ }
72
+ static VALUE proc_call_throw_if_error(
73
+ const VALUE &arg0, const int &argc, const VALUE *argv) {
74
+ struct proc_call_t {
75
+ const VALUE &arg0;
76
+ const int &argc;
77
+ const VALUE *argv;
78
+ static VALUE run(VALUE v){
79
+ proc_call_t *arg(reinterpret_cast<proc_call_t *>(v));
80
+ return rb_proc_call_with_block(arg->arg0, arg->argc, arg->argv, Qnil);
81
+ }
82
+ } arg = {arg0, argc, argv};
83
+ int state;
84
+ VALUE res(rb_protect(proc_call_t::run, reinterpret_cast<VALUE>(&arg), &state));
85
+ if(state != 0){throw native_exception(state);}
86
+ return res;
87
+ }
88
+ static std::string inspect_str(const VALUE &v){
89
+ VALUE v_inspect(rb_inspect(v));
90
+ return std::string(RSTRING_PTR(v_inspect), RSTRING_LEN(v_inspect));
91
+ }
92
+ }
93
+ #endif
94
+
95
+ %feature("autodoc", "1");
96
+
97
+ %import "SylphideMath.i"
98
+ %import "Coordinate.i"
99
+
100
+ %extend GPS_Time {
101
+ %typemap(out) std::tm {
102
+ %append_output(SWIG_From(int)($1.tm_year + 1900));
103
+ %append_output(SWIG_From(int)($1.tm_mon + 1));
104
+ %append_output(SWIG_From(int)($1.tm_mday));
105
+ %append_output(SWIG_From(int)($1.tm_hour));
106
+ %append_output(SWIG_From(int)($1.tm_min));
107
+ %append_output(SWIG_From(int)($1.tm_sec));
108
+ }
109
+ #if defined(SWIGRUBY)
110
+ %typemap(in) const std::tm & (std::tm temp = {0}) {
111
+ $1 = &temp;
112
+ int *dst[] = {
113
+ &(temp.tm_year),
114
+ &(temp.tm_mon),
115
+ &(temp.tm_mday),
116
+ &(temp.tm_hour),
117
+ &(temp.tm_min),
118
+ &(temp.tm_sec),
119
+ };
120
+ int i_max(sizeof(dst) / sizeof(dst[0]));
121
+ if(i_max > RARRAY_LEN($input)){i_max = RARRAY_LEN($input);}
122
+ for(int i(0); i < i_max; ++i){
123
+ SWIG_Object obj = rb_ary_entry($input, i);
124
+ int v;
125
+ if(SWIG_IsOK(SWIG_AsVal(int)(obj, &v))){
126
+ if(dst[i] == &(temp.tm_year)){
127
+ *dst[i] = v - 1900;
128
+ }else if(dst[i] == &(temp.tm_mon)){
129
+ *dst[i] = v - 1;
130
+ }else{
131
+ *dst[i] = v;
132
+ }
133
+ }else{
134
+ SWIG_exception(SWIG_TypeError, "int is expected");
135
+ }
136
+ }
137
+ }
138
+ %typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) const std::tm & {
139
+ $1 = (TYPE($input) == T_ARRAY) ? 1 : 0;
140
+ }
141
+ #endif
142
+ %apply int *OUTPUT { int *week };
143
+ %apply FloatT *OUTPUT { FloatT *seconds };
144
+ void to_a(int *week, FloatT *seconds) const {
145
+ *week = self->week;
146
+ *seconds = self->seconds;
147
+ }
148
+ }
149
+
150
+ %define MAKE_ACCESSOR(name, type)
151
+ %rename(%str(name ## =)) set_ ## name;
152
+ type set_ ## name (const type &v) {
153
+ return self->name = v;
154
+ }
155
+ %rename(%str(name)) get_ ## name;
156
+ const type &get_ ## name () const {
157
+ return self->name;
158
+ }
159
+ %enddef
160
+
161
+ %define MAKE_VECTOR2ARRAY(type)
162
+ %typemap(out) std::vector<type> {
163
+ #if defined(SWIGRUBY)
164
+ $result = rb_ary_new();
165
+ #endif
166
+ for($1_type::const_iterator it($1.begin()), it_end($1.end());
167
+ it != it_end; ++it){
168
+ %append_output(SWIG_From(type)(*it));
169
+ }
170
+ }
171
+ %enddef
172
+
173
+ %inline %{
174
+ template <class FloatT>
175
+ struct GPS_Ionospheric_UTC_Parameters : public GPS_SpaceNode<FloatT>::Ionospheric_UTC_Parameters {};
176
+ %}
177
+ %extend GPS_Ionospheric_UTC_Parameters {
178
+ %fragment(SWIG_Traits_frag(FloatT));
179
+ %typemap(in,numinputs=0) FloatT values[4] (FloatT temp[4]) %{
180
+ $1 = temp;
181
+ %}
182
+ %typemap(argout) FloatT values[4] {
183
+ for(int i(0); i < 4; ++i){
184
+ %append_output(swig::from($1[i]));
185
+ }
186
+ }
187
+ %typemap(in) const FloatT values[4] (FloatT temp[4]) {
188
+ #ifdef SWIGRUBY
189
+ if(!(RB_TYPE_P($input, T_ARRAY) && (RARRAY_LEN($input) == 4))){
190
+ SWIG_exception(SWIG_TypeError, "array[4] is expected");
191
+ }
192
+ for(int i(0); i < 4; ++i){
193
+ SWIG_Object obj(RARRAY_AREF($input, i));
194
+ if(!SWIG_IsOK(swig::asval(obj, &temp[i]))){
195
+ SWIG_exception(SWIG_TypeError, "$*1_ltype is expected");
196
+ }
197
+ }
198
+ #endif
199
+ $1 = temp;
200
+ }
201
+ %typemap(in) const unsigned int *buf (unsigned int temp[10]) {
202
+ #ifdef SWIGRUBY
203
+ if((!RB_TYPE_P($input, T_ARRAY))
204
+ || (RARRAY_LEN($input) < sizeof(temp) / sizeof(temp[0]))){
205
+ SWIG_exception(SWIG_TypeError, "array is expected, or too short array");
206
+ }
207
+ $1 = temp;
208
+ for(int i(0); i < sizeof(temp) / sizeof(temp[0]); ++i){
209
+ if(!SWIG_IsOK(SWIG_AsVal(unsigned int)(RARRAY_AREF($input, i), &($1[i])))){
210
+ SWIG_exception(SWIG_TypeError, "$*1_ltype is expected");
211
+ }
212
+ }
213
+ #endif
214
+ }
215
+ %rename("alpha=") set_alpha;
216
+ void set_alpha(const FloatT values[4]){
217
+ for(int i(0); i < 4; ++i){
218
+ self->alpha[i] = values[i];
219
+ }
220
+ }
221
+ %rename("alpha") get_alpha;
222
+ void get_alpha(FloatT values[4]) const {
223
+ for(int i(0); i < 4; ++i){
224
+ values[i] = self->alpha[i];
225
+ }
226
+ }
227
+ %rename("beta=") set_beta;
228
+ void set_beta(const FloatT values[4]){
229
+ for(int i(0); i < 4; ++i){
230
+ self->beta[i] = values[i];
231
+ }
232
+ }
233
+ %rename("beta") get_beta;
234
+ void get_beta(FloatT values[4]) const {
235
+ for(int i(0); i < 4; ++i){
236
+ values[i] = self->beta[i];
237
+ }
238
+ }
239
+ MAKE_ACCESSOR(A1, FloatT);
240
+ MAKE_ACCESSOR(A0, FloatT);
241
+ MAKE_ACCESSOR(t_ot, unsigned int);
242
+ MAKE_ACCESSOR(WN_t, unsigned int);
243
+ MAKE_ACCESSOR(delta_t_LS, int);
244
+ MAKE_ACCESSOR(WN_LSF, unsigned int);
245
+ MAKE_ACCESSOR(DN, unsigned int);
246
+ MAKE_ACCESSOR(delta_t_LSF, int);
247
+ static GPS_Ionospheric_UTC_Parameters<FloatT> parse(const unsigned int *buf){
248
+ typedef typename GPS_SpaceNode<FloatT>
249
+ ::template BroadcastedMessage<unsigned int, 30> parser_t;
250
+ if((parser_t::subframe_id(buf) != 4) || (parser_t::sv_page_id(buf) != 56)){
251
+ throw std::runtime_error("Not valid data");
252
+ }
253
+ typename GPS_SpaceNode<FloatT>::Ionospheric_UTC_Parameters::raw_t raw;
254
+ raw.template update<2, 0>(buf);
255
+ GPS_Ionospheric_UTC_Parameters<FloatT> res;
256
+ (typename GPS_SpaceNode<FloatT>::Ionospheric_UTC_Parameters &)res = raw;
257
+ return res;
258
+ }
259
+ }
260
+
261
+ %inline %{
262
+ template <class FloatT>
263
+ struct GPS_Ephemeris : public GPS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris {
264
+ int iode_subframe3;
265
+ void invalidate() {
266
+ this->iodc = this->iode = iode_subframe3 = -1;
267
+ }
268
+ bool is_consistent() const {
269
+ return !((this->iodc < 0)
270
+ || (this->iode != this->iode_subframe3)
271
+ || ((this->iodc & 0xFF) != this->iode));
272
+ }
273
+ GPS_Ephemeris() : GPS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris() {
274
+ invalidate();
275
+ }
276
+ GPS_Ephemeris(const typename GPS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris &eph)
277
+ : GPS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris(eph),
278
+ iode_subframe3(eph.iode) {}
279
+ };
280
+ %}
281
+ %extend GPS_Ephemeris {
282
+ MAKE_ACCESSOR(svid, unsigned int);
283
+
284
+ MAKE_ACCESSOR(WN, unsigned int);
285
+ MAKE_ACCESSOR(URA, int);
286
+ MAKE_ACCESSOR(SV_health, unsigned int);
287
+ MAKE_ACCESSOR(iodc, int);
288
+ MAKE_ACCESSOR(t_GD, FloatT);
289
+ MAKE_ACCESSOR(t_oc, FloatT);
290
+ MAKE_ACCESSOR(a_f2, FloatT);
291
+ MAKE_ACCESSOR(a_f1, FloatT);
292
+ MAKE_ACCESSOR(a_f0, FloatT);
293
+
294
+ MAKE_ACCESSOR(iode, int);
295
+ MAKE_ACCESSOR(c_rs, FloatT);
296
+ MAKE_ACCESSOR(delta_n, FloatT);
297
+ MAKE_ACCESSOR(M0, FloatT);
298
+ MAKE_ACCESSOR(c_uc, FloatT);
299
+ MAKE_ACCESSOR(e, FloatT);
300
+ MAKE_ACCESSOR(c_us, FloatT);
301
+ MAKE_ACCESSOR(sqrt_A, FloatT);
302
+ MAKE_ACCESSOR(t_oe, FloatT);
303
+ MAKE_ACCESSOR(fit_interval, FloatT);
304
+
305
+ MAKE_ACCESSOR(c_ic, FloatT);
306
+ MAKE_ACCESSOR(Omega0, FloatT);
307
+ MAKE_ACCESSOR(c_is, FloatT);
308
+ MAKE_ACCESSOR(i0, FloatT);
309
+ MAKE_ACCESSOR(c_rc, FloatT);
310
+ MAKE_ACCESSOR(omega, FloatT);
311
+ MAKE_ACCESSOR(dot_Omega0, FloatT);
312
+ MAKE_ACCESSOR(dot_i0, FloatT);
313
+ %typemap(in) const unsigned int *buf (unsigned int temp[10]) {
314
+ #ifdef SWIGRUBY
315
+ if((!RB_TYPE_P($input, T_ARRAY))
316
+ || (RARRAY_LEN($input) < sizeof(temp) / sizeof(temp[0]))){
317
+ SWIG_exception(SWIG_TypeError, "array is expected, or too short array");
318
+ }
319
+ $1 = temp;
320
+ for(int i(0); i < sizeof(temp) / sizeof(temp[0]); ++i){
321
+ if(!SWIG_IsOK(SWIG_AsVal(unsigned int)(RARRAY_AREF($input, i), &($1[i])))){
322
+ SWIG_exception(SWIG_TypeError, "$*1_ltype is expected");
323
+ }
324
+ }
325
+ #endif
326
+ }
327
+ %apply int *OUTPUT { int *subframe_no, int *iodc_or_iode };
328
+ void parse(const unsigned int *buf, int *subframe_no, int *iodc_or_iode){
329
+ typedef typename GPS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris eph_t;
330
+ typename eph_t::raw_t raw;
331
+ eph_t eph;
332
+ *subframe_no = GPS_SpaceNode<FloatT>
333
+ ::template BroadcastedMessage<unsigned int, 30>
334
+ ::subframe_id(buf);
335
+ *iodc_or_iode = -1;
336
+ switch(*subframe_no){
337
+ case 1:
338
+ *iodc_or_iode = raw.template update_subframe1<2, 0>(buf);
339
+ eph = raw;
340
+ self->WN = eph.WN;
341
+ self->URA = eph.URA;
342
+ self->SV_health = eph.SV_health;
343
+ self->iodc = eph.iodc;
344
+ self->t_GD = eph.t_GD;
345
+ self->t_oc = eph.t_oc;
346
+ self->a_f2 = eph.a_f2;
347
+ self->a_f1 = eph.a_f1;
348
+ self->a_f0 = eph.a_f0;
349
+ break;
350
+ case 2:
351
+ *iodc_or_iode = raw.template update_subframe2<2, 0>(buf);
352
+ eph = raw;
353
+ self->iode = eph.iode;
354
+ self->c_rs = eph.c_rs;
355
+ self->delta_n = eph.delta_n;
356
+ self->M0 = eph.M0;
357
+ self->c_uc = eph.c_uc;
358
+ self->e = eph.e;
359
+ self->c_us = eph.c_us;
360
+ self->sqrt_A = eph.sqrt_A;
361
+ self->t_oe = eph.t_oe;
362
+ self->fit_interval = eph_t::raw_t::fit_interval(raw.fit_interval_flag, self->iodc);
363
+ break;
364
+ case 3:
365
+ *iodc_or_iode = self->iode_subframe3 = raw.template update_subframe3<2, 0>(buf);
366
+ eph = raw;
367
+ self->c_ic = eph.c_ic;
368
+ self->Omega0 = eph.Omega0;
369
+ self->c_is = eph.c_is;
370
+ self->i0 = eph.i0;
371
+ self->c_rc = eph.c_rc;
372
+ self->omega = eph.omega;
373
+ self->dot_Omega0 = eph.dot_Omega0;
374
+ self->dot_i0 = eph.dot_i0;
375
+ break;
376
+ }
377
+ }
378
+ %typemap(in,numinputs=0) System_XYZ<FloatT, WGS84> & (System_XYZ<FloatT, WGS84> temp) %{
379
+ $1 = &temp;
380
+ %}
381
+ %typemap(argout) System_XYZ<FloatT, WGS84> & {
382
+ %append_output(SWIG_NewPointerObj((new $*1_ltype(*$1)), $1_descriptor, SWIG_POINTER_OWN));
383
+ }
384
+ void constellation(
385
+ System_XYZ<FloatT, WGS84> &position, System_XYZ<FloatT, WGS84> &velocity,
386
+ const GPS_Time<FloatT> &t, const FloatT &pseudo_range = 0,
387
+ const bool &with_velocity = true) const {
388
+ typename GPS_SpaceNode<FloatT>::SatelliteProperties::constellation_t res(
389
+ self->constellation(t, pseudo_range, with_velocity));
390
+ position = res.position;
391
+ velocity = res.velocity;
392
+ }
393
+ #if defined(SWIGRUBY)
394
+ %rename("consistent?") is_consistent;
395
+ #endif
396
+ }
397
+
398
+ %extend GPS_SpaceNode {
399
+ %fragment(SWIG_Traits_frag(FloatT));
400
+ %typemap(out) const Ionospheric_UTC_Parameters & {
401
+ %set_output(SWIG_NewPointerObj(
402
+ %reinterpret_cast($1, GPS_Ionospheric_UTC_Parameters<FloatT> *),
403
+ $descriptor(GPS_Ionospheric_UTC_Parameters<FloatT> *), 0));
404
+ }
405
+ %ignore satellites() const;
406
+ %ignore satellite(const int &);
407
+ void register_ephemeris(
408
+ const int &prn, const GPS_Ephemeris<FloatT> &eph,
409
+ const int &priority_delta = 1){
410
+ self->satellite(prn).register_ephemeris(eph, priority_delta);
411
+ }
412
+ GPS_Ephemeris<FloatT> ephemeris(const int &prn) const {
413
+ return GPS_Ephemeris<FloatT>(
414
+ %const_cast(self, GPS_SpaceNode<FloatT> *)->satellite(prn).ephemeris());
415
+ }
416
+ %typemap(out) pierce_point_res_t {
417
+ %append_output(swig::from($1.latitude));
418
+ %append_output(swig::from($1.longitude));
419
+ }
420
+ %ignore iono_correction() const;
421
+ %ignore tropo_correction() const;
422
+ int read(const char *fname) {
423
+ std::fstream fin(fname, std::ios::in | std::ios::binary);
424
+ return RINEX_NAV_Reader<FloatT>::read_all(fin, *self);
425
+ }
426
+ }
427
+
428
+ %include navigation/GPS.h
429
+
430
+ %extend GPS_User_PVT {
431
+ %ignore solver_t;
432
+ %ignore base_t;
433
+ %ignore proxy_t;
434
+ %ignore linear_solver;
435
+ %ignore GPS_User_PVT(const base_t &);
436
+ MAKE_VECTOR2ARRAY(int);
437
+ #ifdef SWIGRUBY
438
+ %rename("position_solved?") position_solved;
439
+ %rename("velocity_solved?") velocity_solved;
440
+ #endif
441
+ %fragment(SWIG_Traits_frag(FloatT));
442
+ %typemap(in, numinputs=0) const typename base_t::detection_t ** (typename base_t::detection_t *temp) {
443
+ $1 = &temp;
444
+ }
445
+ %typemap(argout) const typename base_t::detection_t ** {
446
+ if((*$1)->valid){
447
+ %append_output(swig::from((*$1)->wssr));
448
+ %append_output(swig::from((*$1)->wssr_sf));
449
+ %append_output(swig::from((*$1)->weight_max));
450
+ %append_output(swig::from((*$1)->slope_HV[0].max));
451
+ %append_output(SWIG_From(int)(((*$1)->slope_HV[0].prn)));
452
+ %append_output(swig::from((*$1)->slope_HV[1].max));
453
+ %append_output(SWIG_From(int)(((*$1)->slope_HV[1].prn)));
454
+ }
455
+ }
456
+ %typemap(in, numinputs=0) const typename base_t::exclusion_t ** (typename base_t::exclusion_t *temp) {
457
+ $1 = &temp;
458
+ }
459
+ %typemap(argout) const typename base_t::exclusion_t ** {
460
+ if((*$1)->valid){
461
+ %append_output(SWIG_From(int)(((*$1)->excluded)));
462
+ %append_output(SWIG_NewPointerObj(
463
+ (new System_XYZ<FloatT, WGS84>((*$1)->user_position.xyz)),
464
+ $descriptor(System_XYZ<FloatT, WGS84>), SWIG_POINTER_OWN));
465
+ %append_output(SWIG_NewPointerObj(
466
+ (new System_LLH<FloatT, WGS84>((*$1)->user_position.llh)),
467
+ $descriptor(System_LLH<FloatT, WGS84>), SWIG_POINTER_OWN));
468
+ }
469
+ }
470
+ }
471
+ %inline %{
472
+ template <class FloatT>
473
+ struct GPS_User_PVT
474
+ : protected GPS_Solver_RAIM_LSR<FloatT,
475
+ GPS_Solver_Base_Debug<FloatT, GPS_Solver_Base<FloatT> > >::user_pvt_t {
476
+ typedef GPS_Solver_RAIM_LSR<FloatT,
477
+ GPS_Solver_Base_Debug<FloatT, GPS_Solver_Base<FloatT> > > solver_t;
478
+ typedef typename solver_t::user_pvt_t base_t;
479
+ GPS_User_PVT() : base_t() {}
480
+ GPS_User_PVT(const base_t &base) : base_t(base) {}
481
+ enum {
482
+ ERROR_NO = 0,
483
+ ERROR_UNSOLVED,
484
+ ERROR_INVALID_IONO_MODEL,
485
+ ERROR_INSUFFICIENT_SATELLITES,
486
+ ERROR_POSITION_LS,
487
+ ERROR_POSITION_NOT_CONVERGED,
488
+ ERROR_DOP,
489
+ ERROR_VELOCITY_SKIPPED,
490
+ ERROR_VELOCITY_INSUFFICIENT_SATELLITES,
491
+ ERROR_VELOCITY_LS,
492
+ };
493
+ int error_code() const {return (int)(base_t::error_code);}
494
+ const GPS_Time<FloatT> &receiver_time() const {return base_t::receiver_time;}
495
+ const System_XYZ<FloatT, WGS84> &xyz() const {return base_t::user_position.xyz;}
496
+ const System_LLH<FloatT, WGS84> &llh() const {return base_t::user_position.llh;}
497
+ const FloatT &receiver_error() const {return base_t::receiver_error;}
498
+ const System_ENU<FloatT, WGS84> &velocity() const {return base_t::user_velocity_enu;}
499
+ const FloatT &receiver_error_rate() const {return base_t::receiver_error_rate;}
500
+ const FloatT &gdop() const {return base_t::dop.g;}
501
+ const FloatT &pdop() const {return base_t::dop.p;}
502
+ const FloatT &hdop() const {return base_t::dop.h;}
503
+ const FloatT &vdop() const {return base_t::dop.v;}
504
+ const FloatT &tdop() const {return base_t::dop.t;}
505
+ const unsigned int &used_satellites() const {return base_t::used_satellites;}
506
+ std::vector<int> used_satellite_list() const {return base_t::used_satellite_mask.indices_one();}
507
+ bool position_solved() const {return base_t::position_solved();}
508
+ bool velocity_solved() const {return base_t::velocity_solved();}
509
+
510
+ const Matrix_Frozen<FloatT, Array2D_Dense<FloatT> > &G() const {return base_t::G;}
511
+ const Matrix_Frozen<FloatT, Array2D_Dense<FloatT> > &W() const {return base_t::W;}
512
+ const Matrix_Frozen<FloatT, Array2D_Dense<FloatT> > &delta_r() const {return base_t::delta_r;}
513
+ struct proxy_t : public solver_t {
514
+ typedef typename solver_t
515
+ ::template linear_solver_t<Matrix<FloatT, Array2D_Dense<FloatT> > >
516
+ linear_solver_t;
517
+ };
518
+ Matrix<FloatT, Array2D_Dense<FloatT> > G_enu() const {
519
+ return proxy_t::linear_solver_t::rotate_G(base_t::G, base_t::user_position.ecef2enu());
520
+ }
521
+ typename proxy_t::linear_solver_t linear_solver() const {
522
+ return typename proxy_t::linear_solver_t(base_t::G, base_t::W, base_t::delta_r);
523
+ }
524
+ Matrix<FloatT, Array2D_Dense<FloatT> > C() const {
525
+ return linear_solver().C();
526
+ }
527
+ Matrix<FloatT, Array2D_Dense<FloatT> > C_enu() const {
528
+ return proxy_t::linear_solver_t::rotate_C(C(), base_t::user_position.ecef2enu());
529
+ }
530
+ Matrix<FloatT, Array2D_Dense<FloatT> > S() const {
531
+ Matrix<FloatT, Array2D_Dense<FloatT> > res;
532
+ linear_solver().least_square(res);
533
+ return res;
534
+ }
535
+ Matrix<FloatT, Array2D_Dense<FloatT> > S_enu() const {
536
+ return proxy_t::linear_solver_t::rotate_S(S(), base_t::user_position.ecef2enu());
537
+ }
538
+ Matrix<FloatT, Array2D_Dense<FloatT> > slope_HV() const {
539
+ return linear_solver().slope_HV(S());
540
+ }
541
+ Matrix<FloatT, Array2D_Dense<FloatT> > slope_HV_enu() const {
542
+ return linear_solver().slope_HV(S(), base_t::user_position.ecef2enu());
543
+ }
544
+
545
+ void fd(const typename base_t::detection_t **out) const {*out = &(base_t::FD);}
546
+ void fde_min(
547
+ const typename base_t::detection_t **out0,
548
+ const typename base_t::exclusion_t **out1) const {
549
+ *out0 = *out1 = &(base_t::FDE_min);
550
+ }
551
+ void fde_2nd(
552
+ const typename base_t::detection_t **out0,
553
+ const typename base_t::exclusion_t **out1) const {
554
+ *out0 = *out1 = &(base_t::FDE_2nd);
555
+ }
556
+ };
557
+ %}
558
+
559
+ %extend GPS_Measurement {
560
+ %ignore items_t;
561
+ %ignore items;
562
+ %exception each {
563
+ #ifdef SWIGRUBY
564
+ if(!rb_block_given_p()){
565
+ return rb_enumeratorize(self, ID2SYM(rb_intern("each")), argc, argv);
566
+ }
567
+ #endif
568
+ try {
569
+ $action
570
+ } catch (const native_exception &e) {
571
+ e.regenerate();
572
+ SWIG_fail;
573
+ } catch (const std::exception& e) {
574
+ SWIG_exception_fail(SWIG_RuntimeError, e.what());
575
+ }
576
+ }
577
+ %fragment(SWIG_Traits_frag(FloatT));
578
+ void each() const {
579
+ for(typename GPS_Measurement<FloatT>::items_t::const_iterator
580
+ it(self->items.begin()), it_end(self->items.end());
581
+ it != it_end; ++it){
582
+ for(typename GPS_Measurement<FloatT>::items_t::mapped_type::const_iterator
583
+ it2(it->second.begin()), it2_end(it->second.end());
584
+ it2 != it2_end; ++it2){
585
+ #ifdef SWIGRUBY
586
+ VALUE values[] = {
587
+ SWIG_From(int)(it->first),
588
+ SWIG_From(int)(it2->first),
589
+ swig::from(it2->second)
590
+ };
591
+ yield_throw_if_error(3, values);
592
+ #endif
593
+ }
594
+ }
595
+ }
596
+ #ifdef SWIGRUBY
597
+ VALUE to_hash() const {
598
+ VALUE res(rb_hash_new());
599
+ for(typename GPS_Measurement<FloatT>::items_t::const_iterator
600
+ it(self->items.begin()), it_end(self->items.end());
601
+ it != it_end; ++it){
602
+ VALUE per_sat(rb_hash_new());
603
+ rb_hash_aset(res, SWIG_From(int)(it->first), per_sat);
604
+ for(typename GPS_Measurement<FloatT>::items_t::mapped_type::const_iterator
605
+ it2(it->second.begin()), it2_end(it->second.end());
606
+ it2 != it2_end; ++it2){
607
+ rb_hash_aset(per_sat, SWIG_From(int)(it2->first), swig::from(it2->second));
608
+ }
609
+ }
610
+ return res;
611
+ }
612
+ #endif
613
+ %fragment(SWIG_Traits_frag(GPS_Measurement<FloatT>), "header",
614
+ fragment=SWIG_Traits_frag(FloatT)){
615
+ namespace swig {
616
+ template <>
617
+ bool check<GPS_Measurement<FloatT> >(SWIG_Object obj) {
618
+ #ifdef SWIGRUBY
619
+ return RB_TYPE_P(obj, T_ARRAY) || RB_TYPE_P(obj, T_HASH);
620
+ #else
621
+ return false;
622
+ #endif
623
+ }
624
+ template <>
625
+ int asval(SWIG_Object obj, GPS_Measurement<FloatT> *val) {
626
+ #ifdef SWIGRUBY
627
+ if(RB_TYPE_P(obj, T_ARRAY)){
628
+ int i(0), i_end(RARRAY_LEN(obj));
629
+ VALUE values;
630
+ for(; i < i_end; ++i){
631
+ values = RARRAY_AREF(obj, i);
632
+ if((!RB_TYPE_P(values, T_ARRAY)) || (RARRAY_LEN(values) < 3)){
633
+ break;
634
+ }
635
+ int prn, key;
636
+ FloatT v;
637
+ if((!SWIG_IsOK(SWIG_AsVal(int)(RARRAY_AREF(values, 0), &prn)))
638
+ || (!SWIG_IsOK(SWIG_AsVal(int)(RARRAY_AREF(values, 1), &key)))
639
+ || (!SWIG_IsOK(swig::asval(RARRAY_AREF(values, 2), &v)))){
640
+ break;
641
+ }
642
+ val->add(prn, key, v);
643
+ }
644
+ if(i < i_end){
645
+ SWIG_exception(SWIG_TypeError,
646
+ std::string("Unexpected input [").append(std::to_string(i)).append("]: ")
647
+ .append(inspect_str(values)).c_str());
648
+ }
649
+ return SWIG_OK;
650
+ }else if(RB_TYPE_P(obj, T_HASH)){
651
+ struct arg_t {
652
+ GPS_Measurement<FloatT> *meas;
653
+ int prn;
654
+ static int iter2(VALUE v_k, VALUE v_v, VALUE v_arg){
655
+ int k;
656
+ FloatT v;
657
+ arg_t *arg(reinterpret_cast<arg_t *>(v_arg));
658
+ if((!SWIG_IsOK(SWIG_AsVal(int)(v_k, &k)))
659
+ || (!SWIG_IsOK(swig::asval(v_v, &v)))){
660
+ SWIG_exception(SWIG_TypeError,
661
+ std::string("Unexpected input @ PRN").append(std::to_string(arg->prn)).append(": [")
662
+ .append(inspect_str(v_k)).append(", ")
663
+ .append(inspect_str(v_v)).append("]").c_str());
664
+ }
665
+ arg->meas->add(arg->prn, k, v);
666
+ return ST_CONTINUE;
667
+ }
668
+ static int iter1(VALUE v_prn, VALUE v_key_value, VALUE v_arg){
669
+ arg_t *arg(reinterpret_cast<arg_t *>(v_arg));
670
+ if((!RB_TYPE_P(v_key_value, T_HASH))
671
+ || (!SWIG_IsOK(SWIG_AsVal(int)(v_prn, &(arg->prn))))){
672
+ SWIG_exception(SWIG_TypeError,
673
+ std::string("Unexpected input @ {")
674
+ .append(inspect_str(v_prn)).append(" => ")
675
+ .append(inspect_str(v_key_value)).append("}").c_str());
676
+ }
677
+ rb_hash_foreach(v_key_value,
678
+ #if RUBY_API_VERSION < 20700
679
+ // @see https://docs.ruby-lang.org/ja/latest/doc/news=2f2_7_0.html
680
+ (int (*)(ANYARGS))
681
+ #endif
682
+ arg_t::iter2, v_arg);
683
+ return ST_CONTINUE;
684
+ }
685
+ } arg = {val};
686
+ rb_hash_foreach(obj,
687
+ #if RUBY_API_VERSION < 20700
688
+ (int (*)(ANYARGS))
689
+ #endif
690
+ arg_t::iter1, reinterpret_cast<VALUE>(&arg));
691
+ return SWIG_OK;
692
+ }
693
+ #endif
694
+ return SWIG_ERROR;
695
+ }
696
+ }
697
+ }
698
+ %fragment(SWIG_Traits_frag(GPS_Measurement<FloatT>));
699
+ %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) const GPS_Measurement<FloatT> & {
700
+ $1 = SWIG_CheckState(SWIG_ConvertPtr($input, (void **)0, $1_descriptor, 0))
701
+ || swig::check<GPS_Measurement<FloatT> >($input);
702
+ }
703
+ %typemap(in) const GPS_Measurement<FloatT> & (GPS_Measurement<FloatT> temp) {
704
+ if((!SWIG_IsOK(SWIG_ConvertPtr($input, (void **)&$1, $1_descriptor, 0)))
705
+ && (!SWIG_IsOK(swig::asval($input, ($1 = &temp))))){
706
+ SWIG_exception(SWIG_TypeError, "in method '$symname', expecting type $*1_ltype");
707
+ }
708
+ }
709
+ }
710
+ %copyctor GPS_Measurement;
711
+ #ifdef SWIGRUBY
712
+ %mixin GPS_Measurement "Enumerable";
713
+ #endif
714
+ %inline {
715
+ template <class FloatT>
716
+ struct GPS_Measurement {
717
+ typedef std::map<int, std::map<int, FloatT> > items_t;
718
+ items_t items;
719
+ enum {
720
+ L1_PSEUDORANGE,
721
+ L1_DOPPLER,
722
+ L1_CARRIER_PHASE,
723
+ L1_RANGE_RATE,
724
+ L1_PSEUDORANGE_SIGMA,
725
+ L1_DOPPLER_SIGMA,
726
+ L1_CARRIER_PHASE_SIGMA,
727
+ L1_RANGE_RATE_SIGMA,
728
+ L1_SIGNAL_STRENGTH_dBHz,
729
+ L1_LOCK_SEC,
730
+ ITEMS_PREDEFINED,
731
+ };
732
+ void add(const int &prn, const int &key, const FloatT &value){
733
+ items[prn][key] = value;
734
+ }
735
+ };
736
+ }
737
+
738
+ %extend GPS_SolverOptions {
739
+ %ignore base_t;
740
+ MAKE_ACCESSOR(elevation_mask, FloatT);
741
+ MAKE_ACCESSOR(residual_mask, FloatT);
742
+ MAKE_ACCESSOR(f_10_7, FloatT);
743
+ MAKE_VECTOR2ARRAY(int);
744
+ #ifdef SWIGRUBY
745
+ %rename("ionospheric_models=") set_ionospheric_models;
746
+ %rename("ionospheric_models") get_ionospheric_models;
747
+ #endif
748
+ %typemap(in) const std::vector<int> &models (std::vector<int> temp) {
749
+ $1 = &temp;
750
+ #ifdef SWIGRUBY
751
+ if(RB_TYPE_P($input, T_ARRAY)){
752
+ for(int i(0), i_max(RARRAY_LEN($input)); i < i_max; ++i){
753
+ SWIG_Object obj(RARRAY_AREF($input, i));
754
+ int v;
755
+ if(SWIG_IsOK(SWIG_AsVal(int)(obj, &v))){
756
+ temp.push_back(v);
757
+ }else{
758
+ SWIG_exception(SWIG_TypeError, "$*1_ltype is expected");
759
+ }
760
+ }
761
+ }
762
+ #endif
763
+ }
764
+ }
765
+ %inline %{
766
+ template <class FloatT>
767
+ struct GPS_SolverOptions : public GPS_SinglePositioning<FloatT>::options_t {
768
+ typedef typename GPS_SinglePositioning<FloatT>::options_t base_t;
769
+ void exclude(const int &prn){base_t::exclude_prn.set(prn);}
770
+ void include(const int &prn){base_t::exclude_prn.reset(prn);}
771
+ std::vector<int> excluded() const {return base_t::exclude_prn.excluded();}
772
+ enum {
773
+ IONOSPHERIC_KLOBUCHAR,
774
+ IONOSPHERIC_NTCM_GL,
775
+ IONOSPHERIC_NONE, // which allows no correction
776
+ IONOSPHERIC_MODELS,
777
+ IONOSPHERIC_SKIP = IONOSPHERIC_MODELS, // which means delegating the next slot
778
+ };
779
+ std::vector<int> get_ionospheric_models() const {
780
+ std::vector<int> res;
781
+ for(int i(0); i < base_t::IONOSPHERIC_MODELS; ++i){
782
+ int v((int)(base_t::ionospheric_models[i]));
783
+ if(v == base_t::IONOSPHERIC_SKIP){break;}
784
+ res.push_back(v);
785
+ }
786
+ return res;
787
+ }
788
+ std::vector<int> set_ionospheric_models(const std::vector<int> &models){
789
+ typedef typename base_t::ionospheric_model_t model_t;
790
+ for(int i(0), j(0), j_max(models.size()); i < model_t::IONOSPHERIC_MODELS; ++i){
791
+ model_t v(model_t::IONOSPHERIC_SKIP);
792
+ if(j < j_max){
793
+ if((models[j] >= 0) && (models[j] < model_t::IONOSPHERIC_SKIP)){
794
+ v = (model_t)models[j];
795
+ }
796
+ ++j;
797
+ }
798
+ base_t::ionospheric_models[i] = v;
799
+ }
800
+ return get_ionospheric_models();
801
+ }
802
+ };
803
+ %}
804
+
805
+ %extend GPS_Solver {
806
+ %ignore super_t;
807
+ %ignore base_t;
808
+ %ignore gps_t;
809
+ %ignore gps;
810
+ %ignore select_solver;
811
+ %ignore relative_property;
812
+ %ignore satellite_position;
813
+ %ignore update_position_solution;
814
+ %immutable hooks;
815
+ %ignore mark;
816
+ %fragment("hook"{GPS_Solver<FloatT>}, "header",
817
+ fragment=SWIG_From_frag(int),
818
+ fragment=SWIG_Traits_frag(FloatT)){
819
+ template <>
820
+ typename GPS_Solver<FloatT>::base_t::relative_property_t
821
+ GPS_Solver<FloatT>::relative_property(
822
+ const typename GPS_Solver<FloatT>::base_t::prn_t &prn,
823
+ const typename GPS_Solver<FloatT>::base_t::measurement_t::mapped_type &measurement,
824
+ const typename GPS_Solver<FloatT>::base_t::float_t &receiver_error,
825
+ const typename GPS_Solver<FloatT>::base_t::gps_time_t &time_arrival,
826
+ const typename GPS_Solver<FloatT>::base_t::pos_t &usr_pos,
827
+ const typename GPS_Solver<FloatT>::base_t::xyz_t &usr_vel) const {
828
+ union {
829
+ typename base_t::relative_property_t prop;
830
+ FloatT values[7];
831
+ } res = {
832
+ select_solver(prn).relative_property(
833
+ prn, measurement, receiver_error, time_arrival,
834
+ usr_pos, usr_vel)};
835
+ #ifdef SWIGRUBY
836
+ do{
837
+ static const VALUE key(ID2SYM(rb_intern("relative_property")));
838
+ static const int prop_items(sizeof(res.values) / sizeof(res.values[0]));
839
+ VALUE hook(rb_hash_lookup(hooks, key));
840
+ if(NIL_P(hook)){break;}
841
+ VALUE values[] = {
842
+ SWIG_From(int)(prn), // prn
843
+ rb_ary_new_from_args(prop_items, // relative_property
844
+ swig::from(res.prop.weight),
845
+ swig::from(res.prop.range_corrected),
846
+ swig::from(res.prop.range_residual),
847
+ swig::from(res.prop.rate_relative_neg),
848
+ swig::from(res.prop.los_neg[0]),
849
+ swig::from(res.prop.los_neg[1]),
850
+ swig::from(res.prop.los_neg[2])),
851
+ swig::from(receiver_error), // receiver_error
852
+ SWIG_NewPointerObj( // time_arrival
853
+ new base_t::gps_time_t(time_arrival), $descriptor(GPS_Time<FloatT> *), SWIG_POINTER_OWN),
854
+ SWIG_NewPointerObj( // usr_pos.xyz
855
+ new base_t::xyz_t(usr_pos.xyz), $descriptor(System_XYZ<FloatT, WGS84> *), SWIG_POINTER_OWN),
856
+ SWIG_NewPointerObj( // usr_vel
857
+ new base_t::xyz_t(usr_vel), $descriptor(System_XYZ<FloatT, WGS84> *), SWIG_POINTER_OWN)};
858
+ VALUE res_hook(proc_call_throw_if_error(hook, sizeof(values) / sizeof(values[0]), values));
859
+ if((!RB_TYPE_P(res_hook, T_ARRAY))
860
+ || (RARRAY_LEN(res_hook) != prop_items)){
861
+ throw std::runtime_error(
862
+ std::string("[d * ").append(std::to_string(prop_items))
863
+ .append("] is expected (d: " %str(FloatT) "), however ")
864
+ .append(inspect_str(res_hook)));
865
+ }
866
+ for(int i(0); i < prop_items; ++i){
867
+ VALUE v(RARRAY_AREF(res_hook, i));
868
+ if(!SWIG_IsOK(swig::asval(v, &res.values[i]))){
869
+ throw std::runtime_error(
870
+ std::string(%str(FloatT) " is exepcted, however ")
871
+ .append(inspect_str(v))
872
+ .append(" @ [").append(std::to_string(i)).append("]"));
873
+ }
874
+ }
875
+ }while(false);
876
+ #endif
877
+ return res.prop;
878
+ }
879
+ template <>
880
+ bool GPS_Solver<FloatT>::update_position_solution(
881
+ const typename GPS_Solver<FloatT>::base_t::geometric_matrices_t &geomat,
882
+ typename GPS_Solver<FloatT>::base_t::user_pvt_t &res) const {
883
+ #ifdef SWIGRUBY
884
+ do{
885
+ static const VALUE key(ID2SYM(rb_intern("update_position_solution")));
886
+ VALUE hook(rb_hash_lookup(hooks, key));
887
+ if(NIL_P(hook)){break;}
888
+ typename base_t::geometric_matrices_t &geomat_(
889
+ %const_cast(geomat, typename base_t::geometric_matrices_t &));
890
+ VALUE values[] = {
891
+ SWIG_NewPointerObj(&geomat_.G,
892
+ $descriptor(Matrix<FloatT, Array2D_Dense<FloatT>, MatrixViewBase<> > *), 0),
893
+ SWIG_NewPointerObj(&geomat_.W,
894
+ $descriptor(Matrix<FloatT, Array2D_Dense<FloatT>, MatrixViewBase<> > *), 0),
895
+ SWIG_NewPointerObj(&geomat_.delta_r,
896
+ $descriptor(Matrix<FloatT, Array2D_Dense<FloatT>, MatrixViewBase<> > *), 0)};
897
+ proc_call_throw_if_error(hook, sizeof(values) / sizeof(values[0]), values);
898
+ }while(false);
899
+ #endif
900
+ return super_t::update_position_solution(geomat, res);
901
+ }
902
+ }
903
+ %fragment("hook"{GPS_Solver<FloatT>});
904
+ }
905
+ %inline {
906
+ template <class FloatT>
907
+ struct GPS_Solver
908
+ : public GPS_Solver_RAIM_LSR<FloatT,
909
+ GPS_Solver_Base_Debug<FloatT, GPS_Solver_Base<FloatT> > > {
910
+ typedef GPS_Solver_RAIM_LSR<FloatT,
911
+ GPS_Solver_Base_Debug<FloatT, GPS_Solver_Base<FloatT> > > super_t;
912
+ typedef GPS_Solver_Base<FloatT> base_t;
913
+ struct gps_t {
914
+ GPS_SpaceNode<FloatT> space_node;
915
+ GPS_SolverOptions<FloatT> options;
916
+ GPS_SinglePositioning<FloatT> solver;
917
+ gps_t() : space_node(), options(), solver(space_node) {}
918
+ } gps;
919
+ SWIG_Object hooks;
920
+ #ifdef SWIGRUBY
921
+ static void mark(void *ptr){
922
+ GPS_Solver<FloatT> *solver = (GPS_Solver<FloatT> *)ptr;
923
+ if(solver->hooks == Qnil){return;}
924
+ rb_gc_mark(solver->hooks);
925
+ }
926
+ #endif
927
+ GPS_Solver() : super_t(), gps(), hooks() {
928
+ #ifdef SWIGRUBY
929
+ hooks = rb_hash_new();
930
+ #endif
931
+ }
932
+ GPS_SpaceNode<FloatT> &gps_space_node() {return gps.space_node;}
933
+ GPS_SolverOptions<FloatT> &gps_options() {return gps.options;}
934
+ const base_t &select_solver(
935
+ const typename base_t::prn_t &prn) const {
936
+ if(prn > 0 && prn <= 32){return gps.solver;}
937
+ return *this;
938
+ }
939
+ virtual typename base_t::relative_property_t relative_property(
940
+ const typename base_t::prn_t &prn,
941
+ const typename base_t::measurement_t::mapped_type &measurement,
942
+ const typename base_t::float_t &receiver_error,
943
+ const typename base_t::gps_time_t &time_arrival,
944
+ const typename base_t::pos_t &usr_pos,
945
+ const typename base_t::xyz_t &usr_vel) const;
946
+ virtual typename base_t::xyz_t *satellite_position(
947
+ const typename base_t::prn_t &prn,
948
+ const typename base_t::gps_time_t &time,
949
+ typename base_t::xyz_t &res) const {
950
+ return select_solver(prn).satellite_position(prn, time, res);
951
+ }
952
+ virtual bool update_position_solution(
953
+ const typename base_t::geometric_matrices_t &geomat,
954
+ typename base_t::user_pvt_t &res) const;
955
+ GPS_User_PVT<FloatT> solve(
956
+ const GPS_Measurement<FloatT> &measurement,
957
+ const GPS_Time<FloatT> &receiver_time) const {
958
+ const_cast<gps_t &>(gps).space_node.update_all_ephemeris(receiver_time);
959
+ const_cast<gps_t &>(gps).solver.update_options(gps.options);
960
+ return super_t::solve().user_pvt(measurement.items, receiver_time);
961
+ }
962
+ };
963
+ }
964
+
965
+ %fragment(SWIG_From_frag(int));
966
+ %fragment(SWIG_From_frag(bool));
967
+ %fragment(SWIG_From_frag(char));
968
+
969
+ %extend RINEX_Observation {
970
+ %exception read {
971
+ #ifdef SWIGRUBY
972
+ if(!rb_block_given_p()){
973
+ return rb_enumeratorize(self, ID2SYM(rb_intern("read")), argc, argv);
974
+ }
975
+ #endif
976
+ try {
977
+ $action
978
+ } catch (const native_exception &e) {
979
+ e.regenerate();
980
+ SWIG_fail;
981
+ } catch (const std::exception& e) {
982
+ SWIG_exception_fail(SWIG_RuntimeError, e.what());
983
+ }
984
+ }
985
+ %fragment(SWIG_Traits_frag(FloatT));
986
+ static void read(const char *fname) {
987
+ std::fstream fin(fname, std::ios::in | std::ios::binary);
988
+ struct reader_t : public RINEX_OBS_Reader<FloatT> {
989
+ typedef RINEX_OBS_Reader<FloatT> super_t;
990
+ SWIG_Object header;
991
+ SWIG_Object obs_types;
992
+ reader_t(std::istream &in) : RINEX_OBS_Reader<FloatT>(in) {
993
+ #ifdef SWIGRUBY
994
+ { // header
995
+ header = rb_hash_new();
996
+ typedef typename super_t::header_t header_t;
997
+ for(typename header_t::const_iterator
998
+ it(super_t::header().begin()), it_end(super_t::header().end());
999
+ it != it_end; ++it){
1000
+ SWIG_Object types_per_key(rb_ary_new_capa(it->second.size()));
1001
+ for(typename header_t::mapped_type::const_iterator
1002
+ it2(it->second.begin()), it2_end(it->second.end());
1003
+ it2 != it2_end; ++it2){
1004
+ rb_ary_push(types_per_key, rb_str_new_cstr(it2->c_str()));
1005
+ }
1006
+ rb_hash_aset(header, rb_str_new_cstr(it->first.c_str()), types_per_key);
1007
+ }
1008
+ }
1009
+ { // observation types
1010
+ obs_types = rb_hash_new();
1011
+ typedef typename super_t::obs_types_t types_t;
1012
+ for(typename types_t::const_iterator
1013
+ it(super_t::obs_types.begin()), it_end(super_t::obs_types.end());
1014
+ it != it_end; ++it){
1015
+ SWIG_Object types_per_sys(rb_ary_new_capa(it->second.size()));
1016
+ for(typename types_t::mapped_type::const_iterator
1017
+ it2(it->second.begin()), it2_end(it->second.end());
1018
+ it2 != it2_end; ++it2){
1019
+ rb_ary_push(types_per_sys, rb_str_new_cstr(it2->c_str()));
1020
+ }
1021
+ rb_hash_aset(obs_types, SWIG_From(char)(it->first), types_per_sys);
1022
+ }
1023
+ }
1024
+ #endif
1025
+ }
1026
+ } reader(fin);
1027
+ while(reader.has_next()){
1028
+ typedef typename reader_t::observation_t obs_t;
1029
+ obs_t obs(reader.next());
1030
+ #ifdef SWIGRUBY
1031
+ SWIG_Object res(rb_hash_new());
1032
+ static const SWIG_Object
1033
+ sym_header(ID2SYM(rb_intern("header"))),
1034
+ sym_t(ID2SYM(rb_intern("time"))),
1035
+ sym_clke(ID2SYM(rb_intern("rcv_clock_error"))),
1036
+ sym_meas(ID2SYM(rb_intern("meas"))),
1037
+ sym_meas_types(ID2SYM(rb_intern("meas_types")));
1038
+ rb_hash_aset(res, sym_header, reader.header);
1039
+ rb_hash_aset(res, sym_t,
1040
+ SWIG_NewPointerObj(
1041
+ new GPS_Time<FloatT>(obs.t_epoch),
1042
+ $descriptor(GPS_Time<FloatT> *), SWIG_POINTER_OWN));
1043
+ rb_hash_aset(res, sym_clke, swig::from(obs.receiver_clock_error));
1044
+ SWIG_Object meas(rb_hash_new());
1045
+ for(typename obs_t::per_satellite_t::const_iterator
1046
+ it(obs.per_satellite.begin()), it_end(obs.per_satellite.end());
1047
+ it != it_end; ++it){
1048
+ SWIG_Object meas_per_sat(rb_ary_new_capa(it->second.size()));
1049
+ int i(0);
1050
+ for(typename obs_t::per_satellite_t::mapped_type::const_iterator
1051
+ it2(it->second.begin()), it2_end(it->second.end());
1052
+ it2 != it2_end; ++it2, ++i){
1053
+ if(!it2->valid){continue;}
1054
+ rb_ary_store(meas_per_sat, i,
1055
+ rb_ary_new_from_args(3,
1056
+ swig::from(it2->value),
1057
+ SWIG_From(int)(it2->lli),
1058
+ SWIG_From(int)(it2->ss)));
1059
+ }
1060
+ int offset;
1061
+ char sys_c(reader_t::serial2sys(it->first, offset));
1062
+ rb_hash_aset(meas,
1063
+ rb_ary_new_from_args(2,
1064
+ SWIG_From(char)(sys_c),
1065
+ SWIG_From(int)(offset)),
1066
+ meas_per_sat);
1067
+ }
1068
+ rb_hash_aset(res, sym_meas, meas);
1069
+ rb_hash_aset(res, sym_meas_types, reader.obs_types);
1070
+ yield_throw_if_error(1, &res);
1071
+ #endif
1072
+ }
1073
+ }
1074
+ }
1075
+
1076
+ %inline {
1077
+ template <class FloatT>
1078
+ struct RINEX_Observation {};
1079
+ }
1080
+
1081
+ #undef MAKE_ACCESSOR
1082
+ #undef MAKE_VECTOR2ARRAY
1083
+
1084
+ %define CONCRETIZE(type)
1085
+ %template(Time) GPS_Time<type>;
1086
+ %template(SpaceNode) GPS_SpaceNode<type>;
1087
+ %template(Ionospheric_UTC_Parameters) GPS_Ionospheric_UTC_Parameters<type>;
1088
+ %template(Ephemeris) GPS_Ephemeris<type>;
1089
+ %template(PVT) GPS_User_PVT<type>;
1090
+ %template(Measurement) GPS_Measurement<type>;
1091
+ %template(SolverOptions) GPS_SolverOptions<type>;
1092
+ #if defined(SWIGRUBY)
1093
+ %markfunc GPS_Solver<type> "GPS_Solver<type>::mark";
1094
+ #endif
1095
+ %template(Solver) GPS_Solver<type>;
1096
+
1097
+ %template(RINEX_Observation) RINEX_Observation<type>;
1098
+ %enddef
1099
+
1100
+ CONCRETIZE(double);
1101
+
1102
+ #undef CONCRETIZE