gps_pvt 0.1.7 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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(
|