gps_pvt 0.8.3 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +0 -4
- data/LICENSE +30 -0
- data/README.md +11 -11
- data/gps_pvt.gemspec +3 -1
- data/lib/gps_pvt/ntrip.rb +153 -0
- data/lib/gps_pvt/util.rb +7 -6
- data/lib/gps_pvt/version.rb +5 -1
- metadata +22 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39089e2daa55491ccf086809797c2fef68d1e0268e75e6217ed793f091e748de
|
4
|
+
data.tar.gz: cca39a3dbcca26921606019be603526f62766c841a92191ee0a99174f00b54c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: becc6540b82ff9d3a97b4b6c5e58f2a7b0872f63584abdee2c425860e1c47b07700f778550ab95bccb3fc7b6462f9fb2f6249ca7846d1a9a9319471e96577c55
|
7
|
+
data.tar.gz: 67b2b12b88df52a19e84ef68a7773f2ec989dec3858b5d64e0e60961f8f9f4154eda3e36ef1548b61004c8af4cc6b6850ba73c145f15da41832944857c904889
|
data/Gemfile
CHANGED
data/LICENSE
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
(The following license is applied to each file in which there is no license statement.)
|
2
|
+
|
3
|
+
BSD 3-Clause License
|
4
|
+
|
5
|
+
Copyright (c) 2022, M.Naruoka (fenrir)
|
6
|
+
|
7
|
+
Redistribution and use in source and binary forms, with or without
|
8
|
+
modification, are permitted provided that the following conditions are met:
|
9
|
+
|
10
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
11
|
+
list of conditions and the following disclaimer.
|
12
|
+
|
13
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
this list of conditions and the following disclaimer in the documentation
|
15
|
+
and/or other materials provided with the distribution.
|
16
|
+
|
17
|
+
3. Neither the name of the copyright holder nor the names of its
|
18
|
+
contributors may be used to endorse or promote products derived from
|
19
|
+
this software without specific prior written permission.
|
20
|
+
|
21
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
22
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
23
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
24
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
25
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
26
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
27
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
28
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
29
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
CHANGED
@@ -2,14 +2,18 @@
|
|
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 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
|
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 in C++, and wrapped by [SWIG](http://www.swig.org/).
|
6
6
|
|
7
7
|
[](https://badge.fury.io/rb/gps_pvt)
|
8
8
|
[](https://github.com/fenrir-naru/gps_pvt/actions/workflows/main.yml)
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
12
|
-
|
12
|
+
Install it yourself as:
|
13
|
+
|
14
|
+
$ gem install gps_pvt
|
15
|
+
|
16
|
+
Or add this line to your Ruby application's Gemfile:
|
13
17
|
|
14
18
|
```ruby
|
15
19
|
gem 'gps_pvt'
|
@@ -19,11 +23,7 @@ And then execute:
|
|
19
23
|
|
20
24
|
$ bundle install
|
21
25
|
|
22
|
-
|
23
|
-
|
24
|
-
$ gem install gps_pvt
|
25
|
-
|
26
|
-
For Windows users, this gem requires Devkit because of native compilation.
|
26
|
+
For Windows users, this gem requires Devkit because of compilation of native shared library.
|
27
27
|
|
28
28
|
## Usage
|
29
29
|
|
@@ -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). 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:
|
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. Moreover, Ntrip URI of ntrip://(username):(password)@(caster_host):(port)/(mount_point), for exmaple, ```ntrip://test%40example.com:none@rtk2go.com:2101/NAIST-UBX``` (%40 is recognized as '@') is supported (version >= 0.8.4). 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
|
----|----
|
@@ -57,7 +57,7 @@ Additionally, the following command options *--key=value* are available.
|
|
57
57
|
| end_time | time string | end time to perform solution. Its format is the same as start_time. | v0.3.3 |
|
58
58
|
| <a name=opt_online_ephemeris>online_ephemeris</a> | URL string | based on observation, ephemeris which is previously broadcasted from satellite and currently published online will automatically be loaded. If value is not given, the default source "ftp://gssc.esa.int/gnss/data/daily/%Y/brdc/BRDC00IGS_R_%Y%j0000_01D_MN.rnx.gz" is used. The value string is converted with [strftime](https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html) before actual use. | v0.8.1 |
|
59
59
|
|
60
|
-
### For
|
60
|
+
### For advanced user
|
61
61
|
|
62
62
|
This library will be used like:
|
63
63
|
|
@@ -136,14 +136,14 @@ receiver.solver.correction = { # provide by using a Hash
|
|
136
136
|
|
137
137
|
# Dynamic customization of weight for each epoch
|
138
138
|
(class << receiver; self; end).instance_eval{ # do before parse_XXX
|
139
|
-
|
139
|
+
run_orig = instance_method(:run)
|
140
140
|
define_method(:run){|meas, t_meas, &b|
|
141
141
|
meas # observation, same as the 2nd argument of parse_XXX
|
142
142
|
receiver.solver.hooks[:relative_property] = proc{|prn, rel_prop, meas, rcv_e, t_arv, usr_pos, usr_vel|
|
143
143
|
# Do something based on meas, t_meas.
|
144
144
|
rel_prop
|
145
145
|
}
|
146
|
-
run_orig(meas, t_meas, &b)
|
146
|
+
run_orig.bind(self).call(meas, t_meas, &b)
|
147
147
|
}
|
148
148
|
}
|
149
149
|
```
|
data/gps_pvt.gemspec
CHANGED
@@ -59,8 +59,10 @@ Gem::Specification.new do |spec|
|
|
59
59
|
# Uncomment to register a new dependency of your gem
|
60
60
|
# spec.add_dependency "example-gem", "~> 1.0"
|
61
61
|
spec.add_dependency "rubyserial"
|
62
|
-
spec.add_development_dependency "rake"
|
62
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
63
63
|
spec.add_development_dependency "rake-compiler"
|
64
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
65
|
+
spec.add_development_dependency "matrix" if GPS_PVT::version_compare(RUBY_VERSION, "3.1") >= 0
|
64
66
|
|
65
67
|
# For more information and examples about making a new gem, checkout our
|
66
68
|
# guide at: https://bundler.io/guides/creating_gem.html
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# Ntrip (Networked Transport of RTCM via Internet Protocol)
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'uri'
|
5
|
+
require_relative 'version'
|
6
|
+
|
7
|
+
module GPS_PVT
|
8
|
+
class Ntrip < Net::HTTP
|
9
|
+
Net::HTTPResponse.class_eval{
|
10
|
+
orig = singleton_method(:read_new)
|
11
|
+
define_singleton_method(:read_new){|sock|
|
12
|
+
# handle Ntrip(rev1), which does not comply with HTTP
|
13
|
+
unless sock.respond_to?(:ntrip) then
|
14
|
+
orig.call(sock)
|
15
|
+
else
|
16
|
+
str = sock.readline
|
17
|
+
case str
|
18
|
+
when /\A(?:(?:HTTP(?:\/(\d+\.\d+))?|([^\d\s]+))\s+)?(\d\d\d)(?:\s+(.*))?\z/in
|
19
|
+
res = response_class($3).new($1 || '1.1', $3, $2 || $4)
|
20
|
+
each_response_header(sock){|k,v|
|
21
|
+
res.add_field k, v
|
22
|
+
} unless res.message == 'ICY' # or 'SOURCETABLE' for Ntrip(rev1)
|
23
|
+
res
|
24
|
+
else
|
25
|
+
raise Net::HTTPBadResponse, "wrong status line: #{str.dump}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
}
|
29
|
+
}
|
30
|
+
def on_connect
|
31
|
+
super
|
32
|
+
@socket.define_singleton_method(:ntrip){true}
|
33
|
+
end
|
34
|
+
|
35
|
+
SOURCE_TBL_ITEMS = {
|
36
|
+
:STR => [
|
37
|
+
:type, :mountpoint, :identifier, :format, :format_details,
|
38
|
+
:carrier, :nav_system, :network, :country, :latitude, :longitude,
|
39
|
+
:nmea, :solution, :generator, :compression, :authentication, :fee, :bitrate],
|
40
|
+
:CAS => [
|
41
|
+
:type, :host, :port, :identifier, :operator,
|
42
|
+
:nmea, :country, :latitude, :longitude, :fallback_host, :fallback_ip],
|
43
|
+
:NET => [
|
44
|
+
:type, :identifier, :operator, :authentication, :fee,
|
45
|
+
:web_net, :web_str, :web_reg],
|
46
|
+
}
|
47
|
+
def Ntrip.parse_source_table(str)
|
48
|
+
res = {}
|
49
|
+
str.lines.each{|line|
|
50
|
+
values = line.chomp.split(/\s*;\s*/)
|
51
|
+
type = values[0].to_sym
|
52
|
+
next unless keys = SOURCE_TBL_ITEMS[type]
|
53
|
+
next unless (values.size >= keys.size)
|
54
|
+
entry = Hash[*(keys.zip(values).flatten(1))]
|
55
|
+
entry[:misc] = values[(keys.size)..-1] if values.size > keys.size
|
56
|
+
(res[type] ||= []) << entry
|
57
|
+
}
|
58
|
+
res.define_singleton_method(:mount_points){
|
59
|
+
Hash[*((self[:STR] || []).collect{|entry|
|
60
|
+
[entry[:mountpoint], entry]
|
61
|
+
}.flatten(1))]
|
62
|
+
}
|
63
|
+
res
|
64
|
+
end
|
65
|
+
def generate_request(path, header)
|
66
|
+
req = Net::HTTP::Get.new(path, {
|
67
|
+
'User-Agent' => "GPS_PVT NTRIP client/#{GPS_PVT::VERSION}",
|
68
|
+
'Accept' => '*/*',
|
69
|
+
'Ntrip-Version' => 'Ntrip/2.0',
|
70
|
+
}.merge(header.select{|k, v| k.kind_of?(String)}))
|
71
|
+
header.each{|k, v|
|
72
|
+
next unless k.kind_of?(Symbol)
|
73
|
+
req.send(k, *v)
|
74
|
+
}
|
75
|
+
req
|
76
|
+
end
|
77
|
+
def get_source_table(header = {})
|
78
|
+
Ntrip.parse_source_table(request(generate_request('/', header)).read_body)
|
79
|
+
end
|
80
|
+
def get_data(mount_point, header = {}, &b)
|
81
|
+
request(generate_request("/#{mount_point}", header)){|res|
|
82
|
+
res.read_body(&b)
|
83
|
+
}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
require 'open-uri'
|
89
|
+
|
90
|
+
OpenURI.class_eval{
|
91
|
+
check_options_orig = singleton_method(:check_options)
|
92
|
+
define_singleton_method(:check_options){|options|
|
93
|
+
uri = options.delete(:uri)
|
94
|
+
case uri
|
95
|
+
when URI::Ntrip
|
96
|
+
options[:basic_auth] ||=
|
97
|
+
options.delete(:http_basic_authentication) ||
|
98
|
+
([:user, :password].collect{|k|
|
99
|
+
URI::decode_www_form_component(uri.send(k))
|
100
|
+
} rescue nil)
|
101
|
+
options['Ntrip-Version'] ||= "Ntrip/%3.1f"%[options.delete(:version)] if options[:version]
|
102
|
+
options['User-Agent'] ||= options[:user_agent]
|
103
|
+
options.select!{|k, v| v} #compact! Ruby >= 2.4.0
|
104
|
+
true
|
105
|
+
else
|
106
|
+
check_options_orig.call(options)
|
107
|
+
end
|
108
|
+
}
|
109
|
+
open_uri_orig = singleton_method(:open_uri)
|
110
|
+
define_singleton_method(:open_uri){|name, *rest, &b|
|
111
|
+
uri = URI::Generic === name ? name : URI.parse(name)
|
112
|
+
(rest[-1].kind_of?(Hash) ? rest : (rest << {}))[-1][:uri] = uri
|
113
|
+
open_uri_orig.call(uri, *rest, &b)
|
114
|
+
}
|
115
|
+
def OpenURI.open_ntrip(buf, target, proxy, options) # :nodoc:
|
116
|
+
GPS_PVT::Ntrip.start(target.host, target.port){|ntrip|
|
117
|
+
# get source table
|
118
|
+
tbl = ntrip.get_source_table(options)
|
119
|
+
|
120
|
+
# check mount point
|
121
|
+
mnt_pt = target.path.sub(%r|^/|, '')
|
122
|
+
prop = tbl.mount_points[mnt_pt]
|
123
|
+
raise Net::ProtocolError::new("Mount point(#{mnt_pt}) not found") unless prop
|
124
|
+
|
125
|
+
# set stream
|
126
|
+
buf.instance_eval{
|
127
|
+
@io, w = IO::pipe
|
128
|
+
@io.define_singleton_method(:property){prop}
|
129
|
+
Thread::new{
|
130
|
+
begin
|
131
|
+
ntrip.get_data(mnt_pt, options){|data| w << data}
|
132
|
+
rescue Errno::EPIPE;
|
133
|
+
rescue; raise
|
134
|
+
ensure; w.close
|
135
|
+
end
|
136
|
+
}
|
137
|
+
}
|
138
|
+
}
|
139
|
+
end
|
140
|
+
}
|
141
|
+
module URI
|
142
|
+
class Ntrip < HTTP
|
143
|
+
def buffer_open(buf, proxy, options)
|
144
|
+
OpenURI.open_ntrip(buf, self, proxy, options)
|
145
|
+
end
|
146
|
+
include OpenURI::OpenRead
|
147
|
+
end
|
148
|
+
if respond_to?(:register_scheme) then
|
149
|
+
register_scheme('NTRIP', Ntrip)
|
150
|
+
else
|
151
|
+
@@schemes['NTRIP'] = Ntrip
|
152
|
+
end
|
153
|
+
end
|
data/lib/gps_pvt/util.rb
CHANGED
@@ -23,16 +23,18 @@ proc{
|
|
23
23
|
}
|
24
24
|
def eof?; false; end
|
25
25
|
}
|
26
|
-
Kernel
|
27
|
-
open_orig =
|
26
|
+
module Kernel
|
27
|
+
open_orig = instance_method(:open)
|
28
28
|
define_method(:open){|*args, &b|
|
29
|
-
return open_orig.call(*args, &b) unless Serial::SPEC =~ args[0]
|
29
|
+
return open_orig.bind(self).call(*args, &b) unless Serial::SPEC =~ args[0]
|
30
30
|
Serial::new($1, $2 ? $2.to_i : 115200)
|
31
31
|
}
|
32
|
-
|
32
|
+
module_function(:open)
|
33
|
+
end
|
33
34
|
}.call if require 'rubyserial'
|
34
35
|
|
35
36
|
require 'open-uri'
|
37
|
+
require_relative 'ntrip'
|
36
38
|
|
37
39
|
module GPS_PVT
|
38
40
|
module Util
|
@@ -53,8 +55,7 @@ module Util
|
|
53
55
|
end
|
54
56
|
def get_txt(fname_or_uri)
|
55
57
|
is_uri = fname_or_uri.kind_of?(URI)
|
56
|
-
(
|
57
|
-
.send(:open, fname_or_uri){|src|
|
58
|
+
(is_uri ? URI : Kernel).send(:open, fname_or_uri){|src|
|
58
59
|
compressed = proc{
|
59
60
|
case src.content_type
|
60
61
|
when /gzip/; next :gz
|
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.8.
|
4
|
+
version: 0.8.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: 2022-
|
11
|
+
date: 2022-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyserial
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
33
|
+
version: '13.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
40
|
+
version: '13.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake-compiler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
55
69
|
description: This module calculate PVT by using raw observation obtained from a GPS
|
56
70
|
receiver
|
57
71
|
email:
|
@@ -67,6 +81,7 @@ files:
|
|
67
81
|
- CHANGELOG.md
|
68
82
|
- CODE_OF_CONDUCT.md
|
69
83
|
- Gemfile
|
84
|
+
- LICENSE
|
70
85
|
- README.md
|
71
86
|
- Rakefile
|
72
87
|
- bin/console
|
@@ -117,6 +132,7 @@ files:
|
|
117
132
|
- gps_pvt.gemspec
|
118
133
|
- gps_pvt.rbs
|
119
134
|
- lib/gps_pvt.rb
|
135
|
+
- lib/gps_pvt/ntrip.rb
|
120
136
|
- lib/gps_pvt/receiver.rb
|
121
137
|
- lib/gps_pvt/receiver/extension.rb
|
122
138
|
- lib/gps_pvt/ubx.rb
|