gps_pvt 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|