gps_pvt 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +25 -4
- data/lib/gps_pvt/receiver.rb +18 -6
- data/lib/gps_pvt/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c46c810a11cabe3d24070a87094b797ad7b7412784d758722fe6e6f19bf10058
|
4
|
+
data.tar.gz: ce287cf3d49d328b5f9c80258c71037737a53088c7069f3a4221f26b0ad1fef9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55c493e05404597dedfe870c8490458624cc5b9fa7dcaf339a5b171985dcd4a2fe2e941c15b546381d1a5d6a0d7b46722a66b62dffc10d55fe6c547c5167ab1a
|
7
|
+
data.tar.gz: 49663577f15d4a8547a80aaed57d554656255056e76bf085b01357ee94327109e7ef4c543981cce59b1ba16587373d3a5809bce26e85e7f365c0d75c06d82de9
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
GPS_PVT is a Ruby GPS (Global positioning system) PVT (position, velocity and time) solver. It accepts RINEX NAV and OBS files in addition to u-blox ubx format. Its significant features are easy to use with highly flexibility to customize internal solver behavior such as weight for each available satellite.
|
4
4
|
|
5
|
-
The PVT solution is obtained with a stand alone positioning (i.e. neither differential nor kinematic) with least square. Its main internal codes are derived from ones of [ninja-scan-light](https://github.com/fenrir-naru/ninja-scan-light) having capability to calculate tightly-coupled GNSS/INS integrated solution. These codes are written by C++, and wrapped by [SWIG](http://www.swig.org/).
|
5
|
+
The PVT solution is obtained with a stand alone positioning (i.e. neither differential nor kinematic) with application of least square to each snapshot. Its main internal codes are derived from ones of [ninja-scan-light](https://github.com/fenrir-naru/ninja-scan-light) having capability to calculate tightly-coupled GNSS/INS integrated solution. These codes are written by C++, and wrapped by [SWIG](http://www.swig.org/).
|
6
6
|
|
7
7
|
[![Gem Version](https://badge.fury.io/rb/gps_pvt.svg)](https://badge.fury.io/rb/gps_pvt)
|
8
8
|
[![Ruby](https://github.com/fenrir-naru/gps_pvt/actions/workflows/main.yml/badge.svg)](https://github.com/fenrir-naru/gps_pvt/actions/workflows/main.yml)
|
@@ -46,7 +46,8 @@ receiver.parse_rinex_obs(rinex_obs_file)
|
|
46
46
|
|
47
47
|
# Or precise control of outputs
|
48
48
|
receiver.parse_rinex_obs(rinex_obs_file){|pvt, meas| # per epoch
|
49
|
-
meas # => measurement, array of [prn, key, value]; key is represented by GPS_PVT::GPS::Measurement::L1_PSEUDORANGE
|
49
|
+
meas.to_a # => measurement, array of [prn, key, value]; key is represented by GPS_PVT::GPS::Measurement::L1_PSEUDORANGE; instead of .to_a, .to_hash returns {prn => {key => value, ...}, ...}
|
50
|
+
|
50
51
|
pvt # => PVT solution, all properties are shown by pvt.methods
|
51
52
|
# for example
|
52
53
|
if(pvt.position_solved?){
|
@@ -59,6 +60,9 @@ receiver.parse_rinex_obs(rinex_obs_file){|pvt, meas| # per epoch
|
|
59
60
|
pvt.receiver_error_rate # clock error rate in m/s
|
60
61
|
}
|
61
62
|
pvt.used_satellite_list # array of used, i.e., visible and weight>0, satellite
|
63
|
+
pvt.azimuth # azimuth angle [rad] to used satellites in Hash {prn => value, ...}
|
64
|
+
pvt.elevation # elevation angle [rad]
|
65
|
+
|
62
66
|
pvt.G # design matrix in Earth-centered-Earth-fixed (ECEF); .to_a returns double array converted from matrix. its row corresponds to one of used_satellite_list
|
63
67
|
pvt.G_enu # design matrix in East-North-Up (ENU)
|
64
68
|
pvt.W # weight for each satellite
|
@@ -73,11 +77,28 @@ receiver.solver.options.include(prn) # Discard previous setting of exclusion
|
|
73
77
|
receiver.solver.hooks[:relative_property] = proc{|prn, rel_prop, rcv_e, t_arv, usr_pos, usr_vel|
|
74
78
|
# control weight per satellite per iteration
|
75
79
|
weight, range_c, range_r, rate_rel_neg, *los_neg = rel_prop # relative property
|
76
|
-
|
80
|
+
# rcv_e, t_arv, usr_pos, usr_vel are temporary solution of
|
81
|
+
# receiver clock error [m], time of arrival [s], user position and velocity in ECEF, respectively.
|
82
|
+
|
83
|
+
weight = 1 # same as default; identical weight for each visible satellite
|
77
84
|
# or weight based on elevation
|
78
85
|
# elv = GPS_PVT::Coordinate::ENU::relative_rel(GPS_PVT::Coordinate::XYZ::new(*los_neg), usr_pos).elevation
|
79
86
|
# weight = (Math::sin(elv)/0.8)**2
|
80
|
-
|
87
|
+
|
88
|
+
[weight, range_c, range_r, rate_rel_neg] + los_neg # must return relative property
|
89
|
+
}
|
90
|
+
|
91
|
+
# Dynamic customization of weight for each epoch
|
92
|
+
(class << receiver; self; end).instance_eval{ # do before parse_XXX
|
93
|
+
alias_method(:run_orig, :run)
|
94
|
+
define_method(:run){|meas, t_meas, &b|
|
95
|
+
meas # observation, same as the 2nd argument of parse_XXX
|
96
|
+
receiver.solver.hooks[:relative_property] = proc{|prn, rel_prop, rcv_e, t_arv, usr_pos, usr_vel|
|
97
|
+
# Do something based on meas, t_meas.
|
98
|
+
rel_prop
|
99
|
+
}
|
100
|
+
run_orig(meas, t_meas, &b)
|
101
|
+
}
|
81
102
|
}
|
82
103
|
```
|
83
104
|
|
data/lib/gps_pvt/receiver.rb
CHANGED
@@ -138,15 +138,15 @@ class Receiver
|
|
138
138
|
end
|
139
139
|
|
140
140
|
def run(meas, t_meas)
|
141
|
-
|
142
|
-
|
143
|
-
sn.update_all_ephemeris(t_meas)
|
144
|
-
|
141
|
+
=begin
|
142
|
+
$stderr.puts "Measurement time: #{t_meas.to_a} (a.k.a #{"%d/%d/%d %d:%d:%d UTC"%[*t_meas.c_tm]})"
|
145
143
|
meas.to_a.collect{|prn, k, v| prn}.uniq.each{|prn|
|
146
|
-
eph =
|
144
|
+
eph = @solver.gps_space_node.ephemeris(prn)
|
147
145
|
$stderr.puts "XYZ(PRN:#{prn}): #{eph.constellation(t_meas)[0].to_a} (iodc: #{eph.iodc}, iode: #{eph.iode})"
|
148
|
-
}
|
146
|
+
}
|
147
|
+
=end
|
149
148
|
|
149
|
+
#@solver.gps_space_node.update_all_ephemeris(t_meas) # internally called in the following solver.solve
|
150
150
|
pvt = @solver.solve(meas, t_meas)
|
151
151
|
pvt.define_singleton_method(:to_s){
|
152
152
|
(OUTPUT_PVT_ITEMS.transpose[1].collect{|task|
|
@@ -242,9 +242,15 @@ class Receiver
|
|
242
242
|
{
|
243
243
|
:L1_PSEUDORANGE => [16, 8, "E"],
|
244
244
|
:L1_DOPPLER => [24, 4, "e"],
|
245
|
+
:L1_CARRIER_PHASE => [8, 8, "E"],
|
246
|
+
:L1_SIGNAL_STRENGTH_dBHz => [30, 1, "c"],
|
245
247
|
}.each{|k, prop|
|
246
248
|
meas.add(prn, GPS::Measurement.const_get(k), loader.call(*prop))
|
247
249
|
}
|
250
|
+
# bit 0 of RINEX LLI (loss of lock indicator) shows lost lock
|
251
|
+
# between previous and current observation, which maps negative lock seconds
|
252
|
+
meas.add(prn, GPS::Measurement::L1_LOCK_SEC,
|
253
|
+
(packet[6 + 31 + (i * 24)] & 0x01 == 0x01) ? -1 : 0)
|
248
254
|
}
|
249
255
|
after_run.call(run(meas, t_meas), [meas, t_meas])
|
250
256
|
when [0x02, 0x15] # RXM-RAWX
|
@@ -270,6 +276,12 @@ class Receiver
|
|
270
276
|
}],
|
271
277
|
:L1_DOPPLER => [32, 4, "e"],
|
272
278
|
:L1_DOPPLER_SIGMA => [45, 1, nil, proc{|v| 2E-3 * (v[0] & 0xF)}],
|
279
|
+
:L1_CARRIER_PHASE => [24, 8, "E", proc{|v| (trk_stat & 0x2 == 0x2) ? v : nil}],
|
280
|
+
:L1_CARRIER_PHASE_SIGMA => [44, 1, nil, proc{|v|
|
281
|
+
(trk_stat & 0x2 == 0x2) ? (0.004 * (v[0] & 0xF)) : nil
|
282
|
+
}],
|
283
|
+
:L1_SIGNAL_STRENGTH_dBHz => [42, 1],
|
284
|
+
:L1_LOCK_SEC => [40, 2, "v", proc{|v| 1E-3 * v}],
|
273
285
|
}.each{|k, prop|
|
274
286
|
next unless v = loader.call(*prop)
|
275
287
|
meas.add(svid, GPS::Measurement.const_get(k), v)
|
data/lib/gps_pvt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gps_pvt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
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: 2021-12-
|
11
|
+
date: 2021-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|