gps_pvt 0.1.7 → 0.2.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/Rakefile +2 -0
- data/exe/gps_pvt +4 -4
- data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +5 -3
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +4229 -508
- data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +7 -5
- data/ext/ninja-scan-light/tool/navigation/GPS.h +4 -3
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +62 -15
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +6 -5
- data/ext/ninja-scan-light/tool/navigation/QZSS.h +62 -0
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +320 -22
- data/ext/ninja-scan-light/tool/navigation/SBAS.h +2330 -0
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +329 -0
- data/ext/ninja-scan-light/tool/swig/GPS.i +197 -65
- data/lib/gps_pvt/receiver.rb +253 -132
- data/lib/gps_pvt/version.rb +1 -1
- metadata +5 -2
@@ -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,6 +841,8 @@ 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}){
|
@@ -738,6 +853,10 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
738
853
|
? reader.extract_iono_utc_v3(*space_nodes.gps)
|
739
854
|
: reader.extract_iono_utc_v2(*space_nodes.gps);
|
740
855
|
}
|
856
|
+
if(space_nodes.qzss && (space_nodes.gps != space_nodes.qzss)
|
857
|
+
&& (reader.version_type.version >= 302)){
|
858
|
+
reader.extract_iono_utc_v3(*space_nodes.qzss);
|
859
|
+
}
|
741
860
|
res++;
|
742
861
|
for(; reader.has_next(); reader.next()){
|
743
862
|
switch(reader.sys_of_msg){
|
@@ -746,6 +865,20 @@ class RINEX_NAV_Reader : public RINEX_Reader<> {
|
|
746
865
|
space_nodes.gps->satellite(reader.msg.eph.svid).register_ephemeris(reader.msg.eph);
|
747
866
|
res++;
|
748
867
|
break;
|
868
|
+
case super_t::version_type_t::SYS_SBAS: {
|
869
|
+
if(!space_nodes.sbas){break;}
|
870
|
+
typename message_sbas_t::eph_t eph(reader.msg_sbas);
|
871
|
+
space_nodes.sbas->satellite(eph.svid).register_ephemeris(eph);
|
872
|
+
res++;
|
873
|
+
break;
|
874
|
+
}
|
875
|
+
case super_t::version_type_t::SYS_QZSS: {
|
876
|
+
if(!space_nodes.qzss){break;}
|
877
|
+
typename RINEX_NAV<FloatT>::ephemeris_t eph(reader.msg.eph_qzss());
|
878
|
+
space_nodes.qzss->satellite(eph.svid).register_ephemeris(eph);
|
879
|
+
res++;
|
880
|
+
break;
|
881
|
+
}
|
749
882
|
default: break;
|
750
883
|
}
|
751
884
|
}
|
@@ -1190,14 +1323,14 @@ const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>
|
|
1190
1323
|
template <class FloatT>
|
1191
1324
|
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph6_v2[] = {
|
1192
1325
|
GEN_E ( 3, 19, 12, message_t, ura_meter),
|
1193
|
-
|
1326
|
+
GEN_E2(22, 19, 12, message_t, eph.SV_health, unsigned int),
|
1194
1327
|
GEN_E (41, 19, 12, message_t, eph.t_GD),
|
1195
1328
|
GEN_E2(60, 19, 12, message_t, eph.iodc, int),
|
1196
1329
|
};
|
1197
1330
|
template <class FloatT>
|
1198
1331
|
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph6_v3[] = {
|
1199
1332
|
GEN_E ( 4, 19, 12, message_t, ura_meter),
|
1200
|
-
|
1333
|
+
GEN_E2(23, 19, 12, message_t, eph.SV_health, unsigned int),
|
1201
1334
|
GEN_E (42, 19, 12, message_t, eph.t_GD),
|
1202
1335
|
GEN_E2(61, 19, 12, message_t, eph.iodc, int),
|
1203
1336
|
};
|
@@ -1213,6 +1346,80 @@ const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>
|
|
1213
1346
|
GEN_E(23, 19, 12, message_t, fit_interval_hr),
|
1214
1347
|
};
|
1215
1348
|
|
1349
|
+
|
1350
|
+
template <class FloatT>
|
1351
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph0_sbas_v2[] = {
|
1352
|
+
GEN_D( 0, 2, message_sbas_t, svid, int),
|
1353
|
+
GEN_D( 3, 2, message_sbas_t, t_year2, int),
|
1354
|
+
GEN_D( 6, 2, message_sbas_t, t_mon12, int),
|
1355
|
+
GEN_D( 9, 2, message_sbas_t, date_tm.tm_mday, int),
|
1356
|
+
GEN_D(12, 2, message_sbas_t, date_tm.tm_hour, int),
|
1357
|
+
GEN_D(15, 2, message_sbas_t, date_tm.tm_min, int),
|
1358
|
+
GEN_F(17, 5, 1, message_sbas_t, t_sec),
|
1359
|
+
GEN_E(22, 19, 12, message_sbas_t, a_Gf0),
|
1360
|
+
GEN_E(41, 19, 12, message_sbas_t, a_Gf1),
|
1361
|
+
GEN_E(60, 19, 12, message_sbas_t, t_t),
|
1362
|
+
};
|
1363
|
+
template <class FloatT>
|
1364
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph0_sbas_v3[] = {
|
1365
|
+
GEN_I( 1, 2, message_sbas_t, svid, int),
|
1366
|
+
GEN_I( 4, 4, message_sbas_t, t_year4, int),
|
1367
|
+
GEN_I( 9, 2, message_sbas_t, t_mon12, int),
|
1368
|
+
GEN_I(12, 2, message_sbas_t, date_tm.tm_mday, int),
|
1369
|
+
GEN_I(15, 2, message_sbas_t, date_tm.tm_hour, int),
|
1370
|
+
GEN_I(18, 2, message_sbas_t, date_tm.tm_min, int),
|
1371
|
+
GEN_I(21, 2, message_sbas_t, date_tm.tm_sec, int),
|
1372
|
+
GEN_E(23, 19, 12, message_sbas_t, a_Gf0),
|
1373
|
+
GEN_E(42, 19, 12, message_sbas_t, a_Gf1),
|
1374
|
+
GEN_E(61, 19, 12, message_sbas_t, t_t),
|
1375
|
+
};
|
1376
|
+
|
1377
|
+
template <class FloatT>
|
1378
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph1_sbas_v2[] = {
|
1379
|
+
GEN_E( 3, 19, 12, message_sbas_t, x_km),
|
1380
|
+
GEN_E(22, 19, 12, message_sbas_t, dx_km_s),
|
1381
|
+
GEN_E(41, 19, 12, message_sbas_t, ddx_km_s2),
|
1382
|
+
GEN_E2(60, 19, 12, message_sbas_t, health, unsigned int),
|
1383
|
+
};
|
1384
|
+
template <class FloatT>
|
1385
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph1_sbas_v3[] = {
|
1386
|
+
GEN_E( 4, 19, 12, message_sbas_t, x_km),
|
1387
|
+
GEN_E(23, 19, 12, message_sbas_t, dx_km_s),
|
1388
|
+
GEN_E(42, 19, 12, message_sbas_t, ddx_km_s2),
|
1389
|
+
GEN_E2(61, 19, 12, message_sbas_t, health, unsigned int),
|
1390
|
+
};
|
1391
|
+
|
1392
|
+
template <class FloatT>
|
1393
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph2_sbas_v2[] = {
|
1394
|
+
GEN_E( 3, 19, 12, message_sbas_t, y_km),
|
1395
|
+
GEN_E(22, 19, 12, message_sbas_t, dy_km_s),
|
1396
|
+
GEN_E(41, 19, 12, message_sbas_t, ddy_km_s2),
|
1397
|
+
GEN_E(60, 19, 12, message_sbas_t, URA),
|
1398
|
+
};
|
1399
|
+
template <class FloatT>
|
1400
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph2_sbas_v3[] = {
|
1401
|
+
GEN_E( 4, 19, 12, message_sbas_t, y_km),
|
1402
|
+
GEN_E(23, 19, 12, message_sbas_t, dy_km_s),
|
1403
|
+
GEN_E(42, 19, 12, message_sbas_t, ddy_km_s2),
|
1404
|
+
GEN_E(61, 19, 12, message_sbas_t, URA),
|
1405
|
+
};
|
1406
|
+
|
1407
|
+
template <class FloatT>
|
1408
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph3_sbas_v2[] = {
|
1409
|
+
GEN_E( 3, 19, 12, message_sbas_t, z_km),
|
1410
|
+
GEN_E(22, 19, 12, message_sbas_t, dz_km_s),
|
1411
|
+
GEN_E(41, 19, 12, message_sbas_t, ddz_km_s2),
|
1412
|
+
GEN_E2(60, 19, 12, message_sbas_t, iodn, unsigned int),
|
1413
|
+
};
|
1414
|
+
template <class FloatT>
|
1415
|
+
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::eph3_sbas_v3[] = {
|
1416
|
+
GEN_E( 4, 19, 12, message_sbas_t, z_km),
|
1417
|
+
GEN_E(23, 19, 12, message_sbas_t, dz_km_s),
|
1418
|
+
GEN_E(42, 19, 12, message_sbas_t, ddz_km_s2),
|
1419
|
+
GEN_E2(61, 19, 12, message_sbas_t, iodn, unsigned int),
|
1420
|
+
};
|
1421
|
+
|
1422
|
+
|
1216
1423
|
template <class FloatT>
|
1217
1424
|
const typename RINEX_NAV_Reader<FloatT>::convert_item_t RINEX_NAV_Reader<FloatT>::iono_alpha_v2[] = {
|
1218
1425
|
GEN_E( 2, 12, 4, iono_utc_t, alpha[0]),
|
@@ -1511,6 +1718,7 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1511
1718
|
public:
|
1512
1719
|
typedef typename RINEX_NAV<FloatT>::space_node_t space_node_t;
|
1513
1720
|
typedef typename RINEX_NAV<FloatT>::message_t message_t;
|
1721
|
+
typedef typename RINEX_NAV<FloatT>::message_sbas_t message_sbas_t;
|
1514
1722
|
|
1515
1723
|
static const typename super_t::header_item_t default_header[];
|
1516
1724
|
static const int default_header_size;
|
@@ -1569,7 +1777,7 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1569
1777
|
: super_t(out, default_header, default_header_size) {}
|
1570
1778
|
~RINEX_NAV_Writer(){}
|
1571
1779
|
|
1572
|
-
self_t &
|
1780
|
+
self_t &dump(const message_t &msg, const bool &is_qzss = false){
|
1573
1781
|
std::stringstream buf;
|
1574
1782
|
switch(super_t::_version_type.version / 100){
|
1575
1783
|
case 2:
|
@@ -1592,7 +1800,8 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1592
1800
|
for(int i(0); i < 8; ++i){
|
1593
1801
|
std::string s(80, ' ');
|
1594
1802
|
switch(i){
|
1595
|
-
case 0: super_t::convert(reader_t::eph0_v3, s, &msg);
|
1803
|
+
case 0: super_t::convert(reader_t::eph0_v3, s, &msg);
|
1804
|
+
s[0] = is_qzss ? 'J' : 'G'; break;
|
1596
1805
|
case 1: super_t::convert(reader_t::eph1_v3, s, &msg); break;
|
1597
1806
|
case 2: super_t::convert(reader_t::eph2_v3, s, &msg); break;
|
1598
1807
|
case 3: super_t::convert(reader_t::eph3_v3, s, &msg); break;
|
@@ -1608,6 +1817,40 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1608
1817
|
dist << buf.str();
|
1609
1818
|
return *this;
|
1610
1819
|
}
|
1820
|
+
self_t &operator<<(const message_t &msg){
|
1821
|
+
return dump(msg);
|
1822
|
+
}
|
1823
|
+
self_t &operator<<(const message_sbas_t &msg){
|
1824
|
+
std::stringstream buf;
|
1825
|
+
switch(super_t::_version_type.version / 100){
|
1826
|
+
case 2:
|
1827
|
+
for(int i(0); i < 8; ++i){
|
1828
|
+
std::string s(80, ' ');
|
1829
|
+
switch(i){
|
1830
|
+
case 0: super_t::convert(reader_t::eph0_sbas_v2, s, &msg); break;
|
1831
|
+
case 1: super_t::convert(reader_t::eph1_sbas_v2, s, &msg); break;
|
1832
|
+
case 2: super_t::convert(reader_t::eph2_sbas_v2, s, &msg); break;
|
1833
|
+
case 3: super_t::convert(reader_t::eph3_sbas_v2, s, &msg); break;
|
1834
|
+
}
|
1835
|
+
buf << s << std::endl;
|
1836
|
+
}
|
1837
|
+
break;
|
1838
|
+
case 3:
|
1839
|
+
for(int i(0); i < 8; ++i){
|
1840
|
+
std::string s(80, ' ');
|
1841
|
+
switch(i){
|
1842
|
+
case 0: super_t::convert(reader_t::eph0_sbas_v3, s, &msg); s[0] = 'S'; break;
|
1843
|
+
case 1: super_t::convert(reader_t::eph1_sbas_v3, s, &msg); break;
|
1844
|
+
case 2: super_t::convert(reader_t::eph2_sbas_v3, s, &msg); break;
|
1845
|
+
case 3: super_t::convert(reader_t::eph3_sbas_v3, s, &msg); break;
|
1846
|
+
}
|
1847
|
+
buf << s << std::endl;
|
1848
|
+
}
|
1849
|
+
break;
|
1850
|
+
}
|
1851
|
+
dist << buf.str();
|
1852
|
+
return *this;
|
1853
|
+
}
|
1611
1854
|
|
1612
1855
|
public:
|
1613
1856
|
void set_version(
|
@@ -1623,9 +1866,11 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1623
1866
|
int res(-1);
|
1624
1867
|
int systems(0);
|
1625
1868
|
set_version(version, super_t::version_type_t::SYS_UNKNOWN);
|
1626
|
-
|
1869
|
+
do{
|
1870
|
+
if(!space_nodes.gps){break;}
|
1627
1871
|
++systems;
|
1628
1872
|
set_version(version, super_t::version_type_t::SYS_GPS);
|
1873
|
+
if(!space_nodes.gps->is_valid_iono_utc()){break;}
|
1629
1874
|
switch(version / 100){
|
1630
1875
|
case 2:
|
1631
1876
|
if(_header["ION ALPHA"].entries() == 0){iono_alpha(*space_nodes.gps);}
|
@@ -1640,7 +1885,26 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1640
1885
|
if(_header["LEAP SECONDS"].entries() == 0){leap_seconds(*space_nodes.gps);}
|
1641
1886
|
break;
|
1642
1887
|
}
|
1643
|
-
}
|
1888
|
+
}while(false);
|
1889
|
+
do{
|
1890
|
+
if(!space_nodes.sbas){break;}
|
1891
|
+
++systems;
|
1892
|
+
set_version(version, super_t::version_type_t::SYS_SBAS);
|
1893
|
+
}while(false);
|
1894
|
+
do{
|
1895
|
+
if((version < 302) || (!space_nodes.qzss)){break;}
|
1896
|
+
++systems;
|
1897
|
+
set_version(version, super_t::version_type_t::SYS_QZSS);
|
1898
|
+
if(!space_nodes.qzss->is_valid_iono_utc()){break;}
|
1899
|
+
switch(version / 100){
|
1900
|
+
case 3:
|
1901
|
+
if(_header["IONOSPHERIC CORR"].find("GPSA") == _header.end()){iono_alpha(*space_nodes.qzss);}
|
1902
|
+
if(_header["IONOSPHERIC CORR"].find("GPSB") == _header.end()){iono_beta(*space_nodes.qzss);}
|
1903
|
+
if(_header["TIME SYSTEM CORR"].find("QZUT") == _header.end()){utc_params(*space_nodes.qzss);}
|
1904
|
+
if(_header["LEAP SECONDS"].entries() == 0){leap_seconds(*space_nodes.qzss);}
|
1905
|
+
break;
|
1906
|
+
}
|
1907
|
+
}while(false);
|
1644
1908
|
if(systems > 1){
|
1645
1909
|
set_version(version, super_t::version_type_t::SYS_MIXED);
|
1646
1910
|
}
|
@@ -1650,12 +1914,25 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1650
1914
|
struct {
|
1651
1915
|
RINEX_NAV_Writer &w;
|
1652
1916
|
int &counter;
|
1917
|
+
bool gps, qzss;
|
1653
1918
|
void operator()(const typename space_node_t::Satellite::Ephemeris &eph) {
|
1654
|
-
|
1919
|
+
if(gps && (eph.svid <= 32)){
|
1920
|
+
w << message_t(eph);
|
1921
|
+
}else if(qzss && (eph.svid >= 193) && (eph.svid < 202)){
|
1922
|
+
w.dump(message_t::from_qzss(eph), true);
|
1923
|
+
}else{
|
1924
|
+
return;
|
1925
|
+
}
|
1655
1926
|
counter++;
|
1656
1927
|
}
|
1657
|
-
|
1928
|
+
void operator()(const typename message_sbas_t::eph_t &eph) {
|
1929
|
+
w << message_sbas_t(eph);
|
1930
|
+
counter++;
|
1931
|
+
}
|
1932
|
+
} functor = {*this, res, false, false};
|
1658
1933
|
if(space_nodes.gps){
|
1934
|
+
functor.gps = true;
|
1935
|
+
if(space_nodes.gps == space_nodes.qzss){functor.qzss = true;}
|
1659
1936
|
for(typename space_node_t::satellites_t::const_iterator
|
1660
1937
|
it(space_nodes.gps->satellites().begin()), it_end(space_nodes.gps->satellites().end());
|
1661
1938
|
it != it_end; ++it){
|
@@ -1664,6 +1941,27 @@ class RINEX_NAV_Writer : public RINEX_Writer<> {
|
|
1664
1941
|
space_node_t::Satellite::eph_list_t::EACH_ALL_INVERTED);
|
1665
1942
|
}
|
1666
1943
|
}
|
1944
|
+
if(space_nodes.sbas){
|
1945
|
+
for(typename SBAS_SpaceNode<FloatT>::satellites_t::const_iterator
|
1946
|
+
it(space_nodes.sbas->satellites().begin()),
|
1947
|
+
it_end(space_nodes.sbas->satellites().end());
|
1948
|
+
it != it_end; ++it){
|
1949
|
+
it->second.each_ephemeris(
|
1950
|
+
functor,
|
1951
|
+
SBAS_SpaceNode<FloatT>::Satellite::eph_list_t::EACH_ALL_INVERTED);
|
1952
|
+
}
|
1953
|
+
}
|
1954
|
+
if((version >= 302) && (!functor.qzss) && (space_nodes.qzss)){
|
1955
|
+
functor.qzss = true;
|
1956
|
+
functor.gps = false;
|
1957
|
+
for(typename space_node_t::satellites_t::const_iterator
|
1958
|
+
it(space_nodes.qzss->satellites().begin()), it_end(space_nodes.qzss->satellites().end());
|
1959
|
+
it != it_end; ++it){
|
1960
|
+
it->second.each_ephemeris(
|
1961
|
+
functor,
|
1962
|
+
space_node_t::Satellite::eph_list_t::EACH_ALL_INVERTED);
|
1963
|
+
}
|
1964
|
+
}
|
1667
1965
|
return res;
|
1668
1966
|
}
|
1669
1967
|
static int write_all(
|