gps_pvt 0.1.7 → 0.2.3
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 +13 -2
- data/Rakefile +2 -0
- data/exe/gps_pvt +32 -23
- data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +5 -3
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +4444 -671
- data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +284 -19
- data/ext/ninja-scan-light/tool/navigation/GPS.h +12 -46
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +61 -100
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +87 -25
- data/ext/ninja-scan-light/tool/navigation/QZSS.h +62 -0
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +335 -27
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +2330 -0
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +306 -0
- data/ext/ninja-scan-light/tool/param/bit_array.h +4 -3
- data/ext/ninja-scan-light/tool/swig/GPS.i +429 -138
- data/ext/ninja-scan-light/tool/swig/SylphideMath.i +53 -6
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +37 -6
- data/ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb +38 -4
- data/gps_pvt.gemspec +63 -0
- data/lib/gps_pvt/receiver.rb +281 -140
- data/lib/gps_pvt/version.rb +1 -1
- metadata +7 -3
@@ -53,6 +53,7 @@
|
|
53
53
|
#include <limits>
|
54
54
|
|
55
55
|
#include "GPS.h"
|
56
|
+
#include "SBAS.h"
|
56
57
|
|
57
58
|
template <class U = void>
|
58
59
|
class RINEX_Reader {
|
@@ -452,7 +453,6 @@ struct RINEX_NAV {
|
|
452
453
|
FloatT t_oc_sec;
|
453
454
|
FloatT t_oe_WN;
|
454
455
|
FloatT ura_meter;
|
455
|
-
FloatT SV_health_f;
|
456
456
|
FloatT t_ot; ///< Transmitting time [s]
|
457
457
|
FloatT fit_interval_hr;
|
458
458
|
FloatT dummy;
|
@@ -467,7 +467,6 @@ struct RINEX_NAV {
|
|
467
467
|
t_oc_sec(std::fmod(eph.t_oc, 60)),
|
468
468
|
t_oe_WN(eph.WN),
|
469
469
|
ura_meter(ephemeris_t::URA_meter(eph.URA)),
|
470
|
-
SV_health_f(((eph.SV_health & 0x20) && (eph.SV_health & 0x1F == 0)) ? 1 : eph.SV_health),
|
471
470
|
t_ot(0), // TODO
|
472
471
|
fit_interval_hr(eph.fit_interval / (60 * 60)),
|
473
472
|
dummy(0) {
|
@@ -485,17 +484,69 @@ struct RINEX_NAV {
|
|
485
484
|
* RINEX Value: 0 Health OK
|
486
485
|
* RINEX Value: 1 Health not OK (bits 18-22 not stored)
|
487
486
|
* RINEX Value: >32 Health not OK (bits 18-22 stored)
|
487
|
+
* eph.SV_health may have a value greater than 32
|
488
488
|
*/
|
489
|
-
eph.SV_health = (unsigned int)SV_health_f;
|
490
|
-
if(eph.SV_health > 32){
|
491
|
-
eph.SV_health &= 0x3F; // 0b111111
|
492
|
-
}else if(eph.SV_health > 0){
|
493
|
-
eph.SV_health = 0x20; // 0b100000
|
494
|
-
}
|
495
489
|
|
496
490
|
// At least 4 hour validity, then, hours => seconds;
|
497
491
|
eph.fit_interval = ((fit_interval_hr < 4) ? 4 : fit_interval_hr) * 60 * 60;
|
498
492
|
}
|
493
|
+
static message_t from_qzss(const ephemeris_t &eph_){
|
494
|
+
message_t res(eph_);
|
495
|
+
res.eph.svid -= 192;
|
496
|
+
res.fit_interval_hr = (res.fit_interval_hr) > 2 ? 1 : 0;
|
497
|
+
return res;
|
498
|
+
}
|
499
|
+
ephemeris_t eph_qzss() const {
|
500
|
+
ephemeris_t res(eph);
|
501
|
+
res.svid += 192;
|
502
|
+
res.fit_interval = ((fit_interval_hr > 0) ? 4 : 2) * 60 * 60;
|
503
|
+
return res;
|
504
|
+
}
|
505
|
+
};
|
506
|
+
struct message_sbas_t {
|
507
|
+
typedef typename SBAS_SpaceNode<FloatT>
|
508
|
+
::SatelliteProperties::Ephemeris eph_t;
|
509
|
+
int svid;
|
510
|
+
std::tm date_tm;
|
511
|
+
int t_year4, t_year2, t_mon12;
|
512
|
+
FloatT t_sec;
|
513
|
+
FloatT a_Gf0, a_Gf1;
|
514
|
+
FloatT t_t; // Transmission time of message (start of the message) in GPS seconds of the week
|
515
|
+
FloatT x_km, dx_km_s, ddx_km_s2;
|
516
|
+
FloatT y_km, dy_km_s, ddy_km_s2;
|
517
|
+
FloatT z_km, dz_km_s, ddz_km_s2;
|
518
|
+
unsigned int health;
|
519
|
+
FloatT URA;
|
520
|
+
unsigned int iodn;
|
521
|
+
message_sbas_t() {}
|
522
|
+
message_sbas_t(const eph_t &eph)
|
523
|
+
: svid((int)eph.svid - 100),
|
524
|
+
date_tm(eph.base_time().c_tm()),
|
525
|
+
t_year4(date_tm.tm_year + 1900),
|
526
|
+
t_year2(date_tm.tm_year % 100),
|
527
|
+
t_mon12(date_tm.tm_mon + 1),
|
528
|
+
t_sec(date_tm.tm_sec),
|
529
|
+
a_Gf0(eph.a_Gf0), a_Gf1(eph.a_Gf1),
|
530
|
+
t_t(eph.t_0), // TODO maybe differ from t_e slightly
|
531
|
+
x_km(1E-3 * eph.x), dx_km_s(1E-3 * eph.dx), ddx_km_s2(1E-3 * eph.ddx),
|
532
|
+
y_km(1E-3 * eph.y), dy_km_s(1E-3 * eph.dy), ddy_km_s2(1E-3 * eph.ddy),
|
533
|
+
z_km(1E-3 * eph.z), dz_km_s(1E-3 * eph.dz), ddz_km_s2(1E-3 * eph.ddz),
|
534
|
+
health(0), URA(eph.URA), iodn(0) {
|
535
|
+
}
|
536
|
+
operator eph_t() const {
|
537
|
+
eph_t eph = {0};
|
538
|
+
eph.svid = (unsigned int)svid + 100;
|
539
|
+
typename space_node_t::gps_time_t t(date_tm);
|
540
|
+
t += (t_sec - date_tm.tm_sec);
|
541
|
+
eph.WN = t.week;
|
542
|
+
eph.t_0 = t.seconds;
|
543
|
+
eph.a_Gf0 = a_Gf0; eph.a_Gf1 = a_Gf1;
|
544
|
+
eph.x = 1E3 * x_km; eph.dx = 1E3 * dx_km_s; eph.ddx = 1E3 * ddx_km_s2;
|
545
|
+
eph.y = 1E3 * y_km; eph.dy = 1E3 * dy_km_s; eph.ddy = 1E3 * ddy_km_s2;
|
546
|
+
eph.z = 1E3 * z_km; eph.dz = 1E3 * dz_km_s; eph.ddz = 1E3 * ddz_km_s2;
|
547
|
+
eph.URA = URA;
|
548
|
+
return eph;
|
549
|
+
}
|
499
550
|
};
|
500
551
|
};
|
501
552
|
|
@@ -507,6 +558,7 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
507
558
|
public:
|
508
559
|
typedef typename RINEX_NAV<FloatT>::space_node_t space_node_t;
|
509
560
|
typedef typename RINEX_NAV<FloatT>::message_t message_t;
|
561
|
+
typedef typename RINEX_NAV<FloatT>::message_sbas_t message_sbas_t;
|
510
562
|
typedef typename space_node_t::Ionospheric_UTC_Parameters iono_utc_t;
|
511
563
|
|
512
564
|
static const typename super_t::convert_item_t eph0_v2[10], eph0_v3[10];
|
@@ -518,9 +570,15 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
518
570
|
static const typename super_t::convert_item_t eph6_v2[4], eph6_v3[4];
|
519
571
|
static const typename super_t::convert_item_t eph7_v2[2], eph7_v3[2];
|
520
572
|
|
573
|
+
static const typename super_t::convert_item_t eph0_sbas_v2[10], eph0_sbas_v3[10];
|
574
|
+
static const typename super_t::convert_item_t eph1_sbas_v2[4], eph1_sbas_v3[4];
|
575
|
+
static const typename super_t::convert_item_t eph2_sbas_v2[4], eph2_sbas_v3[4];
|
576
|
+
static const typename super_t::convert_item_t eph3_sbas_v2[4], eph3_sbas_v3[4];
|
577
|
+
|
521
578
|
protected:
|
522
579
|
typename super_t::version_type_t::sat_system_t sys_of_msg;
|
523
580
|
message_t msg;
|
581
|
+
message_sbas_t msg_sbas;
|
524
582
|
|
525
583
|
void seek_next_v2_gps() {
|
526
584
|
char buf[256];
|
@@ -564,10 +622,36 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
564
622
|
super_t::_has_next = true;
|
565
623
|
}
|
566
624
|
|
625
|
+
void seek_next_v2_sbas() {
|
626
|
+
char buf[256];
|
627
|
+
|
628
|
+
for(int i(0); i < 4; i++){
|
629
|
+
if((!super_t::src.good())
|
630
|
+
|| super_t::src.getline(buf, sizeof(buf)).fail()){return;}
|
631
|
+
std::string line(buf);
|
632
|
+
|
633
|
+
switch(i){
|
634
|
+
case 0: {
|
635
|
+
super_t::convert(eph0_sbas_v2, line, &msg_sbas);
|
636
|
+
msg_sbas.date_tm.tm_year = msg_sbas.t_year2 + (msg_sbas.t_year2 < 80 ? 100 : 0); // greater than 1980
|
637
|
+
msg_sbas.date_tm.tm_mon = msg_sbas.t_mon12 - 1; // month [0, 11]
|
638
|
+
msg_sbas.date_tm.tm_sec = (int)msg_sbas.t_sec;
|
639
|
+
break;
|
640
|
+
}
|
641
|
+
case 1: super_t::convert(eph1_sbas_v2, line, &msg_sbas); break;
|
642
|
+
case 2: super_t::convert(eph2_sbas_v2, line, &msg_sbas); break;
|
643
|
+
case 3: super_t::convert(eph3_sbas_v2, line, &msg_sbas); break;
|
644
|
+
}
|
645
|
+
}
|
646
|
+
sys_of_msg = super_t::version_type_t::SYS_SBAS;
|
647
|
+
super_t::_has_next = true;
|
648
|
+
}
|
649
|
+
|
567
650
|
void seek_next_v2() {
|
568
651
|
switch(super_t::version_type.sat_system){
|
569
652
|
case super_t::version_type_t::SYS_GPS: seek_next_v2_gps(); return;
|
570
653
|
case super_t::version_type_t::SYS_GLONASS: seek_next_v2_glonass(); return;
|
654
|
+
case super_t::version_type_t::SYS_SBAS: seek_next_v2_sbas(); return;
|
571
655
|
default: break;
|
572
656
|
}
|
573
657
|
}
|
@@ -599,6 +683,35 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
599
683
|
super_t::_has_next = true;
|
600
684
|
}
|
601
685
|
|
686
|
+
template <std::size_t N>
|
687
|
+
void seek_next_v3_sbas(char (&buf)[N]) {
|
688
|
+
super_t::convert(eph0_sbas_v3, std::string(buf), &msg_sbas);
|
689
|
+
msg_sbas.date_tm.tm_year = msg_sbas.t_year4 - 1900; // tm_year base is 1900
|
690
|
+
msg_sbas.date_tm.tm_mon = msg_sbas.t_mon12 - 1; // month [0, 11]
|
691
|
+
msg_sbas.t_sec = msg_sbas.date_tm.tm_sec;
|
692
|
+
|
693
|
+
for(int i(1); i < 4; i++){
|
694
|
+
if((!super_t::src.good())
|
695
|
+
|| super_t::src.getline(buf, sizeof(buf)).fail()){return;}
|
696
|
+
std::string line(buf);
|
697
|
+
|
698
|
+
switch(i){
|
699
|
+
case 1: super_t::convert(eph1_sbas_v3, line, &msg_sbas); break;
|
700
|
+
case 2: super_t::convert(eph2_sbas_v3, line, &msg_sbas); break;
|
701
|
+
case 3: super_t::convert(eph3_sbas_v3, line, &msg_sbas); break;
|
702
|
+
}
|
703
|
+
}
|
704
|
+
sys_of_msg = super_t::version_type_t::SYS_SBAS;
|
705
|
+
super_t::_has_next = true;
|
706
|
+
}
|
707
|
+
|
708
|
+
template <std::size_t N>
|
709
|
+
void seek_next_v3_qzss(char (&buf)[N]) {
|
710
|
+
seek_next_v3_gps(buf);
|
711
|
+
if(!super_t::_has_next){return;}
|
712
|
+
sys_of_msg = super_t::version_type_t::SYS_QZSS;
|
713
|
+
}
|
714
|
+
|
602
715
|
template <std::size_t N>
|
603
716
|
void seek_next_v3_not_implemented(char (&buf)[N], const int &lines) {
|
604
717
|
for(int i(1); i < lines; i++){
|
@@ -619,9 +732,9 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
619
732
|
case 'G': seek_next_v3_gps(buf); return; // GPS
|
620
733
|
case 'E': seek_next_v3_not_implemented(buf, 8); return; // Galileo
|
621
734
|
case 'R': seek_next_v3_not_implemented(buf, 4); return; // Glonass
|
622
|
-
case 'J':
|
735
|
+
case 'J': seek_next_v3_qzss(buf); return; // QZSS
|
623
736
|
case 'C': seek_next_v3_not_implemented(buf, 8); return; // Beido
|
624
|
-
case 'S':
|
737
|
+
case 'S': seek_next_v3_sbas(buf); return; // SBAS
|
625
738
|
case 'T': seek_next_v3_not_implemented(buf, 8); return; // IRNSS
|
626
739
|
default: break;
|
627
740
|
}
|
@@ -659,19 +772,19 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
659
772
|
bool alpha, beta, utc, leap;
|
660
773
|
super_t::header_t::const_iterator it;
|
661
774
|
|
662
|
-
if(alpha = ((it = _header.find("ION ALPHA")) != _header.end())){
|
775
|
+
if((alpha = ((it = _header.find("ION ALPHA")) != _header.end()))){
|
663
776
|
super_t::convert(iono_alpha_v2, it->second.front(), &iono_utc);
|
664
777
|
}
|
665
778
|
|
666
|
-
if(beta = ((it = _header.find("ION BETA")) != _header.end())){
|
779
|
+
if((beta = ((it = _header.find("ION BETA")) != _header.end()))){
|
667
780
|
super_t::convert(iono_beta_v2, it->second.front(), &iono_utc);
|
668
781
|
}
|
669
782
|
|
670
|
-
if(utc = ((it = _header.find("DELTA-UTC: A0,A1,T,W")) != _header.end())){
|
783
|
+
if((utc = ((it = _header.find("DELTA-UTC: A0,A1,T,W")) != _header.end()))){
|
671
784
|
super_t::convert(utc_v2, it->second.front(), &iono_utc);
|
672
785
|
}
|
673
786
|
|
674
|
-
if(leap = ((it = _header.find("LEAP SECONDS")) != _header.end())){
|
787
|
+
if((leap = ((it = _header.find("LEAP SECONDS")) != _header.end()))){
|
675
788
|
super_t::convert(utc_leap_v2, it->second.front(), &iono_utc);
|
676
789
|
}
|
677
790
|
|
@@ -728,17 +841,25 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
728
841
|
|
729
842
|
struct space_node_list_t {
|
730
843
|
space_node_t *gps;
|
844
|
+
SBAS_SpaceNode<FloatT> *sbas;
|
845
|
+
space_node_t *qzss;
|
731
846
|
};
|
732
847
|
|
733
848
|
static int read_all(std::istream &in, space_node_list_t &space_nodes = {0}){
|
734
|
-
int res(-1);
|
735
849
|
RINEX_NAV_Reader reader(in);
|
850
|
+
if(reader.version_type.file_type != version_type_t::FTYPE_NAVIGATION){
|
851
|
+
return -1;
|
852
|
+
}
|
736
853
|
if(space_nodes.gps){
|
737
854
|
(reader.version_type.version >= 300)
|
738
855
|
? reader.extract_iono_utc_v3(*space_nodes.gps)
|
739
856
|
: reader.extract_iono_utc_v2(*space_nodes.gps);
|
740
857
|
}
|
741
|
-
|
858
|
+
if(space_nodes.qzss && (space_nodes.gps != space_nodes.qzss)
|
859
|
+
&& (reader.version_type.version >= 302)){
|
860
|
+
reader.extract_iono_utc_v3(*space_nodes.qzss);
|
861
|
+
}
|
862
|
+
int res(0);
|
742
863
|
for(; reader.has_next(); reader.next()){
|
743
864
|
switch(reader.sys_of_msg){
|
744
865
|
case super_t::version_type_t::SYS_GPS:
|
@@ -746,6 +867,20 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
746
867
|
space_nodes.gps->satellite(reader.msg.eph.svid).register_ephemeris(reader.msg.eph);
|
747
868
|
res++;
|
748
869
|
break;
|
870
|
+
case super_t::version_type_t::SYS_SBAS: {
|
871
|
+
if(!space_nodes.sbas){break;}
|
872
|
+
typename message_sbas_t::eph_t eph(reader.msg_sbas);
|
873
|
+
space_nodes.sbas->satellite(eph.svid).register_ephemeris(eph);
|
874
|
+
res++;
|
875
|
+
break;
|
876
|
+
}
|
877
|
+
case super_t::version_type_t::SYS_QZSS: {
|
878
|
+
if(!space_nodes.qzss){break;}
|
879
|
+
typename RINEX_NAV<FloatT>::ephemeris_t eph(reader.msg.eph_qzss());
|
880
|
+
space_nodes.qzss->satellite(eph.svid).register_ephemeris(eph);
|
881
|
+
res++;
|
882
|
+
break;
|
883
|
+
}
|
749
884
|
default: break;
|
750
885
|
}
|
751
886
|
}
|
@@ -1007,6 +1142,9 @@ class RINEX_OBS_Reader : public RINEX_Reader<> {
|
|
1007
1142
|
RINEX_OBS_Reader(std::istream &in)
|
1008
1143
|
: super_t(in, self_t::modify_header),
|
1009
1144
|
obs_types() {
|
1145
|
+
if(super_t::version_type.file_type != version_type_t::FTYPE_OBSERVATION){
|
1146
|
+
return;
|
1147
|
+
}
|
1010
1148
|
typedef super_t::header_t::const_iterator it_t;
|
1011
1149
|
typedef super_t::header_t::mapped_type::const_iterator it2_t;
|
1012
1150
|
it_t it;
|
@@ -1190,14 +1328,14 @@ const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>
|
|
1190
1328
|
template <class FloatT>
|
1191
1329
|
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph6_v2[] = {
|
1192
1330
|
GEN_E ( 3, 19, 12, message_t, ura_meter),
|
1193
|
-
|
1331
|
+
GEN_E2(22, 19, 12, message_t, eph.SV_health, unsigned int),
|
1194
1332
|
GEN_E (41, 19, 12, message_t, eph.t_GD),
|
1195
1333
|
GEN_E2(60, 19, 12, message_t, eph.iodc, int),
|
1196
1334
|
};
|
1197
1335
|
template <class FloatT>
|
1198
1336
|
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph6_v3[] = {
|
1199
1337
|
GEN_E ( 4, 19, 12, message_t, ura_meter),
|
1200
|
-
|
1338
|
+
GEN_E2(23, 19, 12, message_t, eph.SV_health, unsigned int),
|
1201
1339
|
GEN_E (42, 19, 12, message_t, eph.t_GD),
|
1202
1340
|
GEN_E2(61, 19, 12, message_t, eph.iodc, int),
|
1203
1341
|
};
|
@@ -1213,6 +1351,80 @@ const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>
|
|
1213
1351
|
GEN_E(23, 19, 12, message_t, fit_interval_hr),
|
1214
1352
|
};
|
1215
1353
|
|
1354
|
+
|
1355
|
+
template <class FloatT>
|
1356
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph0_sbas_v2[] = {
|
1357
|
+
GEN_D( 0, 2, message_sbas_t, svid, int),
|
1358
|
+
GEN_D( 3, 2, message_sbas_t, t_year2, int),
|
1359
|
+
GEN_D( 6, 2, message_sbas_t, t_mon12, int),
|
1360
|
+
GEN_D( 9, 2, message_sbas_t, date_tm.tm_mday, int),
|
1361
|
+
GEN_D(12, 2, message_sbas_t, date_tm.tm_hour, int),
|
1362
|
+
GEN_D(15, 2, message_sbas_t, date_tm.tm_min, int),
|
1363
|
+
GEN_F(17, 5, 1, message_sbas_t, t_sec),
|
1364
|
+
GEN_E(22, 19, 12, message_sbas_t, a_Gf0),
|
1365
|
+
GEN_E(41, 19, 12, message_sbas_t, a_Gf1),
|
1366
|
+
GEN_E(60, 19, 12, message_sbas_t, t_t),
|
1367
|
+
};
|
1368
|
+
template <class FloatT>
|
1369
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph0_sbas_v3[] = {
|
1370
|
+
GEN_I( 1, 2, message_sbas_t, svid, int),
|
1371
|
+
GEN_I( 4, 4, message_sbas_t, t_year4, int),
|
1372
|
+
GEN_I( 9, 2, message_sbas_t, t_mon12, int),
|
1373
|
+
GEN_I(12, 2, message_sbas_t, date_tm.tm_mday, int),
|
1374
|
+
GEN_I(15, 2, message_sbas_t, date_tm.tm_hour, int),
|
1375
|
+
GEN_I(18, 2, message_sbas_t, date_tm.tm_min, int),
|
1376
|
+
GEN_I(21, 2, message_sbas_t, date_tm.tm_sec, int),
|
1377
|
+
GEN_E(23, 19, 12, message_sbas_t, a_Gf0),
|
1378
|
+
GEN_E(42, 19, 12, message_sbas_t, a_Gf1),
|
1379
|
+
GEN_E(61, 19, 12, message_sbas_t, t_t),
|
1380
|
+
};
|
1381
|
+
|
1382
|
+
template <class FloatT>
|
1383
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph1_sbas_v2[] = {
|
1384
|
+
GEN_E( 3, 19, 12, message_sbas_t, x_km),
|
1385
|
+
GEN_E(22, 19, 12, message_sbas_t, dx_km_s),
|
1386
|
+
GEN_E(41, 19, 12, message_sbas_t, ddx_km_s2),
|
1387
|
+
GEN_E2(60, 19, 12, message_sbas_t, health, unsigned int),
|
1388
|
+
};
|
1389
|
+
template <class FloatT>
|
1390
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph1_sbas_v3[] = {
|
1391
|
+
GEN_E( 4, 19, 12, message_sbas_t, x_km),
|
1392
|
+
GEN_E(23, 19, 12, message_sbas_t, dx_km_s),
|
1393
|
+
GEN_E(42, 19, 12, message_sbas_t, ddx_km_s2),
|
1394
|
+
GEN_E2(61, 19, 12, message_sbas_t, health, unsigned int),
|
1395
|
+
};
|
1396
|
+
|
1397
|
+
template <class FloatT>
|
1398
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph2_sbas_v2[] = {
|
1399
|
+
GEN_E( 3, 19, 12, message_sbas_t, y_km),
|
1400
|
+
GEN_E(22, 19, 12, message_sbas_t, dy_km_s),
|
1401
|
+
GEN_E(41, 19, 12, message_sbas_t, ddy_km_s2),
|
1402
|
+
GEN_E(60, 19, 12, message_sbas_t, URA),
|
1403
|
+
};
|
1404
|
+
template <class FloatT>
|
1405
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph2_sbas_v3[] = {
|
1406
|
+
GEN_E( 4, 19, 12, message_sbas_t, y_km),
|
1407
|
+
GEN_E(23, 19, 12, message_sbas_t, dy_km_s),
|
1408
|
+
GEN_E(42, 19, 12, message_sbas_t, ddy_km_s2),
|
1409
|
+
GEN_E(61, 19, 12, message_sbas_t, URA),
|
1410
|
+
};
|
1411
|
+
|
1412
|
+
template <class FloatT>
|
1413
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph3_sbas_v2[] = {
|
1414
|
+
GEN_E( 3, 19, 12, message_sbas_t, z_km),
|
1415
|
+
GEN_E(22, 19, 12, message_sbas_t, dz_km_s),
|
1416
|
+
GEN_E(41, 19, 12, message_sbas_t, ddz_km_s2),
|
1417
|
+
GEN_E2(60, 19, 12, message_sbas_t, iodn, unsigned int),
|
1418
|
+
};
|
1419
|
+
template <class FloatT>
|
1420
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph3_sbas_v3[] = {
|
1421
|
+
GEN_E( 4, 19, 12, message_sbas_t, z_km),
|
1422
|
+
GEN_E(23, 19, 12, message_sbas_t, dz_km_s),
|
1423
|
+
GEN_E(42, 19, 12, message_sbas_t, ddz_km_s2),
|
1424
|
+
GEN_E2(61, 19, 12, message_sbas_t, iodn, unsigned int),
|
1425
|
+
};
|
1426
|
+
|
1427
|
+
|
1216
1428
|
template <class FloatT>
|
1217
1429
|
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::iono_alpha_v2[] = {
|
1218
1430
|
GEN_E( 2, 12, 4, iono_utc_t, alpha[0]),
|
@@ -1511,6 +1723,7 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1511
1723
|
public:
|
1512
1724
|
typedef typename RINEX_NAV<FloatT>::space_node_t space_node_t;
|
1513
1725
|
typedef typename RINEX_NAV<FloatT>::message_t message_t;
|
1726
|
+
typedef typename RINEX_NAV<FloatT>::message_sbas_t message_sbas_t;
|
1514
1727
|
|
1515
1728
|
static const typename super_t::header_item_t default_header[];
|
1516
1729
|
static const int default_header_size;
|
@@ -1569,7 +1782,7 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1569
1782
|
: super_t(out, default_header, default_header_size) {}
|
1570
1783
|
~RINEX_NAV_Writer(){}
|
1571
1784
|
|
1572
|
-
self_t &
|
1785
|
+
self_t &dump(const message_t &msg, const bool &is_qzss = false){
|
1573
1786
|
std::stringstream buf;
|
1574
1787
|
switch(super_t::_version_type.version / 100){
|
1575
1788
|
case 2:
|
@@ -1592,7 +1805,8 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1592
1805
|
for(int i(0); i < 8; ++i){
|
1593
1806
|
std::string s(80, ' ');
|
1594
1807
|
switch(i){
|
1595
|
-
case 0: super_t::convert(reader_t::eph0_v3, s, &msg);
|
1808
|
+
case 0: super_t::convert(reader_t::eph0_v3, s, &msg);
|
1809
|
+
s[0] = is_qzss ? 'J' : 'G'; break;
|
1596
1810
|
case 1: super_t::convert(reader_t::eph1_v3, s, &msg); break;
|
1597
1811
|
case 2: super_t::convert(reader_t::eph2_v3, s, &msg); break;
|
1598
1812
|
case 3: super_t::convert(reader_t::eph3_v3, s, &msg); break;
|
@@ -1608,6 +1822,40 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1608
1822
|
dist << buf.str();
|
1609
1823
|
return *this;
|
1610
1824
|
}
|
1825
|
+
self_t &operator<<(const message_t &msg){
|
1826
|
+
return dump(msg);
|
1827
|
+
}
|
1828
|
+
self_t &operator<<(const message_sbas_t &msg){
|
1829
|
+
std::stringstream buf;
|
1830
|
+
switch(super_t::_version_type.version / 100){
|
1831
|
+
case 2:
|
1832
|
+
for(int i(0); i < 8; ++i){
|
1833
|
+
std::string s(80, ' ');
|
1834
|
+
switch(i){
|
1835
|
+
case 0: super_t::convert(reader_t::eph0_sbas_v2, s, &msg); break;
|
1836
|
+
case 1: super_t::convert(reader_t::eph1_sbas_v2, s, &msg); break;
|
1837
|
+
case 2: super_t::convert(reader_t::eph2_sbas_v2, s, &msg); break;
|
1838
|
+
case 3: super_t::convert(reader_t::eph3_sbas_v2, s, &msg); break;
|
1839
|
+
}
|
1840
|
+
buf << s << std::endl;
|
1841
|
+
}
|
1842
|
+
break;
|
1843
|
+
case 3:
|
1844
|
+
for(int i(0); i < 8; ++i){
|
1845
|
+
std::string s(80, ' ');
|
1846
|
+
switch(i){
|
1847
|
+
case 0: super_t::convert(reader_t::eph0_sbas_v3, s, &msg); s[0] = 'S'; break;
|
1848
|
+
case 1: super_t::convert(reader_t::eph1_sbas_v3, s, &msg); break;
|
1849
|
+
case 2: super_t::convert(reader_t::eph2_sbas_v3, s, &msg); break;
|
1850
|
+
case 3: super_t::convert(reader_t::eph3_sbas_v3, s, &msg); break;
|
1851
|
+
}
|
1852
|
+
buf << s << std::endl;
|
1853
|
+
}
|
1854
|
+
break;
|
1855
|
+
}
|
1856
|
+
dist << buf.str();
|
1857
|
+
return *this;
|
1858
|
+
}
|
1611
1859
|
|
1612
1860
|
public:
|
1613
1861
|
void set_version(
|
@@ -1617,15 +1865,22 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1617
1865
|
version, super_t::version_type_t::FTYPE_NAVIGATION, sys));
|
1618
1866
|
}
|
1619
1867
|
|
1868
|
+
struct space_node_list_t {
|
1869
|
+
const space_node_t *gps;
|
1870
|
+
const SBAS_SpaceNode<FloatT> *sbas;
|
1871
|
+
const space_node_t *qzss;
|
1872
|
+
};
|
1620
1873
|
int write_all(
|
1621
|
-
const
|
1874
|
+
const space_node_list_t &space_nodes,
|
1622
1875
|
const int &version = 304){
|
1623
1876
|
int res(-1);
|
1624
1877
|
int systems(0);
|
1625
1878
|
set_version(version, super_t::version_type_t::SYS_UNKNOWN);
|
1626
|
-
|
1879
|
+
do{
|
1880
|
+
if(!space_nodes.gps){break;}
|
1627
1881
|
++systems;
|
1628
1882
|
set_version(version, super_t::version_type_t::SYS_GPS);
|
1883
|
+
if(!space_nodes.gps->is_valid_iono_utc()){break;}
|
1629
1884
|
switch(version / 100){
|
1630
1885
|
case 2:
|
1631
1886
|
if(_header["ION ALPHA"].entries() == 0){iono_alpha(*space_nodes.gps);}
|
@@ -1640,7 +1895,26 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1640
1895
|
if(_header["LEAP SECONDS"].entries() == 0){leap_seconds(*space_nodes.gps);}
|
1641
1896
|
break;
|
1642
1897
|
}
|
1643
|
-
}
|
1898
|
+
}while(false);
|
1899
|
+
do{
|
1900
|
+
if(!space_nodes.sbas){break;}
|
1901
|
+
++systems;
|
1902
|
+
set_version(version, super_t::version_type_t::SYS_SBAS);
|
1903
|
+
}while(false);
|
1904
|
+
do{
|
1905
|
+
if((version < 302) || (!space_nodes.qzss)){break;}
|
1906
|
+
++systems;
|
1907
|
+
set_version(version, super_t::version_type_t::SYS_QZSS);
|
1908
|
+
if(!space_nodes.qzss->is_valid_iono_utc()){break;}
|
1909
|
+
switch(version / 100){
|
1910
|
+
case 3:
|
1911
|
+
if(_header["IONOSPHERIC CORR"].find("GPSA") == _header.end()){iono_alpha(*space_nodes.qzss);}
|
1912
|
+
if(_header["IONOSPHERIC CORR"].find("GPSB") == _header.end()){iono_beta(*space_nodes.qzss);}
|
1913
|
+
if(_header["TIME SYSTEM CORR"].find("QZUT") == _header.end()){utc_params(*space_nodes.qzss);}
|
1914
|
+
if(_header["LEAP SECONDS"].entries() == 0){leap_seconds(*space_nodes.qzss);}
|
1915
|
+
break;
|
1916
|
+
}
|
1917
|
+
}while(false);
|
1644
1918
|
if(systems > 1){
|
1645
1919
|
set_version(version, super_t::version_type_t::SYS_MIXED);
|
1646
1920
|
}
|
@@ -1650,12 +1924,25 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1650
1924
|
struct {
|
1651
1925
|
RINEX_NAV_Writer &w;
|
1652
1926
|
int &counter;
|
1927
|
+
bool gps, qzss;
|
1653
1928
|
void operator()(const typename space_node_t::Satellite::Ephemeris &eph) {
|
1654
|
-
|
1929
|
+
if(gps && (eph.svid <= 32)){
|
1930
|
+
w << message_t(eph);
|
1931
|
+
}else if(qzss && (eph.svid >= 193) && (eph.svid < 202)){
|
1932
|
+
w.dump(message_t::from_qzss(eph), true);
|
1933
|
+
}else{
|
1934
|
+
return;
|
1935
|
+
}
|
1936
|
+
counter++;
|
1937
|
+
}
|
1938
|
+
void operator()(const typename message_sbas_t::eph_t &eph) {
|
1939
|
+
w << message_sbas_t(eph);
|
1655
1940
|
counter++;
|
1656
1941
|
}
|
1657
|
-
} functor = {*this, res};
|
1942
|
+
} functor = {*this, res, false, false};
|
1658
1943
|
if(space_nodes.gps){
|
1944
|
+
functor.gps = true;
|
1945
|
+
if(space_nodes.gps == space_nodes.qzss){functor.qzss = true;}
|
1659
1946
|
for(typename space_node_t::satellites_t::const_iterator
|
1660
1947
|
it(space_nodes.gps->satellites().begin()), it_end(space_nodes.gps->satellites().end());
|
1661
1948
|
it != it_end; ++it){
|
@@ -1664,16 +1951,37 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1664
1951
|
space_node_t::Satellite::eph_list_t::EACH_ALL_INVERTED);
|
1665
1952
|
}
|
1666
1953
|
}
|
1954
|
+
if(space_nodes.sbas){
|
1955
|
+
for(typename SBAS_SpaceNode<FloatT>::satellites_t::const_iterator
|
1956
|
+
it(space_nodes.sbas->satellites().begin()),
|
1957
|
+
it_end(space_nodes.sbas->satellites().end());
|
1958
|
+
it != it_end; ++it){
|
1959
|
+
it->second.each_ephemeris(
|
1960
|
+
functor,
|
1961
|
+
SBAS_SpaceNode<FloatT>::Satellite::eph_list_t::EACH_ALL_INVERTED);
|
1962
|
+
}
|
1963
|
+
}
|
1964
|
+
if((version >= 302) && (!functor.qzss) && (space_nodes.qzss)){
|
1965
|
+
functor.qzss = true;
|
1966
|
+
functor.gps = false;
|
1967
|
+
for(typename space_node_t::satellites_t::const_iterator
|
1968
|
+
it(space_nodes.qzss->satellites().begin()), it_end(space_nodes.qzss->satellites().end());
|
1969
|
+
it != it_end; ++it){
|
1970
|
+
it->second.each_ephemeris(
|
1971
|
+
functor,
|
1972
|
+
space_node_t::Satellite::eph_list_t::EACH_ALL_INVERTED);
|
1973
|
+
}
|
1974
|
+
}
|
1667
1975
|
return res;
|
1668
1976
|
}
|
1669
1977
|
static int write_all(
|
1670
1978
|
std::ostream &out,
|
1671
|
-
const
|
1979
|
+
const space_node_list_t &space_nodes,
|
1672
1980
|
const int &version = 304){
|
1673
1981
|
return RINEX_NAV_Writer(out).write_all(space_nodes, version);
|
1674
1982
|
}
|
1675
1983
|
int write_all(const space_node_t &space_node, const int &version = 304){
|
1676
|
-
|
1984
|
+
space_node_list_t list = {&space_node};
|
1677
1985
|
return write_all(list, version);
|
1678
1986
|
}
|
1679
1987
|
static int write_all(std::ostream &out, const space_node_t &space_node, const int &version = 304){
|