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