gps_pvt 0.1.4 → 0.2.0
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.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/Rakefile +9 -4
- data/exe/gps_pvt +4 -4
- data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +5 -3
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +4229 -508
- data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +7 -5
- data/ext/ninja-scan-light/tool/navigation/GPS.h +5 -4
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +62 -15
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +6 -5
- data/ext/ninja-scan-light/tool/navigation/QZSS.h +62 -0
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +571 -113
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +2330 -0
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +329 -0
- data/ext/ninja-scan-light/tool/swig/GPS.i +197 -65
- data/lib/gps_pvt/receiver.rb +311 -132
- data/lib/gps_pvt/version.rb +1 -1
- metadata +9 -7
- data/gps_pvt.gemspec +0 -57
data/lib/gps_pvt/receiver.rb
CHANGED
@@ -7,102 +7,126 @@ require_relative 'GPS'
|
|
7
7
|
|
8
8
|
module GPS_PVT
|
9
9
|
class Receiver
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
}
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
21
|
-
pvt
|
22
|
-
|
23
|
-
|
34
|
+
labels,
|
35
|
+
proc{|pvt|
|
36
|
+
next [nil] * 5 unless pvt.position_solved?
|
37
|
+
labels.collect{|k| pvt.send(k)}
|
38
|
+
}
|
24
39
|
]
|
25
|
-
}
|
26
|
-
|
27
|
-
labels = [:g, :p, :h, :v, :t].collect{|k| "#{k}dop".to_sym}
|
28
|
-
[
|
29
|
-
labels,
|
40
|
+
}.call] + [[
|
41
|
+
[:v_north, :v_east, :v_down, :receiver_clock_error_dot_ms],
|
30
42
|
proc{|pvt|
|
31
|
-
next [nil] *
|
32
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
}
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
next ([nil] * 6) unless
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
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})"
|
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{|i|
|
77
|
+
next ([nil] * 6) unless i2 = sats.index(i)
|
78
|
+
[r[i2, 0], w[i2, i2]] +
|
79
|
+
[:azimuth, :elevation].collect{|f|
|
80
|
+
pvt.send(f)[i] / Math::PI * 180
|
81
|
+
} + [pvt.slopeH[i], pvt.slopeV[i]]
|
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]]
|
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
|
86
104
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
}.
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
105
|
+
def self.meas_items(opt = {})
|
106
|
+
opt = {
|
107
|
+
:satellites => (1..32).to_a,
|
108
|
+
}.merge(opt)
|
109
|
+
[[
|
110
|
+
opt[:satellites].collect{|prn, label|
|
111
|
+
[:L1_range, :L1_rate].collect{|str| "#{str}(#{label || prn})"}
|
112
|
+
}.flatten,
|
113
|
+
proc{|meas|
|
114
|
+
meas_hash = Hash[*(meas.collect{|prn, k, v| [[prn, k], v]}.flatten(1))]
|
115
|
+
opt[:satellites].collect{|prn|
|
116
|
+
[:L1_PSEUDORANGE, [:L1_DOPPLER, GPS::SpaceNode.L1_WaveLength]].collect{|k, sf|
|
117
|
+
meas_hash[[prn, GPS::Measurement.const_get(k)]] * (sf || 1) rescue nil
|
118
|
+
}
|
96
119
|
}
|
97
120
|
}
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
def
|
102
|
-
(
|
121
|
+
]]
|
122
|
+
end
|
123
|
+
|
124
|
+
def header
|
125
|
+
(@output[:pvt] + @output[:meas]).transpose[0].flatten.join(',')
|
103
126
|
end
|
104
127
|
|
105
128
|
attr_accessor :solver
|
129
|
+
attr_accessor :base_station
|
106
130
|
|
107
131
|
def initialize(options = {})
|
108
132
|
@solver = GPS::Solver::new
|
@@ -110,8 +134,17 @@ class Receiver
|
|
110
134
|
rel_prop[0] = 1 if rel_prop[0] > 0 # weight = 1
|
111
135
|
rel_prop
|
112
136
|
}
|
137
|
+
@debug = {}
|
138
|
+
output_options = {
|
139
|
+
:system => [[:GPS, 1..32], [:QZSS, 193..202]],
|
140
|
+
:satellites => (1..32).to_a + (193..202).to_a, # [idx, ...] or [[idx, label], ...] is acceptable
|
141
|
+
}
|
113
142
|
options = options.reject{|k, v|
|
114
143
|
case k
|
144
|
+
when :debug
|
145
|
+
v = v.split(/,/)
|
146
|
+
@debug[v[0].upcase.to_sym] = v[1..-1]
|
147
|
+
next true
|
115
148
|
when :weight
|
116
149
|
case v.to_sym
|
117
150
|
when :elevation # (same as underneath C++ library)
|
@@ -127,6 +160,77 @@ class Receiver
|
|
127
160
|
when :identical # same as default
|
128
161
|
next true
|
129
162
|
end
|
163
|
+
when :base_station
|
164
|
+
crd, sys = v.split(/ *, */).collect.with_index{|item, i|
|
165
|
+
case item
|
166
|
+
when /^([\+-]?\d+\.?\d*)([XYZNEDU]?)$/ # ex) meter[X], degree[N]
|
167
|
+
[$1.to_f, ($2 + "XY?"[i])[0]]
|
168
|
+
when /^([\+-]?\d+)_(?:(\d+)_(\d+\.?\d*)|(\d+\.?\d*))([NE])$/ # ex) deg_min_secN
|
169
|
+
[$1.to_f + ($2 || $4).to_f / 60 + ($3 || 0).to_f / 3600, $5]
|
170
|
+
else
|
171
|
+
raise "Unknown coordinate spec.: #{item}"
|
172
|
+
end
|
173
|
+
}.transpose
|
174
|
+
raise "Unknown base station: #{v}" if crd.size != 3
|
175
|
+
@base_station = case (sys = sys.join.to_sym)
|
176
|
+
when :XYZ, :XY?
|
177
|
+
Coordinate::XYZ::new(*crd)
|
178
|
+
when :NED, :ENU, :NE?, :EN? # :NE? => :NEU, :EN? => :ENU
|
179
|
+
(0..1).each{|i| crd[i] *= (Math::PI / 180)}
|
180
|
+
([:NED, :NE?].include?(sys) ?
|
181
|
+
Coordinate::LLH::new(crd[0], crd[1], crd[2] * (:NED == sys ? -1 : 1)) :
|
182
|
+
Coordinate::LLH::new(crd[1], crd[0], crd[2])).xyz
|
183
|
+
else
|
184
|
+
raise "Unknown coordinate system: #{sys}"
|
185
|
+
end
|
186
|
+
$stderr.puts "Base station (LLH): #{
|
187
|
+
llh = @base_station.llh.to_a
|
188
|
+
llh[0..1].collect{|rad| rad / Math::PI * 180} + [llh[2]]
|
189
|
+
}"
|
190
|
+
next true
|
191
|
+
when :with, :without
|
192
|
+
[v].flatten.each{|spec| # array is acceptable
|
193
|
+
sys, svid = case spec
|
194
|
+
when Integer
|
195
|
+
[nil, spec]
|
196
|
+
when /([a-zA-Z]+)(?::(-?\d+))?/
|
197
|
+
[$1.upcase.to_sym, (Integre($2) rescue nil)]
|
198
|
+
when /-?\d+/
|
199
|
+
[nil, $&.to_i]
|
200
|
+
else
|
201
|
+
next false
|
202
|
+
end
|
203
|
+
mode = if svid && (svid < 0) then
|
204
|
+
svid *= -1
|
205
|
+
(k == :with) ? :exclude : :include
|
206
|
+
else
|
207
|
+
(k == :with) ? :include : :exclude
|
208
|
+
end
|
209
|
+
if (sys == :GPS) || (sys == :QZSS) \
|
210
|
+
|| (svid && ((1..32).include?(svid) || (193..202).include?(svid))) then
|
211
|
+
[svid || ((1..32).to_a + (193..202).to_a)].flatten.each{
|
212
|
+
@solver.gps_options.send(mode, svid)
|
213
|
+
}
|
214
|
+
elsif (sys == :SBAS) || (svid && (120..158).include?(svid)) then
|
215
|
+
prns = [svid || (120..158).to_a].flatten
|
216
|
+
unless (i = output_options[:system].index{|sys, range| sys == :SBAS}) then
|
217
|
+
i = -1
|
218
|
+
output_options[:system] << [:SBAS, []]
|
219
|
+
else
|
220
|
+
output_options[:system][i].reject!{|prn| prns.include?(prn)}
|
221
|
+
end
|
222
|
+
output_options[:satellites].reject!{|prn, label| prns.include?(prn)}
|
223
|
+
if mode == :include then
|
224
|
+
output_options[:system][i][1] += prns
|
225
|
+
output_options[:satellites] += prns
|
226
|
+
end
|
227
|
+
prns.each{|prn| @solver.sbas_options.send(mode, prn)}
|
228
|
+
else
|
229
|
+
next false
|
230
|
+
end
|
231
|
+
$stderr.puts "#{mode.capitalize} satellite: #{[sys, svid].compact.join(':')}"
|
232
|
+
}
|
233
|
+
next true
|
130
234
|
end
|
131
235
|
false
|
132
236
|
}
|
@@ -135,9 +239,35 @@ class Receiver
|
|
135
239
|
opt.elevation_mask = 0.0 / 180 * Math::PI # 0 deg
|
136
240
|
opt.residual_mask = 1E4 # 10 km
|
137
241
|
}.call(@solver.gps_options)
|
242
|
+
@output = {
|
243
|
+
:pvt => Receiver::pvt_items(output_options),
|
244
|
+
:meas => Receiver::meas_items(output_options),
|
245
|
+
}
|
138
246
|
end
|
139
247
|
|
140
|
-
|
248
|
+
GPS::Measurement.class_eval{
|
249
|
+
proc{
|
250
|
+
key2sym = []
|
251
|
+
GPS::Measurement.constants.each{|k|
|
252
|
+
i = GPS::Measurement.const_get(k)
|
253
|
+
key2sym[i] = k if i.kind_of?(Integer)
|
254
|
+
}
|
255
|
+
define_method(:to_a2){
|
256
|
+
to_a.collect{|prn, k, v| [prn, key2sym[k] || k, v]}
|
257
|
+
}
|
258
|
+
define_method(:to_hash2){
|
259
|
+
Hash[*(to_hash.collect{|prn, k_v|
|
260
|
+
[prn, Hash[*(k_v.collect{|k, v| [key2sym[k] || k, v]}.flatten(1))]]
|
261
|
+
}.flatten(1))]
|
262
|
+
}
|
263
|
+
}.call
|
264
|
+
alias_method(:add_orig, :add)
|
265
|
+
define_method(:add){|prn, key, value|
|
266
|
+
add_orig(prn, key.kind_of?(Symbol) ? GPS::Measurement.const_get(key) : key, value)
|
267
|
+
}
|
268
|
+
}
|
269
|
+
|
270
|
+
def run(meas, t_meas, ref_pos = @base_station)
|
141
271
|
=begin
|
142
272
|
$stderr.puts "Measurement time: #{t_meas.to_a} (a.k.a #{"%d/%d/%d %d:%d:%d UTC"%[*t_meas.c_tm]})"
|
143
273
|
meas.to_a.collect{|prn, k, v| prn}.uniq.each{|prn|
|
@@ -148,10 +278,14 @@ class Receiver
|
|
148
278
|
|
149
279
|
#@solver.gps_space_node.update_all_ephemeris(t_meas) # internally called in the following solver.solve
|
150
280
|
pvt = @solver.solve(meas, t_meas)
|
281
|
+
pvt.define_singleton_method(:rel_ENU){
|
282
|
+
Coordinate::ENU::relative(xyz, ref_pos)
|
283
|
+
} if (ref_pos && pvt.position_solved?)
|
284
|
+
output = @output
|
151
285
|
pvt.define_singleton_method(:to_s){
|
152
|
-
(
|
286
|
+
(output[:pvt].transpose[1].collect{|task|
|
153
287
|
task.call(pvt)
|
154
|
-
} +
|
288
|
+
} + output[:meas].transpose[1].collect{|task|
|
155
289
|
task.call(meas)
|
156
290
|
}).flatten.join(',')
|
157
291
|
}
|
@@ -172,7 +306,7 @@ class Receiver
|
|
172
306
|
self.instance_variable_set(k, Hash[*(sats.zip(values).flatten(1))])
|
173
307
|
}
|
174
308
|
[:@slopeH, :@slopeV] \
|
175
|
-
.zip((self.slope_HV_enu.to_a.transpose
|
309
|
+
.zip((self.fd ? self.slope_HV_enu.to_a.transpose : [nil, nil])) \
|
176
310
|
.each{|k, values|
|
177
311
|
self.instance_variable_set(k,
|
178
312
|
Hash[*(values ? sats.zip(values).flatten(1) : [])])
|
@@ -185,30 +319,41 @@ class Receiver
|
|
185
319
|
}
|
186
320
|
|
187
321
|
proc{
|
188
|
-
eph_list = Hash[*(1..32).collect{|prn|
|
322
|
+
eph_list = Hash[*((1..32).to_a + (193..202).to_a).collect{|prn|
|
189
323
|
eph = GPS::Ephemeris::new
|
190
324
|
eph.svid = prn
|
191
325
|
[prn, eph]
|
192
326
|
}.flatten(1)]
|
193
|
-
define_method(:register_ephemeris){|t_meas, prn, bcast_data|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
327
|
+
define_method(:register_ephemeris){|t_meas, sys, prn, bcast_data|
|
328
|
+
case sys
|
329
|
+
when :GPS, :QZSS
|
330
|
+
next unless eph = eph_list[prn]
|
331
|
+
sn = @solver.gps_space_node
|
332
|
+
subframe, iodc_or_iode = eph.parse(bcast_data)
|
333
|
+
if iodc_or_iode < 0 then
|
334
|
+
begin
|
335
|
+
sn.update_iono_utc(
|
336
|
+
GPS::Ionospheric_UTC_Parameters::parse(bcast_data))
|
337
|
+
[:alpha, :beta].each{|k|
|
338
|
+
$stderr.puts "Iono #{k}: #{sn.iono_utc.send(k)}"
|
339
|
+
} if false
|
340
|
+
rescue
|
341
|
+
end
|
342
|
+
next
|
343
|
+
end
|
344
|
+
if t_meas and eph.consistent? then
|
345
|
+
eph.WN = ((t_meas.week / 1024).to_i * 1024) + (eph.WN % 1024)
|
346
|
+
sn.register_ephemeris(prn, eph)
|
347
|
+
eph.invalidate
|
348
|
+
end
|
349
|
+
when :SBAS
|
350
|
+
case @solver.sbas_space_node.decode_message(bcast_data[0..7], prn, t_meas)
|
351
|
+
when 26
|
352
|
+
['', "IGP broadcasted by PRN#{prn} @ #{Time::utc(*t_meas.c_tm)}",
|
353
|
+
@solver.sbas_space_node.ionospheric_grid_points(prn)].each{|str|
|
354
|
+
$stderr.puts str
|
355
|
+
} if @debug[:SBAS_IGP]
|
205
356
|
end
|
206
|
-
next
|
207
|
-
end
|
208
|
-
if t_meas and eph.consistent? then
|
209
|
-
eph.WN = ((t_meas.week / 1024).to_i * 1024) + (eph.WN % 1024)
|
210
|
-
sn.register_ephemeris(prn, eph)
|
211
|
-
eph.invalidate
|
212
357
|
end
|
213
358
|
}
|
214
359
|
}.call
|
@@ -222,6 +367,24 @@ class Receiver
|
|
222
367
|
|
223
368
|
after_run = b || proc{|pvt| puts pvt.to_s}
|
224
369
|
|
370
|
+
gnss_serial = proc{|svid, sys|
|
371
|
+
if sys then # new numbering
|
372
|
+
sys = [:GPS, :SBAS, :Galileo, :BeiDou, :IMES, :QZSS, :GLONASS][sys] if sys.kind_of?(Integer)
|
373
|
+
case sys
|
374
|
+
when :QZSS; svid += 192
|
375
|
+
end
|
376
|
+
else # old numbering
|
377
|
+
sys = case svid
|
378
|
+
when 1..32; :GPS
|
379
|
+
when 120..158; :SBAS
|
380
|
+
when 193..202; :QZSS
|
381
|
+
when 65..96; svid -= 64; :GLONASS
|
382
|
+
when 255; :GLONASS
|
383
|
+
end
|
384
|
+
end
|
385
|
+
[sys, svid]
|
386
|
+
}
|
387
|
+
|
225
388
|
t_meas = nil
|
226
389
|
ubx.each_packet.with_index(1){|packet, i|
|
227
390
|
$stderr.print '.' if i % 1000 == 0
|
@@ -245,11 +408,11 @@ class Receiver
|
|
245
408
|
:L1_CARRIER_PHASE => [8, 8, "E"],
|
246
409
|
:L1_SIGNAL_STRENGTH_dBHz => [30, 1, "c"],
|
247
410
|
}.each{|k, prop|
|
248
|
-
meas.add(prn,
|
411
|
+
meas.add(prn, k, loader.call(*prop))
|
249
412
|
}
|
250
413
|
# bit 0 of RINEX LLI (loss of lock indicator) shows lost lock
|
251
414
|
# between previous and current observation, which maps negative lock seconds
|
252
|
-
meas.add(prn,
|
415
|
+
meas.add(prn, :L1_LOCK_SEC,
|
253
416
|
(packet[6 + 31 + (i * 24)] & 0x01 == 0x01) ? -1 : 0)
|
254
417
|
}
|
255
418
|
after_run.call(run(meas, t_meas), [meas, t_meas])
|
@@ -266,8 +429,11 @@ class Receiver
|
|
266
429
|
v = post.call(v) if post
|
267
430
|
v
|
268
431
|
}
|
269
|
-
|
270
|
-
|
432
|
+
sys, svid = gnss_serial.call(*loader.call(36, 2).reverse)
|
433
|
+
case sys
|
434
|
+
when :GPS, :QZSS;
|
435
|
+
else; next
|
436
|
+
end
|
271
437
|
trk_stat = loader.call(46, 1)[0]
|
272
438
|
{
|
273
439
|
:L1_PSEUDORANGE => [16, 8, "E", proc{|v| (trk_stat & 0x1 == 0x1) ? v : nil}],
|
@@ -280,26 +446,28 @@ class Receiver
|
|
280
446
|
:L1_CARRIER_PHASE_SIGMA => [44, 1, nil, proc{|v|
|
281
447
|
(trk_stat & 0x2 == 0x2) ? (0.004 * (v[0] & 0xF)) : nil
|
282
448
|
}],
|
283
|
-
:L1_SIGNAL_STRENGTH_dBHz => [42, 1],
|
449
|
+
:L1_SIGNAL_STRENGTH_dBHz => [42, 1, "C"],
|
284
450
|
:L1_LOCK_SEC => [40, 2, "v", proc{|v| 1E-3 * v}],
|
285
451
|
}.each{|k, prop|
|
286
452
|
next unless v = loader.call(*prop)
|
287
|
-
meas.add(svid,
|
453
|
+
meas.add(svid, k, v)
|
288
454
|
}
|
289
455
|
}
|
290
456
|
after_run.call(run(meas, t_meas), [meas, t_meas])
|
291
457
|
when [0x02, 0x11] # RXM-SFRB
|
458
|
+
sys, svid = gnss_serial.call(packet[6 + 1])
|
292
459
|
register_ephemeris(
|
293
460
|
t_meas,
|
294
|
-
|
461
|
+
sys, svid,
|
295
462
|
packet.slice(6 + 2, 40).each_slice(4).collect{|v|
|
296
|
-
|
463
|
+
res = v.pack("C*").unpack("V")[0]
|
464
|
+
(sys == :GPS) ? ((res & 0xFFFFFF) << 6) : res
|
297
465
|
})
|
298
466
|
when [0x02, 0x13] # RXM-SFRBX
|
299
|
-
|
467
|
+
sys, svid = gnss_serial.call(packet[6 + 1], packet[6])
|
300
468
|
register_ephemeris(
|
301
469
|
t_meas,
|
302
|
-
|
470
|
+
sys, svid,
|
303
471
|
packet.slice(6 + 8, 4 * packet[6 + 4]).each_slice(4).collect{|v|
|
304
472
|
v.pack("C*").unpack("V")[0]
|
305
473
|
})
|
@@ -321,22 +489,33 @@ class Receiver
|
|
321
489
|
GPS::RINEX_Observation::read(fname){|item|
|
322
490
|
$stderr.print '.' if (count += 1) % 1000 == 0
|
323
491
|
t_meas = item[:time]
|
324
|
-
|
492
|
+
|
493
|
+
types ||= Hash[*(item[:meas_types].collect{|sys, values|
|
494
|
+
[sys, values.collect.with_index{|type_, i|
|
495
|
+
case type_
|
496
|
+
when "C1", "C1C"
|
497
|
+
[i, :L1_PSEUDORANGE]
|
498
|
+
when "L1", "L1C"
|
499
|
+
[i, :L1_CARRIER_PHASE]
|
500
|
+
when "D1", "D1C"
|
501
|
+
[i, :L1_DOPPLER]
|
502
|
+
when "S1", "S1C"
|
503
|
+
[i, :L1_SIGNAL_STRENGTH_dBHz]
|
504
|
+
else
|
505
|
+
nil
|
506
|
+
end
|
507
|
+
}.compact]
|
508
|
+
}.flatten(1))]
|
509
|
+
|
325
510
|
meas = GPS::Measurement::new
|
326
|
-
types ||= (item[:meas_types]['G'] || item[:meas_types][' ']).collect.with_index{|type_, i|
|
327
|
-
case type_
|
328
|
-
when "C1", "C1C"
|
329
|
-
[i, GPS::Measurement::L1_PSEUDORANGE]
|
330
|
-
when "D1", "D1C"
|
331
|
-
[i, GPS::Measurement::L1_DOPPLER]
|
332
|
-
else
|
333
|
-
nil
|
334
|
-
end
|
335
|
-
}.compact
|
336
511
|
item[:meas].each{|k, v|
|
337
512
|
sys, prn = k
|
338
|
-
|
339
|
-
|
513
|
+
case sys
|
514
|
+
when 'G', ' '
|
515
|
+
when 'J'; prn += 192
|
516
|
+
else; next
|
517
|
+
end
|
518
|
+
(types[sys] || []).each{|i, type_|
|
340
519
|
meas.add(prn, type_, v[i][0]) if v[i]
|
341
520
|
}
|
342
521
|
}
|
data/lib/gps_pvt/version.rb
CHANGED
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.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fenrir(M.Naruoka)
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-26 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,7 +89,6 @@ 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
|
89
|
-
- gps_pvt.gemspec
|
90
92
|
- lib/gps_pvt.rb
|
91
93
|
- lib/gps_pvt/receiver.rb
|
92
94
|
- lib/gps_pvt/ubx.rb
|
@@ -97,7 +99,7 @@ licenses: []
|
|
97
99
|
metadata:
|
98
100
|
homepage_uri: https://github.com/fenrir-naru/gps_pvt
|
99
101
|
source_code_uri: https://github.com/fenrir-naru/gps_pvt
|
100
|
-
post_install_message:
|
102
|
+
post_install_message:
|
101
103
|
rdoc_options: []
|
102
104
|
require_paths:
|
103
105
|
- lib
|
@@ -112,8 +114,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
114
|
- !ruby/object:Gem::Version
|
113
115
|
version: '0'
|
114
116
|
requirements: []
|
115
|
-
rubygems_version: 3.
|
116
|
-
signing_key:
|
117
|
+
rubygems_version: 3.0.3
|
118
|
+
signing_key:
|
117
119
|
specification_version: 4
|
118
120
|
summary: GPS position, velocity, and time (PVT) solver
|
119
121
|
test_files: []
|