gps_pvt 0.1.7 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -2
- data/Rakefile +2 -0
- data/exe/gps_pvt +32 -23
- data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +5 -3
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +4444 -671
- data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +284 -19
- data/ext/ninja-scan-light/tool/navigation/GPS.h +12 -46
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +61 -100
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +87 -25
- data/ext/ninja-scan-light/tool/navigation/QZSS.h +62 -0
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +335 -27
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +2330 -0
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +306 -0
- data/ext/ninja-scan-light/tool/param/bit_array.h +4 -3
- data/ext/ninja-scan-light/tool/swig/GPS.i +429 -138
- data/ext/ninja-scan-light/tool/swig/SylphideMath.i +53 -6
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +37 -6
- data/ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb +38 -4
- data/gps_pvt.gemspec +63 -0
- data/lib/gps_pvt/receiver.rb +281 -140
- data/lib/gps_pvt/version.rb +1 -1
- metadata +7 -3
@@ -15,16 +15,19 @@
|
|
15
15
|
#include <iostream>
|
16
16
|
#include <fstream>
|
17
17
|
#include <exception>
|
18
|
+
#include <sstream>
|
18
19
|
|
19
20
|
#include "navigation/GPS.h"
|
21
|
+
#include "navigation/SBAS.h"
|
22
|
+
#include "navigation/QZSS.h"
|
20
23
|
#include "navigation/RINEX.h"
|
21
24
|
|
22
25
|
#include "navigation/GPS_Solver_Base.h"
|
23
26
|
#include "navigation/GPS_Solver.h"
|
24
27
|
#include "navigation/GPS_Solver_RAIM.h"
|
28
|
+
#include "navigation/SBAS_Solver.h"
|
25
29
|
|
26
30
|
#if defined(__cplusplus) && (__cplusplus < 201103L)
|
27
|
-
#include <sstream>
|
28
31
|
namespace std {
|
29
32
|
template <class T>
|
30
33
|
inline std::string to_string(const T &value){
|
@@ -156,6 +159,14 @@ static std::string inspect_str(const VALUE &v){
|
|
156
159
|
*week = self->week;
|
157
160
|
*seconds = self->seconds;
|
158
161
|
}
|
162
|
+
#if defined(SWIG)
|
163
|
+
int __cmp__(const GPS_Time<FloatT> &t) const {
|
164
|
+
return ((self->week < t.week) ? -1
|
165
|
+
: ((self->week > t.week) ? 1
|
166
|
+
: (self->seconds < t.seconds ? -1
|
167
|
+
: (self->seconds > t.seconds ? 1 : 0))));
|
168
|
+
}
|
169
|
+
#endif
|
159
170
|
}
|
160
171
|
|
161
172
|
%define MAKE_ACCESSOR(name, type)
|
@@ -180,6 +191,26 @@ const type &get_ ## name () const {
|
|
180
191
|
}
|
181
192
|
}
|
182
193
|
%enddef
|
194
|
+
#if defined(SWIGRUBY)
|
195
|
+
%define MAKE_ARRAY_INPUT(type, arg_name, f_conv)
|
196
|
+
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) type arg_name[ANY] {
|
197
|
+
$1 = RB_TYPE_P($input, T_ARRAY) ? 1 : 0;
|
198
|
+
}
|
199
|
+
%typemap(in) type arg_name[ANY] ($*1_ltype temp[$1_dim0]) {
|
200
|
+
if(!(RB_TYPE_P($input, T_ARRAY) && (RARRAY_LEN($input) == $1_dim0))){
|
201
|
+
SWIG_exception(SWIG_TypeError, "array[$1_dim0] is expected");
|
202
|
+
}
|
203
|
+
for(int i(0); i < $1_dim0; ++i){
|
204
|
+
if(!SWIG_IsOK(f_conv(RARRAY_AREF($input, i), &temp[i]))){
|
205
|
+
SWIG_exception(SWIG_TypeError, "$*1_ltype is expected");
|
206
|
+
}
|
207
|
+
}
|
208
|
+
$1 = temp;
|
209
|
+
}
|
210
|
+
%enddef
|
211
|
+
#else
|
212
|
+
#define MAKE_ARRAY_INPUT(type, arg_name, f_conv)
|
213
|
+
#endif
|
183
214
|
|
184
215
|
%inline %{
|
185
216
|
template <class FloatT>
|
@@ -195,34 +226,8 @@ struct GPS_Ionospheric_UTC_Parameters : public GPS_SpaceNode<FloatT>::Ionospheri
|
|
195
226
|
%append_output(swig::from($1[i]));
|
196
227
|
}
|
197
228
|
}
|
198
|
-
|
199
|
-
|
200
|
-
if(!(RB_TYPE_P($input, T_ARRAY) && (RARRAY_LEN($input) == 4))){
|
201
|
-
SWIG_exception(SWIG_TypeError, "array[4] is expected");
|
202
|
-
}
|
203
|
-
for(int i(0); i < 4; ++i){
|
204
|
-
SWIG_Object obj(RARRAY_AREF($input, i));
|
205
|
-
if(!SWIG_IsOK(swig::asval(obj, &temp[i]))){
|
206
|
-
SWIG_exception(SWIG_TypeError, "$*1_ltype is expected");
|
207
|
-
}
|
208
|
-
}
|
209
|
-
#endif
|
210
|
-
$1 = temp;
|
211
|
-
}
|
212
|
-
%typemap(in) const unsigned int *buf (unsigned int temp[10]) {
|
213
|
-
#ifdef SWIGRUBY
|
214
|
-
if((!RB_TYPE_P($input, T_ARRAY))
|
215
|
-
|| (RARRAY_LEN($input) < sizeof(temp) / sizeof(temp[0]))){
|
216
|
-
SWIG_exception(SWIG_TypeError, "array is expected, or too short array");
|
217
|
-
}
|
218
|
-
$1 = temp;
|
219
|
-
for(int i(0); i < sizeof(temp) / sizeof(temp[0]); ++i){
|
220
|
-
if(!SWIG_IsOK(SWIG_AsVal(unsigned int)(RARRAY_AREF($input, i), &($1[i])))){
|
221
|
-
SWIG_exception(SWIG_TypeError, "$*1_ltype is expected");
|
222
|
-
}
|
223
|
-
}
|
224
|
-
#endif
|
225
|
-
}
|
229
|
+
MAKE_ARRAY_INPUT(const FloatT, values, swig::asval);
|
230
|
+
MAKE_ARRAY_INPUT(const unsigned int, buf, SWIG_AsVal(unsigned int));
|
226
231
|
%rename("alpha=") set_alpha;
|
227
232
|
void set_alpha(const FloatT values[4]){
|
228
233
|
for(int i(0); i < 4; ++i){
|
@@ -255,7 +260,7 @@ struct GPS_Ionospheric_UTC_Parameters : public GPS_SpaceNode<FloatT>::Ionospheri
|
|
255
260
|
MAKE_ACCESSOR(WN_LSF, unsigned int);
|
256
261
|
MAKE_ACCESSOR(DN, unsigned int);
|
257
262
|
MAKE_ACCESSOR(delta_t_LSF, int);
|
258
|
-
static GPS_Ionospheric_UTC_Parameters<FloatT> parse(const unsigned int
|
263
|
+
static GPS_Ionospheric_UTC_Parameters<FloatT> parse(const unsigned int buf[10]){
|
259
264
|
typedef typename GPS_SpaceNode<FloatT>
|
260
265
|
::BroadcastedMessage<unsigned int, 30> parser_t;
|
261
266
|
if((parser_t::subframe_id(buf) != 4) || (parser_t::sv_page_id(buf) != 56)){
|
@@ -321,22 +326,10 @@ struct GPS_Ephemeris : public GPS_SpaceNode<FloatT>::SatelliteProperties::Epheme
|
|
321
326
|
MAKE_ACCESSOR(omega, FloatT);
|
322
327
|
MAKE_ACCESSOR(dot_Omega0, FloatT);
|
323
328
|
MAKE_ACCESSOR(dot_i0, FloatT);
|
324
|
-
|
325
|
-
|
326
|
-
if((!RB_TYPE_P($input, T_ARRAY))
|
327
|
-
|| (RARRAY_LEN($input) < sizeof(temp) / sizeof(temp[0]))){
|
328
|
-
SWIG_exception(SWIG_TypeError, "array is expected, or too short array");
|
329
|
-
}
|
330
|
-
$1 = temp;
|
331
|
-
for(int i(0); i < sizeof(temp) / sizeof(temp[0]); ++i){
|
332
|
-
if(!SWIG_IsOK(SWIG_AsVal(unsigned int)(RARRAY_AREF($input, i), &($1[i])))){
|
333
|
-
SWIG_exception(SWIG_TypeError, "$*1_ltype is expected");
|
334
|
-
}
|
335
|
-
}
|
336
|
-
#endif
|
337
|
-
}
|
329
|
+
|
330
|
+
MAKE_ARRAY_INPUT(const unsigned int, buf, SWIG_AsVal(unsigned int));
|
338
331
|
%apply int *OUTPUT { int *subframe_no, int *iodc_or_iode };
|
339
|
-
void parse(const unsigned int
|
332
|
+
void parse(const unsigned int buf[10], int *subframe_no, int *iodc_or_iode){
|
340
333
|
typedef typename GPS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris eph_t;
|
341
334
|
typename eph_t::raw_t raw;
|
342
335
|
eph_t eph;
|
@@ -428,15 +421,84 @@ struct GPS_Ephemeris : public GPS_SpaceNode<FloatT>::SatelliteProperties::Epheme
|
|
428
421
|
%append_output(swig::from($1.latitude));
|
429
422
|
%append_output(swig::from($1.longitude));
|
430
423
|
}
|
431
|
-
%ignore iono_correction() const;
|
432
|
-
%ignore tropo_correction() const;
|
433
424
|
int read(const char *fname) {
|
434
425
|
std::fstream fin(fname, std::ios::in | std::ios::binary);
|
435
|
-
|
426
|
+
typename RINEX_NAV_Reader<FloatT>::space_node_list_t space_nodes = {self};
|
427
|
+
space_nodes.qzss = self;
|
428
|
+
return RINEX_NAV_Reader<FloatT>::read_all(fin, space_nodes);
|
436
429
|
}
|
437
430
|
}
|
438
431
|
|
439
432
|
%include navigation/GPS.h
|
433
|
+
%include navigation/QZSS.h
|
434
|
+
|
435
|
+
%inline %{
|
436
|
+
template <class FloatT>
|
437
|
+
struct SBAS_Ephemeris : public SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris {
|
438
|
+
SBAS_Ephemeris() : SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris() {}
|
439
|
+
SBAS_Ephemeris(const typename SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris &eph)
|
440
|
+
: SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris(eph) {}
|
441
|
+
};
|
442
|
+
%}
|
443
|
+
%extend SBAS_Ephemeris {
|
444
|
+
MAKE_ACCESSOR(svid, unsigned int);
|
445
|
+
|
446
|
+
MAKE_ACCESSOR(WN, unsigned int);
|
447
|
+
MAKE_ACCESSOR(t_0, FloatT);
|
448
|
+
MAKE_ACCESSOR(URA, int);
|
449
|
+
MAKE_ACCESSOR( x, FloatT); MAKE_ACCESSOR( y, FloatT); MAKE_ACCESSOR( z, FloatT);
|
450
|
+
MAKE_ACCESSOR( dx, FloatT); MAKE_ACCESSOR( dy, FloatT); MAKE_ACCESSOR( dz, FloatT);
|
451
|
+
MAKE_ACCESSOR(ddx, FloatT); MAKE_ACCESSOR(ddy, FloatT); MAKE_ACCESSOR(ddz, FloatT);
|
452
|
+
MAKE_ACCESSOR(a_Gf0, FloatT);
|
453
|
+
MAKE_ACCESSOR(a_Gf1, FloatT);
|
454
|
+
%apply GPS_Ephemeris::System_XYZ<FloatT, WGS84> & { System_XYZ<FloatT, WGS84> & }; // TODO ineffective?
|
455
|
+
void constellation(
|
456
|
+
System_XYZ<FloatT, WGS84> &position, System_XYZ<FloatT, WGS84> &velocity,
|
457
|
+
const GPS_Time<FloatT> &t, const FloatT &pseudo_range = 0,
|
458
|
+
const bool &with_velocity = true) const {
|
459
|
+
typename SBAS_SpaceNode<FloatT>::SatelliteProperties::constellation_t res(
|
460
|
+
self->constellation(t, pseudo_range, with_velocity));
|
461
|
+
position = res.position;
|
462
|
+
velocity = res.velocity;
|
463
|
+
}
|
464
|
+
}
|
465
|
+
|
466
|
+
%extend SBAS_SpaceNode {
|
467
|
+
%fragment(SWIG_Traits_frag(FloatT));
|
468
|
+
%ignore satellites() const;
|
469
|
+
%ignore satellite(const int &);
|
470
|
+
%ignore available_satellites(const FloatT &lng_deg) const;
|
471
|
+
void register_ephemeris(
|
472
|
+
const int &prn, const SBAS_Ephemeris<FloatT> &eph,
|
473
|
+
const int &priority_delta = 1){
|
474
|
+
self->satellite(prn).register_ephemeris(eph, priority_delta);
|
475
|
+
}
|
476
|
+
SBAS_Ephemeris<FloatT> ephemeris(const int &prn) const {
|
477
|
+
return SBAS_Ephemeris<FloatT>(
|
478
|
+
%const_cast(self, SBAS_SpaceNode<FloatT> *)->satellite(prn).ephemeris());
|
479
|
+
}
|
480
|
+
int read(const char *fname) {
|
481
|
+
std::fstream fin(fname, std::ios::in | std::ios::binary);
|
482
|
+
RINEX_NAV_Reader<FloatT>::space_node_list_t space_nodes = {NULL};
|
483
|
+
space_nodes.sbas = self;
|
484
|
+
return RINEX_NAV_Reader<FloatT>::read_all(fin, space_nodes);
|
485
|
+
}
|
486
|
+
MAKE_ARRAY_INPUT(const unsigned int, buf, SWIG_AsVal(unsigned int));
|
487
|
+
int decode_message(const unsigned int buf[8],
|
488
|
+
const int &prn, const GPS_Time<FloatT> &t_reception,
|
489
|
+
const bool &LNAV_VNAV_LP_LPV_approach = false){
|
490
|
+
return static_cast<int>(
|
491
|
+
self->decode_message(buf, prn, t_reception, LNAV_VNAV_LP_LPV_approach));
|
492
|
+
}
|
493
|
+
std::string ionospheric_grid_points(const int &prn) const {
|
494
|
+
std::ostringstream ss;
|
495
|
+
ss << %const_cast(self, SBAS_SpaceNode<FloatT> *)->satellite(prn)
|
496
|
+
.ionospheric_grid_points();
|
497
|
+
return ss.str();
|
498
|
+
}
|
499
|
+
}
|
500
|
+
|
501
|
+
%include navigation/SBAS.h
|
440
502
|
|
441
503
|
%extend GPS_User_PVT {
|
442
504
|
%ignore solver_t;
|
@@ -604,23 +666,6 @@ struct GPS_User_PVT
|
|
604
666
|
}
|
605
667
|
}
|
606
668
|
}
|
607
|
-
#ifdef SWIGRUBY
|
608
|
-
VALUE to_hash() const {
|
609
|
-
VALUE res(rb_hash_new());
|
610
|
-
for(typename GPS_Measurement<FloatT>::items_t::const_iterator
|
611
|
-
it(self->items.begin()), it_end(self->items.end());
|
612
|
-
it != it_end; ++it){
|
613
|
-
VALUE per_sat(rb_hash_new());
|
614
|
-
rb_hash_aset(res, SWIG_From(int)(it->first), per_sat);
|
615
|
-
for(typename GPS_Measurement<FloatT>::items_t::mapped_type::const_iterator
|
616
|
-
it2(it->second.begin()), it2_end(it->second.end());
|
617
|
-
it2 != it2_end; ++it2){
|
618
|
-
rb_hash_aset(per_sat, SWIG_From(int)(it2->first), swig::from(it2->second));
|
619
|
-
}
|
620
|
-
}
|
621
|
-
return res;
|
622
|
-
}
|
623
|
-
#endif
|
624
669
|
%fragment(SWIG_Traits_frag(GPS_Measurement<FloatT>), "header",
|
625
670
|
fragment=SWIG_Traits_frag(FloatT)){
|
626
671
|
namespace swig {
|
@@ -704,9 +749,32 @@ struct GPS_User_PVT
|
|
704
749
|
#endif
|
705
750
|
return SWIG_ERROR;
|
706
751
|
}
|
752
|
+
#ifdef SWIGRUBY
|
753
|
+
template <>
|
754
|
+
VALUE from(const GPS_Measurement<FloatT>::items_t::mapped_type &val) {
|
755
|
+
VALUE per_sat(rb_hash_new());
|
756
|
+
for(typename GPS_Measurement<FloatT>::items_t::mapped_type::const_iterator
|
757
|
+
it(val.begin()), it_end(val.end());
|
758
|
+
it != it_end; ++it){
|
759
|
+
rb_hash_aset(per_sat, SWIG_From(int)(it->first), swig::from(it->second));
|
760
|
+
}
|
761
|
+
return per_sat;
|
762
|
+
}
|
763
|
+
#endif
|
707
764
|
}
|
708
765
|
}
|
709
766
|
%fragment(SWIG_Traits_frag(GPS_Measurement<FloatT>));
|
767
|
+
#ifdef SWIGRUBY
|
768
|
+
VALUE to_hash() const {
|
769
|
+
VALUE res(rb_hash_new());
|
770
|
+
for(typename GPS_Measurement<FloatT>::items_t::const_iterator
|
771
|
+
it(self->items.begin()), it_end(self->items.end());
|
772
|
+
it != it_end; ++it){
|
773
|
+
rb_hash_aset(res, SWIG_From(int)(it->first), swig::from(it->second));
|
774
|
+
}
|
775
|
+
return res;
|
776
|
+
}
|
777
|
+
#endif
|
710
778
|
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) const GPS_Measurement<FloatT> & {
|
711
779
|
$1 = SWIG_CheckState(SWIG_ConvertPtr($input, (void **)0, $1_descriptor, 0))
|
712
780
|
|| swig::check<GPS_Measurement<FloatT> >($input);
|
@@ -738,6 +806,7 @@ struct GPS_Measurement {
|
|
738
806
|
L1_RANGE_RATE_SIGMA,
|
739
807
|
L1_SIGNAL_STRENGTH_dBHz,
|
740
808
|
L1_LOCK_SEC,
|
809
|
+
L1_FREQUENCY,
|
741
810
|
ITEMS_PREDEFINED,
|
742
811
|
};
|
743
812
|
void add(const int &prn, const int &key, const FloatT &value){
|
@@ -746,70 +815,66 @@ struct GPS_Measurement {
|
|
746
815
|
};
|
747
816
|
}
|
748
817
|
|
818
|
+
%extend GPS_SolverOptions_Common {
|
819
|
+
%define MAKE_ACCESSOR2(name, type)
|
820
|
+
%rename(%str(name ## =)) set_ ## name;
|
821
|
+
type set_ ## name (const type &v) {
|
822
|
+
return self->cast_general()->name = v;
|
823
|
+
}
|
824
|
+
%rename(%str(name)) get_ ## name;
|
825
|
+
const type &get_ ## name () const {
|
826
|
+
return self->cast_general()->name;
|
827
|
+
}
|
828
|
+
%enddef
|
829
|
+
MAKE_ACCESSOR2(elevation_mask, FloatT);
|
830
|
+
MAKE_ACCESSOR2(residual_mask, FloatT);
|
831
|
+
#undef MAKE_ACCESSOR2
|
832
|
+
MAKE_VECTOR2ARRAY(int);
|
833
|
+
%ignore cast_base;
|
834
|
+
}
|
835
|
+
%inline %{
|
836
|
+
template <class FloatT>
|
837
|
+
struct GPS_SolverOptions_Common {
|
838
|
+
virtual GPS_Solver_GeneralOptions<FloatT> *cast_general() = 0;
|
839
|
+
virtual const GPS_Solver_GeneralOptions<FloatT> *cast_general() const = 0;
|
840
|
+
};
|
841
|
+
%}
|
842
|
+
|
749
843
|
%extend GPS_SolverOptions {
|
750
844
|
%ignore base_t;
|
751
|
-
|
752
|
-
MAKE_ACCESSOR(residual_mask, FloatT);
|
753
|
-
MAKE_ACCESSOR(f_10_7, FloatT);
|
845
|
+
%ignore cast_general;
|
754
846
|
MAKE_VECTOR2ARRAY(int);
|
755
|
-
#ifdef SWIGRUBY
|
756
|
-
%rename("ionospheric_models=") set_ionospheric_models;
|
757
|
-
%rename("ionospheric_models") get_ionospheric_models;
|
758
|
-
#endif
|
759
|
-
%typemap(in) const std::vector<int> &models (std::vector<int> temp) {
|
760
|
-
$1 = &temp;
|
761
|
-
#ifdef SWIGRUBY
|
762
|
-
if(RB_TYPE_P($input, T_ARRAY)){
|
763
|
-
for(int i(0), i_max(RARRAY_LEN($input)); i < i_max; ++i){
|
764
|
-
SWIG_Object obj(RARRAY_AREF($input, i));
|
765
|
-
int v;
|
766
|
-
if(SWIG_IsOK(SWIG_AsVal(int)(obj, &v))){
|
767
|
-
temp.push_back(v);
|
768
|
-
}else{
|
769
|
-
SWIG_exception(SWIG_TypeError, "$*1_ltype is expected");
|
770
|
-
}
|
771
|
-
}
|
772
|
-
}
|
773
|
-
#endif
|
774
|
-
}
|
775
847
|
}
|
776
848
|
%inline %{
|
777
849
|
template <class FloatT>
|
778
|
-
struct GPS_SolverOptions
|
850
|
+
struct GPS_SolverOptions
|
851
|
+
: public GPS_SinglePositioning<FloatT>::options_t,
|
852
|
+
GPS_SolverOptions_Common<FloatT> {
|
779
853
|
typedef typename GPS_SinglePositioning<FloatT>::options_t base_t;
|
780
854
|
void exclude(const int &prn){base_t::exclude_prn.set(prn);}
|
781
855
|
void include(const int &prn){base_t::exclude_prn.reset(prn);}
|
782
856
|
std::vector<int> excluded() const {return base_t::exclude_prn.excluded();}
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
if((models[j] >= 0) && (models[j] < base_t::IONOSPHERIC_SKIP)){
|
805
|
-
v = (model_t)models[j];
|
806
|
-
}
|
807
|
-
++j;
|
808
|
-
}
|
809
|
-
base_t::ionospheric_models[i] = v;
|
810
|
-
}
|
811
|
-
return get_ionospheric_models();
|
812
|
-
}
|
857
|
+
GPS_Solver_GeneralOptions<FloatT> *cast_general(){return this;}
|
858
|
+
const GPS_Solver_GeneralOptions<FloatT> *cast_general() const {return this;}
|
859
|
+
};
|
860
|
+
%}
|
861
|
+
|
862
|
+
%extend SBAS_SolverOptions {
|
863
|
+
%ignore base_t;
|
864
|
+
%ignore cast_general;
|
865
|
+
MAKE_VECTOR2ARRAY(int);
|
866
|
+
}
|
867
|
+
%inline %{
|
868
|
+
template <class FloatT>
|
869
|
+
struct SBAS_SolverOptions
|
870
|
+
: public SBAS_SinglePositioning<FloatT>::options_t,
|
871
|
+
GPS_SolverOptions_Common<FloatT> {
|
872
|
+
typedef typename SBAS_SinglePositioning<FloatT>::options_t base_t;
|
873
|
+
void exclude(const int &prn){base_t::exclude_prn.set(prn);}
|
874
|
+
void include(const int &prn){base_t::exclude_prn.reset(prn);}
|
875
|
+
std::vector<int> excluded() const {return base_t::exclude_prn.excluded();}
|
876
|
+
GPS_Solver_GeneralOptions<FloatT> *cast_general(){return this;}
|
877
|
+
const GPS_Solver_GeneralOptions<FloatT> *cast_general() const {return this;}
|
813
878
|
};
|
814
879
|
%}
|
815
880
|
|
@@ -818,6 +883,8 @@ struct GPS_SolverOptions : public GPS_SinglePositioning<FloatT>::options_t {
|
|
818
883
|
%ignore base_t;
|
819
884
|
%ignore gps_t;
|
820
885
|
%ignore gps;
|
886
|
+
%ignore sbas_t;
|
887
|
+
%ignore sbas;
|
821
888
|
%ignore select_solver;
|
822
889
|
%ignore relative_property;
|
823
890
|
%ignore satellite_position;
|
@@ -826,18 +893,19 @@ struct GPS_SolverOptions : public GPS_SinglePositioning<FloatT>::options_t {
|
|
826
893
|
%ignore mark;
|
827
894
|
%fragment("hook"{GPS_Solver<FloatT>}, "header",
|
828
895
|
fragment=SWIG_From_frag(int),
|
829
|
-
fragment=SWIG_Traits_frag(FloatT)
|
896
|
+
fragment=SWIG_Traits_frag(FloatT),
|
897
|
+
fragment=SWIG_Traits_frag(GPS_Measurement<FloatT>)){
|
830
898
|
template <>
|
831
|
-
|
899
|
+
GPS_Solver<FloatT>::base_t::relative_property_t
|
832
900
|
GPS_Solver<FloatT>::relative_property(
|
833
|
-
const
|
834
|
-
const
|
835
|
-
const
|
836
|
-
const
|
837
|
-
const
|
838
|
-
const
|
901
|
+
const GPS_Solver<FloatT>::base_t::prn_t &prn,
|
902
|
+
const GPS_Solver<FloatT>::base_t::measurement_t::mapped_type &measurement,
|
903
|
+
const GPS_Solver<FloatT>::base_t::float_t &receiver_error,
|
904
|
+
const GPS_Solver<FloatT>::base_t::gps_time_t &time_arrival,
|
905
|
+
const GPS_Solver<FloatT>::base_t::pos_t &usr_pos,
|
906
|
+
const GPS_Solver<FloatT>::base_t::xyz_t &usr_vel) const {
|
839
907
|
union {
|
840
|
-
|
908
|
+
base_t::relative_property_t prop;
|
841
909
|
FloatT values[7];
|
842
910
|
} res = {
|
843
911
|
select_solver(prn).relative_property(
|
@@ -859,6 +927,7 @@ struct GPS_SolverOptions : public GPS_SinglePositioning<FloatT>::options_t {
|
|
859
927
|
swig::from(res.prop.los_neg[0]),
|
860
928
|
swig::from(res.prop.los_neg[1]),
|
861
929
|
swig::from(res.prop.los_neg[2])),
|
930
|
+
swig::from(measurement), // measurement => Hash
|
862
931
|
swig::from(receiver_error), // receiver_error
|
863
932
|
SWIG_NewPointerObj( // time_arrival
|
864
933
|
new base_t::gps_time_t(time_arrival), $descriptor(GPS_Time<FloatT> *), SWIG_POINTER_OWN),
|
@@ -889,29 +958,186 @@ struct GPS_SolverOptions : public GPS_SinglePositioning<FloatT>::options_t {
|
|
889
958
|
}
|
890
959
|
template <>
|
891
960
|
bool GPS_Solver<FloatT>::update_position_solution(
|
892
|
-
const
|
893
|
-
|
961
|
+
const GPS_Solver<FloatT>::base_t::geometric_matrices_t &geomat,
|
962
|
+
GPS_Solver<FloatT>::base_t::user_pvt_t &res) const {
|
894
963
|
#ifdef SWIGRUBY
|
895
964
|
do{
|
896
965
|
static const VALUE key(ID2SYM(rb_intern("update_position_solution")));
|
897
966
|
VALUE hook(rb_hash_lookup(hooks, key));
|
898
967
|
if(NIL_P(hook)){break;}
|
899
|
-
|
900
|
-
%const_cast(geomat,
|
968
|
+
base_t::geometric_matrices_t &geomat_(
|
969
|
+
%const_cast(geomat, base_t::geometric_matrices_t &));
|
901
970
|
VALUE values[] = {
|
902
971
|
SWIG_NewPointerObj(&geomat_.G,
|
903
972
|
$descriptor(Matrix<FloatT, Array2D_Dense<FloatT>, MatrixViewBase<> > *), 0),
|
904
973
|
SWIG_NewPointerObj(&geomat_.W,
|
905
974
|
$descriptor(Matrix<FloatT, Array2D_Dense<FloatT>, MatrixViewBase<> > *), 0),
|
906
975
|
SWIG_NewPointerObj(&geomat_.delta_r,
|
907
|
-
$descriptor(Matrix<FloatT, Array2D_Dense<FloatT>, MatrixViewBase<> > *), 0)
|
976
|
+
$descriptor(Matrix<FloatT, Array2D_Dense<FloatT>, MatrixViewBase<> > *), 0),
|
977
|
+
SWIG_NewPointerObj(&res,
|
978
|
+
$descriptor(GPS_User_PVT<FloatT> *), 0)};
|
908
979
|
proc_call_throw_if_error(hook, sizeof(values) / sizeof(values[0]), values);
|
909
980
|
}while(false);
|
910
981
|
#endif
|
911
982
|
return super_t::update_position_solution(geomat, res);
|
912
983
|
}
|
984
|
+
template <>
|
985
|
+
GPS_Solver<FloatT>::base_t::xyz_t *GPS_Solver<FloatT>::satellite_position(
|
986
|
+
const GPS_Solver<FloatT>::base_t::prn_t &prn,
|
987
|
+
const GPS_Solver<FloatT>::base_t::gps_time_t &time,
|
988
|
+
GPS_Solver<FloatT>::base_t::xyz_t &buf) const {
|
989
|
+
GPS_Solver<FloatT>::base_t::xyz_t *res(
|
990
|
+
select_solver(prn).satellite_position(prn, time, buf));
|
991
|
+
#ifdef SWIGRUBY
|
992
|
+
do{
|
993
|
+
static const VALUE key(ID2SYM(rb_intern("satellite_position")));
|
994
|
+
VALUE hook(rb_hash_lookup(hooks, key));
|
995
|
+
if(NIL_P(hook)){break;}
|
996
|
+
VALUE values[] = {
|
997
|
+
SWIG_From(int)(prn), // prn
|
998
|
+
SWIG_NewPointerObj( // time
|
999
|
+
new base_t::gps_time_t(time), $descriptor(GPS_Time<FloatT> *), SWIG_POINTER_OWN),
|
1000
|
+
(res // position (internally calculated)
|
1001
|
+
? SWIG_NewPointerObj(res, $descriptor(System_XYZ<FloatT, WGS84> *), 0)
|
1002
|
+
: Qnil)};
|
1003
|
+
VALUE res_hook(proc_call_throw_if_error(hook, sizeof(values) / sizeof(values[0]), values));
|
1004
|
+
if(NIL_P(res_hook)){ // unknown position
|
1005
|
+
res = NULL;
|
1006
|
+
break;
|
1007
|
+
}else if(RB_TYPE_P(res_hook, T_ARRAY) && (RARRAY_LEN(res_hook) == 3)){
|
1008
|
+
int i(0);
|
1009
|
+
for(; i < 3; ++i){
|
1010
|
+
VALUE v(RARRAY_AREF(res_hook, i));
|
1011
|
+
if(!SWIG_IsOK(swig::asval(v, &buf[i]))){break;}
|
1012
|
+
}
|
1013
|
+
if(i == 3){
|
1014
|
+
res = &buf;
|
1015
|
+
break;
|
1016
|
+
}
|
1017
|
+
}else if(SWIG_IsOK(SWIG_ConvertPtr(
|
1018
|
+
res_hook, (void **)&res, $descriptor(System_XYZ<FloatT, WGS84> *), 0))){
|
1019
|
+
res = &(buf = *res);
|
1020
|
+
break;
|
1021
|
+
}
|
1022
|
+
throw std::runtime_error(
|
1023
|
+
std::string("System_XYZ or [d * 3] is expected (d: " %str(FloatT) "), however ")
|
1024
|
+
.append(inspect_str(res_hook)));
|
1025
|
+
}while(false);
|
1026
|
+
#endif
|
1027
|
+
return res;
|
1028
|
+
}
|
913
1029
|
}
|
914
1030
|
%fragment("hook"{GPS_Solver<FloatT>});
|
1031
|
+
%ignore update_correction;
|
1032
|
+
#ifdef SWIGRUBY
|
1033
|
+
%fragment("correction"{GPS_Solver<FloatT>}, "header",
|
1034
|
+
fragment=SWIG_From_frag(int),
|
1035
|
+
fragment=SWIG_Traits_frag(FloatT)){
|
1036
|
+
template<>
|
1037
|
+
VALUE GPS_Solver<FloatT>::update_correction(
|
1038
|
+
const bool &update, const VALUE &hash){
|
1039
|
+
typedef range_correction_list_t list_t;
|
1040
|
+
static const VALUE k_root[] = {
|
1041
|
+
ID2SYM(rb_intern("gps_ionospheric")),
|
1042
|
+
ID2SYM(rb_intern("gps_tropospheric")),
|
1043
|
+
ID2SYM(rb_intern("sbas_ionospheric")),
|
1044
|
+
ID2SYM(rb_intern("sbas_tropospheric")),
|
1045
|
+
};
|
1046
|
+
static const VALUE k_opt(ID2SYM(rb_intern("options")));
|
1047
|
+
static const VALUE k_f_10_7(ID2SYM(rb_intern("f_10_7")));
|
1048
|
+
static const VALUE k_known(ID2SYM(rb_intern("known")));
|
1049
|
+
struct {
|
1050
|
+
VALUE sym;
|
1051
|
+
list_t::mapped_type::value_type obj;
|
1052
|
+
} item[] = {
|
1053
|
+
{ID2SYM(rb_intern("no_correction")), &base_t::no_correction},
|
1054
|
+
{ID2SYM(rb_intern("klobuchar")), &this->gps.solver.ionospheric_klobuchar},
|
1055
|
+
{ID2SYM(rb_intern("ntcm_gl")), &this->gps.solver.ionospheric_ntcm_gl},
|
1056
|
+
{ID2SYM(rb_intern("hopfield")), &this->gps.solver.tropospheric_simplified},
|
1057
|
+
{ID2SYM(rb_intern("sbas_igp")), &this->sbas.solver.ionospheric_sbas},
|
1058
|
+
{ID2SYM(rb_intern("sbas_tropo")), &this->sbas.solver.tropospheric_sbas},
|
1059
|
+
};
|
1060
|
+
list_t input;
|
1061
|
+
if(update){
|
1062
|
+
if(!RB_TYPE_P(hash, T_HASH)){
|
1063
|
+
throw std::runtime_error(
|
1064
|
+
std::string("Hash is expected, however ").append(inspect_str(hash)));
|
1065
|
+
}
|
1066
|
+
for(std::size_t i(0); i < sizeof(k_root) / sizeof(k_root[0]); ++i){
|
1067
|
+
VALUE ary = rb_hash_lookup(hash, k_root[i]);
|
1068
|
+
if(NIL_P(ary)){continue;}
|
1069
|
+
if(!RB_TYPE_P(ary, T_ARRAY)){
|
1070
|
+
ary = rb_ary_new_from_values(1, &ary);
|
1071
|
+
}
|
1072
|
+
for(int j(0); j < RARRAY_LEN(ary); ++j){
|
1073
|
+
std::size_t k(0);
|
1074
|
+
VALUE v(rb_ary_entry(ary, j));
|
1075
|
+
for(; k < sizeof(item) / sizeof(item[0]); ++k){
|
1076
|
+
if(v == item[k].sym){break;}
|
1077
|
+
}
|
1078
|
+
if(k >= sizeof(item) / sizeof(item[0])){
|
1079
|
+
continue; // TODO other than symbol
|
1080
|
+
}
|
1081
|
+
input[i].push_back(item[k].obj);
|
1082
|
+
}
|
1083
|
+
}
|
1084
|
+
VALUE opt(rb_hash_lookup(hash, k_opt));
|
1085
|
+
if(RB_TYPE_P(opt, T_HASH)){
|
1086
|
+
swig::asval(rb_hash_lookup(opt, k_f_10_7), // ntcm_gl
|
1087
|
+
&this->gps.solver.ionospheric_ntcm_gl.f_10_7);
|
1088
|
+
}
|
1089
|
+
}
|
1090
|
+
list_t output(update_correction(update, input));
|
1091
|
+
VALUE res = rb_hash_new();
|
1092
|
+
for(list_t::const_iterator it(output.begin()), it_end(output.end());
|
1093
|
+
it != it_end; ++it){
|
1094
|
+
VALUE k;
|
1095
|
+
if((it->first < 0) || (it->first >= (int)(sizeof(k_root) / sizeof(k_root[0])))){
|
1096
|
+
k = SWIG_From(int)(it->first);
|
1097
|
+
}else{
|
1098
|
+
k = k_root[it->first];
|
1099
|
+
}
|
1100
|
+
VALUE v = rb_ary_new();
|
1101
|
+
for(list_t::mapped_type::const_iterator
|
1102
|
+
it2(it->second.begin()), it2_end(it->second.end());
|
1103
|
+
it2 != it2_end; ++it2){
|
1104
|
+
std::size_t i(0);
|
1105
|
+
for(; i < sizeof(item) / sizeof(item[0]); ++i){
|
1106
|
+
if(*it2 == item[i].obj){break;}
|
1107
|
+
}
|
1108
|
+
if(i >= sizeof(item) / sizeof(item[0])){
|
1109
|
+
continue; // TODO other than built-in corrector
|
1110
|
+
}
|
1111
|
+
rb_ary_push(v, item[i].sym);
|
1112
|
+
}
|
1113
|
+
rb_hash_aset(res, k, v);
|
1114
|
+
}
|
1115
|
+
{ // common options
|
1116
|
+
VALUE opt = rb_hash_new();
|
1117
|
+
rb_hash_aset(res, k_opt, opt);
|
1118
|
+
rb_hash_aset(opt, k_f_10_7, // ntcm_gl
|
1119
|
+
swig::from(this->gps.solver.ionospheric_ntcm_gl.f_10_7));
|
1120
|
+
}
|
1121
|
+
{ // known models
|
1122
|
+
VALUE ary = rb_ary_new_capa((int)(sizeof(item) / sizeof(item[0])));
|
1123
|
+
for(std::size_t i(0); i < sizeof(item) / sizeof(item[0]); ++i){
|
1124
|
+
rb_ary_push(ary, item[i].sym);
|
1125
|
+
}
|
1126
|
+
rb_hash_aset(res, k_known, ary);
|
1127
|
+
}
|
1128
|
+
return res;
|
1129
|
+
}
|
1130
|
+
}
|
1131
|
+
%fragment("correction"{GPS_Solver<FloatT>});
|
1132
|
+
%rename("correction") get_correction;
|
1133
|
+
%rename("correction=") set_correction;
|
1134
|
+
VALUE get_correction() const {
|
1135
|
+
return const_cast<GPS_Solver<FloatT> *>(self)->update_correction(false, Qnil);
|
1136
|
+
}
|
1137
|
+
VALUE set_correction(VALUE hash){
|
1138
|
+
return self->update_correction(true, hash);
|
1139
|
+
}
|
1140
|
+
#endif
|
915
1141
|
}
|
916
1142
|
%inline {
|
917
1143
|
template <class FloatT>
|
@@ -927,6 +1153,12 @@ struct GPS_Solver
|
|
927
1153
|
GPS_SinglePositioning<FloatT> solver;
|
928
1154
|
gps_t() : space_node(), options(), solver(space_node) {}
|
929
1155
|
} gps;
|
1156
|
+
struct sbas_t {
|
1157
|
+
SBAS_SpaceNode<FloatT> space_node;
|
1158
|
+
SBAS_SolverOptions<FloatT> options;
|
1159
|
+
SBAS_SinglePositioning<FloatT> solver;
|
1160
|
+
sbas_t() : space_node(), options(), solver(space_node) {}
|
1161
|
+
} sbas;
|
930
1162
|
SWIG_Object hooks;
|
931
1163
|
#ifdef SWIGRUBY
|
932
1164
|
static void mark(void *ptr){
|
@@ -935,17 +1167,36 @@ struct GPS_Solver
|
|
935
1167
|
rb_gc_mark(solver->hooks);
|
936
1168
|
}
|
937
1169
|
#endif
|
938
|
-
GPS_Solver() : super_t(), gps(), hooks() {
|
1170
|
+
GPS_Solver() : super_t(), gps(), sbas(), hooks() {
|
939
1171
|
#ifdef SWIGRUBY
|
940
1172
|
hooks = rb_hash_new();
|
941
1173
|
#endif
|
1174
|
+
typename base_t::range_correction_t ionospheric, tropospheric;
|
1175
|
+
ionospheric.push_back(&sbas.solver.ionospheric_sbas);
|
1176
|
+
ionospheric.push_back(&gps.solver.ionospheric_klobuchar);
|
1177
|
+
tropospheric.push_back(&sbas.solver.tropospheric_sbas);
|
1178
|
+
tropospheric.push_back(&gps.solver.tropospheric_simplified);
|
1179
|
+
gps.solver.ionospheric_correction
|
1180
|
+
= sbas.solver.ionospheric_correction
|
1181
|
+
= ionospheric;
|
1182
|
+
gps.solver.tropospheric_correction
|
1183
|
+
= sbas.solver.tropospheric_correction
|
1184
|
+
= tropospheric;
|
942
1185
|
}
|
943
1186
|
GPS_SpaceNode<FloatT> &gps_space_node() {return gps.space_node;}
|
944
1187
|
GPS_SolverOptions<FloatT> &gps_options() {return gps.options;}
|
1188
|
+
SBAS_SpaceNode<FloatT> &sbas_space_node() {return sbas.space_node;}
|
1189
|
+
SBAS_SolverOptions<FloatT> &sbas_options() {return sbas.options;}
|
945
1190
|
const base_t &select_solver(
|
946
1191
|
const typename base_t::prn_t &prn) const {
|
947
1192
|
if(prn > 0 && prn <= 32){return gps.solver;}
|
948
|
-
return
|
1193
|
+
if(prn >= 120 && prn <= 158){return sbas.solver;}
|
1194
|
+
if(prn > 192 && prn <= 202){return gps.solver;}
|
1195
|
+
// call order: base_t::solve => this returned by select()
|
1196
|
+
// => relative_property() => select_solver()
|
1197
|
+
// For not supported satellite, call loop prevention is required.
|
1198
|
+
static const base_t dummy;
|
1199
|
+
return dummy;
|
949
1200
|
}
|
950
1201
|
virtual typename base_t::relative_property_t relative_property(
|
951
1202
|
const typename base_t::prn_t &prn,
|
@@ -957,9 +1208,7 @@ struct GPS_Solver
|
|
957
1208
|
virtual typename base_t::xyz_t *satellite_position(
|
958
1209
|
const typename base_t::prn_t &prn,
|
959
1210
|
const typename base_t::gps_time_t &time,
|
960
|
-
typename base_t::xyz_t &res) const
|
961
|
-
return select_solver(prn).satellite_position(prn, time, res);
|
962
|
-
}
|
1211
|
+
typename base_t::xyz_t &res) const;
|
963
1212
|
virtual bool update_position_solution(
|
964
1213
|
const typename base_t::geometric_matrices_t &geomat,
|
965
1214
|
typename base_t::user_pvt_t &res) const;
|
@@ -968,8 +1217,44 @@ struct GPS_Solver
|
|
968
1217
|
const GPS_Time<FloatT> &receiver_time) const {
|
969
1218
|
const_cast<gps_t &>(gps).space_node.update_all_ephemeris(receiver_time);
|
970
1219
|
const_cast<gps_t &>(gps).solver.update_options(gps.options);
|
1220
|
+
const_cast<sbas_t &>(sbas).space_node.update_all_ephemeris(receiver_time);
|
1221
|
+
const_cast<sbas_t &>(sbas).solver.update_options(sbas.options);
|
971
1222
|
return super_t::solve().user_pvt(measurement.items, receiver_time);
|
972
1223
|
}
|
1224
|
+
typedef
|
1225
|
+
std::map<int, std::vector<const typename base_t::range_corrector_t *> >
|
1226
|
+
range_correction_list_t;
|
1227
|
+
range_correction_list_t update_correction(
|
1228
|
+
const bool &update,
|
1229
|
+
const range_correction_list_t &list = range_correction_list_t()){
|
1230
|
+
range_correction_list_t res;
|
1231
|
+
typename base_t::range_correction_t *root[] = {
|
1232
|
+
&gps.solver.ionospheric_correction,
|
1233
|
+
&gps.solver.tropospheric_correction,
|
1234
|
+
&sbas.solver.ionospheric_correction,
|
1235
|
+
&sbas.solver.tropospheric_correction,
|
1236
|
+
};
|
1237
|
+
for(std::size_t i(0); i < sizeof(root) / sizeof(root[0]); ++i){
|
1238
|
+
do{
|
1239
|
+
if(!update){break;}
|
1240
|
+
typename range_correction_list_t::const_iterator it(list.find(i));
|
1241
|
+
if(it == list.end()){break;}
|
1242
|
+
root[i]->clear();
|
1243
|
+
for(typename range_correction_list_t::mapped_type::const_iterator
|
1244
|
+
it2(it->second.begin()), it2_end(it->second.end());
|
1245
|
+
it2 != it2_end; ++it2){
|
1246
|
+
root[i]->push_back(*it2);
|
1247
|
+
}
|
1248
|
+
}while(false);
|
1249
|
+
for(typename base_t::range_correction_t::const_iterator
|
1250
|
+
it(root[i]->begin()), it_end(root[i]->end());
|
1251
|
+
it != it_end; ++it){
|
1252
|
+
res[i].push_back(*it);
|
1253
|
+
}
|
1254
|
+
}
|
1255
|
+
return res;
|
1256
|
+
}
|
1257
|
+
SWIG_Object update_correction(const bool &update, const SWIG_Object &hash);
|
973
1258
|
};
|
974
1259
|
}
|
975
1260
|
|
@@ -1091,6 +1376,7 @@ struct RINEX_Observation {};
|
|
1091
1376
|
|
1092
1377
|
#undef MAKE_ACCESSOR
|
1093
1378
|
#undef MAKE_VECTOR2ARRAY
|
1379
|
+
#undef MAKE_ARRAY_INPUT
|
1094
1380
|
|
1095
1381
|
%define CONCRETIZE(type)
|
1096
1382
|
%template(Time) GPS_Time<type>;
|
@@ -1099,12 +1385,17 @@ struct RINEX_Observation {};
|
|
1099
1385
|
%template(Ephemeris) GPS_Ephemeris<type>;
|
1100
1386
|
%template(PVT) GPS_User_PVT<type>;
|
1101
1387
|
%template(Measurement) GPS_Measurement<type>;
|
1388
|
+
%template(SolverOptionsCommon) GPS_SolverOptions_Common<type>;
|
1102
1389
|
%template(SolverOptions) GPS_SolverOptions<type>;
|
1103
1390
|
#if defined(SWIGRUBY)
|
1104
1391
|
%markfunc GPS_Solver<type> "GPS_Solver<type>::mark";
|
1105
1392
|
#endif
|
1106
1393
|
%template(Solver) GPS_Solver<type>;
|
1107
1394
|
|
1395
|
+
%template(Ephemeris_SBAS) SBAS_Ephemeris<type>;
|
1396
|
+
%template(SpaceNode_SBAS) SBAS_SpaceNode<type>;
|
1397
|
+
%template(SolverOptions_SBAS) SBAS_SolverOptions<type>;
|
1398
|
+
|
1108
1399
|
%template(RINEX_Observation) RINEX_Observation<type>;
|
1109
1400
|
%enddef
|
1110
1401
|
|