gps_pvt 0.5.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -7
- data/Rakefile +42 -23
- data/exe/gps_pvt +13 -6
- data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +44 -0
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +9015 -7695
- data/ext/ninja-scan-light/tool/algorithm/interpolate.h +121 -0
- data/ext/ninja-scan-light/tool/navigation/ANTEX.h +747 -0
- data/ext/ninja-scan-light/tool/navigation/GLONASS.h +37 -35
- data/ext/ninja-scan-light/tool/navigation/GLONASS_Solver.h +16 -13
- data/ext/ninja-scan-light/tool/navigation/GPS.h +121 -29
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +19 -12
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +39 -11
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +40 -171
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +21 -13
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +19 -16
- data/ext/ninja-scan-light/tool/navigation/SP3.h +1189 -0
- data/ext/ninja-scan-light/tool/navigation/coordinate.h +81 -1
- data/ext/ninja-scan-light/tool/swig/GPS.i +153 -40
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +503 -0
- data/ext/ninja-scan-light/tool/util/text_helper.h +248 -0
- data/lib/gps_pvt/receiver.rb +24 -0
- data/lib/gps_pvt/util.rb +25 -7
- data/lib/gps_pvt/version.rb +1 -1
- metadata +6 -2
@@ -0,0 +1,248 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2022, M.Naruoka (fenrir)
|
3
|
+
* All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
6
|
+
* are permitted provided that the following conditions are met:
|
7
|
+
*
|
8
|
+
* - Redistributions of source code must retain the above copyright notice,
|
9
|
+
* this list of conditions and the following disclaimer.
|
10
|
+
* - Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
* this list of conditions and the following disclaimer in the documentation
|
12
|
+
* and/or other materials provided with the distribution.
|
13
|
+
* - Neither the name of the naruoka.org nor the names of its contributors
|
14
|
+
* may be used to endorse or promote products derived from this software
|
15
|
+
* without specific prior written permission.
|
16
|
+
*
|
17
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
19
|
+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
21
|
+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
22
|
+
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
23
|
+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
24
|
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
25
|
+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
26
|
+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
28
|
+
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
*
|
30
|
+
*/
|
31
|
+
|
32
|
+
/** @file
|
33
|
+
* @brief Helper class/functions for text processing
|
34
|
+
*
|
35
|
+
*/
|
36
|
+
|
37
|
+
#ifndef __TEXT_HELPER_H__
|
38
|
+
#define __TEXT_HELPER_H__
|
39
|
+
|
40
|
+
#include <istream>
|
41
|
+
#include <ostream>
|
42
|
+
#include <sstream>
|
43
|
+
#include <string>
|
44
|
+
#include <iomanip>
|
45
|
+
#include <ctime>
|
46
|
+
#include <cstddef>
|
47
|
+
#include <cstring>
|
48
|
+
#include <limits>
|
49
|
+
|
50
|
+
template <class U = void>
|
51
|
+
struct TextHelper {
|
52
|
+
struct crlf_stream_t : public std::istream {
|
53
|
+
crlf_stream_t(std::istream &is) : std::istream(is.rdbuf()) {}
|
54
|
+
/**
|
55
|
+
* getline() for multi-platform (in addition to \n, \r\n and \r are supported)
|
56
|
+
*
|
57
|
+
* @see https://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf
|
58
|
+
* @see https://en.cppreference.com/w/cpp/io/basic_istream/getline
|
59
|
+
* TODO gcount() mismatch
|
60
|
+
*/
|
61
|
+
std::istream& getline(
|
62
|
+
typename std::istream::char_type* s,
|
63
|
+
std::streamsize n){
|
64
|
+
std::streamsize i(1), consumed(0);
|
65
|
+
typename std::istream::sentry se(*this, true);
|
66
|
+
if((bool)se){
|
67
|
+
std::streambuf* sb(this->rdbuf());
|
68
|
+
for(; i < n; ++i){
|
69
|
+
int c(sb->sbumpc());
|
70
|
+
if(c == std::streambuf::traits_type::eof()){
|
71
|
+
this->setstate(std::ios::eofbit);
|
72
|
+
break;
|
73
|
+
}
|
74
|
+
++consumed;
|
75
|
+
if(c == '\n'){
|
76
|
+
break;
|
77
|
+
}else if(c == '\r'){
|
78
|
+
if(sb->sgetc() == '\n'){
|
79
|
+
sb->sbumpc();
|
80
|
+
++consumed;
|
81
|
+
}
|
82
|
+
break;
|
83
|
+
}
|
84
|
+
*(s++) = (typename std::istream::char_type)c;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
if(((i == 1) && (consumed == 0)) || (i == n)){
|
88
|
+
this->setstate(std::ios::failbit);
|
89
|
+
}else{
|
90
|
+
*s = '\0';
|
91
|
+
}
|
92
|
+
return *this;
|
93
|
+
}
|
94
|
+
};
|
95
|
+
|
96
|
+
template <class T, bool is_integer = std::numeric_limits<T>::is_integer>
|
97
|
+
struct format_t {
|
98
|
+
static bool d(
|
99
|
+
std::string &buf, const int &offset, const int &length, void *value, const int &opt = 0, const bool &str2val = true){
|
100
|
+
if(str2val){
|
101
|
+
std::stringstream ss(buf.substr(offset, length));
|
102
|
+
ss >> *(T *)value;
|
103
|
+
return (ss.rdstate() & std::ios_base::failbit) == 0;
|
104
|
+
}else{
|
105
|
+
std::stringstream ss;
|
106
|
+
ss << std::setfill(opt == 1 ? '0' : ' ') << std::right << std::setw(length) << *(T *)value;
|
107
|
+
buf.replace(offset, length, ss.str());
|
108
|
+
return true;
|
109
|
+
}
|
110
|
+
}
|
111
|
+
static bool d_blank(
|
112
|
+
std::string &buf, const int &offset, const int &length, void *value,
|
113
|
+
const int &opt = 0, const bool &str2val = true){
|
114
|
+
if((!str2val) && (*(T *)value == 0)){return true;}
|
115
|
+
return d(buf, offset, length, value, opt, str2val);
|
116
|
+
}
|
117
|
+
static bool f(
|
118
|
+
std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
|
119
|
+
if(str2val){
|
120
|
+
std::stringstream ss(buf.substr(offset, length));
|
121
|
+
ss >> *(T *)value;
|
122
|
+
return (ss.rdstate() & std::ios_base::failbit) == 0;
|
123
|
+
}else{
|
124
|
+
std::stringstream ss;
|
125
|
+
ss << std::setfill(' ') << std::right << std::setw(length)
|
126
|
+
<< std::setprecision(precision) << std::fixed
|
127
|
+
<< *(T *)value;
|
128
|
+
buf.replace(offset, length, ss.str());
|
129
|
+
return true;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
static bool f_dot_head(
|
133
|
+
std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
|
134
|
+
bool res(f(buf, offset, length, value, precision, str2val));
|
135
|
+
if((!str2val) && res){
|
136
|
+
if((*(T *)value) >= 0){
|
137
|
+
if((*(T *)value) < 1){
|
138
|
+
int i(length - precision - 2);
|
139
|
+
// 0.12345 => .12345
|
140
|
+
if(i >= 0){buf[i + offset] = ' ';}
|
141
|
+
}
|
142
|
+
}else{
|
143
|
+
if((*(T *)value) > -1){
|
144
|
+
int i(length - precision - 2);
|
145
|
+
// -0.12345 => -.12345
|
146
|
+
if(i >= 0){buf[i + offset] = '-';}
|
147
|
+
if(--i >= 0){buf[i + offset] = ' ';}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
151
|
+
return res;
|
152
|
+
}
|
153
|
+
};
|
154
|
+
template <class T>
|
155
|
+
struct format_t<T, true> : public format_t<T, false> {
|
156
|
+
static bool f(
|
157
|
+
std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
|
158
|
+
double v(*(T *)value);
|
159
|
+
bool res(
|
160
|
+
format_t<double, false>::f(buf, offset, length, &v, precision, str2val));
|
161
|
+
*(T *)value = static_cast<T>(v);
|
162
|
+
return res;
|
163
|
+
}
|
164
|
+
static bool f_dot_head(
|
165
|
+
std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
|
166
|
+
double v(*(T *)value);
|
167
|
+
bool res(
|
168
|
+
format_t<double, false>::f_dot_head(buf, offset, length, &v, precision, str2val));
|
169
|
+
*(T *)value = static_cast<T>(v);
|
170
|
+
return res;
|
171
|
+
}
|
172
|
+
};
|
173
|
+
|
174
|
+
struct convert_item_t {
|
175
|
+
bool (*func)(
|
176
|
+
std::string &buf, const int &offset, const int &length, void *value,
|
177
|
+
const int &opt, const bool &str2val);
|
178
|
+
int offset;
|
179
|
+
int length;
|
180
|
+
int value_offset;
|
181
|
+
int opt;
|
182
|
+
};
|
183
|
+
|
184
|
+
/**
|
185
|
+
* @param recovery if conversion fails, then this functor is invoked.
|
186
|
+
* If recovery is successfully performed, this functor should return true.
|
187
|
+
* The return value of this function reflects it.
|
188
|
+
* @return (bool) if all conversion are successfully performed, true is returned; otherwise false.
|
189
|
+
*/
|
190
|
+
static bool str2val(
|
191
|
+
const convert_item_t *items, const int &size, const std::string &buf, void *values,
|
192
|
+
bool (*recovery)(const int &, const std::string &, void *) = NULL){
|
193
|
+
// str => value
|
194
|
+
bool res(true);
|
195
|
+
for(int i(0); i < size; ++i){
|
196
|
+
if((*items[i].func)(
|
197
|
+
const_cast<std::string &>(buf), items[i].offset, items[i].length, (char *)values + items[i].value_offset,
|
198
|
+
items[i].opt, true)){continue;}
|
199
|
+
res &= (recovery ? (*recovery)(i, buf, values) : false);
|
200
|
+
}
|
201
|
+
return res;
|
202
|
+
}
|
203
|
+
template <int N>
|
204
|
+
static inline bool str2val(
|
205
|
+
const convert_item_t (&items)[N], const std::string &buf, void *values,
|
206
|
+
bool (*recovery)(const int &, const std::string &, void *) = NULL){
|
207
|
+
return str2val(items, N, buf, values, recovery);
|
208
|
+
}
|
209
|
+
|
210
|
+
/**
|
211
|
+
* @return If all conversion are successfully performed, then true; otherwise false;
|
212
|
+
*/
|
213
|
+
static bool val2str(
|
214
|
+
const convert_item_t *items, const int &size,
|
215
|
+
std::string &buf, const void *values){
|
216
|
+
// value => string
|
217
|
+
bool res(true);
|
218
|
+
for(int i(0); i < size; ++i){
|
219
|
+
res &= (*items[i].func)(
|
220
|
+
buf, items[i].offset, items[i].length, (char *)(const_cast<void *>(values)) + items[i].value_offset,
|
221
|
+
items[i].opt, false);
|
222
|
+
}
|
223
|
+
return res;
|
224
|
+
}
|
225
|
+
template <int N>
|
226
|
+
static inline bool val2str(
|
227
|
+
const convert_item_t (&items)[N], std::string &buf, const void *values){
|
228
|
+
return val2str(items, N, buf, values);
|
229
|
+
}
|
230
|
+
};
|
231
|
+
|
232
|
+
template <>
|
233
|
+
template <>
|
234
|
+
struct TextHelper<>::format_t<char, false> {
|
235
|
+
static bool c(
|
236
|
+
std::string &buf, const int &offset, const int &length, void *value,
|
237
|
+
const int &opt = 0, const bool &str2val = true){
|
238
|
+
if(str2val){
|
239
|
+
return buf.copy(static_cast<char *>(value), length, offset) == (std::size_t)length;
|
240
|
+
}else{
|
241
|
+
if((length <= 0) || (!(static_cast<char *>(value)[0]))){return true;}
|
242
|
+
buf.replace(offset, length, static_cast<char *>(value), length);
|
243
|
+
return true;
|
244
|
+
}
|
245
|
+
}
|
246
|
+
};
|
247
|
+
|
248
|
+
#endif /* __TEXT_HELPER__ */
|
data/lib/gps_pvt/receiver.rb
CHANGED
@@ -627,5 +627,29 @@ class Receiver
|
|
627
627
|
}
|
628
628
|
$stderr.puts ", %d epochs."%[count]
|
629
629
|
end
|
630
|
+
|
631
|
+
def attach_sp3(src)
|
632
|
+
fname = Util::get_txt(src)
|
633
|
+
@sp3 ||= GPS::SP3::new
|
634
|
+
read_items = @sp3.read(fname)
|
635
|
+
raise "Format error! (Not SP3) #{src}" if read_items < 0
|
636
|
+
$stderr.puts "Read SP3 file (%s): %d items."%[src, read_items]
|
637
|
+
sats = @sp3.satellites
|
638
|
+
@sp3.class.constants.each{|sys|
|
639
|
+
next unless /^SYS_(?!SYSTEMS)(.*)/ =~ sys.to_s
|
640
|
+
idx, sys_name = [@sp3.class.const_get(sys), $1]
|
641
|
+
next unless sats[idx] > 0
|
642
|
+
next unless @sp3.push(@solver, idx)
|
643
|
+
$stderr.puts "Change ephemeris source of #{sys_name} to SP3"
|
644
|
+
}
|
645
|
+
end
|
646
|
+
|
647
|
+
def attach_antex(src)
|
648
|
+
fname = Util::get_txt(src)
|
649
|
+
raise "Specify SP3 before ANTEX application!" unless @sp3
|
650
|
+
applied_items = @sp3.apply_antex(fname)
|
651
|
+
raise "Format error! (Not ANTEX) #{src}" unless applied_items >= 0
|
652
|
+
$stderr.puts "SP3 correction with ANTEX file (%s): %d items have been processed."%[src, applied_items]
|
653
|
+
end
|
630
654
|
end
|
631
655
|
end
|
data/lib/gps_pvt/util.rb
CHANGED
@@ -1,27 +1,45 @@
|
|
1
1
|
require 'open-uri'
|
2
2
|
require 'tempfile'
|
3
3
|
require 'uri'
|
4
|
-
require 'zlib'
|
5
4
|
|
6
5
|
module GPS_PVT
|
7
6
|
module Util
|
8
7
|
class << self
|
9
|
-
def inflate(src)
|
10
|
-
|
8
|
+
def inflate(src, type = :gz)
|
9
|
+
case type
|
10
|
+
when :gz
|
11
|
+
require 'zlib'
|
12
|
+
Zlib::GzipReader.send(*(src.kind_of?(IO) ? [:new, src] : [:open, src]))
|
13
|
+
when :Z
|
14
|
+
res = IO::popen("uncompress -c #{src.kind_of?(IO) ? '-' : src}", 'r+')
|
15
|
+
res.print(src.read) if src.kind_of?(IO)
|
16
|
+
res.close_write
|
17
|
+
res
|
18
|
+
else
|
19
|
+
raise "Unknown compression type: #{type} of #{src}"
|
20
|
+
end
|
11
21
|
end
|
12
22
|
def get_txt(fname_or_uri)
|
13
23
|
is_uri = fname_or_uri.kind_of?(URI)
|
14
24
|
((is_uri && (RUBY_VERSION >= "2.5.0")) ? URI : Kernel) \
|
15
25
|
.send(:open, fname_or_uri){|src|
|
16
|
-
|
17
|
-
|
26
|
+
compressed = proc{
|
27
|
+
case src.content_type
|
28
|
+
when /gzip/; next :gz
|
29
|
+
end if is_uri
|
30
|
+
case fname_or_uri.to_s
|
31
|
+
when /\.gz$/; next :gz
|
32
|
+
when /\.Z$/; next :Z
|
33
|
+
end
|
34
|
+
nil
|
35
|
+
}.call
|
18
36
|
is_file = src.kind_of?(File) || src.kind_of?(Tempfile)
|
19
37
|
|
20
|
-
return src.path if ((!
|
38
|
+
return src.path if ((!compressed) and is_file)
|
21
39
|
|
22
40
|
Tempfile::open(File::basename($0, '.*')){|dst|
|
23
41
|
dst.binmode
|
24
|
-
dst.write((
|
42
|
+
dst.write((compressed ? inflate(is_file ? src.path : src, compressed) : src).read)
|
25
43
|
dst.rewind
|
26
44
|
dst.path
|
27
45
|
}
|
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.
|
4
|
+
version: 0.6.2
|
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-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -62,6 +62,8 @@ files:
|
|
62
62
|
- ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx
|
63
63
|
- ext/gps_pvt/extconf.rb
|
64
64
|
- ext/ninja-scan-light/tool/algorithm/integral.h
|
65
|
+
- ext/ninja-scan-light/tool/algorithm/interpolate.h
|
66
|
+
- ext/ninja-scan-light/tool/navigation/ANTEX.h
|
65
67
|
- ext/ninja-scan-light/tool/navigation/EGM.h
|
66
68
|
- ext/ninja-scan-light/tool/navigation/GLONASS.h
|
67
69
|
- ext/ninja-scan-light/tool/navigation/GLONASS_Solver.h
|
@@ -76,6 +78,7 @@ files:
|
|
76
78
|
- ext/ninja-scan-light/tool/navigation/RINEX.h
|
77
79
|
- ext/ninja-scan-light/tool/navigation/SBAS.h
|
78
80
|
- ext/ninja-scan-light/tool/navigation/SBAS_Solver.h
|
81
|
+
- ext/ninja-scan-light/tool/navigation/SP3.h
|
79
82
|
- ext/ninja-scan-light/tool/navigation/WGS84.h
|
80
83
|
- ext/ninja-scan-light/tool/navigation/coordinate.h
|
81
84
|
- ext/ninja-scan-light/tool/param/bit_array.h
|
@@ -92,6 +95,7 @@ files:
|
|
92
95
|
- ext/ninja-scan-light/tool/swig/makefile
|
93
96
|
- ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb
|
94
97
|
- ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb
|
98
|
+
- ext/ninja-scan-light/tool/util/text_helper.h
|
95
99
|
- gps_pvt.gemspec
|
96
100
|
- gps_pvt.rbs
|
97
101
|
- lib/gps_pvt.rb
|