gps_pvt 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![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)
|
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
|