gps_pvt 0.1.7 → 0.2.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.
@@ -7,99 +7,125 @@ require_relative 'GPS'
7
7
 
8
8
  module GPS_PVT
9
9
  class Receiver
10
- OUTPUT_PVT_ITEMS = [[
11
- [:week, :itow_rcv, :year, :month, :mday, :hour, :min, :sec],
12
- proc{|pvt|
13
- [:week, :seconds, :c_tm].collect{|f| pvt.receiver_time.send(f)}.flatten
14
- }
15
- ]] + [[
16
- [:receiver_clock_error_meter, :longitude, :latitude, :height, :rel_E, :rel_N, :rel_U],
17
- proc{|pvt|
18
- next [nil] * 7 unless pvt.position_solved?
10
+ def self.pvt_items(opt = {})
11
+ opt = {
12
+ :system => [[:GPS, 1..32]],
13
+ :satellites => (1..32).to_a,
14
+ }.merge(opt)
15
+ [[
16
+ [:week, :itow_rcv, :year, :month, :mday, :hour, :min, :sec],
17
+ proc{|pvt|
18
+ [:week, :seconds, :c_tm].collect{|f| pvt.receiver_time.send(f)}.flatten
19
+ }
20
+ ]] + [[
21
+ [:receiver_clock_error_meter, :longitude, :latitude, :height, :rel_E, :rel_N, :rel_U],
22
+ proc{|pvt|
23
+ next [nil] * 7 unless pvt.position_solved?
24
+ [
25
+ pvt.receiver_error,
26
+ pvt.llh.lng / Math::PI * 180,
27
+ pvt.llh.lat / Math::PI * 180,
28
+ pvt.llh.alt,
29
+ ] + (pvt.rel_ENU.to_a rescue [nil] * 3)
30
+ }
31
+ ]] + [proc{
32
+ labels = [:g, :p, :h, :v, :t].collect{|k| "#{k}dop".to_sym}
19
33
  [
20
- pvt.receiver_error,
21
- pvt.llh.lng / Math::PI * 180,
22
- pvt.llh.lat / Math::PI * 180,
23
- pvt.llh.alt,
24
- ] + (pvt.rel_ENU.to_a rescue [nil] * 3)
25
- }
26
- ]] + [proc{
27
- labels = [:g, :p, :h, :v, :t].collect{|k| "#{k}dop".to_sym}
28
- [
29
- labels,
34
+ labels,
35
+ proc{|pvt|
36
+ next [nil] * 5 unless pvt.position_solved?
37
+ labels.collect{|k| pvt.send(k)}
38
+ }
39
+ ]
40
+ }.call] + [[
41
+ [:v_north, :v_east, :v_down, :receiver_clock_error_dot_ms],
30
42
  proc{|pvt|
31
- next [nil] * 5 unless pvt.position_solved?
32
- labels.collect{|k| pvt.send(k)}
43
+ next [nil] * 4 unless pvt.velocity_solved?
44
+ [:north, :east, :down].collect{|k| pvt.velocity.send(k)} \
45
+ + [pvt.receiver_error_rate]
33
46
  }
34
- ]
35
- }.call] + [[
36
- [:v_north, :v_east, :v_down, :receiver_clock_error_dot_ms],
37
- proc{|pvt|
38
- next [nil] * 4 unless pvt.velocity_solved?
39
- [:north, :east, :down].collect{|k| pvt.velocity.send(k)} \
40
- + [pvt.receiver_error_rate]
41
- }
42
- ]] + [
43
- [:used_satellites, proc{|pvt| pvt.used_satellites}],
44
- [:PRN, proc{|pvt|
45
- ("%32s"%[pvt.used_satellite_list.collect{|i|
46
- 1 << (i - 1)
47
- }.inject(0){|res, v| res | v}.to_s(2)]).scan(/.{8}/).collect{|str|
48
- str.gsub(' ', '0')
49
- }.join('_')
50
- }],
51
- ] + [[
52
- (1..32).collect{|prn|
53
- [:range_residual, :weight, :azimuth, :elevation, :slopeH, :slopeV].collect{|str| "#{str}(#{prn})"}
54
- }.flatten,
55
- proc{|pvt|
56
- next ([nil] * 6 * 32) unless pvt.position_solved?
57
- sats = pvt.used_satellite_list
58
- r, w = [:delta_r, :W].collect{|f| pvt.send(f)}
59
- (1..32).collect{|i|
60
- next ([nil] * 6) unless i2 = sats.index(i)
61
- [r[i2, 0], w[i2, i2]] +
62
- [:azimuth, :elevation].collect{|f|
63
- pvt.send(f)[i] / Math::PI * 180
64
- } + [pvt.slopeH[i], pvt.slopeV[i]]
65
- }.flatten
66
- },
67
- ]] + [[
68
- [:wssr, :wssr_sf, :weight_max,
69
- :slopeH_max, :slopeH_max_PRN, :slopeH_max_elevation,
70
- :slopeV_max, :slopeV_max_PRN, :slopeV_max_elevation],
71
- proc{|pvt|
72
- next [nil] * 9 unless fd = pvt.fd
73
- el_deg = [4, 6].collect{|i| pvt.elevation[fd[i]] / Math::PI * 180}
74
- fd[0..4] + [el_deg[0]] + fd[5..6] + [el_deg[1]]
75
- }
76
- ]] + [[
77
- [:wssr_FDE_min, :wssr_FDE_min_PRN, :wssr_FDE_2nd, :wssr_FDE_2nd_PRN],
78
- proc{|pvt|
79
- [:fde_min, :fde_2nd].collect{|f|
80
- info = pvt.send(f)
81
- next ([nil] * 2) if (!info) || info.empty?
82
- [info[0], info[-3]]
83
- }.flatten
84
- }
85
- ]]
86
-
87
- OUTPUT_MEAS_ITEMS = [[
88
- (1..32).collect{|prn|
89
- [:L1_range, :L1_rate].collect{|str| "#{str}(#{prn})"}
90
- }.flatten,
91
- proc{|meas|
92
- meas_hash = Hash[*(meas.collect{|prn, k, v| [[prn, k], v]}.flatten(1))]
93
- (1..32).collect{|prn|
94
- [:L1_PSEUDORANGE, [:L1_DOPPLER, GPS::SpaceNode.L1_WaveLength]].collect{|k, sf|
95
- meas_hash[[prn, GPS::Measurement.const_get(k)]] * (sf || 1) rescue nil
47
+ ]] + [
48
+ [:used_satellites, proc{|pvt| pvt.used_satellites}],
49
+ ] + opt[:system].collect{|sys, range|
50
+ bit_flip = if range.kind_of?(Array) then
51
+ proc{|res, i|
52
+ res[i] = "1" if i = range.index(i)
53
+ res
54
+ }
55
+ else # expect Range
56
+ base_prn = range.min
57
+ proc{|res, i|
58
+ res[i - base_prn] = "1" if range.include?(i)
59
+ res
60
+ }
61
+ end
62
+ ["#{sys}_PRN", proc{|pvt|
63
+ pvt.used_satellite_list.inject("0" * range.size, &bit_flip) \
64
+ .scan(/.{1,8}/).join('_').reverse
65
+ }]
66
+ } + [[
67
+ opt[:satellites].collect{|prn, label|
68
+ [:range_residual, :weight, :azimuth, :elevation, :slopeH, :slopeV].collect{|str|
69
+ "#{str}(#{label || prn})"
96
70
  }
71
+ }.flatten,
72
+ proc{|pvt|
73
+ next ([nil] * 6 * opt[:satellites].size) unless pvt.position_solved?
74
+ sats = pvt.used_satellite_list
75
+ r, w = [:delta_r, :W].collect{|f| pvt.send(f)}
76
+ opt[:satellites].collect{|prn, label|
77
+ next ([nil] * 6) unless i2 = sats.index(prn)
78
+ [r[i2, 0], w[i2, i2]] +
79
+ [:azimuth, :elevation].collect{|f|
80
+ pvt.send(f)[prn] / Math::PI * 180
81
+ } + [pvt.slopeH[prn], pvt.slopeV[prn]]
82
+ }.flatten
83
+ },
84
+ ]] + [[
85
+ [:wssr, :wssr_sf, :weight_max,
86
+ :slopeH_max, :slopeH_max_PRN, :slopeH_max_elevation,
87
+ :slopeV_max, :slopeV_max_PRN, :slopeV_max_elevation],
88
+ proc{|pvt|
89
+ next [nil] * 9 unless fd = pvt.fd
90
+ el_deg = [4, 6].collect{|i| pvt.elevation[fd[i]] / Math::PI * 180}
91
+ fd[0..4] + [el_deg[0]] + fd[5..6] + [el_deg[1]]
97
92
  }
93
+ ]] + [[
94
+ [:wssr_FDE_min, :wssr_FDE_min_PRN, :wssr_FDE_2nd, :wssr_FDE_2nd_PRN],
95
+ proc{|pvt|
96
+ [:fde_min, :fde_2nd].collect{|f|
97
+ info = pvt.send(f)
98
+ next ([nil] * 2) if (!info) || info.empty?
99
+ [info[0], info[-3]]
100
+ }.flatten
101
+ }
102
+ ]]
103
+ end
104
+
105
+ def self.meas_items(opt = {})
106
+ opt = {
107
+ :satellites => (1..32).to_a,
108
+ }.merge(opt)
109
+ keys = [:PSEUDORANGE, :RANGE_RATE, :DOPPLER, :FREQUENCY].collect{|k|
110
+ GPS::Measurement.const_get("L1_#{k}".to_sym)
98
111
  }
99
- ]]
100
-
101
- def self.header
102
- (OUTPUT_PVT_ITEMS + OUTPUT_MEAS_ITEMS).transpose[0].flatten.join(',')
112
+ [[
113
+ opt[:satellites].collect{|prn, label|
114
+ [:L1_range, :L1_rate].collect{|str| "#{str}(#{label || prn})"}
115
+ }.flatten,
116
+ proc{|meas|
117
+ meas_hash = meas.to_hash
118
+ opt[:satellites].collect{|prn, label|
119
+ pr, rate, doppler, freq = keys.collect{|k| meas_hash[prn][k] rescue nil}
120
+ freq ||= GPS::SpaceNode.L1_Frequency
121
+ [pr, rate || ((doppler * GPS::SpaceNode::light_speed / freq) rescue nil)]
122
+ }
123
+ }
124
+ ]]
125
+ end
126
+
127
+ def header
128
+ (@output[:pvt] + @output[:meas]).transpose[0].flatten.join(',')
103
129
  end
104
130
 
105
131
  attr_accessor :solver
@@ -107,16 +133,30 @@ class Receiver
107
133
 
108
134
  def initialize(options = {})
109
135
  @solver = GPS::Solver::new
110
- @solver.hooks[:relative_property] = proc{|prn, rel_prop, rcv_e, t_arv, usr_pos, usr_vel|
136
+ @solver.hooks[:relative_property] = proc{|prn, rel_prop, meas, rcv_e, t_arv, usr_pos, usr_vel|
111
137
  rel_prop[0] = 1 if rel_prop[0] > 0 # weight = 1
112
138
  rel_prop
113
139
  }
140
+ @debug = {}
141
+ [:gps_options, :sbas_options].each{|target|
142
+ opt = @solver.send(target) # default solver options
143
+ opt.elevation_mask = 0.0 / 180 * Math::PI # 0 deg (use satellite over horizon)
144
+ opt.residual_mask = 1E4 # 10 km (without residual filter, practically)
145
+ }
146
+ output_options = {
147
+ :system => [[:GPS, 1..32], [:QZSS, 193..202]],
148
+ :satellites => (1..32).to_a + (193..202).to_a, # [idx, ...] or [[idx, label], ...] is acceptable
149
+ }
114
150
  options = options.reject{|k, v|
115
151
  case k
152
+ when :debug
153
+ v = v.split(/,/)
154
+ @debug[v[0].upcase.to_sym] = v[1..-1]
155
+ next true
116
156
  when :weight
117
157
  case v.to_sym
118
158
  when :elevation # (same as underneath C++ library)
119
- @solver.hooks[:relative_property] = proc{|prn, rel_prop, rcv_e, t_arv, usr_pos, usr_vel|
159
+ @solver.hooks[:relative_property] = proc{|prn, rel_prop, meas, rcv_e, t_arv, usr_pos, usr_vel|
120
160
  if rel_prop[0] > 0 then
121
161
  elv = Coordinate::ENU::relative_rel(
122
162
  Coordinate::XYZ::new(*rel_prop[4..6]), usr_pos).elevation
@@ -156,14 +196,65 @@ class Receiver
156
196
  llh[0..1].collect{|rad| rad / Math::PI * 180} + [llh[2]]
157
197
  }"
158
198
  next true
199
+ when :with, :without
200
+ [v].flatten.each{|spec| # array is acceptable
201
+ sys, svid = case spec
202
+ when Integer
203
+ [nil, spec]
204
+ when /^([a-zA-Z]+)(?::(-?\d+))?$/
205
+ [$1.upcase.to_sym, (Integer($2) rescue nil)]
206
+ when /^-?\d+$/
207
+ [nil, $&.to_i]
208
+ else
209
+ next false
210
+ end
211
+ mode = if svid && (svid < 0) then
212
+ svid *= -1
213
+ (k == :with) ? :exclude : :include
214
+ else
215
+ (k == :with) ? :include : :exclude
216
+ end
217
+ update_output = proc{|sys_target, prns, labels|
218
+ unless (i = output_options[:system].index{|sys, range| sys == sys_target}) then
219
+ i = -1
220
+ output_options[:system] << [sys_target, []]
221
+ else
222
+ output_options[:system][i].reject!{|prn| prns.include?(prn)}
223
+ end
224
+ output_options[:satellites].reject!{|prn, label| prns.include?(prn)}
225
+ if mode == :include then
226
+ output_options[:system][i][1] += prns
227
+ output_options[:satellites] += (labels ? prns.zip(labels) : prns)
228
+ end
229
+ }
230
+ check_sys_svid = proc{|sys_target, range_in_sys, offset|
231
+ next range_in_sys.include?(svid - (offset || 0)) unless sys # svid is specified without system
232
+ next false unless sys == sys_target
233
+ next true unless svid # All satellites in a target system (svid == nil)
234
+ range_in_sys.include?(svid)
235
+ }
236
+ if check_sys_svid.call(:GPS, 1..32) then
237
+ [svid || (1..32).to_a].flatten.each{|prn| @solver.gps_options.send(mode, prn)}
238
+ elsif check_sys_svid.call(:SBAS, 120..158) then
239
+ prns = [svid || (120..158).to_a].flatten
240
+ update_output.call(:SBAS, prns)
241
+ prns.each{|prn| @solver.sbas_options.send(mode, prn)}
242
+ elsif check_sys_svid.call(:QZSS, 193..202) then
243
+ [svid || (193..202).to_a].flatten.each{|prn| @solver.gps_options.send(mode, prn)}
244
+ else
245
+ raise "Unknown satellite: #{spec}"
246
+ end
247
+ $stderr.puts "#{mode.capitalize} satellite: #{[sys, svid].compact.join(':')}"
248
+ }
249
+ next true
159
250
  end
160
251
  false
161
252
  }
162
253
  raise "Unknown receiver options: #{options.inspect}" unless options.empty?
163
- proc{|opt|
164
- opt.elevation_mask = 0.0 / 180 * Math::PI # 0 deg
165
- opt.residual_mask = 1E4 # 10 km
166
- }.call(@solver.gps_options)
254
+ @output = {
255
+ :pvt => Receiver::pvt_items(output_options),
256
+ :meas => Receiver::meas_items(output_options),
257
+ }
167
258
  end
168
259
 
169
260
  GPS::Measurement.class_eval{
@@ -202,10 +293,11 @@ class Receiver
202
293
  pvt.define_singleton_method(:rel_ENU){
203
294
  Coordinate::ENU::relative(xyz, ref_pos)
204
295
  } if (ref_pos && pvt.position_solved?)
296
+ output = @output
205
297
  pvt.define_singleton_method(:to_s){
206
- (OUTPUT_PVT_ITEMS.transpose[1].collect{|task|
298
+ (output[:pvt].transpose[1].collect{|task|
207
299
  task.call(pvt)
208
- } + OUTPUT_MEAS_ITEMS.transpose[1].collect{|task|
300
+ } + output[:meas].transpose[1].collect{|task|
209
301
  task.call(meas)
210
302
  }).flatten.join(',')
211
303
  }
@@ -226,7 +318,7 @@ class Receiver
226
318
  self.instance_variable_set(k, Hash[*(sats.zip(values).flatten(1))])
227
319
  }
228
320
  [:@slopeH, :@slopeV] \
229
- .zip((self.slope_HV_enu.to_a.transpose rescue [nil, nil])) \
321
+ .zip((self.fd ? self.slope_HV_enu.to_a.transpose : [nil, nil])) \
230
322
  .each{|k, values|
231
323
  self.instance_variable_set(k,
232
324
  Hash[*(values ? sats.zip(values).flatten(1) : [])])
@@ -239,30 +331,41 @@ class Receiver
239
331
  }
240
332
 
241
333
  proc{
242
- eph_list = Hash[*(1..32).collect{|prn|
334
+ eph_list = Hash[*((1..32).to_a + (193..202).to_a).collect{|prn|
243
335
  eph = GPS::Ephemeris::new
244
336
  eph.svid = prn
245
337
  [prn, eph]
246
338
  }.flatten(1)]
247
- define_method(:register_ephemeris){|t_meas, prn, bcast_data|
248
- next unless eph = eph_list[prn]
249
- sn = @solver.gps_space_node
250
- subframe, iodc_or_iode = eph.parse(bcast_data)
251
- if iodc_or_iode < 0 then
252
- begin
253
- sn.update_iono_utc(
254
- GPS::Ionospheric_UTC_Parameters::parse(bcast_data))
255
- [:alpha, :beta].each{|k|
256
- $stderr.puts "Iono #{k}: #{sn.iono_utc.send(k)}"
257
- } if false
258
- rescue
339
+ define_method(:register_ephemeris){|t_meas, sys, prn, bcast_data|
340
+ case sys
341
+ when :GPS, :QZSS
342
+ next unless eph = eph_list[prn]
343
+ sn = @solver.gps_space_node
344
+ subframe, iodc_or_iode = eph.parse(bcast_data)
345
+ if iodc_or_iode < 0 then
346
+ begin
347
+ sn.update_iono_utc(
348
+ GPS::Ionospheric_UTC_Parameters::parse(bcast_data))
349
+ [:alpha, :beta].each{|k|
350
+ $stderr.puts "Iono #{k}: #{sn.iono_utc.send(k)}"
351
+ } if false
352
+ rescue
353
+ end
354
+ next
355
+ end
356
+ if t_meas and eph.consistent? then
357
+ eph.WN = ((t_meas.week / 1024).to_i * 1024) + (eph.WN % 1024)
358
+ sn.register_ephemeris(prn, eph)
359
+ eph.invalidate
360
+ end
361
+ when :SBAS
362
+ case @solver.sbas_space_node.decode_message(bcast_data[0..7], prn, t_meas)
363
+ when 26
364
+ ['', "IGP broadcasted by PRN#{prn} @ #{Time::utc(*t_meas.c_tm)}",
365
+ @solver.sbas_space_node.ionospheric_grid_points(prn)].each{|str|
366
+ $stderr.puts str
367
+ } if @debug[:SBAS_IGP]
259
368
  end
260
- next
261
- end
262
- if t_meas and eph.consistent? then
263
- eph.WN = ((t_meas.week / 1024).to_i * 1024) + (eph.WN % 1024)
264
- sn.register_ephemeris(prn, eph)
265
- eph.invalidate
266
369
  end
267
370
  }
268
371
  }.call
@@ -276,6 +379,24 @@ class Receiver
276
379
 
277
380
  after_run = b || proc{|pvt| puts pvt.to_s}
278
381
 
382
+ gnss_serial = proc{|svid, sys|
383
+ if sys then # new numbering
384
+ sys = [:GPS, :SBAS, :Galileo, :BeiDou, :IMES, :QZSS, :GLONASS][sys] if sys.kind_of?(Integer)
385
+ case sys
386
+ when :QZSS; svid += 192
387
+ end
388
+ else # old numbering
389
+ sys = case svid
390
+ when 1..32; :GPS
391
+ when 120..158; :SBAS
392
+ when 193..202; :QZSS
393
+ when 65..96; svid -= 64; :GLONASS
394
+ when 255; :GLONASS
395
+ end
396
+ end
397
+ [sys, svid]
398
+ }
399
+
279
400
  t_meas = nil
280
401
  ubx.each_packet.with_index(1){|packet, i|
281
402
  $stderr.print '.' if i % 1000 == 0
@@ -320,8 +441,11 @@ class Receiver
320
441
  v = post.call(v) if post
321
442
  v
322
443
  }
323
- next unless (gnss = loader.call(36, 1)[0]) == 0
324
- svid = loader.call(37, 1)[0]
444
+ sys, svid = gnss_serial.call(*loader.call(36, 2).reverse)
445
+ case sys
446
+ when :GPS, :QZSS;
447
+ else; next
448
+ end
325
449
  trk_stat = loader.call(46, 1)[0]
326
450
  {
327
451
  :L1_PSEUDORANGE => [16, 8, "E", proc{|v| (trk_stat & 0x1 == 0x1) ? v : nil}],
@@ -343,17 +467,19 @@ class Receiver
343
467
  }
344
468
  after_run.call(run(meas, t_meas), [meas, t_meas])
345
469
  when [0x02, 0x11] # RXM-SFRB
470
+ sys, svid = gnss_serial.call(packet[6 + 1])
346
471
  register_ephemeris(
347
472
  t_meas,
348
- packet[6 + 1],
473
+ sys, svid,
349
474
  packet.slice(6 + 2, 40).each_slice(4).collect{|v|
350
- (v.pack("C*").unpack("V")[0] & 0xFFFFFF) << 6
475
+ res = v.pack("C*").unpack("V")[0]
476
+ (sys == :GPS) ? ((res & 0xFFFFFF) << 6) : res
351
477
  })
352
478
  when [0x02, 0x13] # RXM-SFRBX
353
- next unless (gnss = packet[6]) == 0
479
+ sys, svid = gnss_serial.call(packet[6 + 1], packet[6])
354
480
  register_ephemeris(
355
481
  t_meas,
356
- packet[6 + 1],
482
+ sys, svid,
357
483
  packet.slice(6 + 8, 4 * packet[6 + 4]).each_slice(4).collect{|v|
358
484
  v.pack("C*").unpack("V")[0]
359
485
  })
@@ -363,8 +489,15 @@ class Receiver
363
489
  end
364
490
 
365
491
  def parse_rinex_nav(fname)
366
- $stderr.puts "Read RINEX NAV file (%s): %d items."%[
367
- fname, @solver.gps_space_node.read(fname)]
492
+ items = [
493
+ @solver.gps_space_node,
494
+ @solver.sbas_space_node,
495
+ ].inject(0){|res, sn|
496
+ loaded_items = sn.send(:read, fname)
497
+ raise "Format error! (Not RINEX) #{fname}" if loaded_items < 0
498
+ res + loaded_items
499
+ }
500
+ $stderr.puts "Read RINEX NAV file (%s): %d items."%[fname, items]
368
501
  end
369
502
 
370
503
  def parse_rinex_obs(fname, &b)
@@ -375,26 +508,34 @@ class Receiver
375
508
  GPS::RINEX_Observation::read(fname){|item|
376
509
  $stderr.print '.' if (count += 1) % 1000 == 0
377
510
  t_meas = item[:time]
378
-
511
+
512
+ types ||= Hash[*(item[:meas_types].collect{|sys, values|
513
+ [sys, values.collect.with_index{|type_, i|
514
+ case type_
515
+ when "C1", "C1C"
516
+ [i, :L1_PSEUDORANGE]
517
+ when "L1", "L1C"
518
+ [i, :L1_CARRIER_PHASE]
519
+ when "D1", "D1C"
520
+ [i, :L1_DOPPLER]
521
+ when "S1", "S1C"
522
+ [i, :L1_SIGNAL_STRENGTH_dBHz]
523
+ else
524
+ nil
525
+ end
526
+ }.compact]
527
+ }.flatten(1))]
528
+
379
529
  meas = GPS::Measurement::new
380
- types ||= (item[:meas_types]['G'] || item[:meas_types][' ']).collect.with_index{|type_, i|
381
- case type_
382
- when "C1", "C1C"
383
- [i, :L1_PSEUDORANGE]
384
- when "L1", "L1C"
385
- [i, :L1_CARRIER_PHASE]
386
- when "D1", "D1C"
387
- [i, :L1_DOPPLER]
388
- when "S1", "S1C"
389
- [i, :L1_SIGNAL_STRENGTH_dBHz]
390
- else
391
- nil
392
- end
393
- }.compact
394
530
  item[:meas].each{|k, v|
395
531
  sys, prn = k
396
- next unless sys == 'G' # GPS only
397
- types.each{|i, type_|
532
+ case sys
533
+ when 'G', ' '
534
+ when 'J'; prn += 192
535
+ else; next
536
+ end
537
+ types[sys] = (types[' '] || []) unless types[sys]
538
+ types[sys].each{|i, type_|
398
539
  meas.add(prn, type_, v[i][0]) if v[i]
399
540
  }
400
541
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GPS_PVT
4
- VERSION = "0.1.7"
4
+ VERSION = "0.2.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.1.7
4
+ version: 0.2.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-01-14 00:00:00.000000000 Z
11
+ date: 2022-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -69,7 +69,10 @@ files:
69
69
  - ext/ninja-scan-light/tool/navigation/GPS_Solver_RAIM.h
70
70
  - ext/ninja-scan-light/tool/navigation/MagneticField.h
71
71
  - ext/ninja-scan-light/tool/navigation/NTCM.h
72
+ - ext/ninja-scan-light/tool/navigation/QZSS.h
72
73
  - ext/ninja-scan-light/tool/navigation/RINEX.h
74
+ - ext/ninja-scan-light/tool/navigation/SBAS.h
75
+ - ext/ninja-scan-light/tool/navigation/SBAS_Solver.h
73
76
  - ext/ninja-scan-light/tool/navigation/WGS84.h
74
77
  - ext/ninja-scan-light/tool/navigation/coordinate.h
75
78
  - ext/ninja-scan-light/tool/param/bit_array.h
@@ -86,6 +89,7 @@ files:
86
89
  - ext/ninja-scan-light/tool/swig/makefile
87
90
  - ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb
88
91
  - ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb
92
+ - gps_pvt.gemspec
89
93
  - lib/gps_pvt.rb
90
94
  - lib/gps_pvt/receiver.rb
91
95
  - lib/gps_pvt/ubx.rb
@@ -111,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
115
  - !ruby/object:Gem::Version
112
116
  version: '0'
113
117
  requirements: []
114
- rubygems_version: 3.0.3
118
+ rubygems_version: 3.3.7
115
119
  signing_key:
116
120
  specification_version: 4
117
121
  summary: GPS position, velocity, and time (PVT) solver