gps_pvt 0.3.3 → 0.5.0
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 +4 -3
- data/Rakefile +2 -0
- data/exe/gps_pvt +37 -5
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +5595 -131
- data/ext/ninja-scan-light/tool/algorithm/integral.h +91 -0
- data/ext/ninja-scan-light/tool/navigation/GLONASS.h +1329 -0
- data/ext/ninja-scan-light/tool/navigation/GLONASS_Solver.h +306 -0
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +7 -0
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +389 -4
- data/ext/ninja-scan-light/tool/swig/GPS.i +217 -6
- data/{sig/gps_pvt.rbs → gps_pvt.rbs} +0 -0
- data/lib/gps_pvt/receiver.rb +68 -16
- data/lib/gps_pvt/util.rb +32 -0
- data/lib/gps_pvt/version.rb +1 -1
- metadata +7 -3
@@ -54,6 +54,7 @@
|
|
54
54
|
|
55
55
|
#include "GPS.h"
|
56
56
|
#include "SBAS.h"
|
57
|
+
#include "GLONASS.h"
|
57
58
|
|
58
59
|
template <class U = void>
|
59
60
|
class RINEX_Reader {
|
@@ -548,6 +549,72 @@ struct RINEX_NAV {
|
|
548
549
|
return eph;
|
549
550
|
}
|
550
551
|
};
|
552
|
+
struct message_glonass_t {
|
553
|
+
typedef typename GLONASS_SpaceNode<FloatT>
|
554
|
+
::SatelliteProperties::Ephemeris_with_Time eph_t;
|
555
|
+
int svid;
|
556
|
+
std::tm date_tm;
|
557
|
+
int t_year4, t_year2, t_mon12;
|
558
|
+
FloatT t_sec;
|
559
|
+
FloatT tau_n_neg, gamma_n;
|
560
|
+
unsigned int t_k;
|
561
|
+
FloatT x_km, dx_km_s, ddx_km_s2;
|
562
|
+
FloatT y_km, dy_km_s, ddy_km_s2;
|
563
|
+
FloatT z_km, dz_km_s, ddz_km_s2;
|
564
|
+
unsigned int B_n, E_n;
|
565
|
+
int freq_num; // 1-24(ver.2), -7-13(ver.3)
|
566
|
+
|
567
|
+
// since ver.3.05
|
568
|
+
unsigned int status_flags, urai, health_flags;
|
569
|
+
FloatT delta_tau;
|
570
|
+
|
571
|
+
message_glonass_t(){
|
572
|
+
status_flags
|
573
|
+
= ((0x01 & 0x3) << 7) // GLONASS-M
|
574
|
+
| ((0x3) << 2); // upload/validity interval = 60 min
|
575
|
+
urai = 15; // unknown
|
576
|
+
health_flags = 0;
|
577
|
+
delta_tau = 0;
|
578
|
+
}
|
579
|
+
message_glonass_t(const eph_t &eph)
|
580
|
+
: svid((int)eph.svid),
|
581
|
+
date_tm(eph.c_tm_utc()),
|
582
|
+
t_year4(date_tm.tm_year + 1900),
|
583
|
+
t_year2(date_tm.tm_year % 100),
|
584
|
+
t_mon12(date_tm.tm_mon + 1),
|
585
|
+
t_sec(date_tm.tm_sec),
|
586
|
+
tau_n_neg(-eph.tau_n), gamma_n(eph.gamma_n), t_k(eph.t_k),
|
587
|
+
x_km(1E-3 * eph.xn), dx_km_s(1E-3 * eph.xn_dot), ddx_km_s2(1E-3 * eph.xn_ddot),
|
588
|
+
y_km(1E-3 * eph.yn), dy_km_s(1E-3 * eph.yn_dot), ddy_km_s2(1E-3 * eph.yn_ddot),
|
589
|
+
z_km(1E-3 * eph.zn), dz_km_s(1E-3 * eph.zn_dot), ddz_km_s2(1E-3 * eph.zn_ddot),
|
590
|
+
B_n(eph.B_n), E_n(eph.E_n),
|
591
|
+
freq_num(eph.freq_ch),
|
592
|
+
urai(eph.F_T_index()), delta_tau(eph.delta_tau_n) {
|
593
|
+
status_flags
|
594
|
+
= ((eph.M & 0x3) << 7)
|
595
|
+
| (eph.P4 ? 0x40 : 0)
|
596
|
+
| (eph.P2 ? 0x10 : 0)
|
597
|
+
| ((eph.P1_index() & 0x3) << 2);
|
598
|
+
health_flags = 0;
|
599
|
+
}
|
600
|
+
operator eph_t() const {
|
601
|
+
typename GLONASS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris eph = {0};
|
602
|
+
eph.svid = (unsigned int)svid;
|
603
|
+
eph.freq_ch = freq_num;
|
604
|
+
eph.tau_n = -tau_n_neg; eph.gamma_n = gamma_n; eph.t_k = t_k;
|
605
|
+
eph.xn = 1E3 * x_km; eph.xn_dot = 1E3 * dx_km_s; eph.xn_ddot = 1E3 * ddx_km_s2;
|
606
|
+
eph.yn = 1E3 * y_km; eph.yn_dot = 1E3 * dy_km_s; eph.yn_ddot = 1E3 * ddy_km_s2;
|
607
|
+
eph.zn = 1E3 * z_km; eph.zn_dot = 1E3 * dz_km_s; eph.zn_ddot = 1E3 * ddz_km_s2;
|
608
|
+
eph.B_n = B_n; eph.E_n = E_n;
|
609
|
+
eph.F_T = eph_t::Ephemeris::raw_t::F_T_value(urai);
|
610
|
+
eph.delta_tau_n = (delta_tau > 0.999999999998E+09 ? 0 : delta_tau);
|
611
|
+
eph.M = ((status_flags >> 7) & 0x3);
|
612
|
+
eph.P4 = (status_flags & 0x40);
|
613
|
+
eph.P2 = (status_flags & 0x10);
|
614
|
+
eph.P1 = eph_t::Ephemeris::raw_t::P1_value((status_flags >> 2) & 0x03);
|
615
|
+
return eph_t(eph, date_tm);
|
616
|
+
}
|
617
|
+
};
|
551
618
|
};
|
552
619
|
|
553
620
|
template <class FloatT = double>
|
@@ -559,6 +626,7 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
559
626
|
typedef typename RINEX_NAV<FloatT>::space_node_t space_node_t;
|
560
627
|
typedef typename RINEX_NAV<FloatT>::message_t message_t;
|
561
628
|
typedef typename RINEX_NAV<FloatT>::message_sbas_t message_sbas_t;
|
629
|
+
typedef typename RINEX_NAV<FloatT>::message_glonass_t message_glonass_t;
|
562
630
|
typedef typename space_node_t::Ionospheric_UTC_Parameters iono_utc_t;
|
563
631
|
|
564
632
|
static const typename super_t::convert_item_t eph0_v2[10], eph0_v3[10];
|
@@ -575,11 +643,18 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
575
643
|
static const typename super_t::convert_item_t eph2_sbas_v2[4], eph2_sbas_v3[4];
|
576
644
|
static const typename super_t::convert_item_t eph3_sbas_v2[4], eph3_sbas_v3[4];
|
577
645
|
|
646
|
+
static const typename super_t::convert_item_t eph0_glonass_v2[10], eph0_glonass_v3[10];
|
647
|
+
static const typename super_t::convert_item_t eph1_glonass_v2[4], eph1_glonass_v3[4];
|
648
|
+
static const typename super_t::convert_item_t eph2_glonass_v2[4], eph2_glonass_v3[4];
|
649
|
+
static const typename super_t::convert_item_t eph3_glonass_v2[4], eph3_glonass_v3[4];
|
650
|
+
static const typename super_t::convert_item_t eph4_glonass_v305[4];
|
651
|
+
|
578
652
|
protected:
|
579
653
|
typename super_t::version_type_t::sat_system_t sys_of_msg;
|
580
654
|
message_t msg;
|
581
655
|
message_sbas_t msg_sbas;
|
582
|
-
|
656
|
+
message_glonass_t msg_glonass;
|
657
|
+
|
583
658
|
void seek_next_v2_gps() {
|
584
659
|
char buf[256];
|
585
660
|
|
@@ -616,9 +691,27 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
616
691
|
for(int i(0); i < 4; i++){
|
617
692
|
if((!super_t::src.good())
|
618
693
|
|| super_t::src.getline(buf, sizeof(buf)).fail()){return;}
|
694
|
+
std::string line(buf);
|
695
|
+
|
696
|
+
switch(i){
|
697
|
+
case 0: {
|
698
|
+
super_t::convert(eph0_glonass_v2, line, &msg_glonass);
|
699
|
+
msg_glonass.date_tm.tm_year = msg_glonass.t_year2 + (msg_glonass.t_year2 < 80 ? 100 : 0); // greater than 1980
|
700
|
+
msg_glonass.date_tm.tm_mon = msg_glonass.t_mon12 - 1; // month [0, 11]
|
701
|
+
msg_glonass.date_tm.tm_sec = (int)msg_glonass.t_sec;
|
702
|
+
break;
|
703
|
+
}
|
704
|
+
case 1: super_t::convert(eph1_glonass_v2, line, &msg_glonass); break;
|
705
|
+
case 2:
|
706
|
+
super_t::convert(eph2_glonass_v2, line, &msg_glonass);
|
707
|
+
if(super_t::version_type.version < 211){
|
708
|
+
//msg_glonass.freq_num; // TODO 1..24? convert to value ranging from -7 to 6?
|
709
|
+
}
|
710
|
+
break;
|
711
|
+
case 3: super_t::convert(eph3_glonass_v2, line, &msg_glonass); break;
|
712
|
+
}
|
619
713
|
}
|
620
|
-
|
621
|
-
sys_of_msg = super_t::version_type_t::SYS_UNKNOWN;
|
714
|
+
sys_of_msg = super_t::version_type_t::SYS_GLONASS;
|
622
715
|
super_t::_has_next = true;
|
623
716
|
}
|
624
717
|
|
@@ -712,6 +805,31 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
712
805
|
sys_of_msg = super_t::version_type_t::SYS_QZSS;
|
713
806
|
}
|
714
807
|
|
808
|
+
template <std::size_t N>
|
809
|
+
void seek_next_v3_glonass(char (&buf)[N]) {
|
810
|
+
super_t::convert(eph0_glonass_v3, std::string(buf), &msg_glonass);
|
811
|
+
msg_glonass.date_tm.tm_year = msg_glonass.t_year4 - 1900; // tm_year base is 1900
|
812
|
+
msg_glonass.date_tm.tm_mon = msg_glonass.t_mon12 - 1; // month [0, 11]
|
813
|
+
msg_glonass.t_sec = msg_glonass.date_tm.tm_sec;
|
814
|
+
|
815
|
+
for(int i(1);
|
816
|
+
i < ((super_t::version_type.version <= 304) ? 4 : 5);
|
817
|
+
i++){
|
818
|
+
if((!super_t::src.good())
|
819
|
+
|| super_t::src.getline(buf, sizeof(buf)).fail()){return;}
|
820
|
+
std::string line(buf);
|
821
|
+
|
822
|
+
switch(i){
|
823
|
+
case 1: super_t::convert(eph1_glonass_v3, line, &msg_glonass); break;
|
824
|
+
case 2: super_t::convert(eph2_glonass_v3, line, &msg_glonass); break;
|
825
|
+
case 3: super_t::convert(eph3_glonass_v3, line, &msg_glonass); break;
|
826
|
+
case 4: super_t::convert(eph4_glonass_v305, line, &msg_glonass); break;
|
827
|
+
}
|
828
|
+
}
|
829
|
+
sys_of_msg = super_t::version_type_t::SYS_GLONASS;
|
830
|
+
super_t::_has_next = true;
|
831
|
+
}
|
832
|
+
|
715
833
|
template <std::size_t N>
|
716
834
|
void seek_next_v3_not_implemented(char (&buf)[N], const int &lines) {
|
717
835
|
for(int i(1); i < lines; i++){
|
@@ -731,7 +849,7 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
731
849
|
switch(buf[0]){
|
732
850
|
case 'G': seek_next_v3_gps(buf); return; // GPS
|
733
851
|
case 'E': seek_next_v3_not_implemented(buf, 8); return; // Galileo
|
734
|
-
case 'R':
|
852
|
+
case 'R': seek_next_v3_glonass(buf); return; // Glonass
|
735
853
|
case 'J': seek_next_v3_qzss(buf); return; // QZSS
|
736
854
|
case 'C': seek_next_v3_not_implemented(buf, 8); return; // Beido
|
737
855
|
case 'S': seek_next_v3_sbas(buf); return; // SBAS
|
@@ -839,10 +957,70 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
839
957
|
return alpha && beta && utc && leap;
|
840
958
|
}
|
841
959
|
|
960
|
+
struct t_corr_glonass_t {
|
961
|
+
int year, month, day;
|
962
|
+
FloatT tau_c_neg, tau_GPS; // TODO check tau_GPS polarity
|
963
|
+
int leap_sec;
|
964
|
+
};
|
965
|
+
static const typename super_t::convert_item_t t_corr_glonass_v2[4];
|
966
|
+
|
967
|
+
bool extract_t_corr_glonass_v2(t_corr_glonass_t &t_corr_glonass) const {
|
968
|
+
bool utc, leap;
|
969
|
+
super_t::header_t::const_iterator it;
|
970
|
+
|
971
|
+
if(utc = ((it = _header.find("CORR TO SYSTEM TIME")) != _header.end())){
|
972
|
+
super_t::convert(t_corr_glonass_v2, it->second.front(), &t_corr_glonass);
|
973
|
+
}
|
974
|
+
|
975
|
+
if(leap = ((it = _header.find("LEAP SECONDS")) != _header.end())){
|
976
|
+
iono_utc_t iono_utc;
|
977
|
+
super_t::convert(utc_leap_v2, it->second.front(), &iono_utc);
|
978
|
+
t_corr_glonass.leap_sec = iono_utc.delta_t_LS;
|
979
|
+
}
|
980
|
+
|
981
|
+
return utc && leap;
|
982
|
+
}
|
983
|
+
|
984
|
+
bool extract_t_corr_glonass_v3(t_corr_glonass_t &t_corr_glonass) const {
|
985
|
+
iono_utc_t iono_utc;
|
986
|
+
bool utc(false), leap(false);
|
987
|
+
typedef super_t::header_t::const_iterator it_t;
|
988
|
+
typedef super_t::header_t::mapped_type::const_iterator it2_t;
|
989
|
+
|
990
|
+
it_t it;
|
991
|
+
|
992
|
+
if((it = _header.find("TIME SYSTEM CORR")) != _header.end()){
|
993
|
+
for(it2_t it2(it->second.begin()), it2_end(it->second.end()); it2 != it2_end; ++it2){
|
994
|
+
if(it2->find("GLUT") != it2->npos){
|
995
|
+
super_t::convert(utc_v3, *it2, &iono_utc);
|
996
|
+
t_corr_glonass.year = t_corr_glonass.month = t_corr_glonass.day = 0;
|
997
|
+
t_corr_glonass.tau_c_neg = iono_utc.A0;
|
998
|
+
}else if(it2->find("GLGP") != it2->npos){
|
999
|
+
super_t::convert(utc_v3, *it2, &iono_utc);
|
1000
|
+
t_corr_glonass.tau_GPS = iono_utc.A0;
|
1001
|
+
}
|
1002
|
+
utc = true;
|
1003
|
+
}
|
1004
|
+
}
|
1005
|
+
|
1006
|
+
if((it = _header.find("LEAP SECONDS")) != _header.end()){
|
1007
|
+
if(version_type.version >= 301){
|
1008
|
+
super_t::convert(utc_leap_v301, it->second.front(), &iono_utc);
|
1009
|
+
}else{
|
1010
|
+
super_t::convert(utc_leap_v2, it->second.front(), &iono_utc);
|
1011
|
+
}
|
1012
|
+
t_corr_glonass.leap_sec = iono_utc.delta_t_LS;
|
1013
|
+
leap = true;
|
1014
|
+
}
|
1015
|
+
|
1016
|
+
return utc && leap;
|
1017
|
+
}
|
1018
|
+
|
842
1019
|
struct space_node_list_t {
|
843
1020
|
space_node_t *gps;
|
844
1021
|
SBAS_SpaceNode<FloatT> *sbas;
|
845
1022
|
space_node_t *qzss;
|
1023
|
+
GLONASS_SpaceNode<FloatT> *glonass;
|
846
1024
|
};
|
847
1025
|
|
848
1026
|
static int read_all(std::istream &in, space_node_list_t &space_nodes = {0}){
|
@@ -859,6 +1037,12 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
859
1037
|
&& (reader.version_type.version >= 302)){
|
860
1038
|
reader.extract_iono_utc_v3(*space_nodes.qzss);
|
861
1039
|
}
|
1040
|
+
t_corr_glonass_t t_corr_glonass = {0};
|
1041
|
+
if(space_nodes.glonass){
|
1042
|
+
(reader.version_type.version >= 300)
|
1043
|
+
? reader.extract_t_corr_glonass_v3(t_corr_glonass)
|
1044
|
+
: reader.extract_t_corr_glonass_v2(t_corr_glonass);
|
1045
|
+
}
|
862
1046
|
int res(0);
|
863
1047
|
for(; reader.has_next(); reader.next()){
|
864
1048
|
switch(reader.sys_of_msg){
|
@@ -881,6 +1065,17 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
881
1065
|
res++;
|
882
1066
|
break;
|
883
1067
|
}
|
1068
|
+
case super_t::version_type_t::SYS_GLONASS: {
|
1069
|
+
if(!space_nodes.glonass){break;}
|
1070
|
+
typename message_glonass_t::eph_t eph0(reader.msg_glonass);
|
1071
|
+
eph0.tau_c = -t_corr_glonass.tau_c_neg;
|
1072
|
+
eph0.tau_GPS = t_corr_glonass.tau_GPS;
|
1073
|
+
typename GLONASS_SpaceNode<FloatT>
|
1074
|
+
::SatelliteProperties::Ephemeris_with_GPS_Time eph(eph0, t_corr_glonass.leap_sec);
|
1075
|
+
space_nodes.glonass->satellite(reader.msg_glonass.svid).register_ephemeris(eph);
|
1076
|
+
res++;
|
1077
|
+
break;
|
1078
|
+
}
|
884
1079
|
default: break;
|
885
1080
|
}
|
886
1081
|
}
|
@@ -1425,6 +1620,86 @@ const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>
|
|
1425
1620
|
};
|
1426
1621
|
|
1427
1622
|
|
1623
|
+
template <class FloatT>
|
1624
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph0_glonass_v2[] = {
|
1625
|
+
GEN_D( 0, 2, message_glonass_t, svid, int),
|
1626
|
+
GEN_D( 3, 2, message_glonass_t, t_year2, int),
|
1627
|
+
GEN_D( 6, 2, message_glonass_t, t_mon12, int),
|
1628
|
+
GEN_D( 9, 2, message_glonass_t, date_tm.tm_mday, int),
|
1629
|
+
GEN_D(12, 2, message_glonass_t, date_tm.tm_hour, int),
|
1630
|
+
GEN_D(15, 2, message_glonass_t, date_tm.tm_min, int),
|
1631
|
+
GEN_F(17, 5, 1, message_glonass_t, t_sec),
|
1632
|
+
GEN_E(22, 19, 12, message_glonass_t, tau_n_neg),
|
1633
|
+
GEN_E(41, 19, 12, message_glonass_t, gamma_n),
|
1634
|
+
GEN_E2(60, 19, 12, message_glonass_t, t_k, unsigned int),
|
1635
|
+
};
|
1636
|
+
template <class FloatT>
|
1637
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph0_glonass_v3[] = {
|
1638
|
+
GEN_I( 1, 2, message_glonass_t, svid, int),
|
1639
|
+
GEN_I( 4, 4, message_glonass_t, t_year4, int),
|
1640
|
+
GEN_I( 9, 2, message_glonass_t, t_mon12, int),
|
1641
|
+
GEN_I(12, 2, message_glonass_t, date_tm.tm_mday, int),
|
1642
|
+
GEN_I(15, 2, message_glonass_t, date_tm.tm_hour, int),
|
1643
|
+
GEN_I(18, 2, message_glonass_t, date_tm.tm_min, int),
|
1644
|
+
GEN_I(21, 2, message_glonass_t, date_tm.tm_sec, int),
|
1645
|
+
GEN_E(23, 19, 12, message_glonass_t, tau_n_neg),
|
1646
|
+
GEN_E(42, 19, 12, message_glonass_t, gamma_n),
|
1647
|
+
GEN_E2(61, 19, 12, message_glonass_t, t_k, unsigned int),
|
1648
|
+
};
|
1649
|
+
|
1650
|
+
template <class FloatT>
|
1651
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph1_glonass_v2[] = {
|
1652
|
+
GEN_E( 3, 19, 12, message_glonass_t, x_km),
|
1653
|
+
GEN_E(22, 19, 12, message_glonass_t, dx_km_s),
|
1654
|
+
GEN_E(41, 19, 12, message_glonass_t, ddx_km_s2),
|
1655
|
+
GEN_E2(60, 19, 12, message_glonass_t, B_n, unsigned int),
|
1656
|
+
};
|
1657
|
+
template <class FloatT>
|
1658
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph1_glonass_v3[] = {
|
1659
|
+
GEN_E( 4, 19, 12, message_glonass_t, x_km),
|
1660
|
+
GEN_E(23, 19, 12, message_glonass_t, dx_km_s),
|
1661
|
+
GEN_E(42, 19, 12, message_glonass_t, ddx_km_s2),
|
1662
|
+
GEN_E2(61, 19, 12, message_glonass_t, B_n, unsigned int),
|
1663
|
+
};
|
1664
|
+
|
1665
|
+
template <class FloatT>
|
1666
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph2_glonass_v2[] = {
|
1667
|
+
GEN_E( 3, 19, 12, message_glonass_t, y_km),
|
1668
|
+
GEN_E(22, 19, 12, message_glonass_t, dy_km_s),
|
1669
|
+
GEN_E(41, 19, 12, message_glonass_t, ddy_km_s2),
|
1670
|
+
GEN_E2(60, 19, 12, message_glonass_t, freq_num, int),
|
1671
|
+
};
|
1672
|
+
template <class FloatT>
|
1673
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph2_glonass_v3[] = {
|
1674
|
+
GEN_E( 4, 19, 12, message_glonass_t, y_km),
|
1675
|
+
GEN_E(23, 19, 12, message_glonass_t, dy_km_s),
|
1676
|
+
GEN_E(42, 19, 12, message_glonass_t, ddy_km_s2),
|
1677
|
+
GEN_E2(61, 19, 12, message_glonass_t, freq_num, int),
|
1678
|
+
};
|
1679
|
+
|
1680
|
+
template <class FloatT>
|
1681
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph3_glonass_v2[] = {
|
1682
|
+
GEN_E( 3, 19, 12, message_glonass_t, z_km),
|
1683
|
+
GEN_E(22, 19, 12, message_glonass_t, dz_km_s),
|
1684
|
+
GEN_E(41, 19, 12, message_glonass_t, ddz_km_s2),
|
1685
|
+
GEN_E2(60, 19, 12, message_glonass_t, E_n, unsigned int),
|
1686
|
+
};
|
1687
|
+
template <class FloatT>
|
1688
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph3_glonass_v3[] = {
|
1689
|
+
GEN_E( 4, 19, 12, message_glonass_t, z_km),
|
1690
|
+
GEN_E(23, 19, 12, message_glonass_t, dz_km_s),
|
1691
|
+
GEN_E(42, 19, 12, message_glonass_t, ddz_km_s2),
|
1692
|
+
GEN_E2(61, 19, 12, message_glonass_t, E_n, unsigned int),
|
1693
|
+
};
|
1694
|
+
|
1695
|
+
template <class FloatT>
|
1696
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph4_glonass_v305[] = {
|
1697
|
+
GEN_E2( 4, 19, 12, message_glonass_t, status_flags, unsigned int),
|
1698
|
+
GEN_E (23, 19, 12, message_glonass_t, delta_tau),
|
1699
|
+
GEN_E2(42, 19, 12, message_glonass_t, urai, unsigned int),
|
1700
|
+
GEN_E2(61, 19, 12, message_glonass_t, health_flags, unsigned int),
|
1701
|
+
};
|
1702
|
+
|
1428
1703
|
template <class FloatT>
|
1429
1704
|
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::iono_alpha_v2[] = {
|
1430
1705
|
GEN_E( 2, 12, 4, iono_utc_t, alpha[0]),
|
@@ -1487,6 +1762,14 @@ const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>
|
|
1487
1762
|
GEN_D(18, 6, iono_utc_t, DN, int),
|
1488
1763
|
};
|
1489
1764
|
|
1765
|
+
template <class FloatT>
|
1766
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::t_corr_glonass_v2[] = {
|
1767
|
+
GEN_D( 0, 6, t_corr_glonass_t, year, int),
|
1768
|
+
GEN_D( 6, 6, t_corr_glonass_t, month, int),
|
1769
|
+
GEN_D(12, 6, t_corr_glonass_t, day, int),
|
1770
|
+
GEN_E(21, 19, 12, t_corr_glonass_t, tau_c_neg),
|
1771
|
+
};
|
1772
|
+
|
1490
1773
|
template <class FloatT>
|
1491
1774
|
const typename RINEX_OBS_Reader<FloatT>::convert_item_t RINEX_OBS_Reader<FloatT>::epoch_flag_v2[] = {
|
1492
1775
|
GEN_I( 1, 2, epoch_flag_t, epoch_year2, int),
|
@@ -1724,6 +2007,7 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1724
2007
|
typedef typename RINEX_NAV<FloatT>::space_node_t space_node_t;
|
1725
2008
|
typedef typename RINEX_NAV<FloatT>::message_t message_t;
|
1726
2009
|
typedef typename RINEX_NAV<FloatT>::message_sbas_t message_sbas_t;
|
2010
|
+
typedef typename RINEX_NAV<FloatT>::message_glonass_t message_glonass_t;
|
1727
2011
|
|
1728
2012
|
static const typename super_t::header_item_t default_header[];
|
1729
2013
|
static const int default_header_size;
|
@@ -1856,6 +2140,45 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1856
2140
|
dist << buf.str();
|
1857
2141
|
return *this;
|
1858
2142
|
}
|
2143
|
+
self_t &operator<<(const message_glonass_t &msg){
|
2144
|
+
std::stringstream buf;
|
2145
|
+
switch(super_t::_version_type.version / 100){
|
2146
|
+
case 2:
|
2147
|
+
for(int i(0); i < 4; ++i){
|
2148
|
+
std::string s(80, ' ');
|
2149
|
+
switch(i){
|
2150
|
+
case 0: super_t::convert(reader_t::eph0_glonass_v2, s, &msg); break;
|
2151
|
+
case 1: super_t::convert(reader_t::eph1_glonass_v2, s, &msg); break;
|
2152
|
+
case 2:
|
2153
|
+
if(super_t::_version_type.version < 211){
|
2154
|
+
//msg_glonass.freq_num; // TODO convert to value 1..24?
|
2155
|
+
}
|
2156
|
+
super_t::convert(reader_t::eph2_glonass_v2, s, &msg);
|
2157
|
+
break;
|
2158
|
+
case 3: super_t::convert(reader_t::eph3_glonass_v2, s, &msg); break;
|
2159
|
+
}
|
2160
|
+
buf << s << std::endl;
|
2161
|
+
}
|
2162
|
+
break;
|
2163
|
+
case 3:
|
2164
|
+
for(int i(0);
|
2165
|
+
i < ((super_t::_version_type.version <= 304) ? 4 : 5);
|
2166
|
+
++i){
|
2167
|
+
std::string s(80, ' ');
|
2168
|
+
switch(i){
|
2169
|
+
case 0: super_t::convert(reader_t::eph0_glonass_v3, s, &msg); s[0] = 'R'; break;
|
2170
|
+
case 1: super_t::convert(reader_t::eph1_glonass_v3, s, &msg); break;
|
2171
|
+
case 2: super_t::convert(reader_t::eph2_glonass_v3, s, &msg); break;
|
2172
|
+
case 3: super_t::convert(reader_t::eph3_glonass_v3, s, &msg); break;
|
2173
|
+
case 4: super_t::convert(reader_t::eph4_glonass_v305, s, &msg); break;
|
2174
|
+
}
|
2175
|
+
buf << s << std::endl;
|
2176
|
+
}
|
2177
|
+
break;
|
2178
|
+
}
|
2179
|
+
dist << buf.str();
|
2180
|
+
return *this;
|
2181
|
+
}
|
1859
2182
|
|
1860
2183
|
public:
|
1861
2184
|
void set_version(
|
@@ -1869,6 +2192,7 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1869
2192
|
const space_node_t *gps;
|
1870
2193
|
const SBAS_SpaceNode<FloatT> *sbas;
|
1871
2194
|
const space_node_t *qzss;
|
2195
|
+
const GLONASS_SpaceNode<FloatT> *glonass;
|
1872
2196
|
};
|
1873
2197
|
int write_all(
|
1874
2198
|
const space_node_list_t &space_nodes,
|
@@ -1915,6 +2239,53 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1915
2239
|
break;
|
1916
2240
|
}
|
1917
2241
|
}while(false);
|
2242
|
+
while(space_nodes.glonass){
|
2243
|
+
++systems;
|
2244
|
+
set_version(version, super_t::version_type_t::SYS_GLONASS);
|
2245
|
+
typename GLONASS_SpaceNode<FloatT>::Satellite::eph_t latest(
|
2246
|
+
space_nodes.glonass->latest_ephemeris());
|
2247
|
+
if(latest.t_b_gps.week <= 0){break;}
|
2248
|
+
typename reader_t::iono_utc_t iono_utc = {0};
|
2249
|
+
iono_utc.t_ot = latest.t_b_gps.seconds;
|
2250
|
+
iono_utc.WN_t = latest.t_b_gps.week;
|
2251
|
+
iono_utc.delta_t_LS = (int)std::floor(0.5
|
2252
|
+
+ typename space_node_t::gps_time_t(latest.c_tm_utc()).interval(latest.t_b_gps));
|
2253
|
+
switch(version / 100){
|
2254
|
+
case 2:
|
2255
|
+
if((_header["CORR TO SYSTEM TIME"].entries() == 0) && (latest.tau_c != 0)){
|
2256
|
+
std::tm t_tm(typename space_node_t::gps_time_t(iono_utc.WN_t, iono_utc.t_ot).c_tm());
|
2257
|
+
typename reader_t::t_corr_glonass_t t_corr_glonass = {
|
2258
|
+
t_tm.tm_year + 1900, t_tm.tm_mon + 1, t_tm.tm_mday, // year, month, day
|
2259
|
+
-latest.tau_c,
|
2260
|
+
};
|
2261
|
+
std::string s(60, ' ');
|
2262
|
+
super_t::convert(reader_t::t_corr_glonass_v2, s, &t_corr_glonass);
|
2263
|
+
_header["CORR TO SYSTEM TIME"] = s;
|
2264
|
+
}
|
2265
|
+
break;
|
2266
|
+
case 3:
|
2267
|
+
if((_header["TIME SYSTEM CORR"].find("GLUT") == _header.end()) && (latest.tau_c != 0)){
|
2268
|
+
std::string s(60, ' ');
|
2269
|
+
iono_utc.A0 = -latest.tau_c;
|
2270
|
+
super_t::convert(reader_t::utc_v3, s, &iono_utc);
|
2271
|
+
_header["TIME SYSTEM CORR"] << s.replace(0, 4, "GLUT", 4);
|
2272
|
+
}
|
2273
|
+
if((_header["TIME SYSTEM CORR"].find("GLGP") == _header.end()) && (latest.tau_GPS != 0)){
|
2274
|
+
std::string s(60, ' ');
|
2275
|
+
iono_utc.A0 = latest.tau_GPS;
|
2276
|
+
super_t::convert(reader_t::utc_v3, s, &iono_utc);
|
2277
|
+
_header["TIME SYSTEM CORR"] << s.replace(0, 4, "GLGP", 4);
|
2278
|
+
}
|
2279
|
+
break;
|
2280
|
+
}
|
2281
|
+
if((_header["LEAP SECONDS"].entries() == 0) && (iono_utc.delta_t_LS != 0)){
|
2282
|
+
// ver.3 can use ver.2 format with blank fields
|
2283
|
+
std::string s(60, ' ');
|
2284
|
+
super_t::convert(reader_t::utc_leap_v2, s, &iono_utc);
|
2285
|
+
_header["LEAP SECONDS"] = s;
|
2286
|
+
}
|
2287
|
+
break;
|
2288
|
+
}
|
1918
2289
|
if(systems > 1){
|
1919
2290
|
set_version(version, super_t::version_type_t::SYS_MIXED);
|
1920
2291
|
}
|
@@ -1939,6 +2310,10 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1939
2310
|
w << message_sbas_t(eph);
|
1940
2311
|
counter++;
|
1941
2312
|
}
|
2313
|
+
void operator()(const typename message_glonass_t::eph_t &eph) {
|
2314
|
+
w << message_glonass_t(eph);
|
2315
|
+
counter++;
|
2316
|
+
}
|
1942
2317
|
} functor = {*this, res, false, false};
|
1943
2318
|
if(space_nodes.gps){
|
1944
2319
|
functor.gps = true;
|
@@ -1972,6 +2347,16 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1972
2347
|
space_node_t::Satellite::eph_list_t::EACH_ALL_INVERTED);
|
1973
2348
|
}
|
1974
2349
|
}
|
2350
|
+
if(space_nodes.glonass){
|
2351
|
+
for(typename GLONASS_SpaceNode<FloatT>::satellites_t::const_iterator
|
2352
|
+
it(space_nodes.glonass->satellites().begin()),
|
2353
|
+
it_end(space_nodes.glonass->satellites().end());
|
2354
|
+
it != it_end; ++it){
|
2355
|
+
it->second.each_ephemeris(
|
2356
|
+
functor,
|
2357
|
+
GLONASS_SpaceNode<FloatT>::Satellite::eph_list_t::EACH_ALL_INVERTED);
|
2358
|
+
}
|
2359
|
+
}
|
1975
2360
|
return res;
|
1976
2361
|
}
|
1977
2362
|
static int write_all(
|