gps_pvt 0.1.5 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -4
- data/Rakefile +9 -4
- data/exe/gps_pvt +32 -23
- data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +5 -3
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +4302 -529
- data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +7 -5
- data/ext/ninja-scan-light/tool/navigation/GPS.h +5 -4
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +62 -15
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +33 -25
- data/ext/ninja-scan-light/tool/navigation/QZSS.h +62 -0
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +583 -115
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +2330 -0
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +329 -0
- data/ext/ninja-scan-light/tool/swig/GPS.i +284 -99
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +18 -1
- data/lib/gps_pvt/receiver.rb +323 -141
- data/lib/gps_pvt/version.rb +1 -1
- metadata +9 -7
- data/gps_pvt.gemspec +0 -57
@@ -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){
|
@@ -180,6 +183,26 @@ const type &get_ ## name () const {
|
|
180
183
|
}
|
181
184
|
}
|
182
185
|
%enddef
|
186
|
+
#if defined(SWIGRUBY)
|
187
|
+
%define MAKE_ARRAY_INPUT(type, arg_name, f_conv)
|
188
|
+
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) type arg_name[ANY] {
|
189
|
+
$1 = RB_TYPE_P($input, T_ARRAY) ? 1 : 0;
|
190
|
+
}
|
191
|
+
%typemap(in) type arg_name[ANY] ($*1_ltype temp[$1_dim0]) {
|
192
|
+
if(!(RB_TYPE_P($input, T_ARRAY) && (RARRAY_LEN($input) == $1_dim0))){
|
193
|
+
SWIG_exception(SWIG_TypeError, "array[$1_dim0] is expected");
|
194
|
+
}
|
195
|
+
for(int i(0); i < $1_dim0; ++i){
|
196
|
+
if(!SWIG_IsOK(f_conv(RARRAY_AREF($input, i), &temp[i]))){
|
197
|
+
SWIG_exception(SWIG_TypeError, "$*1_ltype is expected");
|
198
|
+
}
|
199
|
+
}
|
200
|
+
$1 = temp;
|
201
|
+
}
|
202
|
+
%enddef
|
203
|
+
#else
|
204
|
+
#define MAKE_ARRAY_INPUT(type, arg_name, f_conv)
|
205
|
+
#endif
|
183
206
|
|
184
207
|
%inline %{
|
185
208
|
template <class FloatT>
|
@@ -195,34 +218,8 @@ struct GPS_Ionospheric_UTC_Parameters : public GPS_SpaceNode<FloatT>::Ionospheri
|
|
195
218
|
%append_output(swig::from($1[i]));
|
196
219
|
}
|
197
220
|
}
|
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
|
-
}
|
221
|
+
MAKE_ARRAY_INPUT(const FloatT, values, swig::asval);
|
222
|
+
MAKE_ARRAY_INPUT(const unsigned int, buf, SWIG_AsVal(unsigned int));
|
226
223
|
%rename("alpha=") set_alpha;
|
227
224
|
void set_alpha(const FloatT values[4]){
|
228
225
|
for(int i(0); i < 4; ++i){
|
@@ -255,7 +252,7 @@ struct GPS_Ionospheric_UTC_Parameters : public GPS_SpaceNode<FloatT>::Ionospheri
|
|
255
252
|
MAKE_ACCESSOR(WN_LSF, unsigned int);
|
256
253
|
MAKE_ACCESSOR(DN, unsigned int);
|
257
254
|
MAKE_ACCESSOR(delta_t_LSF, int);
|
258
|
-
static GPS_Ionospheric_UTC_Parameters<FloatT> parse(const unsigned int
|
255
|
+
static GPS_Ionospheric_UTC_Parameters<FloatT> parse(const unsigned int buf[10]){
|
259
256
|
typedef typename GPS_SpaceNode<FloatT>
|
260
257
|
::BroadcastedMessage<unsigned int, 30> parser_t;
|
261
258
|
if((parser_t::subframe_id(buf) != 4) || (parser_t::sv_page_id(buf) != 56)){
|
@@ -321,22 +318,10 @@ struct GPS_Ephemeris : public GPS_SpaceNode<FloatT>::SatelliteProperties::Epheme
|
|
321
318
|
MAKE_ACCESSOR(omega, FloatT);
|
322
319
|
MAKE_ACCESSOR(dot_Omega0, FloatT);
|
323
320
|
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
|
-
}
|
321
|
+
|
322
|
+
MAKE_ARRAY_INPUT(const unsigned int, buf, SWIG_AsVal(unsigned int));
|
338
323
|
%apply int *OUTPUT { int *subframe_no, int *iodc_or_iode };
|
339
|
-
void parse(const unsigned int
|
324
|
+
void parse(const unsigned int buf[10], int *subframe_no, int *iodc_or_iode){
|
340
325
|
typedef typename GPS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris eph_t;
|
341
326
|
typename eph_t::raw_t raw;
|
342
327
|
eph_t eph;
|
@@ -432,11 +417,82 @@ struct GPS_Ephemeris : public GPS_SpaceNode<FloatT>::SatelliteProperties::Epheme
|
|
432
417
|
%ignore tropo_correction() const;
|
433
418
|
int read(const char *fname) {
|
434
419
|
std::fstream fin(fname, std::ios::in | std::ios::binary);
|
435
|
-
|
420
|
+
typename RINEX_NAV_Reader<FloatT>::space_node_list_t space_nodes = {self};
|
421
|
+
space_nodes.qzss = self;
|
422
|
+
return RINEX_NAV_Reader<FloatT>::read_all(fin, space_nodes);
|
436
423
|
}
|
437
424
|
}
|
438
425
|
|
439
426
|
%include navigation/GPS.h
|
427
|
+
%include navigation/QZSS.h
|
428
|
+
|
429
|
+
%inline %{
|
430
|
+
template <class FloatT>
|
431
|
+
struct SBAS_Ephemeris : public SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris {
|
432
|
+
SBAS_Ephemeris() : SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris() {}
|
433
|
+
SBAS_Ephemeris(const typename SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris &eph)
|
434
|
+
: SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris(eph) {}
|
435
|
+
};
|
436
|
+
%}
|
437
|
+
%extend SBAS_Ephemeris {
|
438
|
+
MAKE_ACCESSOR(svid, unsigned int);
|
439
|
+
|
440
|
+
MAKE_ACCESSOR(WN, unsigned int);
|
441
|
+
MAKE_ACCESSOR(t_0, FloatT);
|
442
|
+
MAKE_ACCESSOR(URA, int);
|
443
|
+
MAKE_ACCESSOR( x, FloatT); MAKE_ACCESSOR( y, FloatT); MAKE_ACCESSOR( z, FloatT);
|
444
|
+
MAKE_ACCESSOR( dx, FloatT); MAKE_ACCESSOR( dy, FloatT); MAKE_ACCESSOR( dz, FloatT);
|
445
|
+
MAKE_ACCESSOR(ddx, FloatT); MAKE_ACCESSOR(ddy, FloatT); MAKE_ACCESSOR(ddz, FloatT);
|
446
|
+
MAKE_ACCESSOR(a_Gf0, FloatT);
|
447
|
+
MAKE_ACCESSOR(a_Gf1, FloatT);
|
448
|
+
%apply GPS_Ephemeris::System_XYZ<FloatT, WGS84> & { System_XYZ<FloatT, WGS84> & }; // TODO ineffective?
|
449
|
+
void constellation(
|
450
|
+
System_XYZ<FloatT, WGS84> &position, System_XYZ<FloatT, WGS84> &velocity,
|
451
|
+
const GPS_Time<FloatT> &t, const FloatT &pseudo_range = 0,
|
452
|
+
const bool &with_velocity = true) const {
|
453
|
+
typename SBAS_SpaceNode<FloatT>::SatelliteProperties::constellation_t res(
|
454
|
+
self->constellation(t, pseudo_range, with_velocity));
|
455
|
+
position = res.position;
|
456
|
+
velocity = res.velocity;
|
457
|
+
}
|
458
|
+
}
|
459
|
+
|
460
|
+
%extend SBAS_SpaceNode {
|
461
|
+
%fragment(SWIG_Traits_frag(FloatT));
|
462
|
+
%ignore satellites() const;
|
463
|
+
%ignore satellite(const int &);
|
464
|
+
%ignore available_satellites(const FloatT &lng_deg) const;
|
465
|
+
void register_ephemeris(
|
466
|
+
const int &prn, const SBAS_Ephemeris<FloatT> &eph,
|
467
|
+
const int &priority_delta = 1){
|
468
|
+
self->satellite(prn).register_ephemeris(eph, priority_delta);
|
469
|
+
}
|
470
|
+
SBAS_Ephemeris<FloatT> ephemeris(const int &prn) const {
|
471
|
+
return SBAS_Ephemeris<FloatT>(
|
472
|
+
%const_cast(self, SBAS_SpaceNode<FloatT> *)->satellite(prn).ephemeris());
|
473
|
+
}
|
474
|
+
int read(const char *fname) {
|
475
|
+
std::fstream fin(fname, std::ios::in | std::ios::binary);
|
476
|
+
RINEX_NAV_Reader<FloatT>::space_node_list_t space_nodes = {NULL};
|
477
|
+
space_nodes.sbas = self;
|
478
|
+
return RINEX_NAV_Reader<FloatT>::read_all(fin, space_nodes);
|
479
|
+
}
|
480
|
+
MAKE_ARRAY_INPUT(const unsigned int, buf, SWIG_AsVal(unsigned int));
|
481
|
+
int decode_message(const unsigned int buf[8],
|
482
|
+
const int &prn, const GPS_Time<FloatT> &t_reception,
|
483
|
+
const bool &LNAV_VNAV_LP_LPV_approach = false){
|
484
|
+
return static_cast<int>(
|
485
|
+
self->decode_message(buf, prn, t_reception, LNAV_VNAV_LP_LPV_approach));
|
486
|
+
}
|
487
|
+
std::string ionospheric_grid_points(const int &prn) const {
|
488
|
+
std::ostringstream ss;
|
489
|
+
ss << %const_cast(self, SBAS_SpaceNode<FloatT> *)->satellite(prn)
|
490
|
+
.ionospheric_grid_points();
|
491
|
+
return ss.str();
|
492
|
+
}
|
493
|
+
}
|
494
|
+
|
495
|
+
%include navigation/SBAS.h
|
440
496
|
|
441
497
|
%extend GPS_User_PVT {
|
442
498
|
%ignore solver_t;
|
@@ -604,23 +660,6 @@ struct GPS_User_PVT
|
|
604
660
|
}
|
605
661
|
}
|
606
662
|
}
|
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
663
|
%fragment(SWIG_Traits_frag(GPS_Measurement<FloatT>), "header",
|
625
664
|
fragment=SWIG_Traits_frag(FloatT)){
|
626
665
|
namespace swig {
|
@@ -704,9 +743,32 @@ struct GPS_User_PVT
|
|
704
743
|
#endif
|
705
744
|
return SWIG_ERROR;
|
706
745
|
}
|
746
|
+
#ifdef SWIGRUBY
|
747
|
+
template <>
|
748
|
+
VALUE from(const GPS_Measurement<FloatT>::items_t::mapped_type &val) {
|
749
|
+
VALUE per_sat(rb_hash_new());
|
750
|
+
for(typename GPS_Measurement<FloatT>::items_t::mapped_type::const_iterator
|
751
|
+
it(val.begin()), it_end(val.end());
|
752
|
+
it != it_end; ++it){
|
753
|
+
rb_hash_aset(per_sat, SWIG_From(int)(it->first), swig::from(it->second));
|
754
|
+
}
|
755
|
+
return per_sat;
|
756
|
+
}
|
757
|
+
#endif
|
707
758
|
}
|
708
759
|
}
|
709
760
|
%fragment(SWIG_Traits_frag(GPS_Measurement<FloatT>));
|
761
|
+
#ifdef SWIGRUBY
|
762
|
+
VALUE to_hash() const {
|
763
|
+
VALUE res(rb_hash_new());
|
764
|
+
for(typename GPS_Measurement<FloatT>::items_t::const_iterator
|
765
|
+
it(self->items.begin()), it_end(self->items.end());
|
766
|
+
it != it_end; ++it){
|
767
|
+
rb_hash_aset(res, SWIG_From(int)(it->first), swig::from(it->second));
|
768
|
+
}
|
769
|
+
return res;
|
770
|
+
}
|
771
|
+
#endif
|
710
772
|
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) const GPS_Measurement<FloatT> & {
|
711
773
|
$1 = SWIG_CheckState(SWIG_ConvertPtr($input, (void **)0, $1_descriptor, 0))
|
712
774
|
|| swig::check<GPS_Measurement<FloatT> >($input);
|
@@ -746,12 +808,23 @@ struct GPS_Measurement {
|
|
746
808
|
};
|
747
809
|
}
|
748
810
|
|
749
|
-
%extend
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
811
|
+
%extend GPS_SolverOptions_Common {
|
812
|
+
%define MAKE_ACCESSOR2(name, type)
|
813
|
+
%rename(%str(name ## =)) set_ ## name;
|
814
|
+
type set_ ## name (const type &v) {
|
815
|
+
return self->cast_general()->name = v;
|
816
|
+
}
|
817
|
+
%rename(%str(name)) get_ ## name;
|
818
|
+
const type &get_ ## name () const {
|
819
|
+
return self->cast_general()->name;
|
820
|
+
}
|
821
|
+
%enddef
|
822
|
+
MAKE_ACCESSOR2(elevation_mask, FloatT);
|
823
|
+
MAKE_ACCESSOR2(residual_mask, FloatT);
|
824
|
+
MAKE_ACCESSOR2(f_10_7, FloatT);
|
825
|
+
#undef MAKE_ACCESSOR2
|
754
826
|
MAKE_VECTOR2ARRAY(int);
|
827
|
+
%ignore cast_base;
|
755
828
|
#ifdef SWIGRUBY
|
756
829
|
%rename("ionospheric_models=") set_ionospheric_models;
|
757
830
|
%rename("ionospheric_models") get_ionospheric_models;
|
@@ -775,49 +848,92 @@ struct GPS_Measurement {
|
|
775
848
|
}
|
776
849
|
%inline %{
|
777
850
|
template <class FloatT>
|
778
|
-
struct
|
779
|
-
typedef typename GPS_SinglePositioning<FloatT>::options_t base_t;
|
780
|
-
void exclude(const int &prn){base_t::exclude_prn.set(prn);}
|
781
|
-
void include(const int &prn){base_t::exclude_prn.reset(prn);}
|
782
|
-
std::vector<int> excluded() const {return base_t::exclude_prn.excluded();}
|
851
|
+
struct GPS_SolverOptions_Common {
|
783
852
|
enum {
|
784
853
|
IONOSPHERIC_KLOBUCHAR,
|
854
|
+
IONOSPHERIC_SBAS,
|
785
855
|
IONOSPHERIC_NTCM_GL,
|
786
856
|
IONOSPHERIC_NONE, // which allows no correction
|
787
857
|
IONOSPHERIC_MODELS,
|
788
858
|
IONOSPHERIC_SKIP = IONOSPHERIC_MODELS, // which means delegating the next slot
|
789
859
|
};
|
860
|
+
virtual GPS_Solver_GeneralOptions<FloatT> *cast_general() = 0;
|
861
|
+
virtual const GPS_Solver_GeneralOptions<FloatT> *cast_general() const = 0;
|
790
862
|
std::vector<int> get_ionospheric_models() const {
|
863
|
+
typedef GPS_Solver_GeneralOptions<FloatT> general_t;
|
864
|
+
const general_t *general(this->cast_general());
|
791
865
|
std::vector<int> res;
|
792
|
-
for(int i(0); i <
|
793
|
-
int v((int)(
|
794
|
-
if(v ==
|
866
|
+
for(int i(0); i < general_t::IONOSPHERIC_MODELS; ++i){
|
867
|
+
int v((int)(general->ionospheric_models[i]));
|
868
|
+
if(v == general_t::IONOSPHERIC_SKIP){break;}
|
795
869
|
res.push_back(v);
|
796
870
|
}
|
797
871
|
return res;
|
798
872
|
}
|
799
873
|
std::vector<int> set_ionospheric_models(const std::vector<int> &models){
|
800
|
-
typedef
|
801
|
-
|
802
|
-
|
874
|
+
typedef GPS_Solver_GeneralOptions<FloatT> general_t;
|
875
|
+
general_t *general(this->cast_general());
|
876
|
+
typedef typename general_t::ionospheric_model_t model_t;
|
877
|
+
for(int i(0), j(0), j_max(models.size()); i < general_t::IONOSPHERIC_MODELS; ++i){
|
878
|
+
model_t v(general_t::IONOSPHERIC_SKIP);
|
803
879
|
if(j < j_max){
|
804
|
-
if((models[j] >= 0) && (models[j] <
|
880
|
+
if((models[j] >= 0) && (models[j] < general_t::IONOSPHERIC_SKIP)){
|
805
881
|
v = (model_t)models[j];
|
806
882
|
}
|
807
883
|
++j;
|
808
884
|
}
|
809
|
-
|
885
|
+
general->ionospheric_models[i] = v;
|
810
886
|
}
|
811
887
|
return get_ionospheric_models();
|
812
888
|
}
|
813
889
|
};
|
814
890
|
%}
|
815
891
|
|
892
|
+
%extend GPS_SolverOptions {
|
893
|
+
%ignore base_t;
|
894
|
+
%ignore cast_general;
|
895
|
+
MAKE_VECTOR2ARRAY(int);
|
896
|
+
}
|
897
|
+
%inline %{
|
898
|
+
template <class FloatT>
|
899
|
+
struct GPS_SolverOptions
|
900
|
+
: public GPS_SinglePositioning<FloatT>::options_t,
|
901
|
+
GPS_SolverOptions_Common<FloatT> {
|
902
|
+
typedef typename GPS_SinglePositioning<FloatT>::options_t base_t;
|
903
|
+
void exclude(const int &prn){base_t::exclude_prn.set(prn);}
|
904
|
+
void include(const int &prn){base_t::exclude_prn.reset(prn);}
|
905
|
+
std::vector<int> excluded() const {return base_t::exclude_prn.excluded();}
|
906
|
+
GPS_Solver_GeneralOptions<FloatT> *cast_general(){return this;}
|
907
|
+
const GPS_Solver_GeneralOptions<FloatT> *cast_general() const {return this;}
|
908
|
+
};
|
909
|
+
%}
|
910
|
+
|
911
|
+
%extend SBAS_SolverOptions {
|
912
|
+
%ignore base_t;
|
913
|
+
%ignore cast_general;
|
914
|
+
MAKE_VECTOR2ARRAY(int);
|
915
|
+
}
|
916
|
+
%inline %{
|
917
|
+
template <class FloatT>
|
918
|
+
struct SBAS_SolverOptions
|
919
|
+
: public SBAS_SinglePositioning<FloatT>::options_t,
|
920
|
+
GPS_SolverOptions_Common<FloatT> {
|
921
|
+
typedef typename SBAS_SinglePositioning<FloatT>::options_t base_t;
|
922
|
+
void exclude(const int &prn){base_t::exclude_prn.set(prn);}
|
923
|
+
void include(const int &prn){base_t::exclude_prn.reset(prn);}
|
924
|
+
std::vector<int> excluded() const {return base_t::exclude_prn.excluded();}
|
925
|
+
GPS_Solver_GeneralOptions<FloatT> *cast_general(){return this;}
|
926
|
+
const GPS_Solver_GeneralOptions<FloatT> *cast_general() const {return this;}
|
927
|
+
};
|
928
|
+
%}
|
929
|
+
|
816
930
|
%extend GPS_Solver {
|
817
931
|
%ignore super_t;
|
818
932
|
%ignore base_t;
|
819
933
|
%ignore gps_t;
|
820
934
|
%ignore gps;
|
935
|
+
%ignore sbas_t;
|
936
|
+
%ignore sbas;
|
821
937
|
%ignore select_solver;
|
822
938
|
%ignore relative_property;
|
823
939
|
%ignore satellite_position;
|
@@ -826,18 +942,19 @@ struct GPS_SolverOptions : public GPS_SinglePositioning<FloatT>::options_t {
|
|
826
942
|
%ignore mark;
|
827
943
|
%fragment("hook"{GPS_Solver<FloatT>}, "header",
|
828
944
|
fragment=SWIG_From_frag(int),
|
829
|
-
fragment=SWIG_Traits_frag(FloatT)
|
945
|
+
fragment=SWIG_Traits_frag(FloatT),
|
946
|
+
fragment=SWIG_Traits_frag(GPS_Measurement<FloatT>)){
|
830
947
|
template <>
|
831
|
-
|
948
|
+
GPS_Solver<FloatT>::base_t::relative_property_t
|
832
949
|
GPS_Solver<FloatT>::relative_property(
|
833
|
-
const
|
834
|
-
const
|
835
|
-
const
|
836
|
-
const
|
837
|
-
const
|
838
|
-
const
|
950
|
+
const GPS_Solver<FloatT>::base_t::prn_t &prn,
|
951
|
+
const GPS_Solver<FloatT>::base_t::measurement_t::mapped_type &measurement,
|
952
|
+
const GPS_Solver<FloatT>::base_t::float_t &receiver_error,
|
953
|
+
const GPS_Solver<FloatT>::base_t::gps_time_t &time_arrival,
|
954
|
+
const GPS_Solver<FloatT>::base_t::pos_t &usr_pos,
|
955
|
+
const GPS_Solver<FloatT>::base_t::xyz_t &usr_vel) const {
|
839
956
|
union {
|
840
|
-
|
957
|
+
base_t::relative_property_t prop;
|
841
958
|
FloatT values[7];
|
842
959
|
} res = {
|
843
960
|
select_solver(prn).relative_property(
|
@@ -859,6 +976,7 @@ struct GPS_SolverOptions : public GPS_SinglePositioning<FloatT>::options_t {
|
|
859
976
|
swig::from(res.prop.los_neg[0]),
|
860
977
|
swig::from(res.prop.los_neg[1]),
|
861
978
|
swig::from(res.prop.los_neg[2])),
|
979
|
+
swig::from(measurement), // measurement => Hash
|
862
980
|
swig::from(receiver_error), // receiver_error
|
863
981
|
SWIG_NewPointerObj( // time_arrival
|
864
982
|
new base_t::gps_time_t(time_arrival), $descriptor(GPS_Time<FloatT> *), SWIG_POINTER_OWN),
|
@@ -889,15 +1007,15 @@ struct GPS_SolverOptions : public GPS_SinglePositioning<FloatT>::options_t {
|
|
889
1007
|
}
|
890
1008
|
template <>
|
891
1009
|
bool GPS_Solver<FloatT>::update_position_solution(
|
892
|
-
const
|
893
|
-
|
1010
|
+
const GPS_Solver<FloatT>::base_t::geometric_matrices_t &geomat,
|
1011
|
+
GPS_Solver<FloatT>::base_t::user_pvt_t &res) const {
|
894
1012
|
#ifdef SWIGRUBY
|
895
1013
|
do{
|
896
1014
|
static const VALUE key(ID2SYM(rb_intern("update_position_solution")));
|
897
1015
|
VALUE hook(rb_hash_lookup(hooks, key));
|
898
1016
|
if(NIL_P(hook)){break;}
|
899
|
-
|
900
|
-
%const_cast(geomat,
|
1017
|
+
base_t::geometric_matrices_t &geomat_(
|
1018
|
+
%const_cast(geomat, base_t::geometric_matrices_t &));
|
901
1019
|
VALUE values[] = {
|
902
1020
|
SWIG_NewPointerObj(&geomat_.G,
|
903
1021
|
$descriptor(Matrix<FloatT, Array2D_Dense<FloatT>, MatrixViewBase<> > *), 0),
|
@@ -910,6 +1028,51 @@ struct GPS_SolverOptions : public GPS_SinglePositioning<FloatT>::options_t {
|
|
910
1028
|
#endif
|
911
1029
|
return super_t::update_position_solution(geomat, res);
|
912
1030
|
}
|
1031
|
+
template <>
|
1032
|
+
GPS_Solver<FloatT>::base_t::xyz_t *GPS_Solver<FloatT>::satellite_position(
|
1033
|
+
const GPS_Solver<FloatT>::base_t::prn_t &prn,
|
1034
|
+
const GPS_Solver<FloatT>::base_t::gps_time_t &time,
|
1035
|
+
GPS_Solver<FloatT>::base_t::xyz_t &buf) const {
|
1036
|
+
GPS_Solver<FloatT>::base_t::xyz_t *res(
|
1037
|
+
select_solver(prn).satellite_position(prn, time, buf));
|
1038
|
+
#ifdef SWIGRUBY
|
1039
|
+
do{
|
1040
|
+
static const VALUE key(ID2SYM(rb_intern("satellite_position")));
|
1041
|
+
VALUE hook(rb_hash_lookup(hooks, key));
|
1042
|
+
if(NIL_P(hook)){break;}
|
1043
|
+
VALUE values[] = {
|
1044
|
+
SWIG_From(int)(prn), // prn
|
1045
|
+
SWIG_NewPointerObj( // time
|
1046
|
+
new base_t::gps_time_t(time), $descriptor(GPS_Time<FloatT> *), SWIG_POINTER_OWN),
|
1047
|
+
(res // position (internally calculated)
|
1048
|
+
? SWIG_NewPointerObj(res, $descriptor(System_XYZ<FloatT, WGS84> *), 0)
|
1049
|
+
: Qnil)};
|
1050
|
+
VALUE res_hook(proc_call_throw_if_error(hook, sizeof(values) / sizeof(values[0]), values));
|
1051
|
+
if(NIL_P(res_hook)){ // unknown position
|
1052
|
+
res = NULL;
|
1053
|
+
break;
|
1054
|
+
}else if(RB_TYPE_P(res_hook, T_ARRAY) && (RARRAY_LEN(res_hook) == 3)){
|
1055
|
+
int i(0);
|
1056
|
+
for(; i < 3; ++i){
|
1057
|
+
VALUE v(RARRAY_AREF(res_hook, i));
|
1058
|
+
if(!SWIG_IsOK(swig::asval(v, &buf[i]))){break;}
|
1059
|
+
}
|
1060
|
+
if(i == 3){
|
1061
|
+
res = &buf;
|
1062
|
+
break;
|
1063
|
+
}
|
1064
|
+
}else if(SWIG_IsOK(SWIG_ConvertPtr(
|
1065
|
+
res_hook, (void **)&res, $descriptor(System_XYZ<FloatT, WGS84> *), 0))){
|
1066
|
+
res = &(buf = *res);
|
1067
|
+
break;
|
1068
|
+
}
|
1069
|
+
throw std::runtime_error(
|
1070
|
+
std::string("System_XYZ or [d * 3] is expected (d: " %str(FloatT) "), however ")
|
1071
|
+
.append(inspect_str(res_hook)));
|
1072
|
+
}while(false);
|
1073
|
+
#endif
|
1074
|
+
return res;
|
1075
|
+
}
|
913
1076
|
}
|
914
1077
|
%fragment("hook"{GPS_Solver<FloatT>});
|
915
1078
|
}
|
@@ -927,6 +1090,12 @@ struct GPS_Solver
|
|
927
1090
|
GPS_SinglePositioning<FloatT> solver;
|
928
1091
|
gps_t() : space_node(), options(), solver(space_node) {}
|
929
1092
|
} gps;
|
1093
|
+
struct sbas_t {
|
1094
|
+
SBAS_SpaceNode<FloatT> space_node;
|
1095
|
+
SBAS_SolverOptions<FloatT> options;
|
1096
|
+
SBAS_SinglePositioning<FloatT> solver;
|
1097
|
+
sbas_t() : space_node(), options(), solver(space_node) {}
|
1098
|
+
} sbas;
|
930
1099
|
SWIG_Object hooks;
|
931
1100
|
#ifdef SWIGRUBY
|
932
1101
|
static void mark(void *ptr){
|
@@ -935,17 +1104,27 @@ struct GPS_Solver
|
|
935
1104
|
rb_gc_mark(solver->hooks);
|
936
1105
|
}
|
937
1106
|
#endif
|
938
|
-
GPS_Solver() : super_t(), gps(), hooks() {
|
1107
|
+
GPS_Solver() : super_t(), gps(), sbas(), hooks() {
|
1108
|
+
gps.solver.space_node_sbas = &sbas.space_node;
|
1109
|
+
sbas.solver.space_node_gps = &gps.space_node;
|
939
1110
|
#ifdef SWIGRUBY
|
940
1111
|
hooks = rb_hash_new();
|
941
1112
|
#endif
|
942
1113
|
}
|
943
1114
|
GPS_SpaceNode<FloatT> &gps_space_node() {return gps.space_node;}
|
944
1115
|
GPS_SolverOptions<FloatT> &gps_options() {return gps.options;}
|
1116
|
+
SBAS_SpaceNode<FloatT> &sbas_space_node() {return sbas.space_node;}
|
1117
|
+
SBAS_SolverOptions<FloatT> &sbas_options() {return sbas.options;}
|
945
1118
|
const base_t &select_solver(
|
946
1119
|
const typename base_t::prn_t &prn) const {
|
947
1120
|
if(prn > 0 && prn <= 32){return gps.solver;}
|
948
|
-
return
|
1121
|
+
if(prn >= 120 && prn <= 158){return sbas.solver;}
|
1122
|
+
if(prn > 192 && prn <= 202){return gps.solver;}
|
1123
|
+
// call order: base_t::solve => this returned by select()
|
1124
|
+
// => relative_property() => select_solver()
|
1125
|
+
// For not supported satellite, call loop prevention is required.
|
1126
|
+
static const base_t dummy;
|
1127
|
+
return dummy;
|
949
1128
|
}
|
950
1129
|
virtual typename base_t::relative_property_t relative_property(
|
951
1130
|
const typename base_t::prn_t &prn,
|
@@ -957,9 +1136,7 @@ struct GPS_Solver
|
|
957
1136
|
virtual typename base_t::xyz_t *satellite_position(
|
958
1137
|
const typename base_t::prn_t &prn,
|
959
1138
|
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
|
-
}
|
1139
|
+
typename base_t::xyz_t &res) const;
|
963
1140
|
virtual bool update_position_solution(
|
964
1141
|
const typename base_t::geometric_matrices_t &geomat,
|
965
1142
|
typename base_t::user_pvt_t &res) const;
|
@@ -968,6 +1145,8 @@ struct GPS_Solver
|
|
968
1145
|
const GPS_Time<FloatT> &receiver_time) const {
|
969
1146
|
const_cast<gps_t &>(gps).space_node.update_all_ephemeris(receiver_time);
|
970
1147
|
const_cast<gps_t &>(gps).solver.update_options(gps.options);
|
1148
|
+
const_cast<sbas_t &>(sbas).space_node.update_all_ephemeris(receiver_time);
|
1149
|
+
const_cast<sbas_t &>(sbas).solver.update_options(sbas.options);
|
971
1150
|
return super_t::solve().user_pvt(measurement.items, receiver_time);
|
972
1151
|
}
|
973
1152
|
};
|
@@ -1091,6 +1270,7 @@ struct RINEX_Observation {};
|
|
1091
1270
|
|
1092
1271
|
#undef MAKE_ACCESSOR
|
1093
1272
|
#undef MAKE_VECTOR2ARRAY
|
1273
|
+
#undef MAKE_ARRAY_INPUT
|
1094
1274
|
|
1095
1275
|
%define CONCRETIZE(type)
|
1096
1276
|
%template(Time) GPS_Time<type>;
|
@@ -1099,12 +1279,17 @@ struct RINEX_Observation {};
|
|
1099
1279
|
%template(Ephemeris) GPS_Ephemeris<type>;
|
1100
1280
|
%template(PVT) GPS_User_PVT<type>;
|
1101
1281
|
%template(Measurement) GPS_Measurement<type>;
|
1282
|
+
%template(SolverOptionsCommon) GPS_SolverOptions_Common<type>;
|
1102
1283
|
%template(SolverOptions) GPS_SolverOptions<type>;
|
1103
1284
|
#if defined(SWIGRUBY)
|
1104
1285
|
%markfunc GPS_Solver<type> "GPS_Solver<type>::mark";
|
1105
1286
|
#endif
|
1106
1287
|
%template(Solver) GPS_Solver<type>;
|
1107
1288
|
|
1289
|
+
%template(Ephemeris_SBAS) SBAS_Ephemeris<type>;
|
1290
|
+
%template(SpaceNode_SBAS) SBAS_SpaceNode<type>;
|
1291
|
+
%template(SolverOptions_SBAS) SBAS_SolverOptions<type>;
|
1292
|
+
|
1108
1293
|
%template(RINEX_Observation) RINEX_Observation<type>;
|
1109
1294
|
%enddef
|
1110
1295
|
|
@@ -339,8 +339,9 @@ __RINEX_OBS_TEXT__
|
|
339
339
|
sn.read(input[:rinex_nav])
|
340
340
|
t_meas = GPS::Time::new(1849, 172413)
|
341
341
|
sn.update_all_ephemeris(t_meas)
|
342
|
-
solver.hooks[:relative_property] = proc{|prn, rel_prop, rcv_e, t_arv, usr_pos, usr_vel|
|
342
|
+
solver.hooks[:relative_property] = proc{|prn, rel_prop, meas, rcv_e, t_arv, usr_pos, usr_vel|
|
343
343
|
expect(input[:measurement]).to include(prn)
|
344
|
+
expect(meas).to be_a_kind_of(Hash)
|
344
345
|
expect(t_arv).to be_a_kind_of(GPS::Time)
|
345
346
|
expect(usr_pos).to be_a_kind_of(Coordinate::XYZ)
|
346
347
|
expect(usr_vel).to be_a_kind_of(Coordinate::XYZ)
|
@@ -354,6 +355,22 @@ __RINEX_OBS_TEXT__
|
|
354
355
|
}
|
355
356
|
mat_G, mat_W, mat_delta_r = mats
|
356
357
|
}
|
358
|
+
solver.hooks[:satellite_position] = proc{
|
359
|
+
i = 0
|
360
|
+
proc{|prn, time, pos|
|
361
|
+
expect(input[:measurement]).to include(prn)
|
362
|
+
expect(pos).to be_a_kind_of(Coordinate::XYZ).or eq(nil)
|
363
|
+
# System_XYZ or [x,y,z] or nil(= unknown position) are acceptable
|
364
|
+
case (i += 1) % 5
|
365
|
+
when 0
|
366
|
+
nil
|
367
|
+
when 1
|
368
|
+
pos.to_a
|
369
|
+
else
|
370
|
+
pos
|
371
|
+
end
|
372
|
+
}
|
373
|
+
}.call
|
357
374
|
pvt = solver.solve(
|
358
375
|
input[:measurement].collect{|prn, items|
|
359
376
|
items.collect{|k, v| [prn, k, v]}
|