gps_pvt 0.6.3 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/Rakefile +1 -0
- data/exe/gps_pvt +3 -1
- data/exe/to_ubx +1 -0
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +986 -295
- data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +2 -3
- data/ext/ninja-scan-light/tool/navigation/ANTEX.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/GLONASS_Solver.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +8 -13
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_RAIM.h +29 -1
- data/ext/ninja-scan-light/tool/navigation/MagneticField.h +4 -3
- data/ext/ninja-scan-light/tool/navigation/NTCM.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +29 -14
- data/ext/ninja-scan-light/tool/navigation/RINEX_Clock.h +458 -0
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +3 -3
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/SP3.h +49 -42
- data/ext/ninja-scan-light/tool/param/bit_array.h +2 -2
- data/ext/ninja-scan-light/tool/param/quaternion.h +2 -2
- data/ext/ninja-scan-light/tool/param/vector3.h +2 -2
- data/ext/ninja-scan-light/tool/swig/GPS.i +117 -51
- data/ext/ninja-scan-light/tool/swig/SylphideMath.i +1 -2
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +121 -0
- data/lib/gps_pvt/receiver.rb +27 -2
- data/lib/gps_pvt/version.rb +1 -1
- metadata +3 -2
@@ -22,6 +22,7 @@
|
|
22
22
|
#include "navigation/QZSS.h"
|
23
23
|
#include "navigation/GLONASS.h"
|
24
24
|
#include "navigation/RINEX.h"
|
25
|
+
#include "navigation/RINEX_Clock.h"
|
25
26
|
#include "navigation/SP3.h"
|
26
27
|
#include "navigation/ANTEX.h"
|
27
28
|
|
@@ -228,12 +229,10 @@ struct GPS_Ionospheric_UTC_Parameters : public GPS_SpaceNode<FloatT>::Ionospheri
|
|
228
229
|
%}
|
229
230
|
%extend GPS_Ionospheric_UTC_Parameters {
|
230
231
|
%fragment(SWIG_Traits_frag(FloatT));
|
231
|
-
%typemap(in,numinputs=0) FloatT values[4] (FloatT temp
|
232
|
-
|
233
|
-
%}
|
234
|
-
%typemap(argout) FloatT values[4] {
|
232
|
+
%typemap(in,numinputs=0) const FloatT *values[4] (FloatT *temp) "$1 = &temp;"
|
233
|
+
%typemap(argout) const FloatT *values[4] {
|
235
234
|
for(int i(0); i < 4; ++i){
|
236
|
-
%append_output(swig::from(
|
235
|
+
%append_output(swig::from((*$1)[i]));
|
237
236
|
}
|
238
237
|
}
|
239
238
|
MAKE_ARRAY_INPUT(const FloatT, values, swig::asval);
|
@@ -245,11 +244,7 @@ struct GPS_Ionospheric_UTC_Parameters : public GPS_SpaceNode<FloatT>::Ionospheri
|
|
245
244
|
}
|
246
245
|
}
|
247
246
|
%rename("alpha") get_alpha;
|
248
|
-
void get_alpha(FloatT values[4]) const {
|
249
|
-
for(int i(0); i < 4; ++i){
|
250
|
-
values[i] = self->alpha[i];
|
251
|
-
}
|
252
|
-
}
|
247
|
+
void get_alpha(const FloatT *values[4]) const {*values = self->alpha;}
|
253
248
|
%rename("beta=") set_beta;
|
254
249
|
void set_beta(const FloatT values[4]){
|
255
250
|
for(int i(0); i < 4; ++i){
|
@@ -257,11 +252,7 @@ struct GPS_Ionospheric_UTC_Parameters : public GPS_SpaceNode<FloatT>::Ionospheri
|
|
257
252
|
}
|
258
253
|
}
|
259
254
|
%rename("beta") get_beta;
|
260
|
-
void get_beta(FloatT values[4]) const {
|
261
|
-
for(int i(0); i < 4; ++i){
|
262
|
-
values[i] = self->beta[i];
|
263
|
-
}
|
264
|
-
}
|
255
|
+
void get_beta(const FloatT *values[4]) const {*values = self->beta;}
|
265
256
|
MAKE_ACCESSOR(A1, FloatT);
|
266
257
|
MAKE_ACCESSOR(A0, FloatT);
|
267
258
|
MAKE_ACCESSOR(t_ot, unsigned int);
|
@@ -1006,6 +997,7 @@ const type &get_ ## name () const {
|
|
1006
997
|
%inline %{
|
1007
998
|
template <class FloatT>
|
1008
999
|
struct GPS_SolverOptions_Common {
|
1000
|
+
virtual ~GPS_SolverOptions_Common() {}
|
1009
1001
|
virtual GPS_Solver_GeneralOptions<FloatT> *cast_general() = 0;
|
1010
1002
|
virtual const GPS_Solver_GeneralOptions<FloatT> *cast_general() const = 0;
|
1011
1003
|
};
|
@@ -1206,7 +1198,10 @@ struct GPS_RangeCorrector
|
|
1206
1198
|
if(!res.is_available()){
|
1207
1199
|
static const VALUE key(ID2SYM(rb_intern("relative_property")));
|
1208
1200
|
VALUE hook(rb_hash_lookup(hooks, key));
|
1209
|
-
if(!NIL_P(hook)){
|
1201
|
+
if(!NIL_P(hook)){
|
1202
|
+
if(!res.impl_xyz){res.impl_xyz = this;}
|
1203
|
+
if(!res.impl_t){res.impl_t = this;}
|
1204
|
+
}
|
1210
1205
|
}
|
1211
1206
|
#endif
|
1212
1207
|
return res;
|
@@ -1361,6 +1356,28 @@ struct GPS_RangeCorrector
|
|
1361
1356
|
return self->update_correction(true, hash);
|
1362
1357
|
}
|
1363
1358
|
#endif
|
1359
|
+
#ifdef SWIGRUBY
|
1360
|
+
%typemap(out) typename super_t::options_t {
|
1361
|
+
VALUE res(rb_hash_new());
|
1362
|
+
rb_hash_aset(res, ID2SYM(rb_intern("skip_exclusion")), SWIG_From(bool)($1.skip_exclusion));
|
1363
|
+
%set_output(res);
|
1364
|
+
}
|
1365
|
+
#endif
|
1366
|
+
%rename("options") get_options;
|
1367
|
+
typename super_t::options_t get_options() const {
|
1368
|
+
return self->available_options();
|
1369
|
+
}
|
1370
|
+
%rename("options=") set_options;
|
1371
|
+
typename super_t::options_t set_options(SWIG_Object obj) {
|
1372
|
+
GPS_Solver<FloatT>::super_t::options_t opt(self->available_options());
|
1373
|
+
#ifdef SWIGRUBY
|
1374
|
+
if(!RB_TYPE_P(obj, T_HASH)){SWIG_exception(SWIG_TypeError, "Hash is expected");}
|
1375
|
+
SWIG_AsVal(bool)(
|
1376
|
+
rb_hash_lookup(obj, ID2SYM(rb_intern("skip_exclusion"))),
|
1377
|
+
&opt.skip_exclusion);
|
1378
|
+
#endif
|
1379
|
+
return self->update_options(opt);
|
1380
|
+
}
|
1364
1381
|
}
|
1365
1382
|
%inline {
|
1366
1383
|
template <class FloatT>
|
@@ -1653,31 +1670,8 @@ template <class FloatT>
|
|
1653
1670
|
struct RINEX_Observation {};
|
1654
1671
|
}
|
1655
1672
|
|
1656
|
-
%extend SP3 {
|
1657
|
-
%typemap(in,numinputs=0) int count[ANY] (int temp[$1_dim0]) "$1 = temp;"
|
1658
|
-
%typemap(argout) int count[ANY] {
|
1659
|
-
for(int i(0); i < $1_dim0; ++i){
|
1660
|
-
%append_output(SWIG_From(int)($1[i]));
|
1661
|
-
}
|
1662
|
-
}
|
1663
|
-
void satellites(int count[SP3::SYS_SYSTEMS]) const {
|
1664
|
-
typename SP3_Product<FloatT>::satellite_count_t x(self->satellite_count());
|
1665
|
-
count[SP3<FloatT>::SYS_GPS] = x.gps;
|
1666
|
-
count[SP3<FloatT>::SYS_SBAS] = x.sbas;
|
1667
|
-
count[SP3<FloatT>::SYS_QZSS] = x.qzss;
|
1668
|
-
count[SP3<FloatT>::SYS_GLONASS] = x.glonass;
|
1669
|
-
count[SP3<FloatT>::SYS_GALILEO] = x.galileo;
|
1670
|
-
count[SP3<FloatT>::SYS_BEIDOU] = x.beidou;
|
1671
|
-
}
|
1672
|
-
|
1673
|
-
}
|
1674
1673
|
%inline {
|
1675
|
-
|
1676
|
-
struct SP3 : public SP3_Product<FloatT> {
|
1677
|
-
int read(const char *fname) {
|
1678
|
-
std::fstream fin(fname, std::ios::in | std::ios::binary);
|
1679
|
-
return SP3_Reader<FloatT>::read_all(fin, *this);
|
1680
|
-
}
|
1674
|
+
struct PushableData {
|
1681
1675
|
enum system_t {
|
1682
1676
|
SYS_GPS,
|
1683
1677
|
SYS_SBAS,
|
@@ -1687,20 +1681,21 @@ struct SP3 : public SP3_Product<FloatT> {
|
|
1687
1681
|
SYS_BEIDOU,
|
1688
1682
|
SYS_SYSTEMS,
|
1689
1683
|
};
|
1690
|
-
|
1684
|
+
template <class DataT, class FloatT>
|
1685
|
+
static bool push(DataT &data, GPS_Solver<FloatT> &solver, const system_t &sys){
|
1691
1686
|
switch(sys){
|
1692
1687
|
case SYS_GPS:
|
1693
|
-
return
|
1694
|
-
solver.gps.ephemeris_proxy.gps,
|
1688
|
+
return data.push(
|
1689
|
+
solver.gps.ephemeris_proxy.gps, DataT::SYSTEM_GPS);
|
1695
1690
|
case SYS_SBAS:
|
1696
|
-
return
|
1697
|
-
solver.sbas.solver.satellites,
|
1691
|
+
return data.push(
|
1692
|
+
solver.sbas.solver.satellites, DataT::SYSTEM_SBAS);
|
1698
1693
|
case SYS_QZSS:
|
1699
|
-
return
|
1700
|
-
solver.gps.ephemeris_proxy.qzss,
|
1694
|
+
return data.push(
|
1695
|
+
solver.gps.ephemeris_proxy.qzss, DataT::SYSTEM_QZSS);
|
1701
1696
|
case SYS_GLONASS:
|
1702
|
-
return
|
1703
|
-
solver.glonass.solver.satellites,
|
1697
|
+
return data.push(
|
1698
|
+
solver.glonass.solver.satellites, DataT::SYSTEM_GLONASS);
|
1704
1699
|
case SYS_GALILEO:
|
1705
1700
|
case SYS_BEIDOU:
|
1706
1701
|
default:
|
@@ -1708,7 +1703,8 @@ struct SP3 : public SP3_Product<FloatT> {
|
|
1708
1703
|
}
|
1709
1704
|
return false;
|
1710
1705
|
}
|
1711
|
-
|
1706
|
+
template <class DataT, class FloatT>
|
1707
|
+
static bool push(DataT &data, GPS_Solver<FloatT> &solver){
|
1712
1708
|
system_t target[] = {
|
1713
1709
|
SYS_GPS,
|
1714
1710
|
SYS_SBAS,
|
@@ -1718,10 +1714,39 @@ struct SP3 : public SP3_Product<FloatT> {
|
|
1718
1714
|
//SYS_BEIDOU,
|
1719
1715
|
};
|
1720
1716
|
for(std::size_t i(0); i < sizeof(target) / sizeof(target[0]); ++i){
|
1721
|
-
if(!push(solver, target[i])){return false;}
|
1717
|
+
if(!push(data, solver, target[i])){return false;}
|
1722
1718
|
}
|
1723
1719
|
return true;
|
1724
1720
|
}
|
1721
|
+
};
|
1722
|
+
}
|
1723
|
+
|
1724
|
+
%extend SP3 {
|
1725
|
+
%typemap(out) typename SP3_Product<FloatT>::satellite_count_t {
|
1726
|
+
%append_output(SWIG_From(int)($1.gps));
|
1727
|
+
%append_output(SWIG_From(int)($1.sbas));
|
1728
|
+
%append_output(SWIG_From(int)($1.qzss));
|
1729
|
+
%append_output(SWIG_From(int)($1.glonass));
|
1730
|
+
%append_output(SWIG_From(int)($1.galileo));
|
1731
|
+
%append_output(SWIG_From(int)($1.beidou));
|
1732
|
+
}
|
1733
|
+
}
|
1734
|
+
%inline {
|
1735
|
+
template <class FloatT>
|
1736
|
+
struct SP3 : public SP3_Product<FloatT>, PushableData {
|
1737
|
+
int read(const char *fname) {
|
1738
|
+
std::fstream fin(fname, std::ios::in | std::ios::binary);
|
1739
|
+
return SP3_Reader<FloatT>::read_all(fin, *this);
|
1740
|
+
}
|
1741
|
+
typename SP3_Product<FloatT>::satellite_count_t satellites() const {
|
1742
|
+
return SP3_Product<FloatT>::satellite_count();
|
1743
|
+
}
|
1744
|
+
bool push(GPS_Solver<FloatT> &solver, const PushableData::system_t &sys) const {
|
1745
|
+
return PushableData::push((SP3_Product<FloatT> &)*this, solver, sys);
|
1746
|
+
}
|
1747
|
+
bool push(GPS_Solver<FloatT> &solver) const {
|
1748
|
+
return PushableData::push((SP3_Product<FloatT> &)*this, solver);
|
1749
|
+
}
|
1725
1750
|
System_XYZ<FloatT, WGS84> position(
|
1726
1751
|
const int &sat_id, const GPS_Time<FloatT> &t) const {
|
1727
1752
|
return SP3_Product<FloatT>::select(sat_id, t).position(t);
|
@@ -1748,6 +1773,46 @@ struct SP3 : public SP3_Product<FloatT> {
|
|
1748
1773
|
};
|
1749
1774
|
}
|
1750
1775
|
|
1776
|
+
%extend RINEX_Clock {
|
1777
|
+
%typemap(out) typename RINEX_CLK<FloatT>::satellites_t::count_t {
|
1778
|
+
%append_output(SWIG_From(int)($1.gps));
|
1779
|
+
%append_output(SWIG_From(int)($1.sbas));
|
1780
|
+
%append_output(SWIG_From(int)($1.qzss));
|
1781
|
+
%append_output(SWIG_From(int)($1.glonass));
|
1782
|
+
%append_output(SWIG_From(int)($1.galileo));
|
1783
|
+
%append_output(SWIG_From(int)($1.beidou));
|
1784
|
+
}
|
1785
|
+
}
|
1786
|
+
%inline {
|
1787
|
+
template <class FloatT>
|
1788
|
+
struct RINEX_Clock : public RINEX_CLK<FloatT>::satellites_t, PushableData {
|
1789
|
+
typedef typename RINEX_CLK<FloatT>::satellites_t super_t;
|
1790
|
+
int read(const char *fname) {
|
1791
|
+
std::fstream fin(fname, std::ios::in | std::ios::binary);
|
1792
|
+
return RINEX_CLK_Reader<FloatT>::read_all(fin, *this);
|
1793
|
+
}
|
1794
|
+
typename RINEX_CLK<FloatT>::satellites_t::count_t satellites() const {
|
1795
|
+
return RINEX_CLK<FloatT>::satellites_t::count();
|
1796
|
+
}
|
1797
|
+
bool push(GPS_Solver<FloatT> &solver, const PushableData::system_t &sys) const {
|
1798
|
+
return PushableData::push((typename RINEX_CLK<FloatT>::satellites_t &)*this, solver, sys);
|
1799
|
+
}
|
1800
|
+
bool push(GPS_Solver<FloatT> &solver) const {
|
1801
|
+
return PushableData::push((typename RINEX_CLK<FloatT>::satellites_t &)*this, solver);
|
1802
|
+
}
|
1803
|
+
FloatT clock_error(const int &sat_id, const GPS_Time<FloatT> &t) const {
|
1804
|
+
typename super_t::buf_t::const_iterator it(this->buf.find(sat_id));
|
1805
|
+
if(it == this->buf.end()){return super_t::sat_t::unavailable().clock_error(t);}
|
1806
|
+
return it->second.clock_error(t);
|
1807
|
+
}
|
1808
|
+
FloatT clock_error_dot(const int &sat_id, const GPS_Time<FloatT> &t) const {
|
1809
|
+
typename super_t::buf_t::const_iterator it(this->buf.find(sat_id));
|
1810
|
+
if(it == this->buf.end()){return super_t::sat_t::unavailable().clock_error(t);}
|
1811
|
+
return it->second.clock_error_dot(t);
|
1812
|
+
}
|
1813
|
+
};
|
1814
|
+
}
|
1815
|
+
|
1751
1816
|
#undef MAKE_ACCESSOR
|
1752
1817
|
#undef MAKE_VECTOR2ARRAY
|
1753
1818
|
#undef MAKE_ARRAY_INPUT
|
@@ -1776,6 +1841,7 @@ struct SP3 : public SP3_Product<FloatT> {
|
|
1776
1841
|
|
1777
1842
|
%template(RINEX_Observation) RINEX_Observation<type>;
|
1778
1843
|
%template(SP3) SP3<type>;
|
1844
|
+
%template(RINEX_Clock) RINEX_Clock<type>;
|
1779
1845
|
%enddef
|
1780
1846
|
|
1781
1847
|
CONCRETIZE(double);
|
@@ -592,7 +592,6 @@ struct MatrixUtil {
|
|
592
592
|
}
|
593
593
|
static VALUE read(
|
594
594
|
const VALUE &v, const unsigned int &row = 0, const unsigned int &column = 0) {
|
595
|
-
int state;
|
596
595
|
VALUE values[3] = {v, UINT2NUM(row), UINT2NUM(column)};
|
597
596
|
return funcall_throw_if_error(run, reinterpret_cast<VALUE>(values));
|
598
597
|
}
|
@@ -865,7 +864,7 @@ struct MatrixUtil {
|
|
865
864
|
static const ID with_index[] = {
|
866
865
|
rb_intern("map_with_index"), rb_intern("map_with_index!"),
|
867
866
|
rb_intern("collect_with_index"), rb_intern("collect_with_index!")};
|
868
|
-
for(
|
867
|
+
for(std::size_t i(0); i < sizeof(with_index) / sizeof(with_index[0]); ++i){
|
869
868
|
if(id_callee == with_index[i]){
|
870
869
|
return matrix_yield_get_with_index;
|
871
870
|
}
|
@@ -658,6 +658,73 @@ __ANTEX_TEXT__
|
|
658
658
|
# https://files.igs.org/pub/station/general/igs14.atx
|
659
659
|
f.path
|
660
660
|
},
|
661
|
+
:rinex_clk => Tempfile::open{|f|
|
662
|
+
f.write(<<-__RINEX_CLK_TEXT__)
|
663
|
+
3.00 C RINEX VERSION / TYPE
|
664
|
+
CCLOCK IGSACC @ NOAA NGS PGM / RUN BY / DATE
|
665
|
+
GPS week: 1849 Day: 2 MJD: 57189 COMMENT
|
666
|
+
THE COMBINED CLOCKS ARE A WEIGHTED AVERAGE OF: COMMENT
|
667
|
+
cod emr esa gfz grg jpl COMMENT
|
668
|
+
THE FOLLOWING REFERENCE CLOCKS WERE USED BY ACs: COMMENT
|
669
|
+
WSRT AMC2 BRUX HRAO COMMENT
|
670
|
+
THE COMBINED CLOCKS ARE ALIGNED TO GPS TIME COMMENT
|
671
|
+
USING THE SATELLITE BROADCAST EPHEMERIDES COMMENT
|
672
|
+
All clocks have been re-aligned to the IGS time scale: IGST COMMENT
|
673
|
+
16 LEAP SECONDS
|
674
|
+
1 AS # / TYPES OF DATA
|
675
|
+
IGS IGSACC @ NOAA NGS ANALYSIS CENTER
|
676
|
+
6 # OF SOLN SATS
|
677
|
+
G12 G18 G24 G25 G29 G31 PRN LIST
|
678
|
+
G igs08_1848.atx SYS / PCVS APPLIED
|
679
|
+
END OF HEADER
|
680
|
+
AS G12 2015 06 15 23 45 0.000000 2 3.017937472687e-04 1.069824072610e-11
|
681
|
+
AS G18 2015 06 15 23 45 0.000000 2 4.096815344517e-04 9.225410060960e-12
|
682
|
+
AS G24 2015 06 15 23 45 0.000000 2 -4.998574751545e-05 2.372704308220e-11
|
683
|
+
AS G25 2015 06 15 23 45 0.000000 2 -2.290169594092e-06 1.683218228880e-11
|
684
|
+
AS G29 2015 06 15 23 45 0.000000 2 6.168866864097e-04 1.206217360840e-11
|
685
|
+
AS G31 2015 06 15 23 45 0.000000 2 3.128244102077e-04 2.173867579920e-11
|
686
|
+
AS G12 2015 06 15 23 50 0.000000 2 3.017948525918e-04 1.300769315700e-11
|
687
|
+
AS G18 2015 06 15 23 50 0.000000 2 4.096823340968e-04 8.242414325510e-12
|
688
|
+
AS G24 2015 06 15 23 50 0.000000 2 -4.998578937856e-05 3.095238106380e-11
|
689
|
+
AS G25 2015 06 15 23 50 0.000000 2 -2.291410963946e-06 2.242880773880e-11
|
690
|
+
AS G29 2015 06 15 23 50 0.000000 2 6.168873857128e-04 1.695910016600e-11
|
691
|
+
AS G31 2015 06 15 23 50 0.000000 2 3.128241216228e-04 1.904362802980e-11
|
692
|
+
AS G12 2015 06 15 23 55 0.000000 2 3.017958412577e-04 1.171495359430e-11
|
693
|
+
AS G18 2015 06 15 23 55 0.000000 2 4.096833491457e-04 1.008770038860e-11
|
694
|
+
AS G24 2015 06 15 23 55 0.000000 2 -4.998596967628e-05 2.600074192880e-11
|
695
|
+
AS G25 2015 06 15 23 55 0.000000 2 -2.292650290468e-06 2.671557682290e-11
|
696
|
+
AS G29 2015 06 15 23 55 0.000000 2 6.168880208367e-04 1.729095211710e-11
|
697
|
+
AS G31 2015 06 15 23 55 0.000000 2 3.128236493567e-04 1.807462018720e-11
|
698
|
+
AS G12 2015 06 16 00 00 0.000000 2 3.017967728708e-04 1.000801049580e-11
|
699
|
+
AS G18 2015 06 16 00 00 0.000000 2 4.096840539308e-04 1.041670195750e-11
|
700
|
+
AS G24 2015 06 16 00 00 0.000000 2 -4.998614775959e-05 1.699628132880e-11
|
701
|
+
AS G25 2015 06 16 00 00 0.000000 2 -2.293760646361e-06 1.805118466830e-11
|
702
|
+
AS G29 2015 06 16 00 00 0.000000 2 6.168886213338e-04 2.220055594770e-11
|
703
|
+
AS G31 2015 06 16 00 00 0.000000 2 3.128233311248e-04 1.215284180360e-11
|
704
|
+
AS G12 2015 06 16 00 05 0.000000 2 3.017980078016e-04 1.152529430320e-11
|
705
|
+
AS G18 2015 06 16 00 05 0.000000 2 4.096851745816e-04 1.517949585220e-11
|
706
|
+
AS G24 2015 06 16 00 05 0.000000 2 -4.998569129850e-05 1.987308774570e-11
|
707
|
+
AS G25 2015 06 16 00 05 0.000000 2 -2.295014987154e-06 1.568891027900e-11
|
708
|
+
AS G29 2015 06 16 00 05 0.000000 2 6.168894672506e-04 1.906237292480e-11
|
709
|
+
AS G31 2015 06 16 00 05 0.000000 2 3.128231387506e-04 1.007829428500e-11
|
710
|
+
AS G12 2015 06 16 00 10 0.000000 2 3.017987334831e-04 8.726251168980e-12
|
711
|
+
AS G18 2015 06 16 00 10 0.000000 2 4.096859333261e-04 1.403166740100e-11
|
712
|
+
AS G24 2015 06 16 00 10 0.000000 2 -4.998597422529e-05 1.727695888430e-11
|
713
|
+
AS G25 2015 06 16 00 10 0.000000 2 -2.296262879345e-06 1.460867818340e-11
|
714
|
+
AS G29 2015 06 16 00 10 0.000000 2 6.168900483001e-04 1.556536485070e-11
|
715
|
+
AS G31 2015 06 16 00 10 0.000000 2 3.128226535741e-04 1.258498073020e-11
|
716
|
+
AS G12 2015 06 16 00 15 0.000000 2 3.017999301583e-04 1.006627990480e-11
|
717
|
+
AS G18 2015 06 16 00 15 0.000000 2 4.096864636193e-04 1.460541676660e-11
|
718
|
+
AS G24 2015 06 16 00 15 0.000000 2 -4.998605241609e-05 1.970841363000e-11
|
719
|
+
AS G25 2015 06 16 00 15 0.000000 2 -2.297477664413e-06 1.598459869060e-11
|
720
|
+
AS G29 2015 06 16 00 15 0.000000 2 6.168906691983e-04 1.729396319140e-11
|
721
|
+
AS G31 2015 06 16 00 15 0.000000 2 3.128222195893e-04 1.358710059900e-11
|
722
|
+
__RINEX_CLK_TEXT__
|
723
|
+
# modified version. original data are
|
724
|
+
# https://cddis.nasa.gov/archive/gnss/products/1849/igs1849[12].clk.Z
|
725
|
+
# mirrored: ftp://garner.ucsd.edu/pub/products/1849/igs1849[12].clk.Z
|
726
|
+
f.path
|
727
|
+
},
|
661
728
|
}}
|
662
729
|
let(:solver){
|
663
730
|
res = GPS::Solver::new
|
@@ -778,6 +845,10 @@ __ANTEX_TEXT__
|
|
778
845
|
|
779
846
|
it 'can be modified through hooks' do
|
780
847
|
sn = solver.gps_space_node
|
848
|
+
expect(solver.options).to be_a_kind_of(Hash)
|
849
|
+
expect(solver.options.keys).to include(:skip_exclusion)
|
850
|
+
expect{solver.options = {:skip_exclusion => true}}.not_to raise_error
|
851
|
+
expect(solver.options[:skip_exclusion]).to eq(true)
|
781
852
|
expect(solver.correction[:gps_ionospheric]).to include(:klobuchar)
|
782
853
|
expect(solver.correction[:gps_tropospheric]).to include(:hopfield)
|
783
854
|
expect{solver.correction = nil}.to raise_error(RuntimeError)
|
@@ -937,5 +1008,55 @@ __ANTEX_TEXT__
|
|
937
1008
|
puts ([:lat, :lng].collect{|f| pvt.llh.send(f) / Math::PI * 180} + [pvt.llh.alt]).inspect
|
938
1009
|
}
|
939
1010
|
end
|
1011
|
+
it 'calculates satellite clock error based on RINEX clock' do
|
1012
|
+
clk, sn = [GPS::RINEX_Clock::new, solver.gps_space_node]
|
1013
|
+
expect(clk.read(input[:rinex_clk])).to eq(6 * 7)
|
1014
|
+
proc{|sats|
|
1015
|
+
expect(sats.kind_of?(Array)).to eq(true)
|
1016
|
+
expect(sats[clk.class::SYS_GPS]).to eq(6)
|
1017
|
+
}.call(clk.satellites)
|
1018
|
+
sn.read(input[:rinex_nav])
|
1019
|
+
t0 = GPS::Time::new(1849, 172800)
|
1020
|
+
sn.update_all_ephemeris(t0)
|
1021
|
+
(-5..5).step(1){|dt_min|
|
1022
|
+
t = t0 + (dt_min * 60)
|
1023
|
+
[12, 18, 24, 25, 29, 31].each{|sat_id|
|
1024
|
+
eph = sn.ephemeris(sat_id).constellation(t)
|
1025
|
+
expect(clk.clock_error(sat_id, t)).to be_within(1E-7).of(eph[2]) # 100 ns
|
1026
|
+
expect(clk.clock_error_dot(sat_id, t)).to be_within(1E-10).of(eph[3]) # 100 ps
|
1027
|
+
}
|
1028
|
+
}
|
1029
|
+
end
|
1030
|
+
it 'calculates position without any error with RINEX NAV and CLK' do
|
1031
|
+
sn = solver.gps_space_node
|
1032
|
+
sn.read(input[:rinex_nav])
|
1033
|
+
clk = GPS::RINEX_Clock::new
|
1034
|
+
clk.read(input[:rinex_clk])
|
1035
|
+
expect(clk.push(solver, clk.class::SYS_GPS)).to eq(true)
|
1036
|
+
GPS::RINEX_Observation::read(input[:rinex_obs]){|item|
|
1037
|
+
t_meas = item[:time]
|
1038
|
+
sn.update_all_ephemeris(t_meas)
|
1039
|
+
meas = GPS::Measurement::new
|
1040
|
+
types = (item[:meas_types]['G'] || item[:meas_types][' ']).collect.with_index{|type_, i|
|
1041
|
+
type_ = {
|
1042
|
+
"C1" => :L1_PSEUDORANGE,
|
1043
|
+
"D1" => :L1_RANGE_RATE,
|
1044
|
+
}[type_]
|
1045
|
+
type_ && [i, GPS::Measurement::const_get(type_)]
|
1046
|
+
}.compact
|
1047
|
+
item[:meas].each{|k, v|
|
1048
|
+
sys, prn = k
|
1049
|
+
next unless sys == 'G' # GPS only
|
1050
|
+
types.each{|i, type_|
|
1051
|
+
meas.add(prn, type_, v[i][0]) if v[i]
|
1052
|
+
}
|
1053
|
+
}
|
1054
|
+
pvt = solver.solve(meas, t_meas)
|
1055
|
+
expect(pvt.position_solved?).to eq(true)
|
1056
|
+
[-3952590.4754, 3360273.8926, 3697987.2632].zip(pvt.xyz.to_a).each{|a, b|
|
1057
|
+
expect(a).to be_within(1E+2).of(b) # 10 m
|
1058
|
+
}
|
1059
|
+
}
|
1060
|
+
end
|
940
1061
|
end
|
941
1062
|
end
|
data/lib/gps_pvt/receiver.rb
CHANGED
@@ -19,6 +19,7 @@ class Receiver
|
|
19
19
|
opt = {
|
20
20
|
:system => [[:GPS, 1..32]],
|
21
21
|
:satellites => (1..32).to_a,
|
22
|
+
:FDE => true,
|
22
23
|
}.merge(opt)
|
23
24
|
[[
|
24
25
|
[:week, :itow_rcv, :year, :month, :mday, :hour, :min, :sec_rcv_UTC],
|
@@ -106,7 +107,7 @@ class Receiver
|
|
106
107
|
el_deg = [4, 6].collect{|i| pvt.elevation[fd[i]] / Math::PI * 180}
|
107
108
|
fd[0..4] + [el_deg[0]] + fd[5..6] + [el_deg[1]]
|
108
109
|
}
|
109
|
-
]] + [[
|
110
|
+
]] + (opt[:FDE] ? [[
|
110
111
|
[:wssr_FDE_min, :wssr_FDE_min_PRN, :wssr_FDE_2nd, :wssr_FDE_2nd_PRN],
|
111
112
|
proc{|pvt|
|
112
113
|
[:fde_min, :fde_2nd].collect{|f|
|
@@ -115,7 +116,7 @@ class Receiver
|
|
115
116
|
[info[0], info[-3]]
|
116
117
|
}.flatten
|
117
118
|
}
|
118
|
-
]]
|
119
|
+
]] : [])
|
119
120
|
end
|
120
121
|
|
121
122
|
def self.meas_items(opt = {})
|
@@ -153,6 +154,9 @@ class Receiver
|
|
153
154
|
rel_prop[0] = 1 if rel_prop[0] > 0 # weight = 1
|
154
155
|
rel_prop
|
155
156
|
}
|
157
|
+
@solver.options = {
|
158
|
+
:skip_exclusion => true, # default is to skip fault exclusion calculation
|
159
|
+
}
|
156
160
|
@debug = {}
|
157
161
|
solver_opts = [:gps_options, :sbas_options, :glonass_options].collect{|target|
|
158
162
|
@solver.send(target)
|
@@ -165,8 +169,10 @@ class Receiver
|
|
165
169
|
output_options = {
|
166
170
|
:system => [[:GPS, 1..32], [:QZSS, 193..202]],
|
167
171
|
:satellites => (1..32).to_a + (193..202).to_a, # [idx, ...] or [[idx, label], ...] is acceptable
|
172
|
+
:FDE => false,
|
168
173
|
}
|
169
174
|
options = options.reject{|k, v|
|
175
|
+
def v.to_b; !(self =~ /^(?:false|0|f|off)$/i); end
|
170
176
|
case k
|
171
177
|
when :debug
|
172
178
|
v = v.split(/,/)
|
@@ -280,6 +286,9 @@ class Receiver
|
|
280
286
|
$stderr.puts "#{mode.capitalize} satellite: #{[sys, svid].compact.join(':')}"
|
281
287
|
}
|
282
288
|
next true
|
289
|
+
when :fault_exclusion
|
290
|
+
@solver.options = {:skip_exclusion => !(output_options[:FDE] = v.to_b)}
|
291
|
+
next true
|
283
292
|
end
|
284
293
|
false
|
285
294
|
}
|
@@ -651,5 +660,21 @@ class Receiver
|
|
651
660
|
raise "Format error! (Not ANTEX) #{src}" unless applied_items >= 0
|
652
661
|
$stderr.puts "SP3 correction with ANTEX file (%s): %d items have been processed."%[src, applied_items]
|
653
662
|
end
|
663
|
+
|
664
|
+
def attach_rinex_clk(src)
|
665
|
+
fname = Util::get_txt(src)
|
666
|
+
@clk ||= GPS::RINEX_Clock::new
|
667
|
+
read_items = @clk.read(fname)
|
668
|
+
raise "Format error! (Not RINEX clock) #{src}" if read_items < 0
|
669
|
+
$stderr.puts "Read RINEX clock file (%s): %d items."%[src, read_items]
|
670
|
+
sats = @clk.satellites
|
671
|
+
@clk.class.constants.each{|sys|
|
672
|
+
next unless /^SYS_(?!SYSTEMS)(.*)/ =~ sys.to_s
|
673
|
+
idx, sys_name = [@clk.class.const_get(sys), $1]
|
674
|
+
next unless sats[idx] > 0
|
675
|
+
next unless @clk.push(@solver, idx)
|
676
|
+
$stderr.puts "Change clock error source of #{sys_name} to RINEX clock"
|
677
|
+
}
|
678
|
+
end
|
654
679
|
end
|
655
680
|
end
|
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.7.1
|
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-08-
|
11
|
+
date: 2022-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- ext/ninja-scan-light/tool/navigation/NTCM.h
|
79
79
|
- ext/ninja-scan-light/tool/navigation/QZSS.h
|
80
80
|
- ext/ninja-scan-light/tool/navigation/RINEX.h
|
81
|
+
- ext/ninja-scan-light/tool/navigation/RINEX_Clock.h
|
81
82
|
- ext/ninja-scan-light/tool/navigation/SBAS.h
|
82
83
|
- ext/ninja-scan-light/tool/navigation/SBAS_Solver.h
|
83
84
|
- ext/ninja-scan-light/tool/navigation/SP3.h
|