gps_pvt 0.1.5 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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]}
|