gps_pvt 0.8.1 → 0.8.3

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.
@@ -57,13 +57,15 @@ struct GLONASS_SinglePositioning_Options : public GPS_Solver_GeneralOptions<Floa
57
57
 
58
58
  template <class FloatT, class SolverBaseT = GPS_Solver_Base<FloatT> >
59
59
  class GLONASS_SinglePositioning : public SolverBaseT {
60
- private:
61
- GLONASS_SinglePositioning<FloatT> &operator=(const GLONASS_SinglePositioning<FloatT> &);
62
60
  public:
63
- typedef GLONASS_SinglePositioning<FloatT> self_t;
61
+ typedef GLONASS_SinglePositioning<FloatT, SolverBaseT> self_t;
64
62
  typedef SolverBaseT base_t;
65
63
  typedef SolverBaseT super_t;
64
+ private:
65
+ self_t &operator=(const self_t &);
66
+ GLONASS_SinglePositioning(const self_t &);
66
67
 
68
+ public:
67
69
  #if defined(__GNUC__) && (__GNUC__ < 5)
68
70
  #define inheritate_type(x) typedef typename base_t::x x;
69
71
  #else
@@ -77,12 +77,14 @@ struct GPS_SinglePositioning_Options : public GPS_Solver_GeneralOptions<FloatT>
77
77
 
78
78
  template <class FloatT, class SolverBaseT = GPS_Solver_Base<FloatT> >
79
79
  class GPS_SinglePositioning : public SolverBaseT {
80
- private:
81
- GPS_SinglePositioning<FloatT> &operator=(const GPS_SinglePositioning<FloatT> &);
82
80
  public:
83
- typedef GPS_SinglePositioning<FloatT> self_t;
81
+ typedef GPS_SinglePositioning<FloatT, SolverBaseT> self_t;
84
82
  typedef SolverBaseT base_t;
83
+ private:
84
+ self_t &operator=(const self_t &);
85
+ GPS_SinglePositioning(const self_t &);
85
86
 
87
+ public:
86
88
  #if defined(__GNUC__) && (__GNUC__ < 5)
87
89
  #define inheritate_type(x) typedef typename base_t::x x;
88
90
  #else
@@ -52,6 +52,7 @@ class GPS_Solver_MultiFrequency : public BaseSolver {
52
52
  typedef BaseSolver super_t;
53
53
  private:
54
54
  self_t &operator=(const self_t &);
55
+ GPS_Solver_MultiFrequency(const self_t &);
55
56
  public:
56
57
  #if defined(__GNUC__) && (__GNUC__ < 5)
57
58
  #define inheritate_type(x) typedef typename super_t::x x;
@@ -56,12 +56,14 @@ struct SBAS_SinglePositioning_Options : public GPS_Solver_GeneralOptions<FloatT>
56
56
 
57
57
  template <class FloatT, class SolverBaseT = GPS_Solver_Base<FloatT> >
58
58
  class SBAS_SinglePositioning : public SolverBaseT {
59
- private:
60
- SBAS_SinglePositioning<FloatT> &operator=(const SBAS_SinglePositioning<FloatT> &);
61
59
  public:
62
- typedef SBAS_SinglePositioning<FloatT> self_t;
60
+ typedef SBAS_SinglePositioning<FloatT, SolverBaseT> self_t;
63
61
  typedef SolverBaseT base_t;
62
+ private:
63
+ self_t &operator=(const self_t &);
64
+ SBAS_SinglePositioning(const self_t &);
64
65
 
66
+ public:
65
67
  #if defined(__GNUC__) && (__GNUC__ < 5)
66
68
  #define inheritate_type(x) typedef typename base_t::x x;
67
69
  #else
@@ -29,6 +29,7 @@
29
29
  #include "navigation/GPS_Solver_Base.h"
30
30
  #include "navigation/GPS_Solver.h"
31
31
  #include "navigation/GPS_Solver_RAIM.h"
32
+ #include "navigation/GPS_Solver_MultiFrequency.h"
32
33
  #include "navigation/SBAS_Solver.h"
33
34
  #include "navigation/GLONASS_Solver.h"
34
35
 
@@ -157,6 +158,16 @@ static std::string inspect_str(const VALUE &v){
157
158
  %typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) const std::tm & {
158
159
  $1 = (TYPE($input) == T_ARRAY) ? 1 : 0;
159
160
  }
161
+ %typemap(varout,fragment="SWIG_Traits_frag(FloatT)") leap_second_event_t [] {
162
+ $result = rb_ary_new2(sizeof($1) / sizeof($1[0]));
163
+ for(std::size_t i(0); i < sizeof($1) / sizeof($1[0]); ++i){
164
+ rb_ary_push($result,
165
+ rb_ary_new3(3,
166
+ SWIG_From(int)($1[i].corrected.week),
167
+ swig::from($1[i].corrected.seconds),
168
+ SWIG_From(int)($1[i].leap_seconds)));
169
+ }
170
+ }
160
171
  #endif
161
172
  %ignore canonicalize();
162
173
  %ignore GPS_Time(const int &_week, const float_t &_seconds);
@@ -1119,6 +1130,16 @@ struct GPS_Measurement {
1119
1130
  L1_SIGNAL_STRENGTH_dBHz,
1120
1131
  L1_LOCK_SEC,
1121
1132
  L1_FREQUENCY,
1133
+ #define make_entry(key) L2CM_ ## key, L2CL_ ## key
1134
+ #define make_entry2(key) make_entry(key), make_entry(key ## _SIGMA)
1135
+ make_entry2(PSEUDORANGE),
1136
+ make_entry2(CARRIER_PHASE),
1137
+ make_entry2(DOPPLER),
1138
+ make_entry2(RANGE_RATE),
1139
+ make_entry(SIGNAL_STRENGTH_dBHz),
1140
+ make_entry(LOCK_SEC),
1141
+ #undef make_entry2
1142
+ #undef make_entry
1122
1143
  ITEMS_PREDEFINED,
1123
1144
  };
1124
1145
  void add(const int &prn, const int &key, const FloatT &value){
@@ -1142,7 +1163,7 @@ const type &get_ ## name () const {
1142
1163
  MAKE_ACCESSOR2(residual_mask, FloatT);
1143
1164
  #undef MAKE_ACCESSOR2
1144
1165
  MAKE_VECTOR2ARRAY(int);
1145
- %ignore cast_base;
1166
+ %ignore cast_general;
1146
1167
  }
1147
1168
  %inline %{
1148
1169
  template <class FloatT>
@@ -1156,17 +1177,23 @@ struct GPS_SolverOptions_Common {
1156
1177
  %extend GPS_SolverOptions {
1157
1178
  %ignore base_t;
1158
1179
  %ignore cast_general;
1180
+ #ifdef SWIGRUBY
1181
+ %rename("exclude_L2C?") get_exclude_L2C;
1182
+ %rename("exclude_L2C=") set_exclude_L2C;
1183
+ #endif
1159
1184
  MAKE_VECTOR2ARRAY(int);
1160
1185
  }
1161
1186
  %inline %{
1162
1187
  template <class FloatT>
1163
1188
  struct GPS_SolverOptions
1164
- : public GPS_SinglePositioning<FloatT>::options_t,
1189
+ : public GPS_Solver_MultiFrequency<GPS_SinglePositioning<FloatT> >::options_t,
1165
1190
  GPS_SolverOptions_Common<FloatT> {
1166
- typedef typename GPS_SinglePositioning<FloatT>::options_t base_t;
1191
+ typedef typename GPS_Solver_MultiFrequency<GPS_SinglePositioning<FloatT> >::options_t base_t;
1167
1192
  void exclude(const int &prn){base_t::exclude_prn.set(prn);}
1168
1193
  void include(const int &prn){base_t::exclude_prn.reset(prn);}
1169
1194
  std::vector<int> excluded() const {return base_t::exclude_prn.excluded();}
1195
+ bool get_exclude_L2C() {return base_t::exclude_L2C;}
1196
+ bool set_exclude_L2C(const bool &b) {return base_t::exclude_L2C = b;}
1170
1197
  GPS_Solver_GeneralOptions<FloatT> *cast_general(){return this;}
1171
1198
  const GPS_Solver_GeneralOptions<FloatT> *cast_general() const {return this;}
1172
1199
  };
@@ -1236,7 +1263,8 @@ template <class BaseT, class HookT>
1236
1263
  struct HookableSolver : public BaseT {
1237
1264
  typedef BaseT base_t;
1238
1265
  HookT *hook;
1239
- HookableSolver(const BaseT &base) : BaseT(base), hook(NULL) {}
1266
+ template <class ArgT>
1267
+ HookableSolver(const ArgT &);
1240
1268
  virtual typename base_t::relative_property_t relative_property(
1241
1269
  const typename base_t::prn_t &prn,
1242
1270
  const typename base_t::measurement_t::mapped_type &measurement,
@@ -1289,6 +1317,20 @@ struct HookableSolver : public BaseT {
1289
1317
  fragment=SWIG_From_frag(int),
1290
1318
  fragment=SWIG_Traits_frag(FloatT),
1291
1319
  fragment=SWIG_Traits_frag(GPS_Measurement<FloatT>)){
1320
+ template <> template <>
1321
+ HookableSolver<
1322
+ GPS_Solver_MultiFrequency<GPS_SinglePositioning<FloatT> >,
1323
+ GPS_Solver<FloatT> >
1324
+ ::HookableSolver<GPS_SpaceNode<FloatT> >(const GPS_SpaceNode<FloatT> &sn)
1325
+ : GPS_Solver_MultiFrequency<GPS_SinglePositioning<FloatT> >(sn), hook(NULL) {}
1326
+ template <> template <>
1327
+ HookableSolver<SBAS_SinglePositioning<FloatT>, GPS_Solver<FloatT> >
1328
+ ::HookableSolver<SBAS_SpaceNode<FloatT> >(const SBAS_SpaceNode<FloatT> &sn)
1329
+ : SBAS_SinglePositioning<FloatT>(sn), hook(NULL) {}
1330
+ template <> template <>
1331
+ HookableSolver<GLONASS_SinglePositioning<FloatT>, GPS_Solver<FloatT> >
1332
+ ::HookableSolver<GLONASS_SpaceNode<FloatT> >(const GLONASS_SpaceNode<FloatT> &sn)
1333
+ : GLONASS_SinglePositioning<FloatT>(sn), hook(NULL) {}
1292
1334
  template <>
1293
1335
  GPS_Solver<FloatT>::base_t::relative_property_t
1294
1336
  GPS_Solver<FloatT>::relative_property(
@@ -1581,7 +1623,9 @@ struct GPS_Solver
1581
1623
  struct gps_t {
1582
1624
  GPS_SpaceNode<FloatT> space_node;
1583
1625
  GPS_SolverOptions<FloatT> options;
1584
- HookableSolver<GPS_SinglePositioning<FloatT>, GPS_Solver<FloatT> > solver;
1626
+ HookableSolver<
1627
+ GPS_Solver_MultiFrequency<GPS_SinglePositioning<FloatT> >,
1628
+ GPS_Solver<FloatT> > solver;
1585
1629
  struct ephemeris_proxy_t {
1586
1630
  struct item_t {
1587
1631
  const void *impl;
@@ -1603,19 +1647,21 @@ struct GPS_Solver
1603
1647
  solver.satellites.impl_select = forward;
1604
1648
  }
1605
1649
  } ephemeris_proxy;
1606
- gps_t() : space_node(), options(), solver(GPS_SinglePositioning<FloatT>(space_node)), ephemeris_proxy(solver) {}
1650
+ gps_t() : space_node(), options(), solver(space_node), ephemeris_proxy(solver) {
1651
+ options.exclude_L2C = true;
1652
+ }
1607
1653
  } gps;
1608
1654
  struct sbas_t {
1609
1655
  SBAS_SpaceNode<FloatT> space_node;
1610
1656
  SBAS_SolverOptions<FloatT> options;
1611
1657
  HookableSolver<SBAS_SinglePositioning<FloatT>, GPS_Solver<FloatT> > solver;
1612
- sbas_t() : space_node(), options(), solver(SBAS_SinglePositioning<FloatT>(space_node)) {}
1658
+ sbas_t() : space_node(), options(), solver(space_node) {}
1613
1659
  } sbas;
1614
1660
  struct glonass_t {
1615
1661
  GLONASS_SpaceNode<FloatT> space_node;
1616
1662
  GLONASS_SolverOptions<FloatT> options;
1617
1663
  HookableSolver<GLONASS_SinglePositioning<FloatT>, GPS_Solver<FloatT> > solver;
1618
- glonass_t() : space_node(), options(), solver(GLONASS_SinglePositioning<FloatT>(space_node)) {}
1664
+ glonass_t() : space_node(), options(), solver(space_node) {}
1619
1665
  } glonass;
1620
1666
  SWIG_Object hooks;
1621
1667
  typedef std::vector<GPS_RangeCorrector<FloatT> > user_correctors_t;
@@ -759,6 +759,10 @@ __RINEX_CLK_TEXT__
759
759
  puts "Measurement time: #{t_meas.to_a} (a.k.a #{"%d/%d/%d %02d:%02d:%02d UTC"%[*t_meas.c_tm]})"
760
760
  expect(t_meas.c_tm).to eq([2015, 6, 15, 23, 53, 33])
761
761
  expect(GPS::Time::new(0, t_meas.serialize)).to eq(t_meas)
762
+ expect(t_meas.leap_seconds).to eq(sn.iono_utc.delta_t_LS)
763
+ expect(GPS::Time::leap_second_events.select{|wn, sec, leap|
764
+ t_meas >= GPS::Time::new(wn, sec)
765
+ }[0][2]).to eq(sn.iono_utc.delta_t_LS)
762
766
 
763
767
  sn.update_all_ephemeris(t_meas)
764
768
 
@@ -924,6 +928,9 @@ __RINEX_CLK_TEXT__
924
928
  }}.not_to raise_error
925
929
  expect(solver.correction[:gps_ionospheric]).to include(:no_correction)
926
930
  expect(solver.correction[:options][:f_10_7]).to eq(10)
931
+ expect(solver.gps_options.exclude_L2C?).to eq(true) #default
932
+ solver.gps_options.exclude_L2C = false
933
+ expect(solver.gps_options.exclude_L2C?).to eq(false)
927
934
  sn.read(input[:rinex_nav])
928
935
  t_meas = GPS::Time::new(1849, 172413)
929
936
  sn.update_all_ephemeris(t_meas)
@@ -29,15 +29,24 @@ class Receiver
29
29
  return (eph.valid?(t) ? eph : nil)
30
30
  end
31
31
 
32
- def attach_online_ephemeris(uri_template = nil)
33
- if (!uri_template) || (uri_template =~ /^\s*$/) then
34
- uri_template = "ftp://gssc.esa.int/gnss/data/daily/%Y/brdc/BRDC00IGS_R_%Y%j0000_01D_MN.rnx.gz"
35
- end
32
+ def attach_online_ephemeris(uri_template = [nil])
33
+ uri_template = uri_template.collect{|v|
34
+ if (!v) || (v =~ /^\s*$/) then
35
+ "ftp://gssc.esa.int/gnss/data/daily/%Y/brdc/BRDC00IGS_R_%Y%j0000_01D_MN.rnx.gz"
36
+ else
37
+ v
38
+ end
39
+ }.uniq
36
40
  loader = proc{|t_meas|
37
41
  utc = Time::utc(*t_meas.c_tm)
38
- uri = URI::parse(utc.strftime(uri_template))
39
- self.parse_rinex_nav(uri)
40
- uri
42
+ uri_template.each{|v|
43
+ uri = URI::parse(utc.strftime(v))
44
+ begin
45
+ self.parse_rinex_nav(uri)
46
+ rescue Net::FTPError, Net::HTTPExceptions => e
47
+ $stderr.puts "Skip to read due to %s (%s)"%[e.inspect.gsub(/[\r\n]/, ' '), uri]
48
+ end
49
+ }
41
50
  }
42
51
  run_orig = self.method(:run)
43
52
  eph_list = {}
@@ -290,6 +290,11 @@ class Receiver
290
290
  when :fault_exclusion
291
291
  @solver.options = {:skip_exclusion => !(output_options[:FDE] = v.to_b)}
292
292
  next true
293
+ when :use_signal
294
+ {
295
+ :GPS_L2C => proc{@solver.gps_options.exclude_L2C = false},
296
+ }[v.to_sym].call rescue next false
297
+ next true
293
298
  end
294
299
  false
295
300
  }
@@ -334,9 +339,9 @@ class Receiver
334
339
  }.flatten(1))]
335
340
  }
336
341
  }.call
337
- alias_method(:add_orig, :add)
342
+ add_orig = instance_method(:add)
338
343
  define_method(:add){|prn, key, value|
339
- add_orig(prn, key.kind_of?(Symbol) ? GPS::Measurement.const_get(key) : key, value)
344
+ add_orig.bind(self).call(prn, key.kind_of?(Symbol) ? GPS::Measurement.const_get(key) : key, value)
340
345
  }
341
346
  }
342
347
 
@@ -523,33 +528,39 @@ class Receiver
523
528
  v
524
529
  }
525
530
  sys, svid = gnss_serial.call(*loader.call(36, 2).reverse)
526
- # sigID check to restrict signal to L1 if version(>0); @see UBX-18010854
527
- next if (packet[6 + 13] != 0) && (loader.call(38, 1, "C") != 0)
531
+ sigid = (packet[6 + 13] != 0) ? loader.call(38, 1, "C") : 0 # sigID if version(>0); @see UBX-18010854
528
532
  case sys
529
- when :GPS, :SBAS, :QZSS;
533
+ when :GPS
534
+ sigid = {0 => :L1, 3 => :L2CL, 4 => :L2CM}[sigid]
535
+ when :SBAS
536
+ sigid = :L1
537
+ when :QZSS
538
+ sigid = {0 => :L1, 5 => :L2CL, 4 => :L2CM}[sigid]
530
539
  when :GLONASS
531
540
  svid += 0x100
541
+ sigid = {0 => :L1}[sigid] # TODO: to support {2 -> :L2}
532
542
  meas.add(svid, :L1_FREQUENCY,
533
543
  GPS::SpaceNode_GLONASS::L1_frequency(loader.call(39, 1, "C") - 7))
534
544
  else; next
535
545
  end
546
+ next unless sigid
536
547
  trk_stat = loader.call(46, 1)[0]
537
548
  {
538
- :L1_PSEUDORANGE => [16, 8, "E", proc{|v| (trk_stat & 0x1 == 0x1) ? v : nil}],
539
- :L1_PSEUDORANGE_SIGMA => [43, 1, nil, proc{|v|
549
+ :PSEUDORANGE => [16, 8, "E", proc{|v| (trk_stat & 0x1 == 0x1) ? v : nil}],
550
+ :PSEUDORANGE_SIGMA => [43, 1, nil, proc{|v|
540
551
  (trk_stat & 0x1 == 0x1) ? (1E-2 * (1 << (v[0] & 0xF))) : nil
541
552
  }],
542
- :L1_DOPPLER => [32, 4, "e"],
543
- :L1_DOPPLER_SIGMA => [45, 1, nil, proc{|v| 2E-3 * (1 << (v[0] & 0xF))}],
544
- :L1_CARRIER_PHASE => [24, 8, "E", proc{|v| (trk_stat & 0x2 == 0x2) ? v : nil}],
545
- :L1_CARRIER_PHASE_SIGMA => [44, 1, nil, proc{|v|
553
+ :DOPPLER => [32, 4, "e"],
554
+ :DOPPLER_SIGMA => [45, 1, nil, proc{|v| 2E-3 * (1 << (v[0] & 0xF))}],
555
+ :CARRIER_PHASE => [24, 8, "E", proc{|v| (trk_stat & 0x2 == 0x2) ? v : nil}],
556
+ :CARRIER_PHASE_SIGMA => [44, 1, nil, proc{|v|
546
557
  (trk_stat & 0x2 == 0x2) ? (0.004 * (v[0] & 0xF)) : nil
547
558
  }],
548
- :L1_SIGNAL_STRENGTH_dBHz => [42, 1, "C"],
549
- :L1_LOCK_SEC => [40, 2, "v", proc{|v| 1E-3 * v}],
559
+ :SIGNAL_STRENGTH_dBHz => [42, 1, "C"],
560
+ :LOCK_SEC => [40, 2, "v", proc{|v| 1E-3 * v}],
550
561
  }.each{|k, prop|
551
562
  next unless v = loader.call(*prop)
552
- meas.add(svid, k, v)
563
+ meas.add(svid, "#{sigid}_#{k}".to_sym, v) rescue nil # unsupported signal
553
564
  }
554
565
  }
555
566
  after_run.call(run(meas, t_meas), [meas, t_meas])
@@ -605,18 +616,19 @@ class Receiver
605
616
 
606
617
  types ||= Hash[*(item[:meas_types].collect{|sys, values|
607
618
  [sys, values.collect.with_index{|type_, i|
608
- case type_
609
- when "C1", "C1C"
610
- [i, :L1_PSEUDORANGE]
611
- when "L1", "L1C"
612
- [i, :L1_CARRIER_PHASE]
613
- when "D1", "D1C"
614
- [i, :L1_DOPPLER]
615
- when "S1", "S1C"
616
- [i, :L1_SIGNAL_STRENGTH_dBHz]
617
- else
618
- nil
619
- end
619
+ sig_obs_type = [case type_[1..-1]
620
+ when /^1C?$/; :L1
621
+ when /^2[XL]$/; :L2CL
622
+ when /^2S$/; :L2CM
623
+ else; nil
624
+ end, {
625
+ 'C' => :PSEUDORANGE,
626
+ 'L' => :CARRIER_PHASE,
627
+ 'D' => :DOPPLER,
628
+ 'S' => :SIGNAL_STRENGTH_dBHz,
629
+ }[type_[0]]]
630
+ next nil unless sig_obs_type.all?
631
+ [i, sig_obs_type.join('_').to_sym]
620
632
  }.compact]
621
633
  }.flatten(1))]
622
634
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GPS_PVT
4
- VERSION = "0.8.1"
4
+ VERSION = "0.8.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gps_pvt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - fenrir(M.Naruoka)
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-17 00:00:00.000000000 Z
11
+ date: 2022-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyserial