gps_pvt 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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