gps_pvt 0.7.2 → 0.8.1
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/Rakefile +1 -0
- data/exe/gps_pvt +3 -18
- 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/gps_pvt.gemspec +1 -0
- data/lib/gps_pvt/receiver/extension.rb +51 -0
- data/lib/gps_pvt/receiver.rb +79 -56
- data/lib/gps_pvt/util.rb +33 -1
- data/lib/gps_pvt/version.rb +1 -1
- metadata +18 -2
@@ -765,9 +765,70 @@ __RINEX_CLK_TEXT__
|
|
765
765
|
[:alpha, :beta].each{|k|
|
766
766
|
puts "Iono #{k}: #{sn.iono_utc.send(k)}"
|
767
767
|
}
|
768
|
+
proc{|raw|
|
769
|
+
expect(raw.size).to eq(10)
|
770
|
+
puts "Raw(IONO): #{raw.collect{|v| "0x%08X" % [v]}.join(', ')}"
|
771
|
+
iono2 = GPS::Ionospheric_UTC_Parameters::parse(raw)
|
772
|
+
[:alpha, :beta].collect{|f|
|
773
|
+
sn.iono_utc.send(f).zip(iono2.send(f))
|
774
|
+
}.flatten(1).zip([-30, -27, -24, -24, 11, 14, 16, 16]).each{|(a, b), sf|
|
775
|
+
expect(a).to be_within((2 ** sf) * 2).of(b)
|
776
|
+
}
|
777
|
+
[
|
778
|
+
[:A1, 2 ** -50], [:A0, 2 ** -30],
|
779
|
+
].each{|k, sf|
|
780
|
+
#p [k, sf.to_f, sn.iono_utc.send(k) - iono2.send(k), sn.iono_utc.send(k), iono2.send(k)]
|
781
|
+
expect(sn.iono_utc.send(k)).to be_within((sf || 1).to_f * 2).of(iono2.send(k))
|
782
|
+
}
|
783
|
+
}.call(sn.iono_utc.dump(t_meas))
|
768
784
|
|
769
785
|
meas.each{|prn, k, v|
|
770
786
|
eph = sn.ephemeris(prn)
|
787
|
+
expect(eph.valid?(t_meas)).to eq(true)
|
788
|
+
sc2rad = 3.1415926535898
|
789
|
+
proc{|raw|
|
790
|
+
expect(raw.size).to eq(30)
|
791
|
+
eph2 = GPS::Ephemeris::new
|
792
|
+
raw.each_slice(10).with_index{|subframe, i|
|
793
|
+
puts "Raw(PRN:#{prn},SF:#{i+1}): #{subframe.collect{|v| "0x%08X" % [v]}.join(', ')}"
|
794
|
+
eph2.parse(subframe)
|
795
|
+
}
|
796
|
+
expect(eph.WN % 1024).to be(eph2.WN % 1024)
|
797
|
+
[
|
798
|
+
#:URA,
|
799
|
+
:SV_health, :iodc,
|
800
|
+
[:t_GD, 2 ** -31], [:t_oc, 2 ** 4], # SF1
|
801
|
+
[:a_f0, 2 ** -31], [:a_f1, 2 ** -43], [:a_f2, 2 ** -55], # SF1
|
802
|
+
:iode, # SF2
|
803
|
+
[:c_rs, 2 ** -5], [:delta_n, sc2rad * 2 ** -43], # SF2
|
804
|
+
[:M0, sc2rad * 2 ** -31], [:c_uc, 2 ** -29], [:e, 2 ** -33], # SF2
|
805
|
+
[:c_us, 2 ** -29], [:sqrt_A, 2 ** -19], [:t_oe, 2 ** 4], # SF2
|
806
|
+
:fit_interval, # SF2
|
807
|
+
[:c_ic, 2 ** -29], [:Omega0, sc2rad * 2 ** -31], [:c_is, 2 ** -29], # SF3
|
808
|
+
[:i0, sc2rad * 2 ** -31], [:c_rc, 2 ** -5], [:omega, sc2rad * 2 ** -31], # SF3
|
809
|
+
[:dot_Omega0, sc2rad * 2 ** -43], [:dot_i0, sc2rad * 2 ** -43], # SF3
|
810
|
+
].each{|k, sf|
|
811
|
+
#p [k, sf.to_f, eph.send(k) - eph2.send(k), eph.send(k), eph2.send(k)]
|
812
|
+
expect(eph.send(k)).to be_within((sf || 1).to_f * 2).of(eph2.send(k))
|
813
|
+
}
|
814
|
+
}.call(eph.dump(t_meas))
|
815
|
+
proc{|raw| # Almanac -> Ephemeris
|
816
|
+
expect(raw.size).to eq(10)
|
817
|
+
puts "Raw(PRN:#{prn},Almanac): #{raw.collect{|v| "0x%08X" % [v]}.join(', ')}"
|
818
|
+
eph2 = GPS::Ephemeris::new
|
819
|
+
eph2.parse_almanac(raw)
|
820
|
+
[
|
821
|
+
:SV_health,
|
822
|
+
[:t_oc, 2 ** 12], [:a_f0, 2 ** -20], [:a_f1, 2 ** -38],
|
823
|
+
[:M0, sc2rad * 2 ** -23], [:e, 2 ** -21],
|
824
|
+
[:sqrt_A, 2 ** -11], [:t_oe, 2 ** 12],
|
825
|
+
[:Omega0, sc2rad * 2 ** -23], [:i0, sc2rad * 2 ** -19],
|
826
|
+
[:omega, sc2rad * 2 ** -23], [:dot_Omega0, sc2rad * 2 ** -38],
|
827
|
+
].each{|k, sf|
|
828
|
+
#p [k, sf.to_f, eph.send(k) - eph2.send(k), eph.send(k), eph2.send(k)]
|
829
|
+
expect(eph.send(k)).to be_within((sf || 1).to_f * 2).of(eph2.send(k))
|
830
|
+
}
|
831
|
+
}.call(eph.dump_almanac(t_meas))
|
771
832
|
puts "XYZ(PRN:#{prn}): #{eph.constellation(t_meas)[0].to_a} (iodc: #{eph.iodc}, iode: #{eph.iode})"
|
772
833
|
}
|
773
834
|
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#ifndef __BIT_COUNTER__
|
2
|
+
#define __BIT_COUNTER__
|
3
|
+
|
4
|
+
#include <climits>
|
5
|
+
|
6
|
+
using namespace std;
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Counting bits utility
|
10
|
+
*/
|
11
|
+
template <class T>
|
12
|
+
struct BitCounter {
|
13
|
+
|
14
|
+
static const int num_of_bits = CHAR_BIT * sizeof(T);
|
15
|
+
|
16
|
+
private:
|
17
|
+
template <int Interval>
|
18
|
+
static T make_mask(){
|
19
|
+
/*
|
20
|
+
* @see http://www.nminoru.jp/~nminoru/programming/bitcount.html
|
21
|
+
*
|
22
|
+
* 01010101010101010101010101010101 1 32
|
23
|
+
* 00110011001100110011001100110011 2 32
|
24
|
+
* 00001111000011110000111100001111 4 32
|
25
|
+
* 00000000111111110000000011111111 8 32
|
26
|
+
* 00000000000000001111111111111111 16 32
|
27
|
+
*/
|
28
|
+
|
29
|
+
T mask(1);
|
30
|
+
for(int i(1); i < Interval; i++){
|
31
|
+
mask <<= 1;
|
32
|
+
mask |= 0x01;
|
33
|
+
}
|
34
|
+
/*
|
35
|
+
// Equivalent to the following if T is built-in type
|
36
|
+
mask <<= Interval;
|
37
|
+
mask = (mask & (-mask)) - 1;
|
38
|
+
*/
|
39
|
+
|
40
|
+
T res(mask);
|
41
|
+
for(unsigned int i(1); i < num_of_bits / Interval / 2; i++){
|
42
|
+
res <<= Interval;
|
43
|
+
res <<= Interval;
|
44
|
+
res |= mask;
|
45
|
+
}
|
46
|
+
return res;
|
47
|
+
}
|
48
|
+
|
49
|
+
template <int Interval, class U = void>
|
50
|
+
struct count_loop {
|
51
|
+
static T run(T bits){
|
52
|
+
bits = count_loop<(Interval >> 1)>::run(bits);
|
53
|
+
static const T mask(make_mask<Interval>());
|
54
|
+
// bit shift and add operators are required at least
|
55
|
+
return (bits & mask) + ((bits >> Interval) & mask);
|
56
|
+
}
|
57
|
+
};
|
58
|
+
template <class U>
|
59
|
+
struct count_loop<1, U> {
|
60
|
+
static T run(T bits){
|
61
|
+
static const T mask(make_mask<1>());
|
62
|
+
return (bits & mask) + ((bits >> 1) & mask);
|
63
|
+
}
|
64
|
+
};
|
65
|
+
|
66
|
+
public:
|
67
|
+
/**
|
68
|
+
* Count bits in a value
|
69
|
+
* @param results
|
70
|
+
*/
|
71
|
+
static T count(const T &v) {
|
72
|
+
return count_loop<(num_of_bits >> 1)>::run(v);
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Count rightmost zeros before the first one (Number of trailing zeros)
|
77
|
+
* @param bits results
|
78
|
+
*/
|
79
|
+
static T ntz(const T &v) {
|
80
|
+
return count((T)((~v) & (v - 1)));
|
81
|
+
}
|
82
|
+
};
|
83
|
+
|
84
|
+
#endif /* __BIT_COUNTER__ */
|
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
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
=begin
|
2
|
+
Receiver extension
|
3
|
+
=end
|
4
|
+
|
5
|
+
module GPS_PVT
|
6
|
+
class Receiver
|
7
|
+
|
8
|
+
# shortcut to access ephemeris registered in receiver
|
9
|
+
def ephemeris(t, sys, prn)
|
10
|
+
eph = case sys
|
11
|
+
when :GPS, :QZSS
|
12
|
+
critical{
|
13
|
+
@solver.gps_space_node.update_all_ephemeris(t)
|
14
|
+
@solver.gps_space_node.ephemeris(prn)
|
15
|
+
}
|
16
|
+
when :SBAS
|
17
|
+
critical{
|
18
|
+
@solver.sbas_space_node.update_all_ephemeris(t)
|
19
|
+
@solver.sbas_space_node.ephemeris(prn)
|
20
|
+
}
|
21
|
+
when :GLONASS
|
22
|
+
critical{
|
23
|
+
@solver.glonass_space_node.update_all_ephemeris(t)
|
24
|
+
@solver.glonass_space_node.ephemeris(prn)
|
25
|
+
}
|
26
|
+
else
|
27
|
+
return nil
|
28
|
+
end
|
29
|
+
return (eph.valid?(t) ? eph : nil)
|
30
|
+
end
|
31
|
+
|
32
|
+
def attach_online_ephemeris(uri_template = nil)
|
33
|
+
if (!uri_template) || (uri_template =~ /^\s*$/) then
|
34
|
+
uri_template = "ftp://gssc.esa.int/gnss/data/daily/%Y/brdc/BRDC00IGS_R_%Y%j0000_01D_MN.rnx.gz"
|
35
|
+
end
|
36
|
+
loader = proc{|t_meas|
|
37
|
+
utc = Time::utc(*t_meas.c_tm)
|
38
|
+
uri = URI::parse(utc.strftime(uri_template))
|
39
|
+
self.parse_rinex_nav(uri)
|
40
|
+
uri
|
41
|
+
}
|
42
|
+
run_orig = self.method(:run)
|
43
|
+
eph_list = {}
|
44
|
+
self.define_singleton_method(:run){|meas, t_meas, *args|
|
45
|
+
w_d = [t_meas.week, (t_meas.seconds.to_i / 86400)]
|
46
|
+
eph_list[w_d] ||= loader.call(t_meas)
|
47
|
+
run_orig.call(meas, t_meas, *args)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/gps_pvt/receiver.rb
CHANGED
@@ -3,7 +3,7 @@ Receiver class to be an top level interface to a user
|
|
3
3
|
(The origin is ninja-scan-light/tool/misc/receiver_debug.rb)
|
4
4
|
=end
|
5
5
|
|
6
|
-
|
6
|
+
require 'gps_pvt/GPS' # in case GPS.so is generated under ext/gps_pvt
|
7
7
|
require_relative 'util'
|
8
8
|
|
9
9
|
module GPS_PVT
|
@@ -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
|
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
|
409
425
|
end
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
when :SBAS
|
416
|
-
case @solver.sbas_space_node.decode_message(bcast_data[0..7], prn, t_meas)
|
417
|
-
when 26
|
418
|
-
['', "IGP broadcasted by PRN#{prn} @ #{Time::utc(*t_meas.c_tm)}",
|
419
|
-
@solver.sbas_space_node.ionospheric_grid_points(prn)].each{|str|
|
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]
|
@@ -505,6 +523,8 @@ class Receiver
|
|
505
523
|
v
|
506
524
|
}
|
507
525
|
sys, svid = gnss_serial.call(*loader.call(36, 2).reverse)
|
526
|
+
# sigID check to restrict signal to L1 if version(>0); @see UBX-18010854
|
527
|
+
next if (packet[6 + 13] != 0) && (loader.call(38, 1, "C") != 0)
|
508
528
|
case sys
|
509
529
|
when :GPS, :SBAS, :QZSS;
|
510
530
|
when :GLONASS
|
@@ -538,10 +558,13 @@ class Receiver
|
|
538
558
|
register_ephemeris(
|
539
559
|
t_meas,
|
540
560
|
sys, svid,
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
561
|
+
proc{|data|
|
562
|
+
case sys # adjust padding
|
563
|
+
when :GPS; data.collect!{|v| (v & 0xFFFFFF) << 6}
|
564
|
+
when :SBAS; data[7] <<= 6
|
565
|
+
end
|
566
|
+
data
|
567
|
+
}.call(packet.slice(6 + 2, 40).pack("C*").unpack("V*")))
|
545
568
|
when [0x02, 0x13] # RXM-SFRBX
|
546
569
|
sys, svid = gnss_serial.call(packet[6 + 1], packet[6])
|
547
570
|
opt = {}
|
@@ -549,9 +572,7 @@ class Receiver
|
|
549
572
|
register_ephemeris(
|
550
573
|
t_meas,
|
551
574
|
sys, svid,
|
552
|
-
packet.slice(6 + 8, 4 * packet[6 + 4]).
|
553
|
-
v.pack("C*").unpack("V")[0]
|
554
|
-
}, opt)
|
575
|
+
packet.slice(6 + 8, 4 * packet[6 + 4]).pack("C*").unpack("V*"), opt)
|
555
576
|
end
|
556
577
|
}
|
557
578
|
$stderr.puts ", found packets are %s"%[ubx_kind.inspect]
|
@@ -564,7 +585,7 @@ class Receiver
|
|
564
585
|
@solver.sbas_space_node,
|
565
586
|
@solver.glonass_space_node,
|
566
587
|
].inject(0){|res, sn|
|
567
|
-
loaded_items = sn.send(:read, fname)
|
588
|
+
loaded_items = critical{sn.send(:read, fname)}
|
568
589
|
raise "Format error! (Not RINEX) #{src}" if loaded_items < 0
|
569
590
|
res + loaded_items
|
570
591
|
}
|
@@ -648,7 +669,7 @@ class Receiver
|
|
648
669
|
next unless /^SYS_(?!SYSTEMS)(.*)/ =~ sys.to_s
|
649
670
|
idx, sys_name = [@sp3.class.const_get(sys), $1]
|
650
671
|
next unless sats[idx] > 0
|
651
|
-
next unless @sp3.push(@solver, idx)
|
672
|
+
next unless critical{@sp3.push(@solver, idx)}
|
652
673
|
$stderr.puts "Change ephemeris source of #{sys_name} to SP3"
|
653
674
|
}
|
654
675
|
end
|
@@ -656,7 +677,7 @@ class Receiver
|
|
656
677
|
def attach_antex(src)
|
657
678
|
fname = Util::get_txt(src)
|
658
679
|
raise "Specify SP3 before ANTEX application!" unless @sp3
|
659
|
-
applied_items = @sp3.apply_antex(fname)
|
680
|
+
applied_items = critical{@sp3.apply_antex(fname)}
|
660
681
|
raise "Format error! (Not ANTEX) #{src}" unless applied_items >= 0
|
661
682
|
$stderr.puts "SP3 correction with ANTEX file (%s): %d items have been processed."%[src, applied_items]
|
662
683
|
end
|
@@ -672,9 +693,11 @@ class Receiver
|
|
672
693
|
next unless /^SYS_(?!SYSTEMS)(.*)/ =~ sys.to_s
|
673
694
|
idx, sys_name = [@clk.class.const_get(sys), $1]
|
674
695
|
next unless sats[idx] > 0
|
675
|
-
next unless @clk.push(@solver, idx)
|
696
|
+
next unless critical{@clk.push(@solver, idx)}
|
676
697
|
$stderr.puts "Change clock error source of #{sys_name} to RINEX clock"
|
677
698
|
}
|
678
699
|
end
|
679
700
|
end
|
680
701
|
end
|
702
|
+
|
703
|
+
require_relative 'receiver/extension'
|
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.1
|
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-
|
11
|
+
date: 2022-11-17 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
|
@@ -98,11 +112,13 @@ files:
|
|
98
112
|
- ext/ninja-scan-light/tool/swig/makefile
|
99
113
|
- ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb
|
100
114
|
- ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb
|
115
|
+
- ext/ninja-scan-light/tool/util/bit_counter.h
|
101
116
|
- ext/ninja-scan-light/tool/util/text_helper.h
|
102
117
|
- gps_pvt.gemspec
|
103
118
|
- gps_pvt.rbs
|
104
119
|
- lib/gps_pvt.rb
|
105
120
|
- lib/gps_pvt/receiver.rb
|
121
|
+
- lib/gps_pvt/receiver/extension.rb
|
106
122
|
- lib/gps_pvt/ubx.rb
|
107
123
|
- lib/gps_pvt/util.rb
|
108
124
|
- lib/gps_pvt/version.rb
|