gps_pvt 0.6.1 → 0.6.4
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/exe/to_ubx +214 -0
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +219 -514
- data/ext/ninja-scan-light/tool/algorithm/interpolate.h +106 -0
- data/ext/ninja-scan-light/tool/navigation/GLONASS.h +37 -35
- data/ext/ninja-scan-light/tool/navigation/GLONASS_Solver.h +16 -13
- data/ext/ninja-scan-light/tool/navigation/GPS.h +29 -25
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +19 -12
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +31 -11
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +21 -13
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +19 -16
- data/ext/ninja-scan-light/tool/navigation/SP3.h +28 -83
- data/ext/ninja-scan-light/tool/swig/GPS.i +33 -39
- data/gps_pvt.gemspec +3 -0
- data/lib/gps_pvt/receiver.rb +3 -3
- data/lib/gps_pvt/version.rb +5 -5
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31809928c7f846ecf08b39d9824f57d8c7e5102f9dac6b309701669ff6e4adda
|
4
|
+
data.tar.gz: 79c384577d9658337d500f4b2144365c0b65d9183115013a15b6f22729d46a57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e25c8140206b57193ba2ba699d413f5e1e1321c0e20a65d852a22bc8e3f7892c296ea1896e95e254911b4e0fbd22ff9c9d904df2c3f1d47eb4c90642a940226a
|
7
|
+
data.tar.gz: ec14caf3d7c0cadebd61eeadc4e133da2d839d9aa1aca93d50807016f26833e87e019f0609e81907c7aa44aed7816ae33ddc996923a4a2ffbedc43141e292ff1
|
data/exe/to_ubx
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'gps_pvt'
|
4
|
+
require 'uri'
|
5
|
+
require 'gps_pvt/ubx'
|
6
|
+
|
7
|
+
# Convert file(s) to ubx format
|
8
|
+
# TODO currently only RINEX observation file is supported.
|
9
|
+
|
10
|
+
$stderr.puts <<__STRING__
|
11
|
+
Usage: #{__FILE__} GPS_file ... > as_you_like.ubx
|
12
|
+
As GPS_file, only rinex_obs(*.YYo) is currently supported.
|
13
|
+
(YY = last two digit of year)
|
14
|
+
File format is automatically determined based on its extention described in above parentheses.
|
15
|
+
If you want to specify its format manually, command options like --rinex_obs=file_name are available.
|
16
|
+
Supported RINEX versions are 2 and 3.
|
17
|
+
RXM-RAWX and RXM-SFRBX are included in output UBX if corresponding file(s) is given.
|
18
|
+
A file having additional ".gz" or ".Z" extension is recognized as a compressed file.
|
19
|
+
Major URL such as http(s)://... or ftp://... is acceptable as an input file name.
|
20
|
+
__STRING__
|
21
|
+
|
22
|
+
options = []
|
23
|
+
misc_options = {
|
24
|
+
:ubx_rawx => false
|
25
|
+
}
|
26
|
+
|
27
|
+
# check options and file format
|
28
|
+
files = ARGV.collect{|arg|
|
29
|
+
next [arg, nil] unless arg =~ /^--([^=]+)=?/
|
30
|
+
k, v = [$1.downcase.to_sym, $']
|
31
|
+
next [v, k] if [:rinex_nav, :rinex_obs].include?(k) # file type
|
32
|
+
options << [$1.to_sym, $']
|
33
|
+
nil
|
34
|
+
}.compact
|
35
|
+
|
36
|
+
# Check file existence and extension
|
37
|
+
files.collect!{|fname, ftype|
|
38
|
+
ftype ||= case fname
|
39
|
+
when /\.\d{2}[nhqg](?:\.gz)?$/; :rinex_nav
|
40
|
+
when /\.\d{2}o(?:\.gz)?$/; :rinex_obs
|
41
|
+
else
|
42
|
+
raise "Format cannot be guessed, use --(format, ex. rinex_obs)=#{fname}"
|
43
|
+
end
|
44
|
+
fname = proc{
|
45
|
+
next fname if File::exist?(fname)
|
46
|
+
if uri = URI::parse(fname) and !uri.instance_of?(URI::Generic) then
|
47
|
+
next uri
|
48
|
+
end
|
49
|
+
raise "File not found: #{fname}"
|
50
|
+
}.call
|
51
|
+
[fname, ftype]
|
52
|
+
}
|
53
|
+
|
54
|
+
options.reject!{|opt|
|
55
|
+
case opt[0]
|
56
|
+
when :ubx_rawx
|
57
|
+
misc_options[opt[0]] = opt[1]
|
58
|
+
true
|
59
|
+
else
|
60
|
+
false
|
61
|
+
end
|
62
|
+
}
|
63
|
+
|
64
|
+
rcv = GPS_PVT::Receiver::new(options)
|
65
|
+
|
66
|
+
obs = []
|
67
|
+
rcv.define_singleton_method(:run){|meas, t_meas, *args|
|
68
|
+
obs << [t_meas, meas]
|
69
|
+
}
|
70
|
+
|
71
|
+
# parse RINEX NAV
|
72
|
+
files.each{|fname, ftype|
|
73
|
+
case ftype
|
74
|
+
when :rinex_nav; rcv.parse_rinex_nav(fname)
|
75
|
+
end
|
76
|
+
}
|
77
|
+
|
78
|
+
# other files
|
79
|
+
files.each{|fname, ftype|
|
80
|
+
case ftype
|
81
|
+
when :rinex_obs; rcv.parse_rinex_obs(fname){}
|
82
|
+
end
|
83
|
+
}
|
84
|
+
|
85
|
+
obs.sort!{|a, b| a[0] <=> b[0]} # Sort by measurement time
|
86
|
+
|
87
|
+
glonass_freq_ch = proc{
|
88
|
+
freq0, delta = [:L1_frequency_base, :L1_frequency_gap].collect{|k|
|
89
|
+
GPS_PVT::GPS::SpaceNode_GLONASS.send(k)
|
90
|
+
}
|
91
|
+
proc{|freq| ((freq - freq0) / delta).to_i}
|
92
|
+
}.call
|
93
|
+
|
94
|
+
gen_raw = proc{|t_meas, meas| # Convert to RXM-RAW(0x10)
|
95
|
+
meas = meas.to_hash
|
96
|
+
ubx = [0xB5, 0x62, 0x02, 0x10, 0, 0]
|
97
|
+
ubx += [(t_meas.seconds * 1E3).to_i, t_meas.week].pack("Vv").unpack("C*")
|
98
|
+
ubx += [0] * 2
|
99
|
+
meas_ubx = meas.collect{|sat, items|
|
100
|
+
res = [0] * 24
|
101
|
+
setter = proc{|value, offset, len, str, pre_proc|
|
102
|
+
array = case value
|
103
|
+
when Array; value
|
104
|
+
when Symbol
|
105
|
+
[items[GPS_PVT::GPS::Measurement.const_get(value)]]
|
106
|
+
else
|
107
|
+
next nil
|
108
|
+
end
|
109
|
+
pre_proc.call(array) if pre_proc
|
110
|
+
next if array.empty?
|
111
|
+
array = array.pack(str).unpack("C*") if str
|
112
|
+
res[offset - 8, len] = array
|
113
|
+
}
|
114
|
+
svid = case sat
|
115
|
+
when 1..32, 120..158, 193..202 # GPS, SBAS, QZSS
|
116
|
+
sat
|
117
|
+
when (0x100 + 1)..(0x100 + 32) # GLONASS
|
118
|
+
sat - 0x100 + 64 # => 65..96
|
119
|
+
else
|
120
|
+
next nil # TODO Galileo, Beidou, ...
|
121
|
+
end
|
122
|
+
|
123
|
+
qi = 6
|
124
|
+
setter.call(:L1_CARRIER_PHASE,
|
125
|
+
8, 8, "E", proc{|v| next if v[0]; qi = 4; v.clear})
|
126
|
+
setter.call(:L1_PSEUDORANGE,
|
127
|
+
16, 8, "E", proc{|v| next if v[0]; qi = 0; v.clear})
|
128
|
+
setter.call(:L1_DOPPLER,
|
129
|
+
24, 4, "e", proc{|v| next if v[0]; qi = 0; v.clear})
|
130
|
+
setter.call([svid, qi], 28, 2)
|
131
|
+
setter.call(:L1_SIGNAL_STRENGTH_dBHz,
|
132
|
+
30, 1, nil, proc{|v| v.replace(v[0] ? [v[0].to_i] : [])})
|
133
|
+
setter.call(:L1_LOCK_SEC,
|
134
|
+
31, 1, nil, proc{|v| v.replace(v[0] ? [(v[0] < 0) ? 1 : 0] : [0])})
|
135
|
+
|
136
|
+
res
|
137
|
+
}.compact
|
138
|
+
ubx[6 + 6] = meas_ubx.size
|
139
|
+
ubx += meas_ubx.flatten(1)
|
140
|
+
ubx += [0, 0]
|
141
|
+
GPS_PVT::UBX::update(ubx).pack("C*")
|
142
|
+
}
|
143
|
+
|
144
|
+
gen_rawx = proc{|t_meas, meas| # Convert to RXM-RAWX(0x15)
|
145
|
+
meas = meas.to_hash
|
146
|
+
ubx = [0xB5, 0x62, 0x02, 0x15, 0, 0]
|
147
|
+
ubx += [t_meas.seconds, t_meas.week].pack("Ev").unpack("C*")
|
148
|
+
ubx += [0] * 6
|
149
|
+
meas_ubx = meas.collect{|sat, items|
|
150
|
+
res = [0] * 32
|
151
|
+
setter = proc{|value, offset, len, str, pre_proc|
|
152
|
+
array = case value
|
153
|
+
when Array; value
|
154
|
+
when Symbol
|
155
|
+
[items[GPS_PVT::GPS::Measurement.const_get(value)]]
|
156
|
+
else
|
157
|
+
next nil
|
158
|
+
end
|
159
|
+
pre_proc.call(array) if pre_proc
|
160
|
+
next if array.empty?
|
161
|
+
array = array.pack(str).unpack("C*") if str
|
162
|
+
res[offset - 16, len] = array
|
163
|
+
}
|
164
|
+
sys, svid = case sat
|
165
|
+
when 1..32 # GPS
|
166
|
+
[0, sat]
|
167
|
+
when 120..158 # SBAS
|
168
|
+
[1, sat]
|
169
|
+
when 193..202 # QZSS
|
170
|
+
[5, sat]
|
171
|
+
when (0x100 + 1)..(0x100 + 32) # GLONASS
|
172
|
+
setter.call(:L1_FREQUENCY,
|
173
|
+
39, 1, nil, proc{|v| v.replace(v[0] ? glonass_freq_ch.call(v[0]) : [7])})
|
174
|
+
[6, sat - 0x100]
|
175
|
+
else
|
176
|
+
next nil # TODO Galileo, Beidou, ...
|
177
|
+
end
|
178
|
+
setter.call([sys, svid], 36, 2)
|
179
|
+
|
180
|
+
trk_stat = 0
|
181
|
+
setter.call(:L1_PSEUDORANGE,
|
182
|
+
16, 8, "E", proc{|v| v[0] ? (trk_stat |= 0x1) : v.clear})
|
183
|
+
setter.call(:L1_PSEUDORANGE_SIGMA,
|
184
|
+
43, 1, nil, proc{|v|
|
185
|
+
b = (Math::log2(v[0] / 1E-2).to_i & 0xF) rescue 0x8
|
186
|
+
v.replace((trk_stat & 0x1 == 0x1) ? [b] : [])
|
187
|
+
})
|
188
|
+
setter.call(:L1_DOPPLER, 32, 4, "e")
|
189
|
+
setter.call(:L1_DOPPLER_SIGMA,
|
190
|
+
45, 1, nil, proc{|v| v.replace(v[0] ? [Math::log2(v[0] / 2E-3).to_i & 0xF] : [0x8])})
|
191
|
+
setter.call(:L1_CARRIER_PHASE,
|
192
|
+
24, 8, "E", proc{|v| v[0] ? (trk_stat |= 0x2) : v.clear})
|
193
|
+
setter.call(:L1_CARRIER_PHASE_SIGMA,
|
194
|
+
44, 1, nil, proc{|v|
|
195
|
+
b = ((v[0] / 0.004).to_i & 0xF) rescue 0x8
|
196
|
+
v.replace((trk_stat & 0x2 == 0x2) ? [b] : [])
|
197
|
+
})
|
198
|
+
setter.call(:L1_SIGNAL_STRENGTH_dBHz,
|
199
|
+
42, 1, nil, proc{|v| v.replace(v[0] ? [v[0].to_i] : [])})
|
200
|
+
setter.call(:L1_LOCK_SEC,
|
201
|
+
40, 2, "v", proc{|v| v.replace(v[0] ? [(v[0] / 1E-3).to_i] : [])})
|
202
|
+
setter.call([trk_stat], 46, 1)
|
203
|
+
|
204
|
+
res
|
205
|
+
}.compact
|
206
|
+
ubx[6 + 11] = meas_ubx.size
|
207
|
+
ubx += meas_ubx.flatten(1)
|
208
|
+
ubx += [0, 0]
|
209
|
+
GPS_PVT::UBX::update(ubx).pack("C*")
|
210
|
+
}
|
211
|
+
|
212
|
+
gen = misc_options[:ubx_rawx] ? gen_rawx : gen_raw
|
213
|
+
STDOUT.binmode
|
214
|
+
obs.each{|*item| print gen.call(*item)}
|