gps_pvt 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- %typemap(in) const FloatT values[4] (FloatT temp[4]) {
199
- #ifdef SWIGRUBY
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 *buf){
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
- %typemap(in) const unsigned int *buf (unsigned int temp[10]) {
325
- #ifdef SWIGRUBY
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 *buf, int *subframe_no, int *iodc_or_iode){
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,84 @@ 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
- return RINEX_NAV_Reader<FloatT>::read_all(fin, *self);
420
+ typename RINEX_NAV_Reader<FloatT>::space_node_list_t space_nodes = {
421
+ self, // GPS
422
+ NULL, // SBAS
423
+ self, // QZSS
424
+ };
425
+ return RINEX_NAV_Reader<FloatT>::read_all(fin, space_nodes);
436
426
  }
437
427
  }
438
428
 
439
429
  %include navigation/GPS.h
430
+ %include navigation/QZSS.h
431
+
432
+ %inline %{
433
+ template <class FloatT>
434
+ struct SBAS_Ephemeris : public SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris {
435
+ SBAS_Ephemeris() : SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris() {}
436
+ SBAS_Ephemeris(const typename SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris &eph)
437
+ : SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris(eph) {}
438
+ };
439
+ %}
440
+ %extend SBAS_Ephemeris {
441
+ MAKE_ACCESSOR(svid, unsigned int);
442
+
443
+ MAKE_ACCESSOR(WN, unsigned int);
444
+ MAKE_ACCESSOR(t_0, FloatT);
445
+ MAKE_ACCESSOR(URA, int);
446
+ MAKE_ACCESSOR( x, FloatT); MAKE_ACCESSOR( y, FloatT); MAKE_ACCESSOR( z, FloatT);
447
+ MAKE_ACCESSOR( dx, FloatT); MAKE_ACCESSOR( dy, FloatT); MAKE_ACCESSOR( dz, FloatT);
448
+ MAKE_ACCESSOR(ddx, FloatT); MAKE_ACCESSOR(ddy, FloatT); MAKE_ACCESSOR(ddz, FloatT);
449
+ MAKE_ACCESSOR(a_Gf0, FloatT);
450
+ MAKE_ACCESSOR(a_Gf1, FloatT);
451
+ %apply GPS_Ephemeris::System_XYZ<FloatT, WGS84> & { System_XYZ<FloatT, WGS84> & }; // TODO ineffective?
452
+ void constellation(
453
+ System_XYZ<FloatT, WGS84> &position, System_XYZ<FloatT, WGS84> &velocity,
454
+ const GPS_Time<FloatT> &t, const FloatT &pseudo_range = 0,
455
+ const bool &with_velocity = true) const {
456
+ typename SBAS_SpaceNode<FloatT>::SatelliteProperties::constellation_t res(
457
+ self->constellation(t, pseudo_range, with_velocity));
458
+ position = res.position;
459
+ velocity = res.velocity;
460
+ }
461
+ }
462
+
463
+ %extend SBAS_SpaceNode {
464
+ %fragment(SWIG_Traits_frag(FloatT));
465
+ %ignore satellites() const;
466
+ %ignore satellite(const int &);
467
+ %ignore available_satellites(const FloatT &lng_deg) const;
468
+ void register_ephemeris(
469
+ const int &prn, const SBAS_Ephemeris<FloatT> &eph,
470
+ const int &priority_delta = 1){
471
+ self->satellite(prn).register_ephemeris(eph, priority_delta);
472
+ }
473
+ SBAS_Ephemeris<FloatT> ephemeris(const int &prn) const {
474
+ return SBAS_Ephemeris<FloatT>(
475
+ %const_cast(self, SBAS_SpaceNode<FloatT> *)->satellite(prn).ephemeris());
476
+ }
477
+ int read(const char *fname) {
478
+ std::fstream fin(fname, std::ios::in | std::ios::binary);
479
+ RINEX_NAV_Reader<FloatT>::space_node_list_t space_nodes = {NULL, self};
480
+ return RINEX_NAV_Reader<FloatT>::read_all(fin, space_nodes);
481
+ }
482
+ MAKE_ARRAY_INPUT(const unsigned int, buf, SWIG_AsVal(unsigned int));
483
+ int decode_message(const unsigned int buf[8],
484
+ const int &prn, const GPS_Time<FloatT> &t_reception,
485
+ const bool &LNAV_VNAV_LP_LPV_approach = false){
486
+ return static_cast<int>(
487
+ self->decode_message(buf, prn, t_reception, LNAV_VNAV_LP_LPV_approach));
488
+ }
489
+ std::string ionospheric_grid_points(const int &prn) const {
490
+ std::ostringstream ss;
491
+ ss << %const_cast(self, SBAS_SpaceNode<FloatT> *)->satellite(prn)
492
+ .ionospheric_grid_points();
493
+ return ss.str();
494
+ }
495
+ }
496
+
497
+ %include navigation/SBAS.h
440
498
 
441
499
  %extend GPS_User_PVT {
442
500
  %ignore solver_t;
@@ -746,12 +804,23 @@ struct GPS_Measurement {
746
804
  };
747
805
  }
748
806
 
749
- %extend GPS_SolverOptions {
750
- %ignore base_t;
751
- MAKE_ACCESSOR(elevation_mask, FloatT);
752
- MAKE_ACCESSOR(residual_mask, FloatT);
753
- MAKE_ACCESSOR(f_10_7, FloatT);
807
+ %extend GPS_SolverOptions_Common {
808
+ %define MAKE_ACCESSOR2(name, type)
809
+ %rename(%str(name ## =)) set_ ## name;
810
+ type set_ ## name (const type &v) {
811
+ return self->cast_general()->name = v;
812
+ }
813
+ %rename(%str(name)) get_ ## name;
814
+ const type &get_ ## name () const {
815
+ return self->cast_general()->name;
816
+ }
817
+ %enddef
818
+ MAKE_ACCESSOR2(elevation_mask, FloatT);
819
+ MAKE_ACCESSOR2(residual_mask, FloatT);
820
+ MAKE_ACCESSOR2(f_10_7, FloatT);
821
+ #undef MAKE_ACCESSOR2
754
822
  MAKE_VECTOR2ARRAY(int);
823
+ %ignore cast_base;
755
824
  #ifdef SWIGRUBY
756
825
  %rename("ionospheric_models=") set_ionospheric_models;
757
826
  %rename("ionospheric_models") get_ionospheric_models;
@@ -775,49 +844,92 @@ struct GPS_Measurement {
775
844
  }
776
845
  %inline %{
777
846
  template <class FloatT>
778
- struct GPS_SolverOptions : public GPS_SinglePositioning<FloatT>::options_t {
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();}
847
+ struct GPS_SolverOptions_Common {
783
848
  enum {
784
849
  IONOSPHERIC_KLOBUCHAR,
850
+ IONOSPHERIC_SBAS,
785
851
  IONOSPHERIC_NTCM_GL,
786
852
  IONOSPHERIC_NONE, // which allows no correction
787
853
  IONOSPHERIC_MODELS,
788
854
  IONOSPHERIC_SKIP = IONOSPHERIC_MODELS, // which means delegating the next slot
789
855
  };
856
+ virtual GPS_Solver_GeneralOptions<FloatT> *cast_general() = 0;
857
+ virtual const GPS_Solver_GeneralOptions<FloatT> *cast_general() const = 0;
790
858
  std::vector<int> get_ionospheric_models() const {
859
+ typedef GPS_Solver_GeneralOptions<FloatT> general_t;
860
+ const general_t *general(this->cast_general());
791
861
  std::vector<int> res;
792
- for(int i(0); i < base_t::IONOSPHERIC_MODELS; ++i){
793
- int v((int)(base_t::ionospheric_models[i]));
794
- if(v == base_t::IONOSPHERIC_SKIP){break;}
862
+ for(int i(0); i < general_t::IONOSPHERIC_MODELS; ++i){
863
+ int v((int)(general->ionospheric_models[i]));
864
+ if(v == general_t::IONOSPHERIC_SKIP){break;}
795
865
  res.push_back(v);
796
866
  }
797
867
  return res;
798
868
  }
799
869
  std::vector<int> set_ionospheric_models(const std::vector<int> &models){
800
- typedef typename base_t::ionospheric_model_t model_t;
801
- for(int i(0), j(0), j_max(models.size()); i < base_t::IONOSPHERIC_MODELS; ++i){
802
- model_t v(base_t::IONOSPHERIC_SKIP);
870
+ typedef GPS_Solver_GeneralOptions<FloatT> general_t;
871
+ general_t *general(this->cast_general());
872
+ typedef typename general_t::ionospheric_model_t model_t;
873
+ for(int i(0), j(0), j_max(models.size()); i < general_t::IONOSPHERIC_MODELS; ++i){
874
+ model_t v(general_t::IONOSPHERIC_SKIP);
803
875
  if(j < j_max){
804
- if((models[j] >= 0) && (models[j] < base_t::IONOSPHERIC_SKIP)){
876
+ if((models[j] >= 0) && (models[j] < general_t::IONOSPHERIC_SKIP)){
805
877
  v = (model_t)models[j];
806
878
  }
807
879
  ++j;
808
880
  }
809
- base_t::ionospheric_models[i] = v;
881
+ general->ionospheric_models[i] = v;
810
882
  }
811
883
  return get_ionospheric_models();
812
884
  }
813
885
  };
814
886
  %}
815
887
 
888
+ %extend GPS_SolverOptions {
889
+ %ignore base_t;
890
+ %ignore cast_general;
891
+ MAKE_VECTOR2ARRAY(int);
892
+ }
893
+ %inline %{
894
+ template <class FloatT>
895
+ struct GPS_SolverOptions
896
+ : public GPS_SinglePositioning<FloatT>::options_t,
897
+ GPS_SolverOptions_Common<FloatT> {
898
+ typedef typename GPS_SinglePositioning<FloatT>::options_t base_t;
899
+ void exclude(const int &prn){base_t::exclude_prn.set(prn);}
900
+ void include(const int &prn){base_t::exclude_prn.reset(prn);}
901
+ std::vector<int> excluded() const {return base_t::exclude_prn.excluded();}
902
+ GPS_Solver_GeneralOptions<FloatT> *cast_general(){return this;}
903
+ const GPS_Solver_GeneralOptions<FloatT> *cast_general() const {return this;}
904
+ };
905
+ %}
906
+
907
+ %extend SBAS_SolverOptions {
908
+ %ignore base_t;
909
+ %ignore cast_general;
910
+ MAKE_VECTOR2ARRAY(int);
911
+ }
912
+ %inline %{
913
+ template <class FloatT>
914
+ struct SBAS_SolverOptions
915
+ : public SBAS_SinglePositioning<FloatT>::options_t,
916
+ GPS_SolverOptions_Common<FloatT> {
917
+ typedef typename SBAS_SinglePositioning<FloatT>::options_t base_t;
918
+ void exclude(const int &prn){base_t::exclude_prn.set(prn);}
919
+ void include(const int &prn){base_t::exclude_prn.reset(prn);}
920
+ std::vector<int> excluded() const {return base_t::exclude_prn.excluded();}
921
+ GPS_Solver_GeneralOptions<FloatT> *cast_general(){return this;}
922
+ const GPS_Solver_GeneralOptions<FloatT> *cast_general() const {return this;}
923
+ };
924
+ %}
925
+
816
926
  %extend GPS_Solver {
817
927
  %ignore super_t;
818
928
  %ignore base_t;
819
929
  %ignore gps_t;
820
930
  %ignore gps;
931
+ %ignore sbas_t;
932
+ %ignore sbas;
821
933
  %ignore select_solver;
822
934
  %ignore relative_property;
823
935
  %ignore satellite_position;
@@ -927,6 +1039,12 @@ struct GPS_Solver
927
1039
  GPS_SinglePositioning<FloatT> solver;
928
1040
  gps_t() : space_node(), options(), solver(space_node) {}
929
1041
  } gps;
1042
+ struct sbas_t {
1043
+ SBAS_SpaceNode<FloatT> space_node;
1044
+ SBAS_SolverOptions<FloatT> options;
1045
+ SBAS_SinglePositioning<FloatT> solver;
1046
+ sbas_t() : space_node(), options(), solver(space_node) {}
1047
+ } sbas;
930
1048
  SWIG_Object hooks;
931
1049
  #ifdef SWIGRUBY
932
1050
  static void mark(void *ptr){
@@ -935,16 +1053,22 @@ struct GPS_Solver
935
1053
  rb_gc_mark(solver->hooks);
936
1054
  }
937
1055
  #endif
938
- GPS_Solver() : super_t(), gps(), hooks() {
1056
+ GPS_Solver() : super_t(), gps(), sbas(), hooks() {
1057
+ gps.solver.space_node_sbas = &sbas.space_node;
1058
+ sbas.solver.space_node_gps = &gps.space_node;
939
1059
  #ifdef SWIGRUBY
940
1060
  hooks = rb_hash_new();
941
1061
  #endif
942
1062
  }
943
1063
  GPS_SpaceNode<FloatT> &gps_space_node() {return gps.space_node;}
944
1064
  GPS_SolverOptions<FloatT> &gps_options() {return gps.options;}
1065
+ SBAS_SpaceNode<FloatT> &sbas_space_node() {return sbas.space_node;}
1066
+ SBAS_SolverOptions<FloatT> &sbas_options() {return sbas.options;}
945
1067
  const base_t &select_solver(
946
1068
  const typename base_t::prn_t &prn) const {
947
1069
  if(prn > 0 && prn <= 32){return gps.solver;}
1070
+ if(prn >= 120 && prn <= 158){return sbas.solver;}
1071
+ if(prn > 192 && prn <= 202){return gps.solver;}
948
1072
  return *this;
949
1073
  }
950
1074
  virtual typename base_t::relative_property_t relative_property(
@@ -968,6 +1092,8 @@ struct GPS_Solver
968
1092
  const GPS_Time<FloatT> &receiver_time) const {
969
1093
  const_cast<gps_t &>(gps).space_node.update_all_ephemeris(receiver_time);
970
1094
  const_cast<gps_t &>(gps).solver.update_options(gps.options);
1095
+ const_cast<sbas_t &>(sbas).space_node.update_all_ephemeris(receiver_time);
1096
+ const_cast<sbas_t &>(sbas).solver.update_options(sbas.options);
971
1097
  return super_t::solve().user_pvt(measurement.items, receiver_time);
972
1098
  }
973
1099
  };
@@ -1091,6 +1217,7 @@ struct RINEX_Observation {};
1091
1217
 
1092
1218
  #undef MAKE_ACCESSOR
1093
1219
  #undef MAKE_VECTOR2ARRAY
1220
+ #undef MAKE_ARRAY_INPUT
1094
1221
 
1095
1222
  %define CONCRETIZE(type)
1096
1223
  %template(Time) GPS_Time<type>;
@@ -1099,12 +1226,17 @@ struct RINEX_Observation {};
1099
1226
  %template(Ephemeris) GPS_Ephemeris<type>;
1100
1227
  %template(PVT) GPS_User_PVT<type>;
1101
1228
  %template(Measurement) GPS_Measurement<type>;
1229
+ %template(SolverOptionsCommon) GPS_SolverOptions_Common<type>;
1102
1230
  %template(SolverOptions) GPS_SolverOptions<type>;
1103
1231
  #if defined(SWIGRUBY)
1104
1232
  %markfunc GPS_Solver<type> "GPS_Solver<type>::mark";
1105
1233
  #endif
1106
1234
  %template(Solver) GPS_Solver<type>;
1107
1235
 
1236
+ %template(Ephemeris_SBAS) SBAS_Ephemeris<type>;
1237
+ %template(SpaceNode_SBAS) SBAS_SpaceNode<type>;
1238
+ %template(SolverOptions_SBAS) SBAS_SolverOptions<type>;
1239
+
1108
1240
  %template(RINEX_Observation) RINEX_Observation<type>;
1109
1241
  %enddef
1110
1242