gps_pvt 0.2.1 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -5
- data/Rakefile +0 -0
- data/exe/gps_pvt +63 -0
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +784 -745
- data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +723 -436
- data/ext/ninja-scan-light/tool/navigation/GPS.h +15 -44
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +61 -147
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +56 -2
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +2 -2
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +55 -78
- data/ext/ninja-scan-light/tool/param/bit_array.h +4 -3
- data/ext/ninja-scan-light/tool/swig/GPS.i +255 -63
- data/ext/ninja-scan-light/tool/swig/SylphideMath.i +91 -21
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +25 -5
- data/ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb +51 -7
- data/gps_pvt.gemspec +63 -0
- data/lib/gps_pvt/receiver.rb +84 -40
- data/lib/gps_pvt/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b91245b6a851b08ef5ec4b23e6be27cdd1150eaf6f7036249bf971c105bd920d
|
4
|
+
data.tar.gz: 75e5a367d8e1cc0d0e8cc48dae63b3b9b6a72fc86eeeea76bc6d1562ba171f02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3763faded2f4a5ace56f3a5cfde25311792ea06bda6ce5eb987fa10e1add08d9eb505bdb697fefb84b95a212072a824c3c134d298f4adea13d4ea31edfbeb831
|
7
|
+
data.tar.gz: 76b55b2da8d816a4bd2be024191ac0b706e40624035f979411f9192d78e030f2ee10ab4ce186160e8de2006b175728db593b11c25020f734ed9ac22544f0d2fb
|
data/README.md
CHANGED
@@ -27,7 +27,8 @@ For Windows users, this gem requires Devkit because of native compilation.
|
|
27
27
|
|
28
28
|
## Usage
|
29
29
|
|
30
|
-
For user who just generate PVT solution
|
30
|
+
### For user who just generate PVT solution
|
31
|
+
An attached executable is useful. After installation, type
|
31
32
|
|
32
33
|
$ gps_pvt RINEX_or_UBX_file(s)
|
33
34
|
|
@@ -41,7 +42,18 @@ From version 0.2.0, SBAS and QZSS are supported in addition to GPS. QZSS ranging
|
|
41
42
|
|
42
43
|
$ gps_pvt --with=137 RINEX_or_UBX_file(s)
|
43
44
|
|
44
|
-
|
45
|
+
Additionally, the following command options *--key=value* are available.
|
46
|
+
|
47
|
+
| key | value | comment | version |
|
48
|
+
----|----|----|----
|
49
|
+
| base_station | 3 \* (numeric+coordinate) | base position used for relative ENU position calculation. XYZ, NEU formats are acceptable. *ex1) --base_station=0X,0Y,0Z*, *ex2) --base_station=12.34N,56.789E,0U* | v0.1.7 |
|
50
|
+
| elevation_mask_deg | numeric | satellite elevation mask specified in degrees. *ex) --elevation_mask_deg=10* | v0.3.0 |
|
51
|
+
| start_time | time string | start time to perform solution. GPS, UTC and other formats are supported. *ex1) --start_time=1234:5678* represents 5678 seconds in 1234 GPS week, *ex2) --start_time="2000-01-01 00:00:00 UTC"* is in UTC format. | v0.3.3 |
|
52
|
+
| end_time | time string | end time to perform solution. Its format is the same as start_time. | v0.3.3 |
|
53
|
+
|
54
|
+
### For developer
|
55
|
+
|
56
|
+
This library will be used like:
|
45
57
|
|
46
58
|
```ruby
|
47
59
|
require 'gps_pvt'
|
@@ -81,25 +93,41 @@ receiver.parse_rinex_obs(rinex_obs_file){|pvt, meas| # per epoch
|
|
81
93
|
}
|
82
94
|
}
|
83
95
|
|
84
|
-
|
96
|
+
## Further customization
|
97
|
+
# General options
|
85
98
|
receiver.solver.gps_options.exclude(prn) # Exclude satellite; the default is to use every satellite if visible
|
86
99
|
receiver.solver.gps_options.include(prn) # Discard previous setting of exclusion
|
87
100
|
receiver.solver.gps_options.elevation_mask = Math::PI / 180 * 10 # example 10 [deg] elevation mask
|
101
|
+
# receiver.solver.sbas_options is for SBAS.
|
102
|
+
|
103
|
+
# Precise control of properties for each satellite and for each iteration
|
88
104
|
receiver.solver.hooks[:relative_property] = proc{|prn, rel_prop, meas, rcv_e, t_arv, usr_pos, usr_vel|
|
89
|
-
# control weight per satellite per iteration
|
90
105
|
weight, range_c, range_r, rate_rel_neg, *los_neg = rel_prop # relative property
|
91
106
|
# meas is measurement represented by pseudo range of the selected satellite.
|
92
107
|
# rcv_e, t_arv, usr_pos, usr_vel are temporary solution of
|
93
108
|
# receiver clock error [m], time of arrival [s], user position and velocity in ECEF, respectively.
|
94
109
|
|
95
110
|
weight = 1 # same as default; identical weight for each visible satellite
|
96
|
-
# or weight based on elevation
|
111
|
+
# or weight based on elevation, for example:
|
97
112
|
# elv = GPS_PVT::Coordinate::ENU::relative_rel(GPS_PVT::Coordinate::XYZ::new(*los_neg), usr_pos).elevation
|
98
113
|
# weight = (Math::sin(elv)/0.8)**2
|
99
114
|
|
100
115
|
[weight, range_c, range_r, rate_rel_neg] + los_neg # must return relative property
|
101
116
|
}
|
102
117
|
|
118
|
+
# Range correction (since v0.3.0)
|
119
|
+
receiver.solver.correction = { # provide by using a Hash
|
120
|
+
# ionospheric and transpheric models are changeable, and current configuration
|
121
|
+
# can be obtained by receiver.solver.correction without assigner.
|
122
|
+
:gps_ionospheric => proc{|t, usr_pos_xyz, sat_pos_enu|
|
123
|
+
# t, usr_pos_xyz, sat_pos_enu are temporary solution of
|
124
|
+
# time of arrival [s], user position in ECEF,
|
125
|
+
# and satellite position in ENU respectively.
|
126
|
+
0 # must return correction value, delaying is negative.
|
127
|
+
},
|
128
|
+
# combination of (gps or sbas) and (ionospheric or tropospheric) are available
|
129
|
+
}
|
130
|
+
|
103
131
|
# Dynamic customization of weight for each epoch
|
104
132
|
(class << receiver; self; end).instance_eval{ # do before parse_XXX
|
105
133
|
alias_method(:run_orig, :run)
|
data/Rakefile
CHANGED
File without changes
|
data/exe/gps_pvt
CHANGED
@@ -14,6 +14,7 @@ Note: YY = last two digit of year.
|
|
14
14
|
__STRING__
|
15
15
|
|
16
16
|
options = []
|
17
|
+
misc_options = {}
|
17
18
|
|
18
19
|
# check options and file format
|
19
20
|
files = ARGV.collect{|arg|
|
@@ -24,6 +25,40 @@ files = ARGV.collect{|arg|
|
|
24
25
|
nil
|
25
26
|
}.compact
|
26
27
|
|
28
|
+
options.reject!{|opt|
|
29
|
+
case opt[0]
|
30
|
+
when :start_time, :end_time
|
31
|
+
require 'time'
|
32
|
+
gpst_type = GPS_PVT::GPS::Time
|
33
|
+
t = nil
|
34
|
+
if opt[1] =~ /^(?:(\d+):)??(\d+(?:\.\d*)?)$/ then
|
35
|
+
t = [$1 && $1.to_i, $2.to_f]
|
36
|
+
t = gpst_type::new(*t) if t[0]
|
37
|
+
elsif t = (Time::parse(opt[1]) rescue nil) then
|
38
|
+
# leap second handling in Ruby Time is system dependent, thus
|
39
|
+
#t = gpst_type::new(0, t - Time::parse("1980-01-06 00:00:00 +0000"))
|
40
|
+
# is inappropriate.
|
41
|
+
subsec = t.subsec.to_f
|
42
|
+
t = gpst_type::new(t.to_a[0..5].reverse)
|
43
|
+
t += (subsec + gpst_type::guess_leap_seconds(t))
|
44
|
+
else
|
45
|
+
raise "Unknown time format: #{opt[1]}"
|
46
|
+
end
|
47
|
+
case t
|
48
|
+
when gpst_type
|
49
|
+
$stderr.puts(
|
50
|
+
"#{opt[0]}: %d week %f (a.k.a %04d/%02d/%02d %02d:%02d:%02.1f)" \
|
51
|
+
%(t.to_a + t.utc))
|
52
|
+
when Array
|
53
|
+
$stderr.puts("#{opt[0]}: #{t[0] || '(current)'} week #{t[1]}")
|
54
|
+
end
|
55
|
+
misc_options[opt[0]] = t
|
56
|
+
true
|
57
|
+
else
|
58
|
+
false
|
59
|
+
end
|
60
|
+
}
|
61
|
+
|
27
62
|
# Check file existence and extension
|
28
63
|
files.collect!{|fname, ftype|
|
29
64
|
raise "File not found: #{fname}" unless File::exist?(fname)
|
@@ -39,6 +74,34 @@ files.collect!{|fname, ftype|
|
|
39
74
|
|
40
75
|
rcv = GPS_PVT::Receiver::new(options)
|
41
76
|
|
77
|
+
proc{
|
78
|
+
run_orig = rcv.method(:run)
|
79
|
+
t_start, t_end = [nil, nil]
|
80
|
+
tasks = []
|
81
|
+
task = proc{|meas, t_meas, *args|
|
82
|
+
t_start, t_end = [:start_time, :end_time].collect{|k|
|
83
|
+
res = misc_options[k]
|
84
|
+
res.kind_of?(Array) \
|
85
|
+
? GPS_PVT::GPS::Time::new(t_meas.week, res[1]) \
|
86
|
+
: res
|
87
|
+
}
|
88
|
+
task = tasks.shift
|
89
|
+
task.call(*([meas, t_meas] + args))
|
90
|
+
}
|
91
|
+
tasks << proc{|meas, t_meas, *args|
|
92
|
+
next nil if t_start && (t_start > t_meas)
|
93
|
+
task = tasks.shift
|
94
|
+
task.call(*([meas, t_meas] + args))
|
95
|
+
}
|
96
|
+
tasks << proc{|meas, t_meas, *args|
|
97
|
+
next nil if t_end && (t_end < t_meas)
|
98
|
+
run_orig.call(*([meas, t_meas] + args))
|
99
|
+
}
|
100
|
+
rcv.define_singleton_method(:run){|*args|
|
101
|
+
task.call(*args)
|
102
|
+
}
|
103
|
+
}.call if [:start_time, :end_time].any?{|k| misc_options[k]}
|
104
|
+
|
42
105
|
puts rcv.header
|
43
106
|
|
44
107
|
# parse RINEX NAV
|