gps_pvt 0.7.2 → 0.8.1

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: b2eb20de6303a24b0e5b134c7c78cd1edb043ff38d823181e596b4626b6bc536
4
- data.tar.gz: 183ae6e8cfd2577132113bb3684e6e225989ce444d6647820496b13ddd3a4903
3
+ metadata.gz: fb3abd803cfe1b0b5199c4187fe17c2595eb603ab27e09f71b66fde11eeafce0
4
+ data.tar.gz: 351d46d74583346750aec426c087c33bc13f9e9e9adff746567e40df7eb1e39e
5
5
  SHA512:
6
- metadata.gz: a35228704032066f682e15f5abf6f8a2238d90424e6b50182e07b8fc342a1f4150ba6747ca88a9fcaef163e0ce8149a68edf087e6c0f5525a2c7a09553beb504
7
- data.tar.gz: 10ace25d753123375bf8ad46cbd4d7490b13219522b39ee5774a1df6d3ba1fd3fd9f318364a19253981f24a3b83998e5df9bb82700b37d6d7f17bd1ad27ad14d
6
+ metadata.gz: 0fb78d49675fbbcb3fcfeb80debd7ca15f351be478ed5716f94a61b23f26af7ff957ee446a5ab6c4cc2e67abf2f251cf62845a347ea3810282987da04fa9a2e8
7
+ data.tar.gz: ac74ba61920cad427d6e848f4621227d150bfe9a30a2f1465bd6d87681cfdd935e20e8e141575306b87c770b485f8dad1555766b7281980ba1f412adddff4e7c
data/README.md CHANGED
@@ -32,7 +32,7 @@ An attached executable is useful. After installation, type
32
32
 
33
33
  $ gps_pvt file_or_URI(s)
34
34
 
35
- The format of file is automatically determined with its extension, such as .ubx will be treated as UBX format. A compressed file of .gz or .Z can be specified directly (decompression is internally performed), and URI such as http(s)://... and ftp:// is also acceptable. If you want to specify the file format, instead of file_or_URI(s), use the following arguments:
35
+ The format of file is automatically determined with its extension, such as .ubx will be treated as UBX format. A compressed file of .gz or .Z can be specified directly (decompression is internally performed). URI such as http(s)://... and ftp://, and serial port (COMn for Windows and /dev/tty* for *NIX, version >= 0.8.0) are also acceptable. If you want to specify the file format, instead of file_or_URI(s), use the following arguments:
36
36
 
37
37
  | specification | recoginized as |
38
38
  ----|----
data/Rakefile CHANGED
@@ -45,6 +45,7 @@ namespace :git do
45
45
  + (<<-__SPARSE_PATTERNS__).lines.collect{|str| str.chomp.gsub(/^ */, ' ')}.join,
46
46
  tool/param/
47
47
  tool/util/text_helper.h
48
+ tool/util/bit_counter.h
48
49
  tool/algorithm/integral.h
49
50
  tool/algorithm/interpolate.h
50
51
  tool/navigation/GPS*
data/exe/gps_pvt CHANGED
@@ -14,7 +14,7 @@ If you want to specify its format manually, command options like --rinex_nav=fil
14
14
  Other than --rinex_nav, --rinex_obs, -rinex_clk, --ubx, --sp3 or --antex are supported.
15
15
  Supported RINEX versions are 2 and 3.
16
16
  A file having additional ".gz" or ".Z" extension is recognized as a compressed file.
17
- Major URL such as http(s)://... or ftp://... is acceptable as an input file name.
17
+ Major URL such as http(s)://... or ftp://..., and serial port (COMn for Windows, /dev/tty* for *NIX) is acceptable as an input file name.
18
18
  __STRING__
19
19
 
20
20
  options = []
@@ -80,6 +80,7 @@ files.collect!{|fname, ftype|
80
80
  end
81
81
  fname = proc{
82
82
  next fname if File::exist?(fname)
83
+ next fname if ((fname =~ Serial::SPEC) rescue false)
83
84
  if uri = URI::parse(fname) and !uri.instance_of?(URI::Generic) then
84
85
  next uri
85
86
  end
@@ -91,23 +92,7 @@ files.collect!{|fname, ftype|
91
92
  rcv = GPS_PVT::Receiver::new(options)
92
93
 
93
94
  proc{|src|
94
- next unless src
95
- loader = proc{|t_meas|
96
- utc = Time::utc(*t_meas.c_tm)
97
- y, yday = [:year, :yday].collect{|f| utc.send(f)}
98
- uri = URI::parse(
99
- "ftp://gssc.esa.int/gnss/data/daily/" +
100
- "%04d/brdc/BRDC00IGS_R_%04d%03d0000_01D_MN.rnx.gz"%[y, y, yday])
101
- rcv.parse_rinex_nav(uri)
102
- uri
103
- }
104
- run_orig = rcv.method(:run)
105
- eph_list = {}
106
- rcv.define_singleton_method(:run){|meas, t_meas, *args|
107
- w_d = [t_meas.week, (t_meas.seconds.to_i / 86400)]
108
- eph_list[w_d] ||= loader.call(t_meas)
109
- run_orig.call(meas, t_meas, *args)
110
- }
95
+ rcv.attach_online_ephemeris(src) if src
111
96
  }.call(misc_options[:online_ephemeris])
112
97
 
113
98
  proc{
data/exe/to_ubx CHANGED
@@ -21,7 +21,9 @@ __STRING__
21
21
 
22
22
  options = []
23
23
  misc_options = {
24
- :ubx_rawx => false
24
+ :broadcast_data => false,
25
+ :ubx_rawx => false,
26
+ :eph_interval => 60 * 5,
25
27
  }
26
28
 
27
29
  # check options and file format
@@ -53,7 +55,7 @@ files.collect!{|fname, ftype|
53
55
 
54
56
  options.reject!{|opt|
55
57
  case opt[0]
56
- when :ubx_rawx
58
+ when :ubx_rawx, :online_ephemeris, :broadcast_data, :eph_interval
57
59
  misc_options[opt[0]] = opt[1]
58
60
  true
59
61
  else
@@ -68,6 +70,10 @@ rcv.define_singleton_method(:run){|meas, t_meas, *args|
68
70
  obs << [t_meas, meas]
69
71
  }
70
72
 
73
+ proc{|src|
74
+ rcv.attach_online_ephemeris(src) if src
75
+ }.call(misc_options[:online_ephemeris])
76
+
71
77
  # parse RINEX NAV
72
78
  files.each{|fname, ftype|
73
79
  case ftype
@@ -84,6 +90,92 @@ files.each{|fname, ftype|
84
90
 
85
91
  obs.sort!{|a, b| a[0] <=> b[0]} # Sort by measurement time
86
92
 
93
+ # Add dummy before actual first observation in order to notify time to solver
94
+ obs.unshift([obs[0][0] - 1, GPS_PVT::GPS::Measurement::new])
95
+
96
+ gen_sfrb, gen_sfrbx = proc{
97
+ cache = {}
98
+ sfrb_tmpl = [0xB5, 0x62, 0x02, 0x11, 0, 0]
99
+ sfrb_tmpl += [0, 0] # ch, id
100
+ sfrbx_tmpl = [0xB5, 0x62, 0x02, 0x13, 0, 0]
101
+ sfrbx_tmpl += [0, 0, 0, 0, 0, 0, 2, 0] # version = 2
102
+ iono_utc = rcv.solver.gps_space_node.iono_utc.instance_eval{
103
+ f_orig = method(:dump)
104
+ define_singleton_method(:dump){|t_meas|
105
+ rcv.solver.gps_space_node.is_valid_iono_utc ? f_orig.call(t_meas) : []
106
+ }
107
+ self
108
+ }
109
+ [proc{|t_meas, meas| # Convert to RXM-SFRB(0x11)
110
+ meas.collect{|sat, items|
111
+ t_prv, eph, ch = cache.include?(sat) ? cache[sat] : []
112
+ next nil if t_prv && (t_meas - t_prv < misc_options[:eph_interval])
113
+ sfrb = sfrb_tmpl.clone
114
+ sfrb[6] = (ch ||= (cache.size % 0x100))
115
+ sfrb[7] = sat
116
+ res = case sat
117
+ when 1..32 # GPS
118
+ next nil unless (eph = rcv.ephemeris(t_meas, :GPS, sat))
119
+ (eph.dump(t_meas) + iono_utc.dump(t_meas)).each_slice(10).collect{|subframe|
120
+ ubx = sfrb + subframe.collect{|word|
121
+ word >> 6
122
+ }.pack("V*").unpack("C*") + [0, 0]
123
+ GPS_PVT::UBX::update(ubx)
124
+ }
125
+ when 120..158 # SBAS
126
+ next nil unless (eph = rcv.ephemeris(t_meas, :SBAS, sat))
127
+ ubx = sfrb + proc{|msg|
128
+ msg[7] >>= 6
129
+ msg
130
+ }.call(eph.dump + [0, 0]).pack("V*").unpack("C*") + [0, 0]
131
+ GPS_PVT::UBX::update(ubx)
132
+ else
133
+ next nil
134
+ end
135
+ cache[sat] = [t_meas, eph, ch]
136
+ res
137
+ }.compact.flatten.pack("C*")
138
+ },
139
+ proc{|t_meas, meas| # Convert to RXM-SFRBX(0x13)
140
+ meas.collect{|sat, items|
141
+ t_prv, eph, ch = cache.include?(sat) ? cache[sat] : []
142
+ next nil if t_prv && (t_meas - t_prv < misc_options[:eph_interval])
143
+ sfrbx = sfrbx_tmpl.clone
144
+
145
+ res = case sat
146
+ when 1..32, 193..202 # GPS, QZSS
147
+ sys = sat <= 32 ? :GPS : :QZSS
148
+ next nil unless (eph = rcv.ephemeris(t_meas, sys, sat))
149
+ sfrbx[6..7] = [GPS_PVT::UBX::GNSS_ID[sys], sys == :QZSS ? (sat - 192) : sat] # sys, id
150
+ sfrbx[10] = 10 # words
151
+ sfrbx[11] = (ch ||= (cache.size % 0x100)) # ch
152
+ (eph.dump(t_meas) + iono_utc.dump(t_meas)).each_slice(10).collect{|subframe|
153
+ GPS_PVT::UBX::update(sfrbx + subframe.pack("V*").unpack("C*") + [0, 0])
154
+ }
155
+ when 120..158 # SBAS
156
+ next nil unless (eph = rcv.ephemeris(t_meas, :SBAS, sat))
157
+ sfrbx[6..7] = [GPS_PVT::UBX::GNSS_ID[:SBAS], sat] # sys, id
158
+ sfrbx[10] = 8 # words
159
+ sfrbx[11] = (ch ||= (cache.size % 0x100)) # ch
160
+ GPS_PVT::UBX::update(sfrbx + eph.dump.pack("V*").unpack("C*") + [0, 0])
161
+ when (0x100 + 1)..(0x100 + 32) # GLONASS
162
+ svid = sat - 0x100
163
+ next nil unless (eph = rcv.ephemeris(t_meas, :GLONASS, svid))
164
+ sfrbx[6..7] = [GPS_PVT::UBX::GNSS_ID[:GLONASS], svid] # sys, id
165
+ sfrbx[10] = 4 # words
166
+ sfrbx[11] = (ch ||= (cache.size % 0x100)) # ch
167
+ eph.dump(t_meas).each_slice(3).collect{|str|
168
+ GPS_PVT::UBX::update(sfrbx + (str + [0]).pack("V*").unpack("C*") + [0, 0])
169
+ }
170
+ else
171
+ next nil
172
+ end
173
+ cache[sat] = [t_meas, eph, ch]
174
+ res
175
+ }.compact.flatten.pack("C*")
176
+ }]
177
+ }.call
178
+
87
179
  glonass_freq_ch = proc{
88
180
  freq0, delta = [:L1_frequency_base, :L1_frequency_gap].collect{|k|
89
181
  GPS_PVT::GPS::SpaceNode_GLONASS.send(k)
@@ -92,7 +184,6 @@ glonass_freq_ch = proc{
92
184
  }.call
93
185
 
94
186
  gen_raw = proc{|t_meas, meas| # Convert to RXM-RAW(0x10)
95
- meas = meas.to_hash
96
187
  ubx = [0xB5, 0x62, 0x02, 0x10, 0, 0]
97
188
  ubx += [(t_meas.seconds * 1E3).to_i, t_meas.week].pack("Vv").unpack("C*")
98
189
  ubx += [0] * 2
@@ -142,7 +233,6 @@ gen_raw = proc{|t_meas, meas| # Convert to RXM-RAW(0x10)
142
233
  }
143
234
 
144
235
  gen_rawx = proc{|t_meas, meas| # Convert to RXM-RAWX(0x15)
145
- meas = meas.to_hash
146
236
  ubx = [0xB5, 0x62, 0x02, 0x15, 0, 0]
147
237
  ubx += [t_meas.seconds, t_meas.week].pack("Ev").unpack("C*")
148
238
  ubx += [0] * 6
@@ -170,7 +260,7 @@ gen_rawx = proc{|t_meas, meas| # Convert to RXM-RAWX(0x15)
170
260
  [5, sat]
171
261
  when (0x100 + 1)..(0x100 + 32) # GLONASS
172
262
  setter.call(:L1_FREQUENCY,
173
- 39, 1, nil, proc{|v| v.replace(v[0] ? glonass_freq_ch.call(v[0]) : [7])})
263
+ 39, 1, nil, proc{|v| v.replace([(v[0] ? glonass_freq_ch.call(v[0]) : 0) + 7])} )
174
264
  [6, sat - 0x100]
175
265
  else
176
266
  next nil # TODO Galileo, Beidou, ...
@@ -185,7 +275,7 @@ gen_rawx = proc{|t_meas, meas| # Convert to RXM-RAWX(0x15)
185
275
  b = (Math::log2(v[0] / 1E-2).to_i & 0xF) rescue 0x8
186
276
  v.replace((trk_stat & 0x1 == 0x1) ? [b] : [])
187
277
  })
188
- setter.call(:L1_DOPPLER, 32, 4, "e")
278
+ setter.call(:L1_DOPPLER, 32, 4, "e") rescue next nil
189
279
  setter.call(:L1_DOPPLER_SIGMA,
190
280
  45, 1, nil, proc{|v| v.replace(v[0] ? [Math::log2(v[0] / 2E-3).to_i & 0xF] : [0x8])})
191
281
  setter.call(:L1_CARRIER_PHASE,
@@ -209,6 +299,11 @@ gen_rawx = proc{|t_meas, meas| # Convert to RXM-RAWX(0x15)
209
299
  GPS_PVT::UBX::update(ubx).pack("C*")
210
300
  }
211
301
 
212
- gen = misc_options[:ubx_rawx] ? gen_rawx : gen_raw
302
+ gen_list = []
303
+ gen_list << (misc_options[:ubx_rawx] ? gen_sfrbx : gen_sfrb) if misc_options[:broadcast_data]
304
+ gen_list << (misc_options[:ubx_rawx] ? gen_rawx : gen_raw)
213
305
  STDOUT.binmode
214
- obs.each{|*item| print gen.call(*item)}
306
+ obs.each{|t_meas, meas|
307
+ meas2 = meas.to_hash
308
+ gen_list.each{|gen| print gen.call(t_meas, meas2)}
309
+ }