gps_pvt 0.2.3 → 0.4.0

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: b6820c87f08dcf6c64e70d304c634b32c1bea265d6f360fc79c8c9405822569a
4
- data.tar.gz: 75b9db05a1c23827fc9e1163b476f4e3293a7d09efbf4a9a1cd9636dda7387bd
3
+ metadata.gz: 7ba5a3a5c8364753e1f6384519a015f29459e51e17bd82eb81e398c89e80619f
4
+ data.tar.gz: 565bd717bb178be9784b9b249860270b9d45e33e8af456ab1042db5d75b34c04
5
5
  SHA512:
6
- metadata.gz: f22eb60b17dc0bbd6a8c249deedd39e0fa5ec179bf28abb5c36cdf4191d79219af0dd456af93e8432f93173d07e42debdef11cdcdf6c9327395c38535c7d8de5
7
- data.tar.gz: a7643df74fd9947d07383353d4cdf860b45494b13e2c332ccb2176a771112acd3887a9a8dc95e62ad8f97841506cceaccb79d8ba990dc6148aeb66efc07f51a3
6
+ metadata.gz: 1fef4a8e70a4872f17219f3f97a2ac21d0b5feb44a611d747291d842dd6939cd297426c53cbd16875ece618b610d557542f98c720177a05e95db63f9dcd788c9
7
+ data.tar.gz: 60450ca6f661f0eaeb0c194caa97f4246dd723edbf2f566c5775fa91dffb621357aca7732b54fb7d27b636cb0864b2f26c40efa661fb3afde029b6a4bc985d63
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, an attached executable is useful. After installation, type
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
 
@@ -37,11 +38,22 @@ The format of RINEX_or_UBX_file is automatically determined with its extention,
37
38
  --rinex_obs=filename
38
39
  --ubx=filename
39
40
 
40
- From version 0.2.0, SBAS and QZSS are supported in addition to GPS. QZSS ranging is activated in default, however, SBAS is just utilized for ionospheric correction. If you want to activate SBAS ranging, "--with=(SBAS PRN number, ex. 137)" option is used with gps_pvt executable like
41
+ Since version 0.2.0, SBAS and QZSS are supported in addition to GPS. Since version 0.4.0, GLONASS is also available. QZSS ranging is activated in default, however, SBAS is just utilized for ionospheric correction. GLONASS is also turned off by default. If you want to activate SBAS or GLONASS ranging, "--with=(system or PRN)" options are used with gps_pvt executable like
41
42
 
42
- $ gps_pvt --with=137 RINEX_or_UBX_file(s)
43
+ $ gps_pvt --with=137 --with=GLONASS RINEX_or_UBX_file(s)
43
44
 
44
- For developer, this library will be used in the following:
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
- # Customize solution
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
@@ -29,9 +29,11 @@ namespace :git do
29
29
  # same as #{repo}/.git/info/sparse-checkout
30
30
  "sparse-checkout set" + (<<-__SPARSE_PATTERNS__).lines.collect{|str| str.chomp.gsub(/^ */, ' ')}.join,
31
31
  /tool/param/
32
+ /tool/algorithm/integral.h
32
33
  /tool/navigation/GPS*
33
34
  /tool/navigation/SBAS*
34
35
  /tool/navigation/QZSS*
36
+ /tool/navigation/GLONASS*
35
37
  /tool/navigation/coordinate.h
36
38
  /tool/navigation/EGM.h
37
39
  /tool/navigation/MagneticField.h
data/exe/gps_pvt CHANGED
@@ -6,7 +6,7 @@ require 'gps_pvt'
6
6
 
7
7
  $stderr.puts <<__STRING__
8
8
  Usage: #{__FILE__} GPS_file1 GPS_file2 ...
9
- As GPS_file, rinex_nav(*.YYn, *.YYh, *.YYq), rinex_obs(*.YYo), and ubx(*.ubx) format are currently supported.
9
+ As GPS_file, rinex_nav(*.YYn, *.YYh, *.YYq, *.YYg), rinex_obs(*.YYo), and ubx(*.ubx) format are currently supported.
10
10
  File format is automatically determined based on its extention described in above parentheses.
11
11
  If you want to specify its format manually, --rinex_(nav|obs)=file_name or --ubx=file_name are available.
12
12
  Supported RINEX versions are 2 and 3.
@@ -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,11 +25,45 @@ 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)
30
65
  ftype ||= case fname
31
- when /\.\d{2}[nhq]$/; :rinex_nav
66
+ when /\.\d{2}[nhqg]$/; :rinex_nav
32
67
  when /\.\d{2}o$/; :rinex_obs
33
68
  when /\.ubx$/; :ubx
34
69
  else
@@ -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