gps_pvt 0.8.1 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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