diff --git a/README.md b/README.md
index 6624d618d..8ab71bc3e 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
+link to website: https://gnsssdrbeidoub1igsoc2018.wordpress.com/
+
**Welcome to GNSS-SDR!**
This program is a software-defined receiver which is able to process (that is, to perform detection, synchronization, demodulation and decoding of the navigation message, computation of observables and, finally, computation of position fixes) the following Global Navigation Satellite System's signals:
diff --git a/conf/gnss-sdr_BEIDOU_B1I_ishort.conf b/conf/gnss-sdr_BEIDOU_B1I_ishort.conf
new file mode 100644
index 000000000..c0516e131
--- /dev/null
+++ b/conf/gnss-sdr_BEIDOU_B1I_ishort.conf
@@ -0,0 +1,92 @@
+; This is a GNSS-SDR configuration file
+; The configuration API is described at https://gnss-sdr.org/docs/sp-blocks/
+
+; You can define your own receiver and invoke it by doing
+; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
+;
+
+[GNSS-SDR]
+
+;######### GLOBAL OPTIONS ##################
+;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second].
+GNSS-SDR.internal_fs_sps=25000000
+
+;######### CONTROL_THREAD CONFIG ############
+ControlThread.wait_for_flowgraph=false
+
+;######### SIGNAL_SOURCE CONFIG ############
+SignalSource.implementation=File_Signal_Source
+SignalSource.filename=/home/sergi/gnss-sdr/data/USRP_BDS_B1I_201805171123_fs_25e6_if0e3_ishort.bin
+SignalSource.item_type=ishort
+SignalSource.sampling_frequency=25000000
+SignalSource.samples=0
+SignalSource.repeat=false
+SignalSource.dump=false
+SignalSource.enable_throttle_control=false
+
+;######### SIGNAL_CONDITIONER CONFIG ############
+SignalConditioner.implementation=Signal_Conditioner
+
+DataTypeAdapter.implementation=Ishort_To_Complex
+InputFilter.implementation=Pass_Through
+InputFilter.item_type=gr_complex
+Resampler.implementation=Direct_Resampler
+Resampler.sample_freq_in=25000000
+Resampler.sample_freq_out=25000000
+Resampler.item_type=gr_complex
+
+;######### CHANNELS GLOBAL CONFIG ############
+Channels_B1.count=2
+Channels.in_acquisition=1
+Channel.signal=B1
+
+
+;######### ACQUISITION GLOBAL CONFIG ############
+Acquisition_B1.implementation=BEIDOU_B1I_PCPS_Acquisition
+Acquisition_B1.item_type=gr_complex
+Acquisition_B1.coherent_integration_time_ms=1
+Acquisition_B1.threshold=20
+;Acquisition_B1.pfa=0.000001
+Acquisition_B1.doppler_max=10000
+Acquisition_B1.doppler_step=2500
+Acquisition_B1.dump=true
+Acquisition_B1.dump_filename=./acq_dump.dat
+Acquisition_B1.blocking=false;
+Acquisition_B1.use_CFAR_algorithm=false
+
+;######### TRACKING GLOBAL CONFIG ############
+Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking
+Tracking_B1.item_type=gr_complex
+Tracking_B1.pll_bw_hz=40.0;
+Tracking_B1.dll_bw_hz=8.0;
+Tracking_B1.order=3;
+Tracking_B1.dump=true;
+Tracking_B1.dump_filename=./epl_tracking_ch_
+
+
+;######### TELEMETRY DECODER GPS CONFIG ############
+TelemetryDecoder_B1.implementation=BEIDOU_B1I_Telemetry_Decoder
+TelemetryDecoder_B1.dump=true
+
+
+;######### OBSERVABLES CONFIG ############
+Observables.implementation=Hybrid_Observables
+Observables.dump=true
+Observables.dump_filename=./observables.dat
+
+
+;######### PVT CONFIG ############
+PVT.implementation=RTKLIB_PVT
+PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic
+PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX
+PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad
+PVT.output_rate_ms=100
+PVT.display_rate_ms=500
+PVT.dump_filename=./PVT
+PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
+PVT.flag_nmea_tty_port=false;
+PVT.nmea_dump_devname=/dev/pts/4
+PVT.flag_rtcm_server=false
+PVT.flag_rtcm_tty_port=false
+PVT.rtcm_dump_devname=/dev/pts/1
+PVT.dump=false
diff --git a/conf/gnss-sdr_BEIDOU_B1I_ishort2.conf b/conf/gnss-sdr_BEIDOU_B1I_ishort2.conf
new file mode 100644
index 000000000..f6d0e0d18
--- /dev/null
+++ b/conf/gnss-sdr_BEIDOU_B1I_ishort2.conf
@@ -0,0 +1,94 @@
+; This is a GNSS-SDR configuration file
+; The configuration API is described at https://gnss-sdr.org/docs/sp-blocks/
+
+; You can define your own receiver and invoke it by doing
+; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
+;
+
+[GNSS-SDR]
+
+;######### GLOBAL OPTIONS ##################
+;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second].
+GNSS-SDR.internal_fs_sps=5000000
+
+;######### CONTROL_THREAD CONFIG ############
+ControlThread.wait_for_flowgraph=false
+
+;######### SIGNAL_SOURCE CONFIG ############
+SignalSource.implementation=File_Signal_Source
+SignalSource.filename=/home/sergi/gnss/gnss-sdr/data/stereo_l1_b1.datz
+SignalSource.item_type=ishort
+SignalSource.sampling_frequency=5000000
+SignalSource.samples=0
+SignalSource.repeat=false
+SignalSource.dump=false
+;SignalSource.dump_filename=../data/signal_source.dat
+SignalSource.enable_throttle_control=false
+
+
+;######### SIGNAL_CONDITIONER CONFIG ############
+SignalConditioner.implementation=Signal_Conditioner
+
+DataTypeAdapter.implementation=Ishort_To_Complex
+InputFilter.implementation=Pass_Through
+InputFilter.item_type=gr_complex
+Resampler.implementation=Direct_Resampler
+Resampler.sample_freq_in=5000000
+Resampler.sample_freq_out=5000000
+Resampler.item_type=gr_complex
+
+;######### CHANNELS GLOBAL CONFIG ############
+Channels_B1.count=3
+Channels.in_acquisition=1
+Channel.signal=B1
+
+
+;######### ACQUISITION GLOBAL CONFIG ############
+Acquisition_B1.implementation=BEIDOU_B1I_PCPS_Acquisition
+Acquisition_B1.item_type=gr_complex
+Acquisition_B1.coherent_integration_time_ms=1
+Acquisition_B1.threshold=20
+;Acquisition_B1.pfa=0.000001
+Acquisition_B1.doppler_max=10000
+Acquisition_B1.doppler_step=2500
+Acquisition_B1.dump=true
+Acquisition_B1.dump_filename=./acq_dump.dat
+Acquisition_B1.blocking=false;
+Acquisition_B1.use_CFAR_algorithm=false
+
+;######### TRACKING GLOBAL CONFIG ############
+Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking
+Tracking_B1.item_type=gr_complex
+Tracking_B1.pll_bw_hz=40.0;
+Tracking_B1.dll_bw_hz=8.0;
+Tracking_B1.order=3;
+Tracking_B1.dump=true;
+Tracking_B1.dump_filename=./epl_tracking_ch_
+
+
+;######### TELEMETRY DECODER GPS CONFIG ############
+TelemetryDecoder_B1.implementation=BEIDOU_B1I_Telemetry_Decoder
+TelemetryDecoder_B1.dump=true
+
+
+;######### OBSERVABLES CONFIG ############
+Observables.implementation=Hybrid_Observables
+Observables.dump=true
+Observables.dump_filename=./observables.dat
+
+
+;######### PVT CONFIG ############
+PVT.implementation=RTKLIB_PVT
+PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic
+PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX
+PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad
+PVT.output_rate_ms=100
+PVT.display_rate_ms=500
+PVT.dump_filename=./PVT
+PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
+PVT.flag_nmea_tty_port=false;
+PVT.nmea_dump_devname=/dev/pts/4
+PVT.flag_rtcm_server=false
+PVT.flag_rtcm_tty_port=false
+PVT.rtcm_dump_devname=/dev/pts/1
+PVT.dump=false
diff --git a/conf/gnss-sdr_GPS_L1_ishort.conf b/conf/gnss-sdr_GPS_L1_ishort.conf
index 373049a25..d160f728a 100644
--- a/conf/gnss-sdr_GPS_L1_ishort.conf
+++ b/conf/gnss-sdr_GPS_L1_ishort.conf
@@ -16,7 +16,7 @@ ControlThread.wait_for_flowgraph=false
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=File_Signal_Source
-SignalSource.filename=/archive/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE
+SignalSource.filename=/home/sergi/gnss/gnss-sdr/data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat ; <- PUT YOUR FILE HERE
SignalSource.item_type=ishort
SignalSource.sampling_frequency=4000000
SignalSource.samples=0
@@ -29,13 +29,14 @@ SignalSource.enable_throttle_control=false
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Signal_Conditioner
-DataTypeAdapter.implementation=Ishort_To_Cshort
+DataTypeAdapter.implementation=Ishort_To_Complex
InputFilter.implementation=Pass_Through
-InputFilter.item_type=cshort
+InputFilter.item_type=gr_complex
Resampler.implementation=Direct_Resampler
Resampler.sample_freq_in=4000000
Resampler.sample_freq_out=2000000
-Resampler.item_type=cshort
+Resampler.item_type=gr_complex
+
;######### CHANNELS GLOBAL CONFIG ############
Channels_1C.count=8
@@ -45,19 +46,19 @@ Channel.signal=1C
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
-Acquisition_1C.item_type=cshort
+Acquisition_1C.item_type=gr_complex
Acquisition_1C.coherent_integration_time_ms=1
Acquisition_1C.threshold=0.008
;Acquisition_1C.pfa=0.000001
Acquisition_1C.doppler_max=10000
Acquisition_1C.doppler_step=250
-Acquisition_1C.dump=false
+Acquisition_1C.dump=true
Acquisition_1C.dump_filename=./acq_dump.dat
Acquisition_1C.blocking=false;
;######### TRACKING GLOBAL CONFIG ############
-Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking
-Tracking_1C.item_type=cshort
+Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
+Tracking_1C.item_type=gr_complex
Tracking_1C.pll_bw_hz=40.0;
Tracking_1C.dll_bw_hz=4.0;
Tracking_1C.order=3;
diff --git a/conf/prova.conf b/conf/prova.conf
new file mode 100644
index 000000000..a481302cf
--- /dev/null
+++ b/conf/prova.conf
@@ -0,0 +1,56 @@
+[GNSS-SDR]
+
+
+;######### GLOBAL OPTIONS ##################
+GNSS-SDR.internal_fs_hz=2000000
+
+;######### SIGNAL_SOURCE CONFIG ############
+SignalSource.implementation=File_Signal_Source
+SignalSource.filename=/home/sergi/gnss/gnss-sdr/data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
+SignalSource.item_type=ishort
+SignalSource.sampling_frequency=4000000
+SignalSource.freq=1575420000
+SignalSource.samples=0
+
+;######### SIGNAL_CONDITIONER CONFIG ############
+SignalConditioner.implementation=Signal_Conditioner
+DataTypeAdapter.implementation=Ishort_To_Complex
+InputFilter.implementation=Pass_Through
+InputFilter.item_type=gr_complex
+Resampler.implementation=Direct_Resampler
+Resampler.sample_freq_in=4000000
+Resampler.sample_freq_out=2000000
+Resampler.item_type=gr_complex
+
+;######### CHANNELS GLOBAL CONFIG ############
+Channels_1C.count=8
+Channels.in_acquisition=1
+Channel.signal=1C
+
+;######### ACQUISITION GLOBAL CONFIG ############
+Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
+Acquisition_1C.item_type=gr_complex
+Acquisition_1C.threshold=0.008
+Acquisition_1C.doppler_max=10000
+Acquisition_1C.doppler_step=250
+
+;######### TRACKING GLOBAL CONFIG ############
+Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
+Tracking_1C.item_type=gr_complex
+Tracking_1C.pll_bw_hz=40.0;
+Tracking_1C.dll_bw_hz=4.0;
+
+;######### TELEMETRY DECODER GPS CONFIG ############
+TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
+
+;######### OBSERVABLES CONFIG ############
+Observables.implementation=GPS_L1_CA_Observables
+
+;######### PVT CONFIG ############
+PVT.implementation=GPS_L1_CA_PVT
+PVT.averaging_depth=100
+PVT.flag_averaging=true
+PVT.output_rate_ms=10
+PVT.display_rate_ms=500
+
+
diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.cc b/src/algorithms/PVT/adapters/rtklib_pvt.cc
index 3e63a19a6..945e06e3e 100644
--- a/src/algorithms/PVT/adapters/rtklib_pvt.cc
+++ b/src/algorithms/PVT/adapters/rtklib_pvt.cc
@@ -175,43 +175,46 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
int gal_E5b_count = configuration->property("Channels_7X.count", 0);
int glo_1G_count = configuration->property("Channels_1G.count", 0);
int glo_2G_count = configuration->property("Channels_2G.count", 0);
+ int bds_B1_count = configuration->property("Channels_B1.count", 0);
unsigned int type_of_receiver = 0;
// *******************WARNING!!!!!!!***********
// GPS L5 only configurable for single frequency, single system at the moment!!!!!!
- if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 1;
- if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 2;
- if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 3;
- if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 4;
- if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 5;
- if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 6;
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 1;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 2;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 3;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 4;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 5;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 6;
- if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 7;
+ if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 7;
//if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 8;
- if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 9;
- if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 10;
- if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 11;
- if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 12;
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 9;
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 10;
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 11;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 12;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 13;
- if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 14;
- if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 15;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 14;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 15;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 16;
- if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 17;
- if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 18;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 17;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 18;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 19;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 20;
- if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 21;
+ if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 21;
//if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count = 0)) type_of_receiver = 22;
- if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 23;
- if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 24;
- if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count != 0)) type_of_receiver = 25;
- if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 26;
- if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 27;
- if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 28;
- if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 29;
- if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 30;
- if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 31;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (bds_B1_count == 0)) type_of_receiver = 23;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0) && (bds_B1_count == 0)) type_of_receiver = 24;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count != 0) && (bds_B1_count == 0)) type_of_receiver = 25;
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 26;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 27;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0) && (bds_B1_count == 0)) type_of_receiver = 28;
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0) && (bds_B1_count == 0)) type_of_receiver = 29;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0) && (bds_B1_count == 0)) type_of_receiver = 30;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0) && (bds_B1_count == 0)) type_of_receiver = 31;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0) && (bds_B1_count != 0)) type_of_receiver = 32;
+
//RTKLIB PVT solver options
// Settings 1
int positioning_mode = -1;
@@ -235,7 +238,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
int num_bands = 0;
- if ((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) num_bands = 1;
+ if ((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0) || (bds_B1_count > 0)) num_bands = 1;
if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gps_2S_count > 0) || (glo_2G_count > 0))) num_bands = 2;
if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 2;
if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gps_2S_count > 0) || (glo_2G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 3;
@@ -322,6 +325,8 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
if ((gps_1C_count > 0) || (gps_2S_count > 0) || (gps_L5_count > 0)) nsys += SYS_GPS;
if ((gal_1B_count > 0) || (gal_E5a_count > 0) || (gal_E5b_count > 0)) nsys += SYS_GAL;
if ((glo_1G_count > 0) || (glo_2G_count > 0)) nsys += SYS_GLO;
+ if ((bds_B1_count > 0)) nsys += SYS_BDS;
+
int navigation_system = configuration->property(role + ".navigation_system", nsys); /* (SYS_XXX) see src/algorithms/libs/rtklib/rtklib.h */
if ((navigation_system < 1) || (navigation_system > 255)) /* GPS: 1 SBAS: 2 GPS+SBAS: 3 Galileo: 8 Galileo+GPS: 9 GPS+SBAS+Galileo: 11 All: 255 */
{
diff --git a/src/algorithms/PVT/adapters/rtklib_pvt3.cc b/src/algorithms/PVT/adapters/rtklib_pvt3.cc
new file mode 100644
index 000000000..24f4c9150
--- /dev/null
+++ b/src/algorithms/PVT/adapters/rtklib_pvt3.cc
@@ -0,0 +1,561 @@
+/*!
+ * \file rtklib_pvt.cc
+ * \brief Interface of a Position Velocity and Time computation block
+ * \author Javier Arribas, 2017. jarribas(at)cttc.es
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+
+#include "rtklib_pvt.h"
+#include "configuration_interface.h"
+#include "gnss_sdr_flags.h"
+#include
+#include
+#include
+#include
+#include
+
+
+using google::LogMessage;
+
+RtklibPvt::RtklibPvt(ConfigurationInterface* configuration,
+ std::string role,
+ unsigned int in_streams,
+ unsigned int out_streams) : role_(role),
+ in_streams_(in_streams),
+ out_streams_(out_streams)
+{
+ // dump parameters
+ std::string default_dump_filename = "./pvt.dat";
+ std::string default_nmea_dump_filename = "./nmea_pvt.nmea";
+ std::string default_nmea_dump_devname = "/dev/tty1";
+ std::string default_rtcm_dump_devname = "/dev/pts/1";
+ DLOG(INFO) << "role " << role;
+ dump_ = configuration->property(role + ".dump", false);
+ dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
+
+ // output rate
+ int output_rate_ms = configuration->property(role + ".output_rate_ms", 500);
+
+ // display rate
+ int display_rate_ms = configuration->property(role + ".display_rate_ms", 500);
+
+ // NMEA Printer settings
+ bool flag_nmea_tty_port = configuration->property(role + ".flag_nmea_tty_port", false);
+ std::string nmea_dump_filename = configuration->property(role + ".nmea_dump_filename", default_nmea_dump_filename);
+ std::string nmea_dump_devname = configuration->property(role + ".nmea_dump_devname", default_nmea_dump_devname);
+
+ // RINEX version
+ int rinex_version = configuration->property(role + ".rinex_version", 3);
+ if (FLAGS_RINEX_version.compare("3.01") == 0)
+ {
+ rinex_version = 3;
+ }
+ else if (FLAGS_RINEX_version.compare("3.02") == 0)
+ {
+ rinex_version = 3;
+ }
+ else if (FLAGS_RINEX_version.compare("3") == 0)
+ {
+ rinex_version = 3;
+ }
+ else if (FLAGS_RINEX_version.compare("2.11") == 0)
+ {
+ rinex_version = 2;
+ }
+ else if (FLAGS_RINEX_version.compare("2.10") == 0)
+ {
+ rinex_version = 2;
+ }
+ else if (FLAGS_RINEX_version.compare("2") == 0)
+ {
+ rinex_version = 2;
+ }
+ int rinexobs_rate_ms = boost::math::lcm(configuration->property(role + ".rinexobs_rate_ms", 1000), output_rate_ms);
+ int rinexnav_rate_ms = boost::math::lcm(configuration->property(role + ".rinexnav_rate_ms", 6000), output_rate_ms);
+
+ // RTCM Printer settings
+ bool flag_rtcm_tty_port = configuration->property(role + ".flag_rtcm_tty_port", false);
+ std::string rtcm_dump_devname = configuration->property(role + ".rtcm_dump_devname", default_rtcm_dump_devname);
+ bool flag_rtcm_server = configuration->property(role + ".flag_rtcm_server", false);
+ unsigned short rtcm_tcp_port = configuration->property(role + ".rtcm_tcp_port", 2101);
+ unsigned short rtcm_station_id = configuration->property(role + ".rtcm_station_id", 1234);
+ // RTCM message rates: least common multiple with output_rate_ms
+ int rtcm_MT1019_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1019_rate_ms", 5000), output_rate_ms);
+ int rtcm_MT1020_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1020_rate_ms", 5000), output_rate_ms);
+ int rtcm_MT1045_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1045_rate_ms", 5000), output_rate_ms);
+ int rtcm_MSM_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MSM_rate_ms", 1000), output_rate_ms);
+ int rtcm_MT1077_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1077_rate_ms", rtcm_MSM_rate_ms), output_rate_ms);
+ int rtcm_MT1087_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1087_rate_ms", rtcm_MSM_rate_ms), output_rate_ms);
+ int rtcm_MT1097_rate_ms = boost::math::lcm(configuration->property(role + ".rtcm_MT1097_rate_ms", rtcm_MSM_rate_ms), output_rate_ms);
+ std::map rtcm_msg_rate_ms;
+ rtcm_msg_rate_ms[1019] = rtcm_MT1019_rate_ms;
+ rtcm_msg_rate_ms[1020] = rtcm_MT1020_rate_ms;
+ rtcm_msg_rate_ms[1045] = rtcm_MT1045_rate_ms;
+ for (int k = 1071; k < 1078; k++) // All GPS MSM
+ {
+ rtcm_msg_rate_ms[k] = rtcm_MT1077_rate_ms;
+ }
+ for (int k = 1081; k < 1088; k++) // All GLONASS MSM
+ {
+ rtcm_msg_rate_ms[k] = rtcm_MT1087_rate_ms;
+ }
+ for (int k = 1091; k < 1098; k++) // All Galileo MSM
+ {
+ rtcm_msg_rate_ms[k] = rtcm_MT1097_rate_ms;
+ }
+ // getting names from the config file, if available
+ // default filename for assistance data
+ const std::string eph_default_xml_filename = "./gps_ephemeris.xml";
+ const std::string utc_default_xml_filename = "./gps_utc_model.xml";
+ const std::string iono_default_xml_filename = "./gps_iono.xml";
+ const std::string ref_time_default_xml_filename = "./gps_ref_time.xml";
+ const std::string ref_location_default_xml_filename = "./gps_ref_location.xml";
+ eph_xml_filename_ = configuration->property("GNSS-SDR.SUPL_gps_ephemeris_xml", eph_default_xml_filename);
+ //std::string utc_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_utc_model.xml", utc_default_xml_filename);
+ //std::string iono_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_iono_xml", iono_default_xml_filename);
+ //std::string ref_time_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_time_xml", ref_time_default_xml_filename);
+ //std::string ref_location_xml_filename = configuration_->property("GNSS-SDR.SUPL_gps_ref_location_xml", ref_location_default_xml_filename);
+
+ // Infer the type of receiver
+ /*
+ * TYPE | RECEIVER
+ * 0 | Unknown
+ * 1 | GPS L1 C/A
+ * 2 | GPS L2C
+ * 3 | GPS L5
+ * 4 | Galileo E1B
+ * 5 | Galileo E5a
+ * 6 | Galileo E5b
+ * 7 | GPS L1 C/A + GPS L2C
+ * 8 | GPS L1 C/A + GPS L5
+ * 9 | GPS L1 C/A + Galileo E1B
+ * 10 | GPS L1 C/A + Galileo E5a
+ * 11 | GPS L1 C/A + Galileo E5b
+ * 12 | Galileo E1B + GPS L2C
+ * 13 | Galileo E1B + GPS L5
+ * 14 | Galileo E1B + Galileo E5a
+ * 15 | Galileo E1B + Galileo E5b
+ * 16 | GPS L2C + GPS L5
+ * 17 | GPS L2C + Galileo E5a
+ * 18 | GPS L2C + Galileo E5b
+ * 19 | GPS L5 + Galileo E5a
+ * 20 | GPS L5 + Galileo E5b
+ * 21 | GPS L1 C/A + Galileo E1B + GPS L2C
+ * 22 | GPS L1 C/A + Galileo E1B + GPS L5
+ * 23 | GLONASS L1 C/A
+ * 24 | GLONASS L2 C/A
+ * 25 | GLONASS L1 C/A + GLONASS L2 C/A
+ * 26 | GPS L1 C/A + GLONASS L1 C/A
+ * 27 | Galileo E1B + GLONASS L1 C/A
+ * 28 | GPS L2C + GLONASS L1 C/A
+ */
+ int gps_1C_count = configuration->property("Channels_1C.count", 0);
+ int gps_2S_count = configuration->property("Channels_2S.count", 0);
+ int gps_L5_count = configuration->property("Channels_L5.count", 0);
+ int gal_1B_count = configuration->property("Channels_1B.count", 0);
+ int gal_E5a_count = configuration->property("Channels_5X.count", 0);
+ int gal_E5b_count = configuration->property("Channels_7X.count", 0);
+ int glo_1G_count = configuration->property("Channels_1G.count", 0);
+ int glo_2G_count = configuration->property("Channels_2G.count", 0);
+
+ unsigned int type_of_receiver = 0;
+
+ // *******************WARNING!!!!!!!***********
+ // GPS L5 only configurable for single frequency, single system at the moment!!!!!!
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 1;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 2;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 3;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 4;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 5;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 6;
+
+ if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 7;
+ //if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 8;
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 9;
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 10;
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 11;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 12;
+ //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 13;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 14;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 15;
+ //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 16;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count != 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 17;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count != 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 18;
+ //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 19;
+ //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0)) type_of_receiver = 20;
+ if ((gps_1C_count != 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count == 0)) type_of_receiver = 21;
+ //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count = 0)) type_of_receiver = 22;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 23;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 24;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count != 0)) type_of_receiver = 25;
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 26;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 27;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_2G_count == 0)) type_of_receiver = 28;
+ if ((gps_1C_count != 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 29;
+ if ((gps_1C_count == 0) && (gps_2S_count == 0) && (gps_L5_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 30;
+ if ((gps_1C_count == 0) && (gps_2S_count != 0) && (gps_L5_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count == 0) && (glo_2G_count != 0)) type_of_receiver = 31;
+ //RTKLIB PVT solver options
+ // Settings 1
+ int positioning_mode = -1;
+ std::string default_pos_mode("Single");
+ std::string positioning_mode_str = configuration->property(role + ".positioning_mode", default_pos_mode); /* (PMODE_XXX) see src/algorithms/libs/rtklib/rtklib.h */
+ if (positioning_mode_str.compare("Single") == 0) positioning_mode = PMODE_SINGLE;
+ if (positioning_mode_str.compare("Static") == 0) positioning_mode = PMODE_STATIC;
+ if (positioning_mode_str.compare("Kinematic") == 0) positioning_mode = PMODE_KINEMA;
+ if (positioning_mode_str.compare("PPP_Static") == 0) positioning_mode = PMODE_PPP_STATIC;
+ if (positioning_mode_str.compare("PPP_Kinematic") == 0) positioning_mode = PMODE_PPP_KINEMA;
+
+ if (positioning_mode == -1)
+ {
+ //warn user and set the default
+ std::cout << "WARNING: Bad specification of positioning mode." << std::endl;
+ std::cout << "positioning_mode possible values: Single / Static / Kinematic / PPP_Static / PPP_Kinematic" << std::endl;
+ std::cout << "positioning_mode specified value: " << positioning_mode_str << std::endl;
+ std::cout << "Setting positioning_mode to Single" << std::endl;
+ positioning_mode = PMODE_SINGLE;
+ }
+
+ int num_bands = 0;
+
+ if ((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) num_bands = 1;
+ if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gps_2S_count > 0) || (glo_2G_count > 0))) num_bands = 2;
+ if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 2;
+ if (((gps_1C_count > 0) || (gal_1B_count > 0) || (glo_1G_count > 0)) && ((gps_2S_count > 0) || (glo_2G_count > 0)) && ((gal_E5a_count > 0) || (gal_E5b_count > 0) || (gps_L5_count > 0))) num_bands = 3;
+
+ int number_of_frequencies = configuration->property(role + ".num_bands", num_bands); /* (1:L1, 2:L1+L2, 3:L1+L2+L5) */
+ if ((number_of_frequencies < 1) || (number_of_frequencies > 3))
+ {
+ //warn user and set the default
+ number_of_frequencies = num_bands;
+ }
+
+ double elevation_mask = configuration->property(role + ".elevation_mask", 15.0);
+ if ((elevation_mask < 0.0) || (elevation_mask > 90.0))
+ {
+ //warn user and set the default
+ LOG(WARNING) << "Erroneous Elevation Mask. Setting to default value of 15.0 degrees";
+ elevation_mask = 15.0;
+ }
+
+ int dynamics_model = configuration->property(role + ".dynamics_model", 0); /* dynamics model (0:none, 1:velocity, 2:accel) */
+ if ((dynamics_model < 0) || (dynamics_model > 2))
+ {
+ //warn user and set the default
+ LOG(WARNING) << "Erroneous Dynamics Model configuration. Setting to default value of (0:none)";
+ dynamics_model = 0;
+ }
+
+ std::string default_iono_model("OFF");
+ std::string iono_model_str = configuration->property(role + ".iono_model", default_iono_model); /* (IONOOPT_XXX) see src/algorithms/libs/rtklib/rtklib.h */
+ int iono_model = -1;
+ if (iono_model_str.compare("OFF") == 0) iono_model = IONOOPT_OFF;
+ if (iono_model_str.compare("Broadcast") == 0) iono_model = IONOOPT_BRDC;
+ if (iono_model_str.compare("SBAS") == 0) iono_model = IONOOPT_SBAS;
+ if (iono_model_str.compare("Iono-Free-LC") == 0) iono_model = IONOOPT_IFLC;
+ if (iono_model_str.compare("Estimate_STEC") == 0) iono_model = IONOOPT_EST;
+ if (iono_model_str.compare("IONEX") == 0) iono_model = IONOOPT_TEC;
+ if (iono_model == -1)
+ {
+ //warn user and set the default
+ std::cout << "WARNING: Bad specification of ionospheric model." << std::endl;
+ std::cout << "iono_model possible values: OFF / Broadcast / SBAS / Iono-Free-LC / Estimate_STEC / IONEX" << std::endl;
+ std::cout << "iono_model specified value: " << iono_model_str << std::endl;
+ std::cout << "Setting iono_model to OFF" << std::endl;
+ iono_model = IONOOPT_OFF; /* 0: ionosphere option: correction off */
+ }
+
+ std::string default_trop_model("OFF");
+ int trop_model = -1;
+ std::string trop_model_str = configuration->property(role + ".trop_model", default_trop_model); /* (TROPOPT_XXX) see src/algorithms/libs/rtklib/rtklib.h */
+ if (trop_model_str.compare("OFF") == 0) trop_model = TROPOPT_OFF;
+ if (trop_model_str.compare("Saastamoinen") == 0) trop_model = TROPOPT_SAAS;
+ if (trop_model_str.compare("SBAS") == 0) trop_model = TROPOPT_SBAS;
+ if (trop_model_str.compare("Estimate_ZTD") == 0) trop_model = TROPOPT_EST;
+ if (trop_model_str.compare("Estimate_ZTD_Grad") == 0) trop_model = TROPOPT_ESTG;
+ if (trop_model == -1)
+ {
+ //warn user and set the default
+ std::cout << "WARNING: Bad specification of tropospheric model." << std::endl;
+ std::cout << "trop_model possible values: OFF / Saastamoinen / SBAS / Estimate_ZTD / Estimate_ZTD_Grad" << std::endl;
+ std::cout << "trop_model specified value: " << trop_model_str << std::endl;
+ std::cout << "Setting trop_model to OFF" << std::endl;
+ trop_model = TROPOPT_OFF;
+ }
+
+ /* RTKLIB positioning options */
+ int sat_PCV = 0; /* Set whether the satellite antenna PCV (phase center variation) model is used or not. This feature requires a Satellite Antenna PCV File. */
+ int rec_PCV = 0; /* Set whether the receiver antenna PCV (phase center variation) model is used or not. This feature requires a Receiver Antenna PCV File. */
+
+ /* Set whether the phase windup correction for PPP modes is applied or not. Only applicable to PPP‐* modes.*/
+ int phwindup = configuration->property(role + ".phwindup", 0);
+
+ /* Set whether the GPS Block IIA satellites in eclipse are excluded or not.
+ The eclipsing Block IIA satellites often degrade the PPP solutions due to unpredicted behavior of yaw‐attitude. Only applicable to PPP‐* modes.*/
+ int reject_GPS_IIA = configuration->property(role + ".reject_GPS_IIA", 0);
+
+ /* Set whether RAIM (receiver autonomous integrity monitoring) FDE (fault detection and exclusion) feature is enabled or not.
+ In case of RAIM FDE enabled, a satellite is excluded if SSE (sum of squared errors) of residuals is over a threshold.
+ The excluded satellite is selected to indicate the minimum SSE. */
+ int raim_fde = configuration->property(role + ".raim_fde", 0);
+
+ int earth_tide = configuration->property(role + ".earth_tide", 0);
+
+ int nsys = 0;
+ if ((gps_1C_count > 0) || (gps_2S_count > 0) || (gps_L5_count > 0)) nsys += SYS_GPS;
+ if ((gal_1B_count > 0) || (gal_E5a_count > 0) || (gal_E5b_count > 0)) nsys += SYS_GAL;
+ if ((glo_1G_count > 0) || (glo_2G_count > 0)) nsys += SYS_GLO;
+ int navigation_system = configuration->property(role + ".navigation_system", nsys); /* (SYS_XXX) see src/algorithms/libs/rtklib/rtklib.h */
+ if ((navigation_system < 1) || (navigation_system > 255)) /* GPS: 1 SBAS: 2 GPS+SBAS: 3 Galileo: 8 Galileo+GPS: 9 GPS+SBAS+Galileo: 11 All: 255 */
+ {
+ //warn user and set the default
+ LOG(WARNING) << "Erroneous Navigation System. Setting to default value of (0:none)";
+ navigation_system = nsys;
+ }
+
+ // Settings 2
+ std::string default_gps_ar("Continuous");
+ std::string integer_ambiguity_resolution_gps_str = configuration->property(role + ".AR_GPS", default_gps_ar); /* Integer Ambiguity Resolution mode for GPS (0:off,1:continuous,2:instantaneous,3:fix and hold,4:ppp-ar) */
+ int integer_ambiguity_resolution_gps = -1;
+ if (integer_ambiguity_resolution_gps_str.compare("OFF") == 0) integer_ambiguity_resolution_gps = ARMODE_OFF;
+ if (integer_ambiguity_resolution_gps_str.compare("Continuous") == 0) integer_ambiguity_resolution_gps = ARMODE_CONT;
+ if (integer_ambiguity_resolution_gps_str.compare("Instantaneous") == 0) integer_ambiguity_resolution_gps = ARMODE_INST;
+ if (integer_ambiguity_resolution_gps_str.compare("Fix-and-Hold") == 0) integer_ambiguity_resolution_gps = ARMODE_FIXHOLD;
+ if (integer_ambiguity_resolution_gps_str.compare("PPP-AR") == 0) integer_ambiguity_resolution_gps = ARMODE_PPPAR;
+ if (integer_ambiguity_resolution_gps == -1)
+ {
+ //warn user and set the default
+ std::cout << "WARNING: Bad specification of GPS ambiguity resolution method." << std::endl;
+ std::cout << "AR_GPS possible values: OFF / Continuous / Instantaneous / Fix-and-Hold / PPP-AR" << std::endl;
+ std::cout << "AR_GPS specified value: " << integer_ambiguity_resolution_gps_str << std::endl;
+ std::cout << "Setting AR_GPS to OFF" << std::endl;
+ integer_ambiguity_resolution_gps = ARMODE_OFF;
+ }
+
+ int integer_ambiguity_resolution_glo = configuration->property(role + ".AR_GLO", 1); /* Integer Ambiguity Resolution mode for GLONASS (0:off,1:on,2:auto cal,3:ext cal) */
+ if ((integer_ambiguity_resolution_glo < 0) || (integer_ambiguity_resolution_glo > 3))
+ {
+ //warn user and set the default
+ LOG(WARNING) << "Erroneous Integer Ambiguity Resolution for GLONASS . Setting to default value of (1:on)";
+ integer_ambiguity_resolution_glo = 1;
+ }
+
+ int integer_ambiguity_resolution_bds = configuration->property(role + ".AR_DBS", 1); /* Integer Ambiguity Resolution mode for BEIDOU (0:off,1:on) */
+ if ((integer_ambiguity_resolution_bds < 0) || (integer_ambiguity_resolution_bds > 1))
+ {
+ //warn user and set the default
+ LOG(WARNING) << "Erroneous Integer Ambiguity Resolution for BEIDOU . Setting to default value of (1:on)";
+ integer_ambiguity_resolution_bds = 1;
+ }
+
+ double min_ratio_to_fix_ambiguity = configuration->property(role + ".min_ratio_to_fix_ambiguity", 3.0); /* Set the integer ambiguity validation threshold for ratio‐test,
+ which uses the ratio of squared residuals of the best integer vector to the second‐best vector. */
+
+ int min_lock_to_fix_ambiguity = configuration->property(role + ".min_lock_to_fix_ambiguity", 0); /* Set the minimum lock count to fix integer ambiguity.
+ If the lock count is less than the value, the ambiguity is excluded from the fixed integer vector. */
+
+ double min_elevation_to_fix_ambiguity = configuration->property(role + ".min_elevation_to_fix_ambiguity", 0.0); /* Set the minimum elevation (deg) to fix integer ambiguity.
+ If the elevation of the satellite is less than the value, the ambiguity is excluded from the fixed integer vector. */
+
+ int outage_reset_ambiguity = configuration->property(role + ".outage_reset_ambiguity", 5); /* Set the outage count to reset ambiguity. If the data outage count is over the value, the estimated ambiguity is reset to the initial value. */
+
+ double slip_threshold = configuration->property(role + ".slip_threshold", 0.05); /* set the cycle‐slip threshold (m) of geometry‐free LC carrier‐phase difference between epochs */
+
+ double threshold_reject_gdop = configuration->property(role + ".threshold_reject_gdop", 30.0); /* reject threshold of GDOP. If the GDOP is over the value, the observable is excluded for the estimation process as an outlier. */
+
+ double threshold_reject_innovation = configuration->property(role + ".threshold_reject_innovation", 30.0); /* reject threshold of innovation (m). If the innovation is over the value, the observable is excluded for the estimation process as an outlier. */
+
+ int number_filter_iter = configuration->property(role + ".number_filter_iter", 1); /* Set the number of iteration in the measurement update of the estimation filter.
+ If the baseline length is very short like 1 m, the iteration may be effective to handle
+ the nonlinearity of measurement equation. */
+
+ /// Statistics
+ double bias_0 = configuration->property(role + ".bias_0", 30.0);
+
+ double iono_0 = configuration->property(role + ".iono_0", 0.03);
+
+ double trop_0 = configuration->property(role + ".trop_0", 0.3);
+
+ double sigma_bias = configuration->property(role + ".sigma_bias", 1e-4); /* Set the process noise standard deviation of carrier‐phase
+ bias (ambiguity) (cycle/sqrt(s)) */
+
+ double sigma_iono = configuration->property(role + ".sigma_iono", 1e-3); /* Set the process noise standard deviation of vertical ionospheric delay per 10 km baseline (m/sqrt(s)). */
+
+ double sigma_trop = configuration->property(role + ".sigma_trop", 1e-4); /* Set the process noise standard deviation of zenith tropospheric delay (m/sqrt(s)). */
+
+ double sigma_acch = configuration->property(role + ".sigma_acch", 1e-1); /* Set the process noise standard deviation of the receiver acceleration as
+ the horizontal component. (m/s2/sqrt(s)). If Receiver Dynamics is set to OFF, they are not used. */
+
+ double sigma_accv = configuration->property(role + ".sigma_accv", 1e-2); /* Set the process noise standard deviation of the receiver acceleration as
+ the vertical component. (m/s2/sqrt(s)). If Receiver Dynamics is set to OFF, they are not used. */
+
+ double sigma_pos = configuration->property(role + ".sigma_pos", 0.0);
+
+ double code_phase_error_ratio_l1 = configuration->property(role + ".code_phase_error_ratio_l1", 100.0);
+ double code_phase_error_ratio_l2 = configuration->property(role + ".code_phase_error_ratio_l2", 100.0);
+ double code_phase_error_ratio_l5 = configuration->property(role + ".code_phase_error_ratio_l5", 100.0);
+ double carrier_phase_error_factor_a = configuration->property(role + ".carrier_phase_error_factor_a", 0.003);
+ double carrier_phase_error_factor_b = configuration->property(role + ".carrier_phase_error_factor_b", 0.003);
+
+ snrmask_t snrmask = {{}, {{}, {}}};
+
+ prcopt_t rtklib_configuration_options = {
+ positioning_mode, /* positioning mode (PMODE_XXX) see src/algorithms/libs/rtklib/rtklib.h */
+ 0, /* solution type (0:forward,1:backward,2:combined) */
+ number_of_frequencies, /* number of frequencies (1:L1, 2:L1+L2, 3:L1+L2+L5)*/
+ navigation_system, /* navigation system */
+ elevation_mask * D2R, /* elevation mask angle (degrees) */
+ snrmask, /* snrmask_t snrmask SNR mask */
+ 0, /* satellite ephemeris/clock (EPHOPT_XXX) */
+ integer_ambiguity_resolution_gps, /* AR mode (0:off,1:continuous,2:instantaneous,3:fix and hold,4:ppp-ar) */
+ integer_ambiguity_resolution_glo, /* GLONASS AR mode (0:off,1:on,2:auto cal,3:ext cal) */
+ integer_ambiguity_resolution_bds, /* BeiDou AR mode (0:off,1:on) */
+ outage_reset_ambiguity, /* obs outage count to reset bias */
+ min_lock_to_fix_ambiguity, /* min lock count to fix ambiguity */
+ 10, /* min fix count to hold ambiguity */
+ 1, /* max iteration to resolve ambiguity */
+ iono_model, /* ionosphere option (IONOOPT_XXX) */
+ trop_model, /* troposphere option (TROPOPT_XXX) */
+ dynamics_model, /* dynamics model (0:none, 1:velocity, 2:accel) */
+ earth_tide, /* earth tide correction (0:off,1:solid,2:solid+otl+pole) */
+ number_filter_iter, /* number of filter iteration */
+ 0, /* code smoothing window size (0:none) */
+ 0, /* interpolate reference obs (for post mission) */
+ 0, /* sbssat_t sbssat SBAS correction options */
+ 0, /* sbsion_t sbsion[MAXBAND+1] SBAS satellite selection (0:all) */
+ 0, /* rover position for fixed mode */
+ 0, /* base position for relative mode */
+ /* 0:pos in prcopt, 1:average of single pos, */
+ /* 2:read from file, 3:rinex header, 4:rtcm pos */
+ {code_phase_error_ratio_l1, code_phase_error_ratio_l2, code_phase_error_ratio_l5}, /* eratio[NFREQ] code/phase error ratio */
+ {100.0, carrier_phase_error_factor_a, carrier_phase_error_factor_b, 0.0, 1.0}, /* err[5]: measurement error factor [0]:reserved, [1-3]:error factor a/b/c of phase (m) , [4]:doppler frequency (hz) */
+ {bias_0, iono_0, trop_0}, /* std[3]: initial-state std [0]bias,[1]iono [2]trop*/
+ {sigma_bias, sigma_iono, sigma_trop, sigma_acch, sigma_accv, sigma_pos}, /* prn[6] process-noise std */
+ 5e-12, /* sclkstab: satellite clock stability (sec/sec) */
+ {min_ratio_to_fix_ambiguity, 0.9999, 0.25, 0.1, 0.05, 0.0, 0.0, 0.0}, /* thresar[8]: AR validation threshold */
+ min_elevation_to_fix_ambiguity, /* elevation mask of AR for rising satellite (deg) */
+ 0.0, /* elevation mask to hold ambiguity (deg) */
+ slip_threshold, /* slip threshold of geometry-free phase (m) */
+ 30.0, /* max difference of time (sec) */
+ threshold_reject_innovation, /* reject threshold of innovation (m) */
+ threshold_reject_gdop, /* reject threshold of gdop */
+ {}, /* double baseline[2] baseline length constraint {const,sigma} (m) */
+ {}, /* double ru[3] rover position for fixed mode {x,y,z} (ecef) (m) */
+ {}, /* double rb[3] base position for relative mode {x,y,z} (ecef) (m) */
+ {"", ""}, /* char anttype[2][MAXANT] antenna types {rover,base} */
+ {{}, {}}, /* double antdel[2][3] antenna delta {{rov_e,rov_n,rov_u},{ref_e,ref_n,ref_u}} */
+ {}, /* pcv_t pcvr[2] receiver antenna parameters {rov,base} */
+ {}, /* unsigned char exsats[MAXSAT] excluded satellites (1:excluded, 2:included) */
+ 0, /* max averaging epoches */
+ 0, /* initialize by restart */
+ 1, /* output single by dgps/float/fix/ppp outage */
+ {"", ""}, /* char rnxopt[2][256] rinex options {rover,base} */
+ {sat_PCV, rec_PCV, phwindup, reject_GPS_IIA, raim_fde}, /* posopt[6] positioning options [0]: satellite and receiver antenna PCV model; [1]: interpolate antenna parameters; [2]: apply phase wind-up correction for PPP modes; [3]: exclude measurements of GPS Block IIA satellites satellite [4]: RAIM FDE (fault detection and exclusion) [5]: handle day-boundary clock jump */
+ 0, /* solution sync mode (0:off,1:on) */
+ {{}, {}}, /* odisp[2][6*11] ocean tide loading parameters {rov,base} */
+ {{}, {{}, {}}, {{}, {}}, {}, {}}, /* exterr_t exterr extended receiver error model */
+ 0, /* disable L2-AR */
+ {} /* char pppopt[256] ppp option "-GAP_RESION=" default gap to reset iono parameters (ep) */
+ };
+
+ rtkinit(&rtk, &rtklib_configuration_options);
+
+ // make PVT object
+ pvt_ = rtklib_make_pvt_cc(in_streams_, dump_, dump_filename_, output_rate_ms, display_rate_ms, flag_nmea_tty_port, nmea_dump_filename, nmea_dump_devname, rinex_version, rinexobs_rate_ms, rinexnav_rate_ms, flag_rtcm_server, flag_rtcm_tty_port, rtcm_tcp_port, rtcm_station_id, rtcm_msg_rate_ms, rtcm_dump_devname, type_of_receiver, rtk);
+ DLOG(INFO) << "pvt(" << pvt_->unique_id() << ")";
+ if (out_streams_ > 0)
+ {
+ LOG(ERROR) << "The PVT block does not have an output stream";
+ }
+}
+
+
+bool RtklibPvt::save_assistance_to_XML()
+{
+ LOG(INFO) << "SUPL: Try to save GPS ephemeris to XML file " << eph_xml_filename_;
+ std::map eph_map = pvt_->get_GPS_L1_ephemeris_map();
+
+ if (eph_map.size() > 0)
+ {
+ try
+ {
+ std::ofstream ofs(eph_xml_filename_.c_str(), std::ofstream::trunc | std::ofstream::out);
+ boost::archive::xml_oarchive xml(ofs);
+ xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", eph_map);
+ ofs.close();
+ LOG(INFO) << "Saved GPS L1 Ephemeris map data";
+ }
+ catch (const std::exception& e)
+ {
+ LOG(WARNING) << e.what();
+ return false;
+ }
+ return true; // return variable (true == succeeded)
+ }
+ else
+ {
+ LOG(WARNING) << "Failed to save Ephemeris, map is empty";
+ return false;
+ }
+}
+
+
+RtklibPvt::~RtklibPvt()
+{
+ rtkfree(&rtk);
+ save_assistance_to_XML();
+}
+
+
+void RtklibPvt::connect(gr::top_block_sptr top_block)
+{
+ if (top_block)
+ { /* top_block is not null */
+ };
+ // Nothing to connect internally
+ DLOG(INFO) << "nothing to connect internally";
+}
+
+
+void RtklibPvt::disconnect(gr::top_block_sptr top_block)
+{
+ if (top_block)
+ { /* top_block is not null */
+ };
+ // Nothing to disconnect
+}
+
+
+gr::basic_block_sptr RtklibPvt::get_left_block()
+{
+ return pvt_;
+}
+
+
+gr::basic_block_sptr RtklibPvt::get_right_block()
+{
+ return pvt_; // this is a sink, nothing downstream
+}
diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc
index f055915cc..269699cfd 100644
--- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc
+++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc
@@ -231,6 +231,37 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg)
DLOG(INFO) << "New GLONASS GNAV Almanac has arrived "
<< ", GLONASS GNAV Slot Number =" << glonass_gnav_almanac->d_n_A;
}
+ // ************* BEIDOU telemetry *****************
+ if (pmt::any_ref(msg).type() == typeid(std::shared_ptr))
+ {
+ // ### BEIDOU EPHEMERIS ###
+ std::shared_ptr beidou_eph;
+ beidou_eph = boost::any_cast>(pmt::any_ref(msg));
+ DLOG(INFO) << "Ephemeris record has arrived from SAT ID "
+ << beidou_eph->i_satellite_PRN << " (Block "
+ << beidou_eph->satelliteBlock[beidou_eph->i_satellite_PRN] << ")"
+ << "inserted with Toe=" << beidou_eph->d_Toe << " and BEIDOU Week="
+ << beidou_eph->i_BEIDOU_week;
+ // update/insert new ephemeris record to the global ephemeris map
+ d_ls_pvt->beidou_ephemeris_map[beidou_eph->i_satellite_PRN] = *beidou_eph;
+ }
+ else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr))
+ {
+ // ### BEIDOU IONO ###
+ std::shared_ptr beidou_iono;
+ beidou_iono = boost::any_cast>(pmt::any_ref(msg));
+ d_ls_pvt->beidou_iono = *beidou_iono;
+ DLOG(INFO) << "New IONO record has arrived ";
+ }
+ else if (pmt::any_ref(msg).type() == typeid(std::shared_ptr))
+ {
+ // ### BEIDOU UTC MODEL ###
+ std::shared_ptr beidou_utc_model;
+ beidou_utc_model = boost::any_cast>(pmt::any_ref(msg));
+ d_ls_pvt->beidou_utc_model = *beidou_utc_model;
+ DLOG(INFO) << "New UTC record has arrived ";
+ }
+
else
{
LOG(WARNING) << "msg_handler_telemetry unknown object type!";
@@ -482,6 +513,28 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
{
LOG(INFO) << "Failed to save GLONASS GNAV Ephemeris, map is empty";
}
+ // save Beidou B1I ephemeris to XML file
+ file_name = "eph_BEIDOU_b1I.xml";
+
+ if (d_ls_pvt->beidou_ephemeris_map.size() > 0)
+ {
+ try
+ {
+ std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
+ boost::archive::xml_oarchive xml(ofs);
+ xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", d_ls_pvt->beidou_ephemeris_map);
+ ofs.close();
+ LOG(INFO) << "Saved BEIDOU Ephemeris map data";
+ }
+ catch (std::exception& e)
+ {
+ LOG(WARNING) << e.what();
+ }
+ }
+ else
+ {
+ LOG(WARNING) << "Failed to save BEIDOU Ephemeris, map is empty";
+ }
// Save GPS UTC model parameters
file_name = "gps_utc_model.xml";
@@ -728,6 +781,14 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
d_rtcm_printer->lock_time(d_ls_pvt->glonass_gnav_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time
}
}
+/* if (d_ls_pvt->beidou_ephemeris_map.size() > 0)
+ {
+ if (tmp_eph_iter_bds != d_ls_pvt->beidou_ephemeris_map.end())
+ {
+ d_rtcm_printer->lock_time(d_ls_pvt->beidou_ephemeris_map.find(in[i][epoch].PRN)->second, in[i][epoch].RX_time, in[i][epoch]); // keep track of locking time
+ }
+ }
+*/
}
catch (const boost::exception& ex)
{
@@ -872,6 +933,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
* 29 | GPS L1 C/A + GLONASS L2 C/A
* 30 | Galileo E1B + GLONASS L2 C/A
* 31 | GPS L2C + GLONASS L2 C/A
+ * 32 | Beidou B1I
*/
// ####################### RINEX FILES #################
@@ -880,6 +942,8 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
std::map::const_iterator gps_ephemeris_iter;
std::map::const_iterator gps_cnav_ephemeris_iter;
std::map::const_iterator glonass_gnav_ephemeris_iter;
+ std::map::const_iterator beidou_ephemeris_iter;
+
std::map::const_iterator gnss_observables_iter;
if (!b_rinex_header_written) // & we have utc data in nav message!
@@ -888,6 +952,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin();
gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin();
glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin();
+ beidou_ephemeris_iter = d_ls_pvt->beidou_ephemeris_map.cbegin();
if (type_of_rx == 1) // GPS L1 C/A only
{
@@ -1110,6 +1175,17 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
b_rinex_header_written = true; // do not write header anymore
}
}
+/* if (type_of_rx == 32) // Beidou B1I only
+ {
+ if (beidou_ephemeris_iter != d_ls_pvt->beidou_ephemeris_map.cend())
+ {
+ rp->rinex_obs_header(rp->obsFile, beidou_ephemeris_iter->second, d_rx_time);
+ rp->rinex_nav_header(rp->navFile, d_ls_pvt->beidou_iono, d_ls_pvt->beidou_utc_model);
+ b_rinex_header_written = true; // do not write header anymore
+ }
+ }
+*/
+
}
if (b_rinex_header_written) // The header is already written, we can now log the navigation message data
{
@@ -1183,11 +1259,17 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
{
rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_cnav_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map);
}
+/* if (type_of_rx == 32) // GPS L1 C/A only
+ {
+ rp->log_rinex_nav(rp->navFile, d_ls_pvt->beidou_ephemeris_map);
+ }
+*/
}
galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin();
gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin();
gps_cnav_ephemeris_iter = d_ls_pvt->gps_cnav_ephemeris_map.cbegin();
glonass_gnav_ephemeris_iter = d_ls_pvt->glonass_gnav_ephemeris_map.cbegin();
+ beidou_ephemeris_iter = d_ls_pvt->beidou_ephemeris_map.cbegin();
// Log observables into the RINEX file
if (flag_write_RINEX_obs_output)
@@ -1439,6 +1521,21 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
b_rinex_header_updated = true; // do not write header anymore
}
}
+/* if (type_of_rx == 32) // Beidou
+ {
+ if (beidou_ephemeris_iter != d_ls_pvt->beidou_ephemeris_map.end())
+ {
+ rp->log_rinex_obs(rp->obsFile, beidou_ephemeris_iter->second, d_rx_time, gnss_observables_map);
+ }
+ if (!b_rinex_header_updated and (d_ls_pvt->beidou_utc_model.d_A0 != 0))
+ {
+ rp->update_obs_header(rp->obsFile, d_ls_pvt->beidou_utc_model);
+ rp->update_nav_header(rp->navFile, d_ls_pvt->beidou_utc_model, d_ls_pvt->beidou_iono);
+ b_rinex_header_updated = true;
+ }
+ }
+*/
+
}
}
@@ -2244,8 +2341,8 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
// std::cout << TEXT_MAGENTA << "Observable RX time (GPST) " << boost::posix_time::to_simple_string(p_time) << TEXT_RESET << std::endl;
DLOG(INFO) << "Position at " << boost::posix_time::to_simple_string(d_ls_pvt->get_position_UTC_time())
- << " UTC using " << d_ls_pvt->get_num_valid_observations() << " observations is Lat = " << d_ls_pvt->get_latitude() << " [deg], Long = " << d_ls_pvt->get_longitude()
- << " [deg], Height = " << d_ls_pvt->get_height() << " [m]";
+ << " UTC using " << d_ls_pvt->get_num_valid_observations() << " observations is Lat = " << d_ls_pvt->get_latitude() << " [deg], Long = " << d_ls_pvt->get_longitude()
+ << " [deg], Height = " << d_ls_pvt->get_height() << " [m]";
/* std::cout << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_ls_pvt->get_position_UTC_time())
<< " UTC using "<< d_ls_pvt->get_num_valid_observations() <<" observations is HDOP = " << d_ls_pvt->get_hdop() << " VDOP = "
diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc
index 4d43c18b4..57f899ce8 100644
--- a/src/algorithms/PVT/libs/rtklib_solver.cc
+++ b/src/algorithms/PVT/libs/rtklib_solver.cc
@@ -57,6 +57,7 @@
#include "Galileo_E1.h"
#include "GLONASS_L1_L2_CA.h"
#include
+#include "../../../core/system_parameters/Beidou_B1I.h"
using google::LogMessage;
@@ -140,6 +141,8 @@ bool rtklib_solver::get_PVT(const std::map& gnss_observables_
std::map::const_iterator gps_ephemeris_iter;
std::map::const_iterator gps_cnav_ephemeris_iter;
std::map::const_iterator glonass_gnav_ephemeris_iter;
+ std::map::const_iterator beidou_ephemeris_iter;
+
const Glonass_Gnav_Utc_Model gnav_utc = this->glonass_gnav_utc_model;
this->set_averaging_flag(flag_averaging);
@@ -449,6 +452,34 @@ bool rtklib_solver::get_PVT(const std::map& gnss_observables_
}
break;
}
+ case 'C':
+ {
+ // BEIDOU B1I
+ // - find the ephemeris for the current BEIDOU SV observation. The SV PRN ID is the map key
+ std::string sig_(gnss_observables_iter->second.Signal);
+ if (sig_.compare("B1") == 0)
+ {
+ beidou_ephemeris_iter = beidou_ephemeris_map.find(gnss_observables_iter->second.PRN);
+ if (beidou_ephemeris_iter != beidou_ephemeris_map.cend())
+ {
+ // convert ephemeris from GNSS-SDR class to RTKLIB structure
+ eph_data[valid_obs] = eph_to_rtklib(beidou_ephemeris_iter->second);
+ // convert observation from GNSS-SDR class to RTKLIB structure
+ obsd_t newobs = {{0, 0}, '0', '0', {}, {}, {}, {}, {}, {}};
+ obs_data[valid_obs + glo_valid_obs] = insert_obs_to_rtklib(newobs,
+ gnss_observables_iter->second,
+ beidou_ephemeris_iter->second.i_BEIDOU_week,
+ 0);
+ valid_obs++;
+ }
+ else // the ephemeris are not available for this SV
+ {
+ DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->first;
+ }
+ }
+ break;
+ }
+
default:
DLOG(INFO) << "Hybrid observables: Unknown GNSS";
break;
diff --git a/src/algorithms/PVT/libs/rtklib_solver.h b/src/algorithms/PVT/libs/rtklib_solver.h
index df9dd9ab5..ab06a1d66 100644
--- a/src/algorithms/PVT/libs/rtklib_solver.h
+++ b/src/algorithms/PVT/libs/rtklib_solver.h
@@ -65,6 +65,7 @@
#include
#include