gps_pvt 0.6.1 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- 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)}
|