gps_pvt 0.6.0 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ae7a4026e4f061c13eda89c325a64eba31907fc358433104a8f8bb2b185be4a
4
- data.tar.gz: 2271e46713a750224bb700292552d670d7a3f483c3f6499b8fc719f686e3a88a
3
+ metadata.gz: f9ab8f442240a2b92bfcb975ec6cb72000ec7d257bf7d5f41e0765905b9fa020
4
+ data.tar.gz: 52ed9e2141f4e0bc111da34be34b28414557fd02f003c3fbff84db571135ad1a
5
5
  SHA512:
6
- metadata.gz: 69b901d4cd1b31c72423acfe0e6e2185a44c5df4b2eae7f6969e9525dec9cb807bab49fd1e1ae1e05c582b596cd0ebdbf0738d2cdbdc42fe87a4c2feb9510be5
7
- data.tar.gz: 8bec3d3eac56beb25895dcdae4ffa084acf4967ae6c9b06b5234574bcca7197cdc01937ec27ef4547013e0bdd4b3e1e5e69a8f7494d1052d4bfc0b6cd47fba06
6
+ metadata.gz: 63cc7efd29e6e576c15380bd43550b427015f57d99a545b3373ef829d496e87df799feed2b6499c2bf336619a81bb193ddd1c350990cc85ee7c52a7aadf0d264
7
+ data.tar.gz: 7911e374e8d1f33f283be0fd7a59262bd1bd2d0315d631456e37659b4729812c260f3f65495bb6de851e8ac7246f148d47129080717aeccc715cc1138e17e158
data/exe/to_ubx ADDED
@@ -0,0 +1,213 @@
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
+ obs.each{|*item| print gen.call(*item)}