gps_pvt 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a67291f7ea2d3146cace6c9e5f9c3262d89c1bd22534d6c147265c6189089c8
4
- data.tar.gz: 211daa142bb6282341367f0ccd375d66a0083e6de01ec7841ac4833795c3a6cc
3
+ metadata.gz: f9ab8f442240a2b92bfcb975ec6cb72000ec7d257bf7d5f41e0765905b9fa020
4
+ data.tar.gz: 52ed9e2141f4e0bc111da34be34b28414557fd02f003c3fbff84db571135ad1a
5
5
  SHA512:
6
- metadata.gz: 80a279b8018856c9d0d73b311c44efd97ce2794dc12353f10462a1b1b65aedc177ae6284fc324feb1980a02da2c2127ab8649058f840fc8279340f1152af3f62
7
- data.tar.gz: ce708fe585b811a99a8e0e42862df7bcac023d44859b17ea08b9e6816425845b5ab0a31b207b79a870ca6d52dc43313b00eb67a5b38746ace843c54264ceca1e
6
+ metadata.gz: 63cc7efd29e6e576c15380bd43550b427015f57d99a545b3373ef829d496e87df799feed2b6499c2bf336619a81bb193ddd1c350990cc85ee7c52a7aadf0d264
7
+ data.tar.gz: 7911e374e8d1f33f283be0fd7a59262bd1bd2d0315d631456e37659b4729812c260f3f65495bb6de851e8ac7246f148d47129080717aeccc715cc1138e17e158
data/exe/to_ubx ADDED
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'gps_pvt'
4
+ require 'uri'
5
+ require 'gps_pvt/ubx'
6
+
7
+ # Convert file(s) to ubx format
8
+ # TODO currently only RINEX observation file is supported.
9
+
10
+ $stderr.puts <<__STRING__
11
+ Usage: #{__FILE__} GPS_file ... > as_you_like.ubx
12
+ As GPS_file, only rinex_obs(*.YYo) is currently supported.
13
+ (YY = last two digit of year)
14
+ File format is automatically determined based on its extention described in above parentheses.
15
+ If you want to specify its format manually, command options like --rinex_obs=file_name are available.
16
+ Supported RINEX versions are 2 and 3.
17
+ RXM-RAWX and RXM-SFRBX are included in output UBX if corresponding file(s) is given.
18
+ A file having additional ".gz" or ".Z" extension is recognized as a compressed file.
19
+ Major URL such as http(s)://... or ftp://... is acceptable as an input file name.
20
+ __STRING__
21
+
22
+ options = []
23
+ misc_options = {
24
+ :ubx_rawx => false
25
+ }
26
+
27
+ # check options and file format
28
+ files = ARGV.collect{|arg|
29
+ next [arg, nil] unless arg =~ /^--([^=]+)=?/
30
+ k, v = [$1.downcase.to_sym, $']
31
+ next [v, k] if [:rinex_nav, :rinex_obs].include?(k) # file type
32
+ options << [$1.to_sym, $']
33
+ nil
34
+ }.compact
35
+
36
+ # Check file existence and extension
37
+ files.collect!{|fname, ftype|
38
+ ftype ||= case fname
39
+ when /\.\d{2}[nhqg](?:\.gz)?$/; :rinex_nav
40
+ when /\.\d{2}o(?:\.gz)?$/; :rinex_obs
41
+ else
42
+ raise "Format cannot be guessed, use --(format, ex. rinex_obs)=#{fname}"
43
+ end
44
+ fname = proc{
45
+ next fname if File::exist?(fname)
46
+ if uri = URI::parse(fname) and !uri.instance_of?(URI::Generic) then
47
+ next uri
48
+ end
49
+ raise "File not found: #{fname}"
50
+ }.call
51
+ [fname, ftype]
52
+ }
53
+
54
+ options.reject!{|opt|
55
+ case opt[0]
56
+ when :ubx_rawx
57
+ misc_options[opt[0]] = opt[1]
58
+ true
59
+ else
60
+ false
61
+ end
62
+ }
63
+
64
+ rcv = GPS_PVT::Receiver::new(options)
65
+
66
+ obs = []
67
+ rcv.define_singleton_method(:run){|meas, t_meas, *args|
68
+ obs << [t_meas, meas]
69
+ }
70
+
71
+ # parse RINEX NAV
72
+ files.each{|fname, ftype|
73
+ case ftype
74
+ when :rinex_nav; rcv.parse_rinex_nav(fname)
75
+ end
76
+ }
77
+
78
+ # other files
79
+ files.each{|fname, ftype|
80
+ case ftype
81
+ when :rinex_obs; rcv.parse_rinex_obs(fname){}
82
+ end
83
+ }
84
+
85
+ obs.sort!{|a, b| a[0] <=> b[0]} # Sort by measurement time
86
+
87
+ glonass_freq_ch = proc{
88
+ freq0, delta = [:L1_frequency_base, :L1_frequency_gap].collect{|k|
89
+ GPS_PVT::GPS::SpaceNode_GLONASS.send(k)
90
+ }
91
+ proc{|freq| ((freq - freq0) / delta).to_i}
92
+ }.call
93
+
94
+ gen_raw = proc{|t_meas, meas| # Convert to RXM-RAW(0x10)
95
+ meas = meas.to_hash
96
+ ubx = [0xB5, 0x62, 0x02, 0x10, 0, 0]
97
+ ubx += [(t_meas.seconds * 1E3).to_i, t_meas.week].pack("Vv").unpack("C*")
98
+ ubx += [0] * 2
99
+ meas_ubx = meas.collect{|sat, items|
100
+ res = [0] * 24
101
+ setter = proc{|value, offset, len, str, pre_proc|
102
+ array = case value
103
+ when Array; value
104
+ when Symbol
105
+ [items[GPS_PVT::GPS::Measurement.const_get(value)]]
106
+ else
107
+ next nil
108
+ end
109
+ pre_proc.call(array) if pre_proc
110
+ next if array.empty?
111
+ array = array.pack(str).unpack("C*") if str
112
+ res[offset - 8, len] = array
113
+ }
114
+ svid = case sat
115
+ when 1..32, 120..158, 193..202 # GPS, SBAS, QZSS
116
+ sat
117
+ when (0x100 + 1)..(0x100 + 32) # GLONASS
118
+ sat - 0x100 + 64 # => 65..96
119
+ else
120
+ next nil # TODO Galileo, Beidou, ...
121
+ end
122
+
123
+ qi = 6
124
+ setter.call(:L1_CARRIER_PHASE,
125
+ 8, 8, "E", proc{|v| next if v[0]; qi = 4; v.clear})
126
+ setter.call(:L1_PSEUDORANGE,
127
+ 16, 8, "E", proc{|v| next if v[0]; qi = 0; v.clear})
128
+ setter.call(:L1_DOPPLER,
129
+ 24, 4, "e", proc{|v| next if v[0]; qi = 0; v.clear})
130
+ setter.call([svid, qi], 28, 2)
131
+ setter.call(:L1_SIGNAL_STRENGTH_dBHz,
132
+ 30, 1, nil, proc{|v| v.replace(v[0] ? [v[0].to_i] : [])})
133
+ setter.call(:L1_LOCK_SEC,
134
+ 31, 1, nil, proc{|v| v.replace(v[0] ? [(v[0] < 0) ? 1 : 0] : [0])})
135
+
136
+ res
137
+ }.compact
138
+ ubx[6 + 6] = meas_ubx.size
139
+ ubx += meas_ubx.flatten(1)
140
+ ubx += [0, 0]
141
+ GPS_PVT::UBX::update(ubx).pack("C*")
142
+ }
143
+
144
+ gen_rawx = proc{|t_meas, meas| # Convert to RXM-RAWX(0x15)
145
+ meas = meas.to_hash
146
+ ubx = [0xB5, 0x62, 0x02, 0x15, 0, 0]
147
+ ubx += [t_meas.seconds, t_meas.week].pack("Ev").unpack("C*")
148
+ ubx += [0] * 6
149
+ meas_ubx = meas.collect{|sat, items|
150
+ res = [0] * 32
151
+ setter = proc{|value, offset, len, str, pre_proc|
152
+ array = case value
153
+ when Array; value
154
+ when Symbol
155
+ [items[GPS_PVT::GPS::Measurement.const_get(value)]]
156
+ else
157
+ next nil
158
+ end
159
+ pre_proc.call(array) if pre_proc
160
+ next if array.empty?
161
+ array = array.pack(str).unpack("C*") if str
162
+ res[offset - 16, len] = array
163
+ }
164
+ sys, svid = case sat
165
+ when 1..32 # GPS
166
+ [0, sat]
167
+ when 120..158 # SBAS
168
+ [1, sat]
169
+ when 193..202 # QZSS
170
+ [5, sat]
171
+ when (0x100 + 1)..(0x100 + 32) # GLONASS
172
+ setter.call(:L1_FREQUENCY,
173
+ 39, 1, nil, proc{|v| v.replace(v[0] ? glonass_freq_ch.call(v[0]) : [7])})
174
+ [6, sat - 0x100]
175
+ else
176
+ next nil # TODO Galileo, Beidou, ...
177
+ end
178
+ setter.call([sys, svid], 36, 2)
179
+
180
+ trk_stat = 0
181
+ setter.call(:L1_PSEUDORANGE,
182
+ 16, 8, "E", proc{|v| v[0] ? (trk_stat |= 0x1) : v.clear})
183
+ setter.call(:L1_PSEUDORANGE_SIGMA,
184
+ 43, 1, nil, proc{|v|
185
+ b = (Math::log2(v[0] / 1E-2).to_i & 0xF) rescue 0x8
186
+ v.replace((trk_stat & 0x1 == 0x1) ? [b] : [])
187
+ })
188
+ setter.call(:L1_DOPPLER, 32, 4, "e")
189
+ setter.call(:L1_DOPPLER_SIGMA,
190
+ 45, 1, nil, proc{|v| v.replace(v[0] ? [Math::log2(v[0] / 2E-3).to_i & 0xF] : [0x8])})
191
+ setter.call(:L1_CARRIER_PHASE,
192
+ 24, 8, "E", proc{|v| v[0] ? (trk_stat |= 0x2) : v.clear})
193
+ setter.call(:L1_CARRIER_PHASE_SIGMA,
194
+ 44, 1, nil, proc{|v|
195
+ b = ((v[0] / 0.004).to_i & 0xF) rescue 0x8
196
+ v.replace((trk_stat & 0x2 == 0x2) ? [b] : [])
197
+ })
198
+ setter.call(:L1_SIGNAL_STRENGTH_dBHz,
199
+ 42, 1, nil, proc{|v| v.replace(v[0] ? [v[0].to_i] : [])})
200
+ setter.call(:L1_LOCK_SEC,
201
+ 40, 2, "v", proc{|v| v.replace(v[0] ? [(v[0] / 1E-3).to_i] : [])})
202
+ setter.call([trk_stat], 46, 1)
203
+
204
+ res
205
+ }.compact
206
+ ubx[6 + 11] = meas_ubx.size
207
+ ubx += meas_ubx.flatten(1)
208
+ ubx += [0, 0]
209
+ GPS_PVT::UBX::update(ubx).pack("C*")
210
+ }
211
+
212
+ gen = misc_options[:ubx_rawx] ? gen_rawx : gen_raw
213
+ obs.each{|*item| print gen.call(*item)}
@@ -34,6 +34,9 @@
34
34
 
35
35
  #include <cstddef>
36
36
  #include <vector>
37
+ #include <map>
38
+ #include <algorithm>
39
+ #include <stdexcept>
37
40
 
38
41
  /*
39
42
  * perform Neville's interpolation (with derivative)
@@ -118,4 +121,107 @@ Ty interpolate_Neville(
118
121
  return interpolate_Neville(x_given, y_given, x, y_buf, n)[0];
119
122
  }
120
123
 
124
+ template <class Tx, class Ty, class Tx_delta = Tx>
125
+ struct InterpolatableSet {
126
+ struct condition_t {
127
+ std::size_t max_x_size; ///< maximum number of data used for interpolation
128
+ Tx_delta max_dx_range; ///< maximum acceptable absolute difference between x and x0
129
+ };
130
+
131
+ typedef typename std::vector<std::pair<Tx, Ty> > buffer_t;
132
+ buffer_t buf;
133
+ Tx x0, x_lower, x_upper;
134
+ std::vector<Tx_delta> dx;
135
+ bool ready;
136
+
137
+ InterpolatableSet() : x0(), dx(), ready(false) {}
138
+
139
+ /**
140
+ * update interpolation source
141
+ * @param force_update If true, update is forcibly performed irrespective of current state
142
+ * @param cnd condition for source data selection
143
+ */
144
+ InterpolatableSet &update(
145
+ const Tx &x, const std::map<Tx, Ty> &xy_table,
146
+ const condition_t &cnd,
147
+ const bool &force_update = false){
148
+
149
+ do{
150
+ if(force_update){break;}
151
+ if(dx.size() <= 2){break;}
152
+ if(x < x_lower){break;}
153
+ if(x > x_upper){break;}
154
+ return *this;
155
+ }while(false);
156
+
157
+ // If the 1st and 2nd nearest items are changed, then recalculate interpolation targets.
158
+ struct {
159
+ const Tx &x_base;
160
+ bool operator()(
161
+ const typename std::map<Tx, Ty>::value_type &rhs,
162
+ const typename std::map<Tx, Ty>::value_type &lhs) const {
163
+ return std::abs(rhs.first - x_base) < std::abs(lhs.first - x_base);
164
+ }
165
+ } cmp = {(x0 = x)};
166
+
167
+ buf.resize(cnd.max_x_size);
168
+ dx.clear();
169
+ // extract x where x0-dx_range <= x <= x0+dx_range, then sort by ascending order of |x-x0|
170
+ for(typename buffer_t::const_iterator
171
+ it(buf.begin()),
172
+ it_end(std::partial_sort_copy(
173
+ xy_table.lower_bound(x - cnd.max_dx_range),
174
+ xy_table.upper_bound(x + cnd.max_dx_range),
175
+ buf.begin(), buf.end(), cmp));
176
+ it != it_end; ++it){
177
+ dx.push_back(it->first - x0);
178
+ }
179
+ if(dx.size() >= 2){ // calculate a necessary condition to update samples for new x
180
+ // According to Nth nearest points, x range in which the order of extracted samples
181
+ // is retained can be calculated.
182
+ bool ascending(buf[0].first <= buf[1].first);
183
+ Tx &xa(ascending ? x_lower : x_upper), &xb(ascending ? x_upper : x_lower);
184
+ xa = x0;
185
+ for(std::size_t i(2); i < buf.size(); ++i){
186
+ if(ascending ? (dx[1] <= dx[i]) : (dx[1] >= dx[i])){continue;}
187
+ xa = x0 + (dx[1] + dx[i]) / 2;
188
+ break;
189
+ }
190
+ xb = x0 + (dx[0] + dx[1]) / 2;
191
+ }
192
+ ready = (dx.size() >= cnd.max_x_size);
193
+
194
+ return *this;
195
+ }
196
+
197
+ template <class Ty2, class Ty2_Iterator>
198
+ Ty2 interpolate2(
199
+ const Tx &x, const Ty2_Iterator &y,
200
+ Ty2 *derivative = NULL) const {
201
+ int order(dx.size() - 1);
202
+ do{
203
+ if(order > 0){break;}
204
+ if((order == 0) && (!derivative)){return y[0];}
205
+ throw std::range_error("Insufficient records for interpolation");
206
+ }while(false);
207
+ std::vector<Ty2> y_buf(order), dy_buf(order);
208
+ interpolate_Neville(
209
+ dx, y, x - x0, y_buf, order,
210
+ &dy_buf, derivative ? 1 : 0);
211
+ if(derivative){*derivative = dy_buf[0];}
212
+ return y_buf[0];
213
+ }
214
+
215
+ Ty interpolate(const Tx &x, Ty *derivative = NULL) const {
216
+ struct second_iterator : public buffer_t::const_iterator {
217
+ second_iterator(const typename buffer_t::const_iterator &it)
218
+ : buffer_t::const_iterator(it) {}
219
+ const Ty &operator[](const int &n) const {
220
+ return buffer_t::const_iterator::operator[](n).second;
221
+ }
222
+ } y_it(buf.begin());
223
+ return interpolate2(x, y_it, derivative);
224
+ }
225
+ };
226
+
121
227
  #endif /* __INTERPOLATE_H__ */
@@ -41,7 +41,6 @@
41
41
  #include <cstring>
42
42
  #include <map>
43
43
  #include <set>
44
- #include <algorithm>
45
44
  #include <stdexcept>
46
45
 
47
46
  #include "util/text_helper.h"
@@ -61,22 +60,15 @@ struct SP3_Product {
61
60
  typedef std::map<GPS_Time<FloatT>, prop_t> history_t;
62
61
  history_t pos_history;
63
62
  history_t vel_history;
64
-
65
- static const struct interpolate_cnd_t {
66
- std::size_t max_epochs; ///< maximum number of epochs used for interpolation
67
- FloatT max_delta_t; ///< maximum acceptable absolute time difference between t and epoch
68
- } interpolate_cnd_default;
63
+
64
+ typedef InterpolatableSet<GPS_Time<FloatT>, prop_t, FloatT> interpolator_t;
65
+ typedef typename interpolator_t::condition_t interpolate_cnd_t;
66
+ static const interpolate_cnd_t interpolate_cnd_default;
69
67
 
70
68
  mutable struct {
71
- struct target_t {
72
-
73
- typedef typename std::vector<std::pair<GPS_Time<FloatT>, prop_t> > buf_t;
74
- buf_t buf;
75
- GPS_Time<FloatT> t0;
76
- std::vector<FloatT> dt;
77
- bool updated_full_cnd;
69
+ struct target_t : public interpolator_t {
78
70
 
79
- target_t() : t0(0, 0), updated_full_cnd(false) {}
71
+ target_t() : interpolator_t() {}
80
72
 
81
73
  /**
82
74
  * update interpolation source
@@ -88,58 +80,13 @@ struct SP3_Product {
88
80
  const bool &force_update = false,
89
81
  const interpolate_cnd_t &cnd = interpolate_cnd_default){
90
82
 
91
- FloatT t_diff(t0 - t);
92
- if((!force_update)
93
- && ((std::abs(t_diff) <= 10)
94
- || ((dt.size() >= 2)
95
- && (std::abs(t_diff + dt[0]) <= std::abs(t_diff + dt[1])))) ){
96
- return *this;
97
- }
98
-
99
- // If the 1st and 2nd nearest epochs are changed, then recalculate interpolation targets.
100
- struct {
101
- const GPS_Time<FloatT> &t_base;
102
- bool operator()(
103
- const typename history_t::value_type &rhs,
104
- const typename history_t::value_type &lhs) const {
105
- return std::abs(rhs.first - t_base) < std::abs(lhs.first - t_base);
106
- }
107
- } cmp = {(t0 = t)};
108
-
109
- buf.resize(cnd.max_epochs);
110
- dt.clear();
111
- // extract t where t0-dt <= t <= t0+dt, then sort by ascending order of |t-t0|
112
- for(typename buf_t::const_iterator
113
- it(buf.begin()),
114
- it_end(std::partial_sort_copy(
115
- history.lower_bound(t - cnd.max_delta_t),
116
- history.upper_bound(t + cnd.max_delta_t),
117
- buf.begin(), buf.end(), cmp));
118
- it != it_end; ++it){
119
- dt.push_back(it->first - t0);
120
- }
121
- updated_full_cnd = (dt.size() >= cnd.max_epochs);
122
-
83
+ if((!force_update) && (std::abs(t - interpolator_t::x0) <= 10)){return *this;}
84
+ interpolator_t::update(t, history, cnd, force_update);
123
85
  return *this;
124
86
  }
125
87
 
126
- template <class Ty, class Ty_Array>
127
- Ty interpolate(
128
- const GPS_Time<FloatT> &t, const Ty_Array &y,
129
- Ty *derivative = NULL) const {
130
- int order(dt.size() - 1);
131
- do{
132
- if(order > 0){break;}
133
- if((order == 0) && (!derivative)){return y[0];}
134
- throw std::range_error("Insufficient records for interpolation");
135
- }while(false);
136
- std::vector<Ty> y_buf(order), dy_buf(order);
137
- interpolate_Neville(
138
- dt, y, t - t0, y_buf, order,
139
- &dy_buf, derivative ? 1 : 0);
140
- if(derivative){*derivative = dy_buf[0];}
141
- return y_buf[0];
142
- }
88
+ typedef typename interpolator_t::buffer_t buf_t;
89
+
143
90
  Vector3<FloatT> interpolate_xyz(
144
91
  const GPS_Time<FloatT> &t,
145
92
  Vector3<FloatT> *derivative = NULL) const {
@@ -149,8 +96,8 @@ struct SP3_Product {
149
96
  const Vector3<FloatT> &operator[](const int &n) const {
150
97
  return buf_t::const_iterator::operator[](n).second.xyz;
151
98
  }
152
- } xyz(buf.begin());
153
- return interpolate(t, xyz, derivative);
99
+ } xyz(interpolator_t::buf.begin());
100
+ return interpolator_t::interpolate2(t, xyz, derivative);
154
101
  }
155
102
  FloatT interpolate_clk(
156
103
  const GPS_Time<FloatT> &t,
@@ -161,8 +108,8 @@ struct SP3_Product {
161
108
  const FloatT &operator[](const int &n) const {
162
109
  return buf_t::const_iterator::operator[](n).second.clk;
163
110
  }
164
- } clk(buf.begin());
165
- return interpolate(t, clk, derivative);
111
+ } clk(interpolator_t::buf.begin());
112
+ return interpolator_t::interpolate2(t, clk, derivative);
166
113
  }
167
114
  } pos_clk, vel_rate;
168
115
  } subset;
@@ -175,7 +122,7 @@ struct SP3_Product {
175
122
  bool precheck(const GPS_Time<FloatT> &t) const {
176
123
  // Only position/clock is checked, because velocity/rate can be calculated based on pos/clk.
177
124
  subset.pos_clk.update(t, pos_history);
178
- return subset.pos_clk.updated_full_cnd;
125
+ return subset.pos_clk.ready;
179
126
  }
180
127
 
181
128
  typename GPS_SpaceNode<FloatT>::SatelliteProperties::constellation_t
@@ -381,8 +328,11 @@ static typename GPS_Solver_Base<FloatT>::satellite_t select_ ## sys( \
381
328
  template <class FloatT>
382
329
  const typename SP3_Product<FloatT>::per_satellite_t::interpolate_cnd_t
383
330
  SP3_Product<FloatT>::per_satellite_t::interpolate_cnd_default = {
384
- 9, // max_epochs
385
- 60 * 60 * 2, // max_delta_t, default is 2 hr = 15 min interval records; (2 hr * 2 / (9 - 1) = 15 min)
331
+ 9, // maximum number of epochs used for interpolation
332
+ /* maximum acceptable absolute time difference between t and epoch,
333
+ * default is 2 hr = 15 min interval records; (2 hr * 2 / (9 - 1) = 15 min)
334
+ */
335
+ 60 * 60 * 2,
386
336
  };
387
337
 
388
338
  template <class FloatT>
data/gps_pvt.gemspec CHANGED
@@ -53,6 +53,9 @@ Gem::Specification.new do |spec|
53
53
  }.flatten
54
54
  }.call
55
55
 
56
+ spec.rdoc_options << '--exclude=ext/ninja-scan-light'
57
+ spec.extra_rdoc_files = []
58
+
56
59
  # Uncomment to register a new dependency of your gem
57
60
  # spec.add_dependency "example-gem", "~> 1.0"
58
61
  spec.add_development_dependency "rake"
@@ -410,7 +410,7 @@ class Receiver
410
410
  @solver.sbas_space_node.ionospheric_grid_points(prn)].each{|str|
411
411
  $stderr.puts str
412
412
  } if @debug[:SBAS_IGP]
413
- end
413
+ end if t_meas
414
414
  when :GLONASS
415
415
  next unless eph = eph_glonass_list[prn]
416
416
  leap_sec = @solver.gps_space_node.is_valid_utc ?
@@ -508,10 +508,10 @@ class Receiver
508
508
  {
509
509
  :L1_PSEUDORANGE => [16, 8, "E", proc{|v| (trk_stat & 0x1 == 0x1) ? v : nil}],
510
510
  :L1_PSEUDORANGE_SIGMA => [43, 1, nil, proc{|v|
511
- (trk_stat & 0x1 == 0x1) ? (1E-2 * (v[0] & 0xF)) : nil
511
+ (trk_stat & 0x1 == 0x1) ? (1E-2 * (1 << (v[0] & 0xF))) : nil
512
512
  }],
513
513
  :L1_DOPPLER => [32, 4, "e"],
514
- :L1_DOPPLER_SIGMA => [45, 1, nil, proc{|v| 2E-3 * (v[0] & 0xF)}],
514
+ :L1_DOPPLER_SIGMA => [45, 1, nil, proc{|v| 2E-3 * (1 << (v[0] & 0xF))}],
515
515
  :L1_CARRIER_PHASE => [24, 8, "E", proc{|v| (trk_stat & 0x2 == 0x2) ? v : nil}],
516
516
  :L1_CARRIER_PHASE_SIGMA => [44, 1, nil, proc{|v|
517
517
  (trk_stat & 0x2 == 0x2) ? (0.004 * (v[0] & 0xF)) : nil
@@ -1,5 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
- module GPS_PVT
4
- VERSION = "0.6.2"
5
- end
1
+ # frozen_string_literal: true
2
+
3
+ module GPS_PVT
4
+ VERSION = "0.6.3"
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.6.2
4
+ version: 0.6.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-08-03 00:00:00.000000000 Z
11
+ date: 2022-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -44,6 +44,7 @@ email:
44
44
  - fenrir.naru@gmail.com
45
45
  executables:
46
46
  - gps_pvt
47
+ - to_ubx
47
48
  extensions:
48
49
  - ext/gps_pvt/extconf.rb
49
50
  extra_rdoc_files: []
@@ -57,6 +58,7 @@ files:
57
58
  - bin/console
58
59
  - bin/setup
59
60
  - exe/gps_pvt
61
+ - exe/to_ubx
60
62
  - ext/gps_pvt/Coordinate/Coordinate_wrap.cxx
61
63
  - ext/gps_pvt/GPS/GPS_wrap.cxx
62
64
  - ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx
@@ -109,7 +111,8 @@ metadata:
109
111
  homepage_uri: https://github.com/fenrir-naru/gps_pvt
110
112
  source_code_uri: https://github.com/fenrir-naru/gps_pvt
111
113
  post_install_message:
112
- rdoc_options: []
114
+ rdoc_options:
115
+ - "--exclude=ext/ninja-scan-light"
113
116
  require_paths:
114
117
  - lib
115
118
  required_ruby_version: !ruby/object:Gem::Requirement