gps_pvt 0.6.3 → 0.7.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 +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
|