gps_pvt 0.7.2 → 0.8.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 +1 -1
- data/exe/gps_pvt +2 -1
- data/gps_pvt.gemspec +1 -0
- data/lib/gps_pvt/receiver.rb +66 -48
- data/lib/gps_pvt/util.rb +33 -1
- data/lib/gps_pvt/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5bccc645ba148e24c0d8b43c1663ed245a6306eedfd376bdccf0f817977d5964
|
4
|
+
data.tar.gz: 13b461cf2ce59b7064f4c69f13969f3e758974ae6dd331bf3628a901f76b3762
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cebbb365561e4a2a56cadde92d69f03490313d56baa33ed5e14749220385a85813ee91cbdb93cb3980f66d69d95e1a63fb2852fb8441992767b64e7a80558ec5
|
7
|
+
data.tar.gz: 251feae90231587a9e1c720ab20675084573b6ef1fc50429ad04223a1ad269eccc16d0e79cb7f4ffa547be95c1129a83e12e3edb5dc1495d20245cb1afc39693
|
data/README.md
CHANGED
@@ -32,7 +32,7 @@ An attached executable is useful. After installation, type
|
|
32
32
|
|
33
33
|
$ gps_pvt file_or_URI(s)
|
34
34
|
|
35
|
-
The format of file is automatically determined with its extension, such as .ubx will be treated as UBX format. A compressed file of .gz or .Z can be specified directly (decompression is internally performed)
|
35
|
+
The format of file is automatically determined with its extension, such as .ubx will be treated as UBX format. A compressed file of .gz or .Z can be specified directly (decompression is internally performed). URI such as http(s)://... and ftp://, and serial port (COMn for Windows and /dev/tty* for *NIX, version >= 0.8.0) are also acceptable. If you want to specify the file format, instead of file_or_URI(s), use the following arguments:
|
36
36
|
|
37
37
|
| specification | recoginized as |
|
38
38
|
----|----
|
data/exe/gps_pvt
CHANGED
@@ -14,7 +14,7 @@ If you want to specify its format manually, command options like --rinex_nav=fil
|
|
14
14
|
Other than --rinex_nav, --rinex_obs, -rinex_clk, --ubx, --sp3 or --antex are supported.
|
15
15
|
Supported RINEX versions are 2 and 3.
|
16
16
|
A file having additional ".gz" or ".Z" extension is recognized as a compressed file.
|
17
|
-
Major URL such as http(s)://... or ftp
|
17
|
+
Major URL such as http(s)://... or ftp://..., and serial port (COMn for Windows, /dev/tty* for *NIX) is acceptable as an input file name.
|
18
18
|
__STRING__
|
19
19
|
|
20
20
|
options = []
|
@@ -80,6 +80,7 @@ files.collect!{|fname, ftype|
|
|
80
80
|
end
|
81
81
|
fname = proc{
|
82
82
|
next fname if File::exist?(fname)
|
83
|
+
next fname if ((fname =~ Serial::SPEC) rescue false)
|
83
84
|
if uri = URI::parse(fname) and !uri.instance_of?(URI::Generic) then
|
84
85
|
next uri
|
85
86
|
end
|
data/gps_pvt.gemspec
CHANGED
@@ -58,6 +58,7 @@ Gem::Specification.new do |spec|
|
|
58
58
|
|
59
59
|
# Uncomment to register a new dependency of your gem
|
60
60
|
# spec.add_dependency "example-gem", "~> 1.0"
|
61
|
+
spec.add_dependency "rubyserial"
|
61
62
|
spec.add_development_dependency "rake"
|
62
63
|
spec.add_development_dependency "rake-compiler"
|
63
64
|
|
data/lib/gps_pvt/receiver.rb
CHANGED
@@ -154,6 +154,7 @@ class Receiver
|
|
154
154
|
:skip_exclusion => true, # default is to skip fault exclusion calculation
|
155
155
|
}
|
156
156
|
@debug = {}
|
157
|
+
@semaphore = Mutex::new
|
157
158
|
solver_opts = [:gps_options, :sbas_options, :glonass_options].collect{|target|
|
158
159
|
@solver.send(target)
|
159
160
|
}
|
@@ -298,6 +299,24 @@ class Receiver
|
|
298
299
|
:meas => Receiver::meas_items(output_options),
|
299
300
|
}
|
300
301
|
end
|
302
|
+
|
303
|
+
def critical(&b)
|
304
|
+
begin
|
305
|
+
@semaphore.synchronize{b.call}
|
306
|
+
rescue ThreadError # recovery from deadlock
|
307
|
+
b.call
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
class << self
|
312
|
+
def make_critical(fname)
|
313
|
+
f_orig = instance_method(fname)
|
314
|
+
define_method(fname){|*args, &b|
|
315
|
+
critical{f_orig.bind(self).call(*args, &b)}
|
316
|
+
}
|
317
|
+
end
|
318
|
+
private :make_critical
|
319
|
+
end
|
301
320
|
|
302
321
|
GPS::Measurement.class_eval{
|
303
322
|
proc{
|
@@ -331,7 +350,7 @@ class Receiver
|
|
331
350
|
=end
|
332
351
|
|
333
352
|
#@solver.gps_space_node.update_all_ephemeris(t_meas) # internally called in the following solver.solve
|
334
|
-
pvt = @solver.solve(meas, t_meas)
|
353
|
+
pvt = critical{@solver.solve(meas, t_meas)}
|
335
354
|
pvt.define_singleton_method(:rel_ENU){
|
336
355
|
Coordinate::ENU::relative(xyz, ref_pos)
|
337
356
|
} if (ref_pos && pvt.position_solved?)
|
@@ -378,60 +397,59 @@ class Receiver
|
|
378
397
|
}
|
379
398
|
}
|
380
399
|
|
381
|
-
|
382
|
-
eph_list
|
400
|
+
def register_ephemeris(t_meas, sys, prn, bcast_data, *options)
|
401
|
+
@eph_list ||= Hash[*((1..32).to_a + (193..202).to_a).collect{|prn|
|
383
402
|
eph = GPS::Ephemeris::new
|
384
403
|
eph.svid = prn
|
385
404
|
[prn, eph]
|
386
405
|
}.flatten(1)]
|
387
|
-
eph_glonass_list
|
406
|
+
@eph_glonass_list ||= Hash[*(1..24).collect{|num|
|
388
407
|
eph = GPS::Ephemeris_GLONASS::new
|
389
408
|
eph.svid = num
|
390
409
|
[num, eph]
|
391
410
|
}.flatten(1)]
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
rescue
|
407
|
-
end
|
408
|
-
next
|
409
|
-
end
|
410
|
-
if t_meas and eph.consistent? then
|
411
|
-
eph.WN = ((t_meas.week / 1024).to_i * 1024) + (eph.WN % 1024)
|
412
|
-
sn.register_ephemeris(prn, eph)
|
413
|
-
eph.invalidate
|
411
|
+
opt = options[0] || {}
|
412
|
+
case sys
|
413
|
+
when :GPS, :QZSS
|
414
|
+
return unless eph = @eph_list[prn]
|
415
|
+
sn = @solver.gps_space_node
|
416
|
+
subframe, iodc_or_iode = eph.parse(bcast_data)
|
417
|
+
if iodc_or_iode < 0 then
|
418
|
+
begin
|
419
|
+
sn.update_iono_utc(
|
420
|
+
GPS::Ionospheric_UTC_Parameters::parse(bcast_data))
|
421
|
+
[:alpha, :beta].each{|k|
|
422
|
+
$stderr.puts "Iono #{k}: #{sn.iono_utc.send(k)}"
|
423
|
+
} if false
|
424
|
+
rescue
|
414
425
|
end
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
$stderr.puts str
|
421
|
-
} if @debug[:SBAS_IGP]
|
422
|
-
end if t_meas
|
423
|
-
when :GLONASS
|
424
|
-
next unless eph = eph_glonass_list[prn]
|
425
|
-
leap_sec = @solver.gps_space_node.is_valid_utc ?
|
426
|
-
@solver.gps_space_node.iono_utc.delta_t_LS :
|
427
|
-
GPS::Time::guess_leap_seconds(t_meas)
|
428
|
-
next unless eph.parse(bcast_data[0..3], leap_sec)
|
429
|
-
eph.freq_ch = opt[:freq_ch] || 0
|
430
|
-
@solver.glonass_space_node.register_ephemeris(prn, eph)
|
426
|
+
return
|
427
|
+
end
|
428
|
+
if t_meas and eph.consistent? then
|
429
|
+
eph.WN = ((t_meas.week / 1024).to_i * 1024) + (eph.WN % 1024)
|
430
|
+
sn.register_ephemeris(prn, eph)
|
431
431
|
eph.invalidate
|
432
432
|
end
|
433
|
-
|
434
|
-
|
433
|
+
when :SBAS
|
434
|
+
case @solver.sbas_space_node.decode_message(bcast_data[0..7], prn, t_meas)
|
435
|
+
when 26
|
436
|
+
['', "IGP broadcasted by PRN#{prn} @ #{Time::utc(*t_meas.c_tm)}",
|
437
|
+
@solver.sbas_space_node.ionospheric_grid_points(prn)].each{|str|
|
438
|
+
$stderr.puts str
|
439
|
+
} if @debug[:SBAS_IGP]
|
440
|
+
end if t_meas
|
441
|
+
when :GLONASS
|
442
|
+
return unless eph = @eph_glonass_list[prn]
|
443
|
+
leap_sec = @solver.gps_space_node.is_valid_utc ?
|
444
|
+
@solver.gps_space_node.iono_utc.delta_t_LS :
|
445
|
+
GPS::Time::guess_leap_seconds(t_meas)
|
446
|
+
return unless eph.parse(bcast_data[0..3], leap_sec)
|
447
|
+
eph.freq_ch = opt[:freq_ch] || 0
|
448
|
+
@solver.glonass_space_node.register_ephemeris(prn, eph)
|
449
|
+
eph.invalidate
|
450
|
+
end
|
451
|
+
end
|
452
|
+
make_critical :register_ephemeris
|
435
453
|
|
436
454
|
def parse_ubx(ubx_fname, &b)
|
437
455
|
$stderr.print "Reading UBX file (%s) "%[ubx_fname]
|
@@ -564,7 +582,7 @@ class Receiver
|
|
564
582
|
@solver.sbas_space_node,
|
565
583
|
@solver.glonass_space_node,
|
566
584
|
].inject(0){|res, sn|
|
567
|
-
loaded_items = sn.send(:read, fname)
|
585
|
+
loaded_items = critical{sn.send(:read, fname)}
|
568
586
|
raise "Format error! (Not RINEX) #{src}" if loaded_items < 0
|
569
587
|
res + loaded_items
|
570
588
|
}
|
@@ -648,7 +666,7 @@ class Receiver
|
|
648
666
|
next unless /^SYS_(?!SYSTEMS)(.*)/ =~ sys.to_s
|
649
667
|
idx, sys_name = [@sp3.class.const_get(sys), $1]
|
650
668
|
next unless sats[idx] > 0
|
651
|
-
next unless @sp3.push(@solver, idx)
|
669
|
+
next unless critical{@sp3.push(@solver, idx)}
|
652
670
|
$stderr.puts "Change ephemeris source of #{sys_name} to SP3"
|
653
671
|
}
|
654
672
|
end
|
@@ -656,7 +674,7 @@ class Receiver
|
|
656
674
|
def attach_antex(src)
|
657
675
|
fname = Util::get_txt(src)
|
658
676
|
raise "Specify SP3 before ANTEX application!" unless @sp3
|
659
|
-
applied_items = @sp3.apply_antex(fname)
|
677
|
+
applied_items = critical{@sp3.apply_antex(fname)}
|
660
678
|
raise "Format error! (Not ANTEX) #{src}" unless applied_items >= 0
|
661
679
|
$stderr.puts "SP3 correction with ANTEX file (%s): %d items have been processed."%[src, applied_items]
|
662
680
|
end
|
@@ -672,7 +690,7 @@ class Receiver
|
|
672
690
|
next unless /^SYS_(?!SYSTEMS)(.*)/ =~ sys.to_s
|
673
691
|
idx, sys_name = [@clk.class.const_get(sys), $1]
|
674
692
|
next unless sats[idx] > 0
|
675
|
-
next unless @clk.push(@solver, idx)
|
693
|
+
next unless critical{@clk.push(@solver, idx)}
|
676
694
|
$stderr.puts "Change clock error source of #{sys_name} to RINEX clock"
|
677
695
|
}
|
678
696
|
end
|
data/lib/gps_pvt/util.rb
CHANGED
@@ -1,7 +1,39 @@
|
|
1
|
-
require 'open-uri'
|
2
1
|
require 'tempfile'
|
3
2
|
require 'uri'
|
4
3
|
|
4
|
+
proc{
|
5
|
+
# port[:baudrate], baudrate default is 115200
|
6
|
+
Serial.class_eval{
|
7
|
+
const_set(:SPEC,
|
8
|
+
if RubySerial::ON_WINDOWS then
|
9
|
+
%r{^(?:\\\\.\\)?(COM\d+)(?::(\d+))?$}
|
10
|
+
elsif RubySerial::ON_LINUX then
|
11
|
+
%r{^(/dev/tty[^:]+)(?::(\d+))?$}
|
12
|
+
else
|
13
|
+
nil
|
14
|
+
end)
|
15
|
+
}
|
16
|
+
Serial.class_eval{
|
17
|
+
read_orig = instance_method(:read)
|
18
|
+
define_method(:read){|len|
|
19
|
+
buf = ''
|
20
|
+
f = read_orig.bind(self)
|
21
|
+
buf += f.call(len - buf.size) while buf.size < len
|
22
|
+
buf
|
23
|
+
}
|
24
|
+
def eof?; false; end
|
25
|
+
}
|
26
|
+
Kernel.instance_eval{
|
27
|
+
open_orig = method(:open)
|
28
|
+
define_method(:open){|*args, &b|
|
29
|
+
return open_orig.call(*args, &b) unless Serial::SPEC =~ args[0]
|
30
|
+
Serial::new($1, $2 ? $2.to_i : 115200)
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}.call if require 'rubyserial'
|
34
|
+
|
35
|
+
require 'open-uri'
|
36
|
+
|
5
37
|
module GPS_PVT
|
6
38
|
module Util
|
7
39
|
class << self
|
data/lib/gps_pvt/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gps_pvt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fenrir(M.Naruoka)
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rubyserial
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rake
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|