gps_pvt 0.1.1
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 +7 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +10 -0
- data/README.md +86 -0
- data/Rakefile +86 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +6613 -0
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +16019 -0
- data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +21050 -0
- data/ext/gps_pvt/extconf.rb +70 -0
- data/ext/ninja-scan-light/tool/navigation/EGM.h +2971 -0
- data/ext/ninja-scan-light/tool/navigation/GPS.h +2432 -0
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +479 -0
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +1081 -0
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_MultiFrequency.h +199 -0
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_RAIM.h +210 -0
- data/ext/ninja-scan-light/tool/navigation/MagneticField.h +928 -0
- data/ext/ninja-scan-light/tool/navigation/NTCM.h +211 -0
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +1781 -0
- data/ext/ninja-scan-light/tool/navigation/WGS84.h +186 -0
- data/ext/ninja-scan-light/tool/navigation/coordinate.h +406 -0
- data/ext/ninja-scan-light/tool/param/bit_array.h +145 -0
- data/ext/ninja-scan-light/tool/param/complex.h +558 -0
- data/ext/ninja-scan-light/tool/param/matrix.h +4049 -0
- data/ext/ninja-scan-light/tool/param/matrix_fixed.h +665 -0
- data/ext/ninja-scan-light/tool/param/matrix_special.h +562 -0
- data/ext/ninja-scan-light/tool/param/quaternion.h +765 -0
- data/ext/ninja-scan-light/tool/param/vector3.h +651 -0
- data/ext/ninja-scan-light/tool/swig/Coordinate.i +177 -0
- data/ext/ninja-scan-light/tool/swig/GPS.i +1102 -0
- data/ext/ninja-scan-light/tool/swig/SylphideMath.i +1234 -0
- data/ext/ninja-scan-light/tool/swig/extconf.rb +5 -0
- data/ext/ninja-scan-light/tool/swig/makefile +53 -0
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +417 -0
- data/ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb +489 -0
- data/gps_pvt.gemspec +57 -0
- data/lib/gps_pvt/receiver.rb +375 -0
- data/lib/gps_pvt/ubx.rb +148 -0
- data/lib/gps_pvt/version.rb +5 -0
- data/lib/gps_pvt.rb +9 -0
- data/sig/gps_pvt.rbs +4 -0
- metadata +117 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
SWIG = swig
|
2
|
+
SWIGFLAGS = -c++ -ruby $(shell if [ -n "$$MSYSTEM" ]; then echo -D__MINGW__; fi)
|
3
|
+
INCLUDES = -I../
|
4
|
+
BUILD_DIR = build_SWIG
|
5
|
+
|
6
|
+
RUBY = ruby
|
7
|
+
RUBY_CONF = extconf.rb
|
8
|
+
|
9
|
+
SRCS = $(shell ls *.i)
|
10
|
+
|
11
|
+
PACKAGES = $(SRCS:.i=.so)
|
12
|
+
|
13
|
+
all : $(BUILD_DIR) depend $(PACKAGES)
|
14
|
+
|
15
|
+
depend : INCLUDES+=-I$(shell echo $${MSYSTEM_PREFIX:-/usr})/include/
|
16
|
+
|
17
|
+
# �w�b�_�[�t�@�C���̈ˑ��W
|
18
|
+
depend : $(SRCS)
|
19
|
+
if [ -f $(BUILD_DIR)/depend.inc ]; then rm -f $(BUILD_DIR)/depend.inc; fi
|
20
|
+
for i in $^; do\
|
21
|
+
$(SWIG) $(SWIGFLAGS) $(INCLUDES) -MM -MP $$i | sed -e 's/[^\.]*\.cxx/$$\(BUILD_DIR\)\/&/g' >> $(BUILD_DIR)/depend.inc;\
|
22
|
+
done
|
23
|
+
|
24
|
+
-include $(BUILD_DIR)/depend.inc
|
25
|
+
|
26
|
+
$(PACKAGES) : $(patsubst %,$(BUILD_DIR)/%,$(PACKAGES))
|
27
|
+
|
28
|
+
$(BUILD_DIR)/BoostDistributions_wrap.cxx : INCLUDES+=-I$(shell echo $${MSYSTEM_PREFIX:-/usr})/include/
|
29
|
+
|
30
|
+
$(BUILD_DIR)/%_wrap.cxx : %.i
|
31
|
+
$(SWIG) $(SWIGFLAGS) $(INCLUDES) -o $@ $<
|
32
|
+
|
33
|
+
$(BUILD_DIR)/%.so : PACKAGE = $(shell echo $@ | sed -e 's/^$(BUILD_DIR)\/\([^\.]*\)\.so/\1/g')
|
34
|
+
$(BUILD_DIR)/%.so : $(BUILD_DIR)/%_wrap.cxx $(RUBY_CONF)
|
35
|
+
echo "building $(PACKAGE) ..."
|
36
|
+
if ! [ -d $(BUILD_DIR)/$(PACKAGE) ]; then mkdir $(BUILD_DIR)/$(PACKAGE); fi
|
37
|
+
cp $(RUBY_CONF) $(BUILD_DIR)/$(PACKAGE)/
|
38
|
+
cp $(BUILD_DIR)/$(PACKAGE)_wrap.cxx $(BUILD_DIR)/$(PACKAGE)/
|
39
|
+
cd $(BUILD_DIR)/$(PACKAGE); \
|
40
|
+
echo 'create_makefile("$(PACKAGE)")' >> $(RUBY_CONF); \
|
41
|
+
$(RUBY) $(RUBY_CONF); \
|
42
|
+
make; \
|
43
|
+
cp *.so ../
|
44
|
+
|
45
|
+
$(BUILD_DIR) :
|
46
|
+
mkdir $@
|
47
|
+
|
48
|
+
clean :
|
49
|
+
rm -rf $(BUILD_DIR)/*
|
50
|
+
|
51
|
+
run : all
|
52
|
+
|
53
|
+
.PHONY : clean all depend
|
@@ -0,0 +1,417 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
$: << File::join(File::dirname(__FILE__), '..', 'build_SWIG')
|
6
|
+
require 'GPS.so'
|
7
|
+
|
8
|
+
describe 'GPS solver' do
|
9
|
+
let(:input){{
|
10
|
+
:rinex_nav => Tempfile::open{|f|
|
11
|
+
if true then
|
12
|
+
f.write(<<-__RINEX_NAV_TEXT__)
|
13
|
+
2.10 N: GPS NAV DATA RINEX VERSION / TYPE
|
14
|
+
teqc 2013Mar15 BKG Frankfurt 20150617 00:16:14UTCPGM / RUN BY / DATE
|
15
|
+
Linux 2.4.21-27.ELsmp|Opteron|gcc -static|Linux x86_64|=+ COMMENT
|
16
|
+
2.10 N: GPS NAV DATA COMMENT
|
17
|
+
teqc 2008Feb15 20150617 00:10:22UTCCOMMENT
|
18
|
+
Linux 2.4.20-8|Pentium IV|gcc -static|Linux|486/DX+ COMMENT
|
19
|
+
1.3970D-08 2.2352D-08 -1.1921D-07 -1.1921D-07 ION ALPHA
|
20
|
+
1.1059D+05 1.6384D+05 -6.5536D+04 -5.2429D+05 ION BETA
|
21
|
+
3.725290298462D-09 1.509903313490D-14 319488 1849 DELTA-UTC: A0,A1,T,W
|
22
|
+
16 LEAP SECONDS
|
23
|
+
Concatenated RINEX files (28/) COMMENT
|
24
|
+
Original file name: brdc1670.15n COMMENT
|
25
|
+
END OF HEADER
|
26
|
+
31 15 6 16 0 0 0.0 3.128303214908D-04-1.136868377216D-12 0.000000000000D+00
|
27
|
+
7.800000000000D+01 1.292812500000D+02 4.074098273975D-09 1.410690806649D+00
|
28
|
+
6.768852472305D-06 8.027532137930D-03 4.271045327187D-06 5.153535821915D+03
|
29
|
+
1.728000000000D+05 9.872019290924D-08 8.650894583569D-01 8.940696716309D-08
|
30
|
+
9.750288799237D-01 3.013750000000D+02-5.268559212524D-01-8.036049019412D-09
|
31
|
+
3.664438352852D-10 1.000000000000D+00 1.849000000000D+03 0.000000000000D+00
|
32
|
+
2.000000000000D+00 0.000000000000D+00-1.350417733192D-08 7.800000000000D+01
|
33
|
+
1.663560000000D+05 4.000000000000D+00
|
34
|
+
24 15 6 16 0 0 0.0-4.998780786991D-05-5.684341886081D-13 0.000000000000D+00
|
35
|
+
9.000000000000D+01 1.401250000000D+02 4.642336229081D-09 2.380519254182D+00
|
36
|
+
7.258728146553D-06 3.228595596738D-03 3.971159458160D-06 5.153673912048D+03
|
37
|
+
1.728000000000D+05-2.980232238770D-08 8.160388274984D-01-1.490116119385D-08
|
38
|
+
9.533772739559D-01 2.969375000000D+02 3.612098431884D-01-8.379634759709D-09
|
39
|
+
4.025167664390D-10 1.000000000000D+00 1.849000000000D+03 0.000000000000D+00
|
40
|
+
2.900000000000D+00 0.000000000000D+00 2.328306436539D-09 9.000000000000D+01
|
41
|
+
1.656600000000D+05 4.000000000000D+00
|
42
|
+
12 15 6 16 0 0 0.0 3.018006682396D-04 3.183231456205D-12 0.000000000000D+00
|
43
|
+
9.000000000000D+01-8.984375000000D+01 4.146244136282D-09 1.019955493515D+00
|
44
|
+
-4.906207323074D-06 5.596161005087D-03 2.166256308556D-06 5.153664655685D+03
|
45
|
+
1.728000000000D+05-3.352761268616D-08 1.926955253672D+00 9.685754776001D-08
|
46
|
+
9.895896897770D-01 3.531562500000D+02 6.166481681571D-01-8.222842514396D-09
|
47
|
+
-2.525105180766D-10 1.000000000000D+00 1.849000000000D+03 0.000000000000D+00
|
48
|
+
2.000000000000D+00 0.000000000000D+00-1.210719347000D-08 9.000000000000D+01
|
49
|
+
1.708800000000D+05 4.000000000000D+00
|
50
|
+
25 15 6 16 0 0 0.0-2.291053533554D-06-4.206412995700D-12 0.000000000000D+00
|
51
|
+
4.300000000000D+01-8.231250000000D+01 4.456614188797D-09 3.514302168106D-01
|
52
|
+
-4.393979907036D-06 4.659408819862D-03 1.480802893639D-06 5.153666315079D+03
|
53
|
+
1.728000000000D+05 0.000000000000D+00 1.880081553172D+00 1.080334186554D-07
|
54
|
+
9.780612252959D-01 3.641250000000D+02 7.406192694225D-01-8.389992700586D-09
|
55
|
+
-1.742929689463D-10 1.000000000000D+00 1.849000000000D+03 0.000000000000D+00
|
56
|
+
2.000000000000D+00 0.000000000000D+00 5.587935447693D-09 4.300000000000D+01
|
57
|
+
1.728000000000D+05
|
58
|
+
18 15 6 15 23 59 44.0 4.096841439605D-04 2.955857780762D-12 0.000000000000D+00
|
59
|
+
0.000000000000D+00-2.200000000000D+01 5.964177003340D-09-4.658085121885D-01
|
60
|
+
-1.063570380211D-06 1.631921075750D-02 5.243346095085D-06 5.153597631454D+03
|
61
|
+
1.727840000000D+05-9.499490261078D-08-1.282443549024D+00 1.769512891769D-07
|
62
|
+
9.246030417022D-01 2.601875000000D+02-1.955724914307D+00-8.981445541829D-09
|
63
|
+
-4.760912596834D-10 1.000000000000D+00 1.849000000000D+03 0.000000000000D+00
|
64
|
+
2.000000000000D+00 0.000000000000D+00-1.117587089539D-08 0.000000000000D+00
|
65
|
+
1.696560000000D+05 4.000000000000D+00
|
66
|
+
29 15 6 16 0 0 0.0 6.168931722641D-04 2.273736754432D-12 0.000000000000D+00
|
67
|
+
7.300000000000D+01-1.041875000000D+02 4.061597753278D-09 5.907941646969D-01
|
68
|
+
-5.280598998070D-06 1.195417135023D-03 1.201778650284D-05 5.153755130768D+03
|
69
|
+
1.728000000000D+05 9.313225746155D-09 2.981267878597D+00-1.303851604462D-08
|
70
|
+
9.739471617229D-01 1.573125000000D+02-5.419126340021D-01-7.659961925303D-09
|
71
|
+
2.107230631757D-10 1.000000000000D+00 1.849000000000D+03 0.000000000000D+00
|
72
|
+
2.000000000000D+00 0.000000000000D+00-9.778887033463D-09 7.300000000000D+01
|
73
|
+
1.656180000000D+05 4.000000000000D+00
|
74
|
+
__RINEX_NAV_TEXT__
|
75
|
+
else # equivalent
|
76
|
+
open(File::join(File::dirname(__FILE__), "..", "..", "test_log", "brdc1670.15n"), 'r'){|io|
|
77
|
+
while (str = io.readline)
|
78
|
+
f.puts("%-80s"%[str.chomp])
|
79
|
+
break if str =~ /END OF HEADER/
|
80
|
+
end
|
81
|
+
while !io.eof?
|
82
|
+
entry = 8.times.collect{io.readline}
|
83
|
+
next unless entry[0] =~ /^([ \d]\d) /
|
84
|
+
prn = $1.to_i
|
85
|
+
next unless entry[6] =~ /(\d\.\d{12})D([+-]\d{2})\s*$/
|
86
|
+
iode = ($1.to_f * (10 ** $2.to_i)).to_i
|
87
|
+
next unless [[12, 90], [18, 0], [24, 90], [25, 43], [29, 73], [31, 78]] \
|
88
|
+
.include?([prn, iode])
|
89
|
+
entry.each{|str|
|
90
|
+
f.print("%-80s\n"%[str.chomp])
|
91
|
+
}
|
92
|
+
end
|
93
|
+
}
|
94
|
+
end
|
95
|
+
f.path
|
96
|
+
},
|
97
|
+
:measurement => proc{
|
98
|
+
l1p = GPS::Measurement::L1_PSEUDORANGE
|
99
|
+
l1d = GPS::Measurement::L1_RANGE_RATE
|
100
|
+
{
|
101
|
+
12 => {l1p => 23707858.8131, l1d => -466.953123206},
|
102
|
+
18 => {l1p => 25319310.9754, l1d => -453.797772239},
|
103
|
+
24 => {l1p => 25683081.3903, l1d => -579.768048832},
|
104
|
+
25 => {l1p => 21551698.5927, l1d => -847.86674626},
|
105
|
+
29 => {l1p => 23637198.3968, l1d => -1560.30646593},
|
106
|
+
31 => {l1p => 23707474.1231, l1d => -1423.67588761},
|
107
|
+
}
|
108
|
+
}.call,
|
109
|
+
:rinex_obs => Tempfile::open{|f|
|
110
|
+
if true then
|
111
|
+
f.write(<<-__RINEX_OBS_TEXT__)
|
112
|
+
2.11 OBSERVATION DATA M (MIXED) RINEX VERSION / TYPE
|
113
|
+
BINEX2RINEX 1.00 GSI, JAPAN 20150617 18:30:58UTCPGM / RUN BY / DATE
|
114
|
+
0228 MARKER NAME
|
115
|
+
GSI, JAPAN GEOSPATIAL INFORMATION AUTHORITY OF JAPAOBSERVER / AGENCY
|
116
|
+
00000 TRIMBLE NETR9 4.93,26/NOV/2014 REC # / TYPE / VERS
|
117
|
+
TRM59800.80 GSI ANT # / TYPE
|
118
|
+
-3952590.4754 3360273.8926 3697987.2632 APPROX POSITION XYZ
|
119
|
+
0.0000 0.0000 0.0000 ANTENNA: DELTA H/E/N
|
120
|
+
1 1 WAVELENGTH FACT L1/2
|
121
|
+
6 L1 C1 L2 P2 S1 S2 # / TYPES OF OBSERV
|
122
|
+
2015 6 16 0 0 0.0000000 GPS TIME OF FIRST OBS
|
123
|
+
30.000 INTERVAL
|
124
|
+
16 LEAP SECONDS
|
125
|
+
smtt on - smooth time tag (ms jumps in phase and range) COMMENT
|
126
|
+
END OF HEADER
|
127
|
+
15 6 16 0 0 0.0000000 0 13R04R14G22G18G25G14R03G12R13G29R23R24 0.000000000
|
128
|
+
G26
|
129
|
+
107962537.996 8 20161244.813 83970896.187 7 20161248.340 53.100
|
130
|
+
45.700
|
131
|
+
108292688.703 7 20315410.305 84227597.491 6 20315417.836 44.900
|
132
|
+
38.600
|
133
|
+
120164532.762 7 22866559.250 93634735.08845 22866565.0164 44.800
|
134
|
+
31.9004
|
135
|
+
127657315.100 5 24292417.195 99473356.27642 24292426.4844 33.000
|
136
|
+
16.9004
|
137
|
+
107108718.011 8 20382088.883 83461307.35447 20382098.2114 52.700
|
138
|
+
44.8004
|
139
|
+
106665594.451 8 20297781.844 83116060.16147 20297788.3284 48.500
|
140
|
+
43.6004
|
141
|
+
112247722.253 8 20968815.328 87303792.973 7 20968819.930 48.200
|
142
|
+
43.900
|
143
|
+
119180856.024 7 22679363.352 92868240.86845 22679370.8554 46.000
|
144
|
+
34.4004
|
145
|
+
113219403.456 7 21202362.125 88059583.077 7 21202366.582 43.300
|
146
|
+
42.600
|
147
|
+
116573807.952 8 22183256.359 90836814.38846 22183263.8554 48.000
|
148
|
+
37.2004
|
149
|
+
118068213.681 8 22071607.477 91830908.595 5 22071616.434 48.300
|
150
|
+
34.300
|
151
|
+
122821571.168 6 22968227.047 95527813.562 5 22968231.008 41.000
|
152
|
+
33.400
|
153
|
+
126887720.863 7 24145939.008 98873654.81144 24145951.6954 42.000
|
154
|
+
24.8004
|
155
|
+
15 6 16 0 0 30.0000000 0 13R04R14G22G18G25G14R03G12R13G29R23R24 0.000000000
|
156
|
+
G26
|
157
|
+
107953906.562 8 20159632.578 83964182.831 7 20159636.547 52.900
|
158
|
+
45.500
|
159
|
+
108275524.990 7 20312191.531 84214247.928 6 20312198.477 46.000
|
160
|
+
37.900
|
161
|
+
120243117.022 7 22881512.617 93695969.52045 22881519.3444 43.200
|
162
|
+
30.0004
|
163
|
+
127752623.271 5 24310554.234 99547622.25842 24310562.6254 34.300
|
164
|
+
14.8004
|
165
|
+
107148475.172 8 20389654.469 83492286.95147 20389663.6914 53.000
|
166
|
+
44.7004
|
167
|
+
106649633.973 8 20294744.781 83103623.41147 20294751.4144 49.800
|
168
|
+
44.5004
|
169
|
+
112354437.822 8 20988750.797 87386793.909 7 20988756.371 48.000
|
170
|
+
44.200
|
171
|
+
119276901.051 7 22697639.727 92943081.07945 22697647.7704 47.500
|
172
|
+
34.6004
|
173
|
+
113277695.919 7 21213278.297 88104921.616 7 21213283.438 43.800
|
174
|
+
42.700
|
175
|
+
116499708.794 8 22169155.719 90779074.87246 22169163.7704 48.500
|
176
|
+
37.6004
|
177
|
+
118027431.830 8 22063984.773 91799189.430 5 22063991.707 49.300
|
178
|
+
35.100
|
179
|
+
122710898.974 6 22947531.234 95441735.252 5 22947536.609 40.900
|
180
|
+
33.600
|
181
|
+
126789541.785 6 24127256.484 98797151.68444 24127268.9224 41.900
|
182
|
+
25.3004
|
183
|
+
15 6 16 0 1 0.0000000 0 13R04R14G22G18G25G14R03G12R13G29R23R24 0.000000000
|
184
|
+
G26
|
185
|
+
107946098.362 8 20158174.969 83958109.762 7 20158178.289 53.200
|
186
|
+
44.900
|
187
|
+
108258590.494 7 20309014.148 84201076.653 6 20309021.145 46.000
|
188
|
+
38.700
|
189
|
+
120321906.821 7 22896506.344 93757364.10145 22896512.2934 44.600
|
190
|
+
30.2004
|
191
|
+
127847866.993 6 24328677.648 99621838.11742 24328687.3954 37.300
|
192
|
+
16.9004
|
193
|
+
107188670.264 8 20397303.531 83523607.79247 20397312.3054 53.700
|
194
|
+
44.3004
|
195
|
+
106634143.554 8 20291797.133 83091552.94947 20291803.6724 49.900
|
196
|
+
44.0004
|
197
|
+
112461605.174 7 21008771.203 87470146.236 7 21008775.176 47.500
|
198
|
+
43.900
|
199
|
+
119373111.958 8 22715948.289 93018050.54445 22715955.9534 48.100
|
200
|
+
34.1004
|
201
|
+
113336078.148 7 21224212.609 88150329.998 7 21224216.957 43.000
|
202
|
+
42.500
|
203
|
+
116425964.067 7 22155122.617 90721611.48746 22155131.1914 46.200
|
204
|
+
37.6004
|
205
|
+
117987330.119 7 22056486.641 91767999.260 5 22056494.809 46.900
|
206
|
+
34.500
|
207
|
+
122600398.977 6 22926865.672 95355790.881 5 22926871.977 39.700
|
208
|
+
32.500
|
209
|
+
126691542.694 6 24108607.188 98720788.84544 24108620.5234 41.700
|
210
|
+
24.8004
|
211
|
+
__RINEX_OBS_TEXT__
|
212
|
+
else # equivalent
|
213
|
+
# GEONET Setagaya from https://terras.gsi.go.jp/data_service.php#11/35.663712/139.630394
|
214
|
+
open(File::join(File::dirname(__FILE__), "..", "..", "test_log", "02281670.15o"), 'r'){|io|
|
215
|
+
99.times{|i|
|
216
|
+
break unless str = io.readline
|
217
|
+
f.write(str)
|
218
|
+
}
|
219
|
+
}
|
220
|
+
end
|
221
|
+
f.path
|
222
|
+
},
|
223
|
+
}}
|
224
|
+
let(:solver){GPS::Solver::new}
|
225
|
+
|
226
|
+
describe 'demo' do
|
227
|
+
it 'calculates position without any error' do
|
228
|
+
sn = solver.gps_space_node
|
229
|
+
puts "RINEX NAV read: %d items."%[sn.read(input[:rinex_nav])]
|
230
|
+
meas = GPS::Measurement::new
|
231
|
+
input[:measurement].each{|prn, items|
|
232
|
+
items.each{|k, v|
|
233
|
+
meas.add(prn, k, v)
|
234
|
+
}
|
235
|
+
}
|
236
|
+
expect(meas.to_hash).to eq(proc{|array|
|
237
|
+
res = {}
|
238
|
+
array.each{|prn, k, v|
|
239
|
+
(res[prn][k] = v) rescue (res[prn] = {k => v})
|
240
|
+
}
|
241
|
+
res
|
242
|
+
}.call(meas.to_a))
|
243
|
+
expect(GPS::Measurement::new(meas.to_a).to_a.sort).to eq(meas.to_a.sort) # accept [[prn, k, v], ...]
|
244
|
+
expect(GPS::Measurement::new(meas.to_hash).to_a.sort).to eq(meas.to_a.sort) # accept {prn => {k => v, ...}, ...}
|
245
|
+
expect{GPS::Measurement::new({:sym => {1 => 2}})}.to raise_error
|
246
|
+
expect{GPS::Measurement::new({1 => {:sym => 2}})}.to raise_error
|
247
|
+
expect{GPS::Measurement::new({1 => [2, 3]})}.to raise_error
|
248
|
+
|
249
|
+
t_meas = GPS::Time::new(1849, 172413)
|
250
|
+
puts "Measurement time: #{t_meas.to_a} (a.k.a #{"%d/%d/%d %02d:%02d:%02d UTC"%[*t_meas.c_tm]})"
|
251
|
+
expect(t_meas.c_tm).to eq([2015, 6, 15, 23, 53, 33])
|
252
|
+
|
253
|
+
sn.update_all_ephemeris(t_meas)
|
254
|
+
|
255
|
+
[:alpha, :beta].each{|k|
|
256
|
+
puts "Iono #{k}: #{sn.iono_utc.send(k)}"
|
257
|
+
}
|
258
|
+
puts solver.gps_options.ionospheric_models
|
259
|
+
|
260
|
+
meas.each{|prn, k, v|
|
261
|
+
eph = sn.ephemeris(prn)
|
262
|
+
puts "XYZ(PRN:#{prn}): #{eph.constellation(t_meas)[0].to_a} (iodc: #{eph.iodc}, iode: #{eph.iode})"
|
263
|
+
}
|
264
|
+
|
265
|
+
run_solver = proc{
|
266
|
+
pvt = solver.solve(meas, t_meas)
|
267
|
+
[
|
268
|
+
:error_code,
|
269
|
+
:position_solved?,
|
270
|
+
[:receiver_time, proc{|v| v.to_a}],
|
271
|
+
:used_satellite_list,
|
272
|
+
[:llh, proc{|llh| llh.to_a.zip([180.0 / Math::PI] * 2 + [1]).collect{|v, sf| v * sf}}],
|
273
|
+
:receiver_error,
|
274
|
+
[:velocity, proc{|xyz| xyz.to_a}],
|
275
|
+
:receiver_error_rate,
|
276
|
+
[:G_enu, proc{|mat| mat.to_s}],
|
277
|
+
:fd,
|
278
|
+
:fde_min,
|
279
|
+
:fde_2nd,
|
280
|
+
].each{|fun, task|
|
281
|
+
task ||= proc{|v| v}
|
282
|
+
puts "pvt.#{fun}: #{task.call(pvt.send(fun))}"
|
283
|
+
}
|
284
|
+
pvt
|
285
|
+
}
|
286
|
+
|
287
|
+
puts "Normal solution ..."
|
288
|
+
pvt = run_solver.call
|
289
|
+
puts
|
290
|
+
|
291
|
+
expect(pvt.position_solved?).to be(true)
|
292
|
+
expect(pvt.receiver_time.to_a).to eq([1849, 172413])
|
293
|
+
expect(pvt.llh.to_a).to eq([:lat, :lng, :alt].collect{|k| pvt.llh.send(k)})
|
294
|
+
expect(pvt.llh.lat / Math::PI * 180).to be_within(1E-9).of(35.6992591268) # latitude
|
295
|
+
expect(pvt.llh.lng / Math::PI * 180).to be_within(1E-9).of(139.541502292) # longitude
|
296
|
+
expect(pvt.llh.alt) .to be_within(1E-4).of(104.279402455) # altitude
|
297
|
+
expect(pvt.receiver_error).to be_within(1E-4).of(1259087.83603)
|
298
|
+
expect(pvt.gdop).to be_within(1E-10).of(3.83282723293)
|
299
|
+
expect(pvt.pdop).to be_within(1E-10).of(3.30873220653)
|
300
|
+
expect(pvt.hdop).to be_within(1E-10).of(2.05428293774)
|
301
|
+
expect(pvt.vdop).to be_within(1E-10).of(2.59376761222)
|
302
|
+
expect(pvt.tdop).to be_within(1E-10).of(1.9346461648)
|
303
|
+
expect(pvt.velocity.to_a).to eq([:e, :n, :u].collect{|k| pvt.velocity.send(k)})
|
304
|
+
expect(pvt.velocity.north).to be_within(1E-7).of(-0.839546227836) # north
|
305
|
+
expect(pvt.velocity.east) .to be_within(1E-7).of(-1.05805616381) # east
|
306
|
+
expect(pvt.velocity.down) .to be_within(1E-7).of(-0.12355474006) # down
|
307
|
+
expect(pvt.receiver_error_rate).to be_within(1E-7).of(-1061.92654151)
|
308
|
+
expect(pvt.G.rows).to eq(6)
|
309
|
+
expect(pvt.W.rows).to eq(6)
|
310
|
+
expect(pvt.delta_r.rows).to eq(6)
|
311
|
+
expect(pvt.G_enu.rows).to eq(6)
|
312
|
+
expect(Math::sqrt(pvt.C[3, 3])).to be_within(1E-10).of(pvt.tdop)
|
313
|
+
expect(Math::sqrt(pvt.C_enu[2, 2])).to be_within(1E-10).of(pvt.vdop)
|
314
|
+
pvt.S.to_a.flatten.zip(
|
315
|
+
((pvt.G.t * pvt.W * pvt.G).inv * (pvt.G.t * pvt.W)).to_a.flatten).each{|a, b|
|
316
|
+
expect(a).to be_within(1E-10).of(b)
|
317
|
+
}
|
318
|
+
pvt.S_enu.to_a.flatten.zip(
|
319
|
+
((pvt.G_enu.t * pvt.W * pvt.G_enu).inv * (pvt.G_enu.t * pvt.W)).to_a.flatten).each{|a, b|
|
320
|
+
expect(a).to be_within(1E-10).of(b)
|
321
|
+
}
|
322
|
+
expect([:rows, :columns].collect{|f| pvt.slope_HV_enu.send(f)}).to eq([6, 2])
|
323
|
+
expect(pvt.used_satellites).to eq(6)
|
324
|
+
expect(pvt.used_satellite_list).to eq([12,18, 24, 25, 29, 31])
|
325
|
+
|
326
|
+
meas.each{|prn, k, v|
|
327
|
+
solver.gps_options.exclude(prn)
|
328
|
+
puts "Excluded(PRN: #{solver.gps_options.excluded.join(', ')}) solution ..."
|
329
|
+
run_solver.call
|
330
|
+
solver.gps_options.excluded.each{|prn|
|
331
|
+
solver.gps_options.include(prn)
|
332
|
+
}
|
333
|
+
puts
|
334
|
+
}
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'can be modified through hooks' do
|
338
|
+
sn = solver.gps_space_node
|
339
|
+
sn.read(input[:rinex_nav])
|
340
|
+
t_meas = GPS::Time::new(1849, 172413)
|
341
|
+
sn.update_all_ephemeris(t_meas)
|
342
|
+
solver.hooks[:relative_property] = proc{|prn, rel_prop, rcv_e, t_arv, usr_pos, usr_vel|
|
343
|
+
expect(input[:measurement]).to include(prn)
|
344
|
+
expect(t_arv).to be_a_kind_of(GPS::Time)
|
345
|
+
expect(usr_pos).to be_a_kind_of(Coordinate::XYZ)
|
346
|
+
expect(usr_vel).to be_a_kind_of(Coordinate::XYZ)
|
347
|
+
weight, range_c, range_r, rate_rel_neg, *los_neg = rel_prop
|
348
|
+
weight = 1
|
349
|
+
[weight, range_c, range_r, rate_rel_neg] + los_neg
|
350
|
+
}
|
351
|
+
solver.hooks[:update_position_solution] = proc{|*mats|
|
352
|
+
mats.each{|mat|
|
353
|
+
expect(mat).to be_a_kind_of(SylphideMath::MatrixD)
|
354
|
+
}
|
355
|
+
mat_G, mat_W, mat_delta_r = mats
|
356
|
+
}
|
357
|
+
pvt = solver.solve(
|
358
|
+
input[:measurement].collect{|prn, items|
|
359
|
+
items.collect{|k, v| [prn, k, v]}
|
360
|
+
}.flatten(1),
|
361
|
+
t_meas)
|
362
|
+
expect(pvt.W).to eq(SylphideMath::MatrixD::I(pvt.W.rows))
|
363
|
+
end
|
364
|
+
|
365
|
+
it 'calculates position without any error with RINEX obs file' do
|
366
|
+
sn = solver.gps_space_node
|
367
|
+
puts "RINEX NAV read: %d items."%[sn.read(input[:rinex_nav])]
|
368
|
+
GPS::RINEX_Observation::read(input[:rinex_obs]){|item|
|
369
|
+
t_meas = item[:time]
|
370
|
+
puts "Measurement time: #{t_meas.to_a} (a.k.a #{"%d/%d/%d %02d:%02d:%02d UTC"%[*t_meas.c_tm]})"
|
371
|
+
sn.update_all_ephemeris(t_meas)
|
372
|
+
|
373
|
+
meas = GPS::Measurement::new
|
374
|
+
types = (item[:meas_types]['G'] || item[:meas_types][' ']).collect.with_index{|type_, i|
|
375
|
+
case type_
|
376
|
+
when "C1"
|
377
|
+
[i, GPS::Measurement::L1_PSEUDORANGE]
|
378
|
+
when "D1"
|
379
|
+
[i, GPS::Measurement::L1_RANGE_RATE]
|
380
|
+
else
|
381
|
+
nil
|
382
|
+
end
|
383
|
+
}.compact
|
384
|
+
item[:meas].each{|k, v|
|
385
|
+
sys, prn = k
|
386
|
+
next unless sys == 'G' # GPS only
|
387
|
+
types.each{|i, type_|
|
388
|
+
meas.add(prn, type_, v[i][0]) if v[i]
|
389
|
+
}
|
390
|
+
}
|
391
|
+
|
392
|
+
pvt = solver.solve(meas, t_meas)
|
393
|
+
expect(pvt.position_solved?).to eq(true)
|
394
|
+
|
395
|
+
puts pvt.llh.to_a.zip([180.0 / Math::PI] * 2 + [1]).collect{|v, sf| v * sf}.inspect
|
396
|
+
if approx_pos = proc{
|
397
|
+
next false unless res = item[:header].select{|k, v| k =~ /APPROX POSITION XYZ/}.values[0]
|
398
|
+
next false unless res = res.collect{|item|
|
399
|
+
item.scan(/([+-]?\d+(?:\.\d+)?)\s*/).flatten
|
400
|
+
}.reject{|item|
|
401
|
+
item.empty?
|
402
|
+
}[0]
|
403
|
+
Coordinate::XYZ::new(*(res.collect{|str| str.to_f}))
|
404
|
+
}.call then
|
405
|
+
approx_pos.to_a.zip(pvt.xyz.to_a).each{|a, b|
|
406
|
+
expect(a).to be_within(1E+1).of(b) # 10 m
|
407
|
+
}
|
408
|
+
end
|
409
|
+
|
410
|
+
pvt.used_satellite_list.each{|prn|
|
411
|
+
eph = sn.ephemeris(prn)
|
412
|
+
puts "XYZ(PRN:#{prn}): #{eph.constellation(t_meas)[0].to_a} (iodc: #{eph.iodc}, iode: #{eph.iode})"
|
413
|
+
}
|
414
|
+
}
|
415
|
+
end
|
416
|
+
end
|
417
|
+
end
|