gps_pvt 0.1.7 → 0.2.3

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