gps_pvt 0.8.0 → 0.8.1
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/Rakefile +1 -0
- data/exe/gps_pvt +1 -17
- data/exe/to_ubx +103 -8
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +1136 -65
- data/ext/ninja-scan-light/tool/navigation/GLONASS.h +137 -9
- data/ext/ninja-scan-light/tool/navigation/GPS.h +301 -50
- data/ext/ninja-scan-light/tool/navigation/QZSS.h +48 -15
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +106 -4
- data/ext/ninja-scan-light/tool/param/bit_array.h +53 -16
- data/ext/ninja-scan-light/tool/swig/GPS.i +228 -24
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +61 -0
- data/ext/ninja-scan-light/tool/util/bit_counter.h +84 -0
- data/lib/gps_pvt/receiver/extension.rb +51 -0
- data/lib/gps_pvt/receiver.rb +13 -8
- data/lib/gps_pvt/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb3abd803cfe1b0b5199c4187fe17c2595eb603ab27e09f71b66fde11eeafce0
|
4
|
+
data.tar.gz: 351d46d74583346750aec426c087c33bc13f9e9e9adff746567e40df7eb1e39e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fb78d49675fbbcb3fcfeb80debd7ca15f351be478ed5716f94a61b23f26af7ff957ee446a5ab6c4cc2e67abf2f251cf62845a347ea3810282987da04fa9a2e8
|
7
|
+
data.tar.gz: ac74ba61920cad427d6e848f4621227d150bfe9a30a2f1465bd6d87681cfdd935e20e8e141575306b87c770b485f8dad1555766b7281980ba1f412adddff4e7c
|
data/Rakefile
CHANGED
data/exe/gps_pvt
CHANGED
@@ -92,23 +92,7 @@ files.collect!{|fname, ftype|
|
|
92
92
|
rcv = GPS_PVT::Receiver::new(options)
|
93
93
|
|
94
94
|
proc{|src|
|
95
|
-
|
96
|
-
loader = proc{|t_meas|
|
97
|
-
utc = Time::utc(*t_meas.c_tm)
|
98
|
-
y, yday = [:year, :yday].collect{|f| utc.send(f)}
|
99
|
-
uri = URI::parse(
|
100
|
-
"ftp://gssc.esa.int/gnss/data/daily/" +
|
101
|
-
"%04d/brdc/BRDC00IGS_R_%04d%03d0000_01D_MN.rnx.gz"%[y, y, yday])
|
102
|
-
rcv.parse_rinex_nav(uri)
|
103
|
-
uri
|
104
|
-
}
|
105
|
-
run_orig = rcv.method(:run)
|
106
|
-
eph_list = {}
|
107
|
-
rcv.define_singleton_method(:run){|meas, t_meas, *args|
|
108
|
-
w_d = [t_meas.week, (t_meas.seconds.to_i / 86400)]
|
109
|
-
eph_list[w_d] ||= loader.call(t_meas)
|
110
|
-
run_orig.call(meas, t_meas, *args)
|
111
|
-
}
|
95
|
+
rcv.attach_online_ephemeris(src) if src
|
112
96
|
}.call(misc_options[:online_ephemeris])
|
113
97
|
|
114
98
|
proc{
|
data/exe/to_ubx
CHANGED
@@ -21,7 +21,9 @@ __STRING__
|
|
21
21
|
|
22
22
|
options = []
|
23
23
|
misc_options = {
|
24
|
-
:
|
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]) :
|
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
|
-
|
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{
|
306
|
+
obs.each{|t_meas, meas|
|
307
|
+
meas2 = meas.to_hash
|
308
|
+
gen_list.each{|gen| print gen.call(t_meas, meas2)}
|
309
|
+
}
|