diff --git a/conf/gnss-sdr_GPS_GLONASS_L1_CA_ibyte.conf b/conf/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf similarity index 97% rename from conf/gnss-sdr_GPS_GLONASS_L1_CA_ibyte.conf rename to conf/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf index 0435d6ff2..ffabae821 100644 --- a/conf/gnss-sdr_GPS_GLONASS_L1_CA_ibyte.conf +++ b/conf/gnss-sdr_GLONASS_L1_CA_GPS_L1_CA_ibyte.conf @@ -107,7 +107,7 @@ Tracking_1C.if=0 Tracking_1C.early_late_space_chips=0.5 Tracking_1C.pll_bw_hz=20.0; Tracking_1C.dll_bw_hz=2.0; -Tracking_1C.dump=true; +Tracking_1C.dump=false; Tracking_1C.dump_filename=/archive/gps_tracking_ch_ Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_Tracking @@ -125,7 +125,7 @@ TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables -Observables.dump=true; +Observables.dump=false; Observables.dump_filename=/archive/gnss_observables.dat ;######### PVT CONFIG ############ @@ -133,7 +133,7 @@ PVT.implementation=RTKLIB_PVT PVT.output_rate_ms=100 PVT.display_rate_ms=500 PVT.trop_model=Saastamoinen -PVT.flag_rtcm_server=true +PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 PVT.rtcm_tcp_port=2101 @@ -141,4 +141,4 @@ PVT.rtcm_MT1019_rate_ms=5000 PVT.rtcm_MT1045_rate_ms=5000 PVT.rtcm_MT1097_rate_ms=1000 PVT.rtcm_MT1077_rate_ms=1000 -PVT.rinex_version=2 +PVT.rinex_version=3 diff --git a/conf/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf b/conf/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf new file mode 100644 index 000000000..b36bb6e31 --- /dev/null +++ b/conf/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf @@ -0,0 +1,147 @@ +[GNSS-SDR] + +;######### GLOBAL OPTIONS ################## +GNSS-SDR.internal_fs_sps=6625000 +Receiver.sources_count=2 +SignalSource.repeat=false + +;######### SIGNAL_SOURCE CONFIG ############ +SignalSource0.implementation=File_Signal_Source +SignalSource0.filename=/archive/NT1065_L2_20160923_fs6625e6_if60e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource0.item_type=ibyte +SignalSource0.sampling_frequency=6625000 +SignalSource0.samples=0 +SignalSource0.dump=false; +SignalSource0.dump_filename=/archive/signal_glonass.bin + +SignalSource1.implementation=File_Signal_Source +SignalSource1.filename=/archive/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE +SignalSource1.item_type=ibyte +SignalSource1.sampling_frequency=6625000 +SignalSource1.samples=0 +SignalSource1.dump=false; +SignalSource1.dump_filename=/archive/signal_glonass.bin + +;######### SIGNAL_CONDITIONER CONFIG ############ +SignalConditioner0.implementation=Signal_Conditioner +DataTypeAdapter0.implementation=Ibyte_To_Complex +InputFilter0.implementation=Freq_Xlating_Fir_Filter +InputFilter0.item_type=gr_complex +InputFilter0.output_item_type=gr_complex +InputFilter0.taps_item_type=float +InputFilter0.number_of_taps=5 +InputFilter0.number_of_bands=2 +InputFilter0.band1_begin=0.0 +InputFilter0.band1_end=0.70 +InputFilter0.band2_begin=0.80 +InputFilter0.band2_end=1.0 +InputFilter0.ampl1_begin=1.0 +InputFilter0.ampl1_end=1.0 +InputFilter0.ampl2_begin=0.0 +InputFilter0.ampl2_end=0.0 +InputFilter0.band1_error=1.0 +InputFilter0.band2_error=1.0 +InputFilter0.filter_type=bandpass +InputFilter0.grid_density=16 +InputFilter0.sampling_frequency=6625000 +InputFilter0.IF=60000 +Resampler0.implementation=Direct_Resampler +Resampler0.sample_freq_in=6625000 +Resampler0.sample_freq_out=6625000 +Resampler0.item_type=gr_complex + +SignalConditioner1.implementation=Signal_Conditioner +DataTypeAdapter1.implementation=Ibyte_To_Complex +InputFilter1.implementation=Pass_Through +InputFilter1.item_type=gr_complex +Resampler1.implementation=Direct_Resampler +Resampler1.sample_freq_in=6625000 +Resampler1.sample_freq_out=6625000 +Resampler1.item_type=gr_complex + +;######### CHANNELS GLOBAL CONFIG ############ +Channels.in_acquisition=5 +Channels_2S.count=5 +Channels_1G.count=5 + +;# Defining GLONASS satellites +Channel0.RF_channel_ID=0 +Channel0.signal=2S +Channel1.RF_channel_ID=0 +Channel1.signal=2S +Channel2.RF_channel_ID=0 +Channel2.signal=2S +Channel3.RF_channel_ID=0 +Channel3.signal=2S +Channel4.RF_channel_ID=0 +Channel4.signal=2S +Channel5.RF_channel_ID=1 +Channel6.RF_channel_ID=1 +Channel7.RF_channel_ID=1 +Channel8.RF_channel_ID=1 +Channel9.RF_channel_ID=1 + + +;######### ACQUISITION GLOBAL CONFIG ############ +Acquisition_2S.implementation=GPS_L2_M_PCPS_Acquisition +Acquisition_2S.item_type=gr_complex +Acquisition_2S.threshold=0.0 +Acquisition_2S.pfa=0.00001 +Acquisition_2S.if=0 +Acquisition_2S.doppler_max=10000 +Acquisition_2S.doppler_step=60 +Acquisition_2S.max_dwells=1 + +Acquisition_1G.implementation=GLONASS_L1_CA_PCPS_Acquisition +Acquisition_1G.item_type=gr_complex +Acquisition_1G.threshold=0.0 +Acquisition_1G.pfa=0.00001 +Acquisition_1G.if=0 +Acquisition_1G.doppler_max=10000 +Acquisition_1G.doppler_step=250 +Acquisition_1G.dump=false; +Acquisition_1G.dump_filename=/archive/glo_acquisition.dat + +;######### TRACKING GLOBAL CONFIG ############ +Tracking_2S.implementation=GPS_L2_M_DLL_PLL_Tracking +Tracking_2S.item_type=gr_complex +Tracking_2S.if=0 +Tracking_2S.early_late_space_chips=0.5 +Tracking_2S.pll_bw_hz=2.0; +Tracking_2S.dll_bw_hz=0.250; +Tracking_2S.order=2; +Tracking_2S.dump=false; +Tracking_2S.dump_filename=/archive/gps_tracking_ch_ + +Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_Tracking +Tracking_1G.item_type=gr_complex +Tracking_1G.if=0 +Tracking_1G.early_late_space_chips=0.5 +Tracking_1G.pll_bw_hz=25.0; +Tracking_1G.dll_bw_hz=3.0; +Tracking_1G.dump=true; +Tracking_1G.dump_filename=/archive/glo_tracking_ch_ + +;######### TELEMETRY DECODER GPS CONFIG ############ +TelemetryDecoder_2S.implementation=GPS_L2C_Telemetry_Decoder +TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder + +;######### OBSERVABLES CONFIG ############ +Observables.implementation=Hybrid_Observables +Observables.dump=false; +Observables.dump_filename=/archive/gnss_observables.dat + +;######### PVT CONFIG ############ +PVT.implementation=RTKLIB_PVT +PVT.output_rate_ms=100 +PVT.display_rate_ms=500 +PVT.trop_model=Saastamoinen +PVT.flag_rtcm_server=true +PVT.flag_rtcm_tty_port=false +PVT.rtcm_dump_devname=/dev/pts/1 +PVT.rtcm_tcp_port=2101 +PVT.rtcm_MT1019_rate_ms=5000 +PVT.rtcm_MT1045_rate_ms=5000 +PVT.rtcm_MT1097_rate_ms=1000 +PVT.rtcm_MT1077_rate_ms=1000 +PVT.rinex_version=3 diff --git a/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf b/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf index d6cbbf891..4d51b83a1 100644 --- a/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf +++ b/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf @@ -27,7 +27,7 @@ Resampler.item_type=gr_complex ;######### CHANNELS GLOBAL CONFIG ############ Channel.signal=1G Channels.in_acquisition=1 -Channels_1G.count=8 +Channels_1G.count=5 Channel0.satellite=24 ; k= Channel1.satellite=1 ; k=1 @@ -43,9 +43,9 @@ Acquisition_1G.pfa=0.0001 Acquisition_1G.if=0 Acquisition_1G.doppler_max=10000 Acquisition_1G.doppler_step=250 -Acquisition_1G.dump=true; +Acquisition_1G.dump=false; Acquisition_1G.dump_filename=/archive/glo_acquisition.dat -Acquisition_1G.coherent_integration_time_ms=1 +;Acquisition_1G.coherent_integration_time_ms=1 ;Acquisition_1G.max_dwells = 5 ;######### TRACKING GLOBAL CONFIG ############ @@ -55,7 +55,7 @@ Tracking_1G.if=0 Tracking_1G.early_late_space_chips=0.5 Tracking_1G.pll_bw_hz=25.0; Tracking_1G.dll_bw_hz=3.0; -Tracking_1G.dump=true; +Tracking_1G.dump=false; Tracking_1G.dump_filename=/archive/glo_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ @@ -63,7 +63,7 @@ TelemetryDecoder_1G.implementation=GLONASS_L1_CA_Telemetry_Decoder ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables -Observables.dump=true; +Observables.dump=false; Observables.dump_filename=/archive/glo_observables.dat ;######### PVT CONFIG ############ @@ -72,7 +72,7 @@ PVT.positioning_mode=Single PVT.output_rate_ms=100 PVT.display_rate_ms=500 PVT.trop_model=Saastamoinen -PVT.flag_rtcm_server=true +PVT.flag_rtcm_server=false PVT.flag_rtcm_tty_port=false PVT.rtcm_dump_devname=/dev/pts/1 PVT.rtcm_tcp_port=2101 @@ -80,4 +80,4 @@ PVT.rtcm_MT1019_rate_ms=5000 PVT.rtcm_MT1045_rate_ms=5000 PVT.rtcm_MT1097_rate_ms=1000 PVT.rtcm_MT1077_rate_ms=1000 -PVT.rinex_version=2 +PVT.rinex_version=3 diff --git a/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf b/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf index ad49d03e0..7e9a9d279 100644 --- a/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf +++ b/conf/gnss-sdr_GLONASS_L1_CA_ibyte_coh_trk.conf @@ -26,10 +26,10 @@ Resampler.item_type=gr_complex ;######### CHANNELS GLOBAL CONFIG ############ Channel.signal=1G -Channels.in_acquisition=1 +Channels.in_acquisition=2 Channels_1G.count=8 -Channel0.satellite=24 ; k= +Channel0.satellite=24 ; k=2 Channel1.satellite=1 ; k=1 Channel2.satellite=2 ; k=-4 Channel3.satellite=20 ; k=-5 @@ -53,9 +53,9 @@ Tracking_1G.implementation=GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking Tracking_1G.item_type=gr_complex Tracking_1G.if=0 Tracking_1G.early_late_space_chips=0.5 -Tracking_1G.pll_bw_hz=25.0; +Tracking_1G.pll_bw_hz=40.0; Tracking_1G.dll_bw_hz=3.0; -Tracking_1G.pll_bw_narrow_hz = 20.0; +Tracking_1G.pll_bw_narrow_hz = 25.0; Tracking_1G.dll_bw_narrow_hz = 2.0; Tracking_1G.extend_correlation_ms = 1; Tracking_1G.dump=true; diff --git a/conf/gnss-sdr_GPS_L1_CA_ibyte.conf b/conf/gnss-sdr_GPS_L1_CA_ibyte.conf index ecb652dca..d2d501308 100644 --- a/conf/gnss-sdr_GPS_L1_CA_ibyte.conf +++ b/conf/gnss-sdr_GPS_L1_CA_ibyte.conf @@ -78,7 +78,7 @@ Observables.dump_filename=/archive/gps_observables.dat ;######### PVT CONFIG ############ PVT.implementation=RTKLIB_PVT -PVT.positioning_mode=Single +PVT.positioning_mode=PPP_Static PVT.output_rate_ms=100 PVT.display_rate_ms=500 PVT.trop_model=Saastamoinen @@ -90,4 +90,4 @@ PVT.rtcm_MT1019_rate_ms=5000 PVT.rtcm_MT1045_rate_ms=5000 PVT.rtcm_MT1097_rate_ms=1000 PVT.rtcm_MT1077_rate_ms=1000 -PVT.rinex_version=2 +PVT.rinex_version=3 diff --git a/src/algorithms/PVT/adapters/rtklib_pvt.cc b/src/algorithms/PVT/adapters/rtklib_pvt.cc index 59b8e38fb..4c425b471 100644 --- a/src/algorithms/PVT/adapters/rtklib_pvt.cc +++ b/src/algorithms/PVT/adapters/rtklib_pvt.cc @@ -150,6 +150,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, * 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); @@ -187,6 +188,7 @@ RtklibPvt::RtklibPvt(ConfigurationInterface* configuration, //if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0) && (glo_1G_count != 0)) type_of_receiver = 25; if( (gps_1C_count != 0) && (gps_2S_count == 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 26; if( (gps_1C_count == 0) && (gps_2S_count == 0) && (gal_1B_count != 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 27; + if( (gps_1C_count == 0) && (gps_2S_count != 0) && (gal_1B_count == 0) && (gal_E5a_count == 0) && (gal_E5b_count == 0) && (glo_1G_count != 0)) type_of_receiver = 28; //RTKLIB PVT solver options // Settings 1 int positioning_mode = -1; diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc index b4a312895..9b6169e50 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc @@ -345,7 +345,8 @@ rtklib_pvt_cc::rtklib_pvt_cc(unsigned int nchannels, bool dump, std::string dump b_rinex_header_written = false; b_rinex_header_updated = false; - rp = std::make_shared(rinex_version); + d_rinex_version = rinex_version; + rp = std::make_shared(d_rinex_version); d_last_status_print_seg = 0; @@ -712,6 +713,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite * 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 */ // ####################### RINEX FILES ################# @@ -843,7 +845,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); b_rinex_header_written = true; // do not write header anymore } } @@ -852,8 +854,8 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite std::string signal("2G"); if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { - rp->rinex_obs_header(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); b_rinex_header_written = true; // do not write header anymore } } @@ -863,7 +865,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite if (glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) { rp->rinex_obs_header(rp->obsFile, glonass_gnav_ephemeris_iter->second, d_rx_time, signal); - rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); b_rinex_header_written = true; // do not write header anymore } } @@ -874,7 +876,13 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite { std::string glo_signal("1G"); rp->rinex_obs_header(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); - rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + if(d_rinex_version == 3) + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + if(d_rinex_version == 2) + { + rp->rinex_nav_header(rp->navFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model); + rp->rinex_nav_header(rp->navGloFile, d_ls_pvt->glonass_gnav_utc_model, glonass_gnav_ephemeris_iter->second); + } b_rinex_header_written = true; // do not write header anymore } } @@ -889,6 +897,16 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite b_rinex_header_written = true; // do not write header anymore } } + if(type_of_rx == 28) // GPS L2C + GLONASS L1 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.cend()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.cend()) ) + { + std::string glo_signal("1G"); + rp->rinex_obs_header(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, glo_signal); + rp->rinex_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + 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 { @@ -924,12 +942,23 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite } if(type_of_rx == 26) // GPS L1 C/A + GLONASS L1 C/A { - rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + if(d_rinex_version == 3) + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + if(d_rinex_version == 2) + { + rp->log_rinex_nav(rp->navFile, d_ls_pvt->gps_ephemeris_map); + rp->log_rinex_nav(rp->navGloFile, d_ls_pvt->glonass_gnav_ephemeris_map); + } + } if(type_of_rx == 27) // Galileo E1B + GLONASS L1 C/A { rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->galileo_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); } + if(type_of_rx == 28) // GPS L2C + GLONASS L1 C/A + { + rp->log_rinex_nav(rp->navMixFile, d_ls_pvt->gps_cnav_ephemeris_map, d_ls_pvt->glonass_gnav_ephemeris_map); + } } galileo_ephemeris_iter = d_ls_pvt->galileo_ephemeris_map.cbegin(); gps_ephemeris_iter = d_ls_pvt->gps_ephemeris_map.cbegin(); @@ -1099,7 +1128,7 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite { if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (gps_ephemeris_iter != d_ls_pvt->gps_ephemeris_map.end()) ) { - rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); } if (!b_rinex_header_updated && (d_ls_pvt->gps_utc_model.d_A0 != 0)) { @@ -1122,6 +1151,19 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite b_rinex_header_updated = true; // do not write header anymore } } + if(type_of_rx == 28) // GPS L2C + GLONASS L1 C/A + { + if ((glonass_gnav_ephemeris_iter != d_ls_pvt->glonass_gnav_ephemeris_map.end()) && (gps_cnav_ephemeris_iter != d_ls_pvt->gps_cnav_ephemeris_map.end()) ) + { + rp->log_rinex_obs(rp->obsFile, gps_cnav_ephemeris_iter->second, glonass_gnav_ephemeris_iter->second, d_rx_time, gnss_observables_map); + } + if (!b_rinex_header_updated && (d_ls_pvt->gps_cnav_utc_model.d_A0 != 0)) + { + rp->update_obs_header(rp->obsFile, d_ls_pvt->gps_cnav_utc_model); + rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_cnav_iono, d_ls_pvt->gps_cnav_utc_model, d_ls_pvt->glonass_gnav_utc_model, d_ls_pvt->glonass_gnav_almanac); + b_rinex_header_updated = true; // do not write header anymore + } + } } } diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h index a46d26180..7e71b21a0 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.h @@ -98,6 +98,7 @@ private: bool d_dump; bool b_rinex_header_written; bool b_rinex_header_updated; + double d_rinex_version; bool b_rtcm_writing_started; int d_rtcm_MT1045_rate_ms; //!< Galileo Broadcast Ephemeris int d_rtcm_MT1019_rate_ms; //!< GPS Broadcast Ephemeris (orbits) diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 555ccc728..4a53b2525 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -143,6 +143,7 @@ Rinex_Printer::Rinex_Printer(int conf_version) observationType["DOPPLER_v2"] = "D"; observationType["SIGNAL_STRENGTH_v2"] = "S"; observationCode["GPS_L1_CA_v2"] = "1"; + observationCode["GLONASS_G1_CA_v2"] = "1"; if ( FLAGS_RINEX_version.compare("3.01") == 0 ) { @@ -415,9 +416,8 @@ std::string Rinex_Printer::getLocalTime() } -void Rinex_Printer::rinex_nav_header(std::fstream& out, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Ephemeris& glonass_gnav_eph) { - if(glonass_gnav_almanac.i_satellite_freq_channel){} std::string line; // -------- Line 1 @@ -464,44 +464,53 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Glonass_Gnav_Utc_M out << line << std::endl; // -------- Line system time correction - line.clear(); - line += std::string("GLUT"); - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 17); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); - line += std::string(10, ' '); - line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + if (version == 3) + { + line.clear(); + line += std::string("GLUT"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; - // -------- Line system time correction 2 - line.clear(); - line += std::string("GLGP"); - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 17); - line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); - line += std::string(10, ' '); - line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + // -------- Line system time correction 2 + line.clear(); + line += std::string("GLGP"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + if (version == 2) + { + // Set reference time and its clock corrections + boost::posix_time::ptime p_utc_ref_time = glonass_gnav_eph.glot_to_utc(glonass_gnav_eph.d_t_b, 0.0); + std::string timestring = boost::posix_time::to_iso_string(p_utc_ref_time); + std::string year (timestring, 0, 4); + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); - - // -------- Line 6 leap seconds - // For leap second information, see http://www.endruntechnologies.com/leap.htm - line.clear(); - // TODO hOW TO MAKE THIS IN GLONASS, the leap second is internally given - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 6); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 6); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 6); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 6); - line += std::string(36, ' '); - line += Rinex_Printer::leftJustify("LEAP SECONDS", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + line.clear(); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += std::string(3, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 19); + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("CORR TO SYSTEM TIME", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } // -------- End of Header line.clear(); @@ -511,7 +520,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Glonass_Gnav_Utc_M out << line << std::endl; } - void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning @@ -634,6 +642,127 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono out << line << std::endl; } +void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps_iono, const Gps_CNAV_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +{ + if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning + std::string line; + stringVersion = "3.02"; + version = 3; + + // -------- Line 1 + line = std::string(5, ' '); + line += stringVersion; + line += std::string(11, ' '); + line += std::string("N: GNSS NAV DATA"); + line += std::string(4, ' '); + line += std::string("M: MIXED"); + line += std::string(12, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("GNSS NAVIGATION MESSAGE FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See http://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line ionospheric info 1 + line.clear(); + line += std::string("GPSA"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha0, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha1, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha2, 10, 2), 12); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha3, 10, 2), 12); + line += std::string(7, ' '); + line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 1 + line.clear(); + line += std::string("GLUT"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 2 + line.clear(); + line += std::string("GLGP"); + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 17); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line system time correction 3 + line.clear(); + line += std::string("GPUT"); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A0, 16, 2), 18); + line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A1, 15, 2), 16); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_t_OT), 7); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_T + 1024), 5); // valid until 2019 + line += std::string(10, ' '); + line += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + + // -------- Line 6 leap seconds + // For leap second information, see http://www.endruntechnologies.com/leap.htm + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LS), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LSF), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_LSF), 6); + line += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_DN), 6); + line += std::string(36, ' '); + line += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- End of Header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { @@ -745,7 +874,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& gali out << line << std::endl; } - void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) { std::string line; @@ -854,7 +982,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono out << line << std::endl; } - void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono & iono, const Gps_CNAV_Utc_Model & utc_model) { std::string line; @@ -970,7 +1097,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_CNAV_Iono & io out << line << std::endl; } - void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, const Gps_Utc_Model& utc_model) { std::string line; @@ -1149,7 +1275,6 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co out << line << std::endl; } - void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac) { std::string line; @@ -1464,7 +1589,6 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Glonass_Gnav_Utc_ std::cout << "The RINEX Navigation file header has been updated with UTC info." << std::endl; } - void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac) { std::vector data; @@ -1560,7 +1684,6 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; } - void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Utc_Model& utc_model, const Gps_Iono& iono) { std::vector data; @@ -2045,6 +2168,112 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_ion } +void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_CNAV_Iono& gps_iono, const Gps_CNAV_Utc_Model& gps_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) +{ + if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning + std::vector data; + std::string line_aux; + + long pos = out.tellp(); + out.seekp(0); + data.clear(); + + bool no_more_finds = false; + std::string line_str; + + while(!out.eof()) + { + std::getline(out, line_str); + + if(!no_more_finds) + { + line_aux.clear(); + + if (line_str.find("GPSA", 0) != std::string::npos) + { + line_aux += std::string("GPSA"); + line_aux += std::string(1, ' '); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha0, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha1, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha2, 10, 2), 12); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha3, 10, 2), 12); + line_aux += std::string(7, ' '); + line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GPUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GPUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A0, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A1, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_t_OT), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_T + 1024), 5); // valid until 2019 + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GLUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GLUT"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_c, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if ((line_str.find("GLGP", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos)) + { + line_aux += std::string("GLGP"); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(glonass_gnav_utc_model.d_tau_gps, 16, 2), 18); + line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(0.0, 15, 2), 16); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 7); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(0.0), 5); + line_aux += std::string(10, ' '); + line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20); + data.push_back(line_aux); + } + else if (line_str.find("LEAP SECONDS", 59) != std::string::npos) + { + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LS), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.d_DeltaT_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_WN_LSF), 6); + line_aux += Rinex_Printer::rightJustify(boost::lexical_cast(gps_utc_model.i_DN), 6); + line_aux += std::string(36, ' '); + line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20); + data.push_back(line_aux); + } + else if (line_str.find("END OF HEADER", 59) != std::string::npos) + { + data.push_back(line_str); + no_more_finds = true; + } + else + { + data.push_back(line_str); + } + + } + else + { + data.push_back(line_str); + } + } + + out.close(); + out.open(navMixfilename, std::ios::out | std::ios::trunc); + out.seekp(0); + for (int i = 0; i < (int) data.size() - 1; i++) + { + out << data[i] << std::endl; + } + out.close(); + out.open(navMixfilename, std::ios::out | std::ios::app); + out.seekp(pos); + std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl; +} + void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac) { if(glonass_gnav_almanac.i_satellite_freq_channel){} //Avoid compiler warning @@ -2144,6 +2373,7 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal } + void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& eph_map) { std::string line; @@ -2827,7 +3057,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::mapsecond, glonass_gnav_ephemeris_iter->second.d_t_k); + boost::posix_time::ptime p_utc_time = glonass_gnav_ephemeris_iter->second.glot_to_utc(glonass_gnav_ephemeris_iter->second.d_t_b, 0.0); std::string timestring = boost::posix_time::to_iso_string(p_utc_time); std::string month (timestring, 4, 2); std::string day (timestring, 6, 2); @@ -3017,7 +3247,6 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& galileo_eph_map) { version = 3; @@ -3029,12 +3258,15 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map) { - version = 3; - stringVersion = "3.02"; Rinex_Printer::log_rinex_nav(out, gps_eph_map); Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map); } +void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& gps_eph_map, const std::map& glonass_gnav_eph_map) +{ + Rinex_Printer::log_rinex_nav(out, gps_eph_map); + Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map); +} void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map& galileo_eph_map, const std::map& glonass_gnav_eph_map) { @@ -3045,6 +3277,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map(0), 3); - line += std::string(1, ' '); + // -------- GLONASS SLOT / FRQ # (On;y version 3) + if (version == 3) + { + // -------- GLONASS SLOT / FRQ # + // TODO Need to provide system with list of all satellites and update this accordingly + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 3); // Number of satellites in list + line += std::string(1, ' '); + line += satelliteSystem["GLONASS"]; + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Slot Number + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Frequency Number + line += std::string(1, ' '); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; - // TODO Add this here, we need to know all satellites in system to get this done - line += satelliteSystem["GLONASS"]; - line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Slot Number - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Frequency Number - line += std::string(1, ' '); - line += std::string(60-line.size(), ' '); - line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; - - // -------- GLONASS CODE/PHS/BIS - // TODO This needs more study, not really suer on what those values are. Setting it to zero to advance in code. - line.clear(); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G1_CA"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G1_P"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G2_CA"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G2_P"]; - line += std::string(1, ' '); - line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); - line += std::string(60-line.size(), ' '); - line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + // -------- GLONASS CODE/PHS/BIS + // No GLONASS Phase bias correction used to align code and phase observations. + line.clear(); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } // -------- END OF HEADER line.clear(); @@ -3375,11 +3598,10 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps { if(glonass_gnav_eph.d_m){} // avoid warning, not needed std::string line; - version = 3; // -------- Line 1 line = std::string(5, ' '); - line += "3.02"; + line += stringVersion; line += std::string(11, ' '); line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); line += satelliteSystem["Mixed"]; @@ -3405,7 +3627,345 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps // -------- Line COMMENT line.clear(); - line += Rinex_Printer::leftJustify("MIXED (GPS/GLONASS) OBSERVATION DATA FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("MIXED (GPS/GLO) OBSERVATION DATA FILE GENERATED BY GNSS-SDR", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + std::string gnss_sdr_version(GNSS_SDR_VERSION); + line += "GNSS-SDR VERSION "; + line += Rinex_Printer::leftJustify(gnss_sdr_version, 43); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("See http://gnss-sdr.org", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER NAME + line.clear(); + line += Rinex_Printer::leftJustify("DEFAULT MARKER NAME", 60); // put a flag or a property, + line += Rinex_Printer::leftJustify("MARKER NAME", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line MARKER TYPE + line.clear(); + line += Rinex_Printer::leftJustify("NON_GEODETIC", 20); // put a flag or a property + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("MARKER TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line OBSERVER / AGENCY + line.clear(); + std::string username; + char c_username[20] = {0}; + int nGet = getlogin_r(c_username, sizeof(c_username) - 1); + if (nGet == 0) + { + username = c_username; + } + else + { + username = "UNKNOWN USER"; + } + line += leftJustify(username, 20); + line += Rinex_Printer::leftJustify("CTTC", 40); // add flag and property + line += Rinex_Printer::leftJustify("OBSERVER / AGENCY", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line REC / TYPE VERS + line.clear(); + line += Rinex_Printer::leftJustify("GNSS-SDR", 20); // add flag and property + line += Rinex_Printer::leftJustify("Software Receiver", 20); // add flag and property + //line += Rinex_Printer::leftJustify(google::VersionString(), 20); // add flag and property + if(gnss_sdr_version.length() > 20) gnss_sdr_version.resize(9, ' '); + line += Rinex_Printer::leftJustify(gnss_sdr_version, 20); + line += Rinex_Printer::leftJustify("REC # / TYPE / VERS", 20); + lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA TYPE + line.clear(); + line += Rinex_Printer::leftJustify("Antenna number", 20); // add flag and property + line += Rinex_Printer::leftJustify("Antenna type", 20); // add flag and property + line += std::string(20, ' '); + line += Rinex_Printer::leftJustify("ANT # / TYPE", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- APPROX POSITION (optional for moving platforms) + // put here real data! + double antena_x = 0.0; + double antena_y = 0.0; + double antena_z = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_x, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_y, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_z, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("APPROX POSITION XYZ", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- ANTENNA: DELTA H/E/N + // put here real data! + double antena_h = 0.0; + double antena_e = 0.0; + double antena_n = 0.0; + line.clear(); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_h, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_e, 4), 14); + line += Rinex_Printer::rightJustify(Rinex_Printer::asString(antena_n, 4), 14); + line += std::string(18, ' '); + line += Rinex_Printer::leftJustify("ANTENNA: DELTA H/E/N", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- SYS / OBS TYPES + if(version == 3) + { + // one line per available system + line.clear(); + line += satelliteSystem["GPS"]; + line += std::string(2, ' '); + std::stringstream strm; + numberTypesObservations = 4; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 3); + // per type of observation + // GPS L1 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L1_CA"]; + // GPS DOPPLER L1 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L1_CA"]; + // GPS L1 CA SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L1_CA"]; + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // Find GLONASS Signal in Mixed file + unsigned int number_of_observations_glo = 0; + std::string signal_("1G"); + std::size_t found_1G = glonass_bands.find(signal_); + if(found_1G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + signal_ = "2G"; + std::size_t found_2G = glonass_bands.find(signal_); + if(found_2G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + line.clear(); + line += satelliteSystem["GLONASS"]; + line += std::string(2, ' '); + line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_glo), 3); + if(found_1G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G1_CA"]; + } + if(found_2G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G2_CA"]; + } + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + if(version == 2) + { + // -------- SYS / OBS TYPES + line.clear(); + std::stringstream strm; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 6); + // per type of observation + // GLONASS L1 C/A PSEUDORANGE + line += Rinex_Printer::rightJustify(observationType["PSEUDORANGE_CA_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + // GLONASS L1 PHASE + line += Rinex_Printer::rightJustify(observationType["CARRIER_PHASE_CA_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + // GLONASS DOPPLER L1 + line += Rinex_Printer::rightJustify(observationType["DOPPLER_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + // GLONASS L1 SIGNAL STRENGTH + line += Rinex_Printer::rightJustify(observationType["SIGNAL_STRENGTH_v2"], 5); + line += observationCode["GLONASS_G1_CA_v2"]; + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("# / TYPES OF OBSERV", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- Signal Strength units (only version 3) + if(version == 3) + { + line.clear(); + line += Rinex_Printer::leftJustify("DBHZ", 20); + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- TIME OF FIRST OBS + line.clear(); + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, d_TOW_first_observation); + std::string timestring=boost::posix_time::to_iso_string(p_gps_time); + std::string year (timestring, 0, 4); + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + std::string hour (timestring, 9, 2); + std::string minutes (timestring, 11, 2); + double gps_t = d_TOW_first_observation; + double seconds = fmod(gps_t, 60); + line += Rinex_Printer::rightJustify(year, 6); + line += Rinex_Printer::rightJustify(month, 6); + line += Rinex_Printer::rightJustify(day, 6); + line += Rinex_Printer::rightJustify(hour, 6); + line += Rinex_Printer::rightJustify(minutes, 6); + line += Rinex_Printer::rightJustify(asString(seconds, 7), 13); + line += Rinex_Printer::rightJustify(std::string("GPS"), 8); + line += std::string(9, ' '); + line += Rinex_Printer::leftJustify("TIME OF FIRST OBS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- GLONASS SLOT / FRQ # (On;y version 3) + if (version == 3) + { + // -------- GLONASS SLOT / FRQ # + // TODO Need to provide system with list of all satellites and update this accordingly + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 3); // Number of satellites in list + line += std::string(1, ' '); + line += satelliteSystem["GLONASS"]; + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Slot Number + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Frequency Number + line += std::string(1, ' '); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- GLONASS CODE/PHS/BIS + // No GLONASS Phase bias correction used to align code and phase observations. + line.clear(); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + } + + // -------- end of header + line.clear(); + line += std::string(60, ' '); + line += Rinex_Printer::leftJustify("END OF HEADER", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; +} + + +void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_CNAV_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double d_TOW_first_observation, const std::string glonass_bands) +{ + if(glonass_gnav_eph.d_m){} // avoid warning, not needed + std::string line; + + // -------- Line 1 + line = std::string(5, ' '); + line += stringVersion; + line += std::string(11, ' '); + line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20); + line += satelliteSystem["Mixed"]; + line += std::string(19, ' '); + line += std::string("RINEX VERSION / TYPE"); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 2 + line.clear(); + line += Rinex_Printer::leftJustify("G = GPS R = GLONASS E = GALILEO S = GEO M = MIXED", 60); + line += Rinex_Printer::leftJustify("COMMENT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line 3 + line.clear(); + line += Rinex_Printer::getLocalTime(); + line += std::string("PGM / RUN BY / DATE"); + line += std::string(1, ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Line COMMENT + line.clear(); + line += Rinex_Printer::leftJustify("MIXED (GPS/GLO) OBSERVATION DATA FILE GENERATED BY GNSS-SDR", 60); line += Rinex_Printer::leftJustify("COMMENT", 20); Rinex_Printer::lengthCheck(line); out << line << std::endl; @@ -3510,99 +4070,96 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps // -------- SYS / OBS TYPES // one line per available system + line.clear(); + line += satelliteSystem["GPS"]; + line += std::string(2, ' '); + std::stringstream strm; + numberTypesObservations = 4; + strm << numberTypesObservations; + line += Rinex_Printer::rightJustify(strm.str(), 3); + // per type of observation + // GPS L1 PSEUDORANGE + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L1 PHASE + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS DOPPLER L1 + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GPS_L2_L2CM"]; + // GPS L1 CA SIGNAL STRENGTH + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GPS_L2_L2CM"]; + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // Find GLONASS Signal in Mixed file + unsigned int number_of_observations_glo = 0; + std::string signal_("1G"); + std::size_t found_1G = glonass_bands.find(signal_); + if(found_1G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + signal_ = "2G"; + std::size_t found_2G = glonass_bands.find(signal_); + if(found_2G != std::string::npos) + { + number_of_observations_glo = number_of_observations_glo + 4; + } + line.clear(); + line += satelliteSystem["GLONASS"]; + line += std::string(2, ' '); + line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_glo), 3); + if(found_1G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G1_CA"]; + } + if(found_2G != std::string::npos) + { + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["CARRIER_PHASE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["DOPPLER"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += observationType["SIGNAL_STRENGTH"]; + line += observationCode["GLONASS_G2_CA"]; + } + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- Signal Strength units (only version 3) line.clear(); - line += satelliteSystem["GPS"]; - line += std::string(2, ' '); - std::stringstream strm; - numberTypesObservations = 4; - strm << numberTypesObservations; - line += Rinex_Printer::rightJustify(strm.str(), 3); - // per type of observation - // GPS L1 PSEUDORANGE - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GPS_L1_CA"]; - // GPS L1 PHASE - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GPS_L1_CA"]; - // GPS DOPPLER L1 - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GPS_L1_CA"]; - // GPS L1 CA SIGNAL STRENGTH - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GPS_L1_CA"]; - line += std::string(60-line.size(), ' '); - line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + line += Rinex_Printer::leftJustify("DBHZ", 20); + line += std::string(40, ' '); + line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; - // Find GLONASS Signal in Mixed file - unsigned int number_of_observations_glo = 0; - std::string signal_("1G"); - std::size_t found_1C = glonass_bands.find(signal_); - if(found_1C != std::string::npos) - { - number_of_observations_glo = number_of_observations_glo + 4; - } - signal_ = "2G"; - std::size_t found_2C = glonass_bands.find(signal_); - if(found_2C != std::string::npos) - { - number_of_observations_glo = number_of_observations_glo + 4; - } - - line.clear(); - line += satelliteSystem["GLONASS"]; - line += std::string(2, ' '); - line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_glo), 3); - - if(found_1C != std::string::npos) - { - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G1_CA"]; - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GLONASS_G1_CA"]; - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GLONASS_G1_CA"]; - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GLONASS_G1_CA"]; - } - - if(found_2C != std::string::npos) - { - line += std::string(1, ' '); - line += observationType["PSEUDORANGE"]; - line += observationCode["GLONASS_G2_CA"]; - line += std::string(1, ' '); - line += observationType["CARRIER_PHASE"]; - line += observationCode["GLONASS_G2_CA"]; - line += std::string(1, ' '); - line += observationType["DOPPLER"]; - line += observationCode["GLONASS_G2_CA"]; - line += std::string(1, ' '); - line += observationType["SIGNAL_STRENGTH"]; - line += observationCode["GLONASS_G2_CA"]; - } - - line += std::string(60-line.size(), ' '); - line += Rinex_Printer::leftJustify("SYS / # / OBS TYPES", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; - - // -------- Signal Strength units - line.clear(); - line += Rinex_Printer::leftJustify("DBHZ", 20); - line += std::string(40, ' '); - line += Rinex_Printer::leftJustify("SIGNAL STRENGTH UNIT", 20); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; // -------- TIME OF FIRST OBS line.clear(); @@ -3627,6 +4184,50 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps Rinex_Printer::lengthCheck(line); out << line << std::endl; + // -------- GLONASS SLOT / FRQ # + // TODO Need to provide system with list of all satellites and update this accordingly + line.clear(); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 3); // Number of satellites in list + line += std::string(1, ' '); + line += satelliteSystem["GLONASS"]; + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Slot Number + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(boost::lexical_cast(0), 2); // Frequency Number + line += std::string(1, ' '); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- GLONASS CODE/PHS/BIS + // No GLONASS Phase bias correction used to align code and phase observations. + line.clear(); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G1_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_CA"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(1, ' '); + line += observationType["PSEUDORANGE"]; + line += observationCode["GLONASS_G2_P"]; + line += std::string(1, ' '); + line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); + line += std::string(60-line.size(), ' '); + line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- end of header line.clear(); line += std::string(60, ' '); @@ -3635,7 +4236,6 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps out << line << std::endl; } - void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double d_TOW_first_observation, const std::string galileo_bands, const std::string glonass_bands) { if(glonass_gnav_eph.d_m){} // avoid warning, not needed @@ -3858,14 +4458,14 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& line.clear(); unsigned int number_of_observations_glo = 0; signal_ = "1G"; - std::size_t found_1C = glonass_bands.find(signal_); - if(found_1C != std::string::npos) + std::size_t found_1G = glonass_bands.find(signal_); + if(found_1G != std::string::npos) { number_of_observations_glo = number_of_observations_glo + 4; } signal_ = "2G"; - std::size_t found_2C = glonass_bands.find(signal_); - if(found_2C != std::string::npos) + std::size_t found_2G = glonass_bands.find(signal_); + if(found_2G != std::string::npos) { number_of_observations_glo = number_of_observations_glo + 4; } @@ -3874,7 +4474,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& line += std::string(2, ' '); line += Rinex_Printer::rightJustify(std::to_string(number_of_observations_glo), 3); - if(found_1C != std::string::npos) + if(found_1G != std::string::npos) { line += std::string(1, ' '); line += observationType["PSEUDORANGE"]; @@ -3890,7 +4490,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Galileo_Ephemeris& line += observationCode["GLONASS_L1_CA"]; } - if(found_2C != std::string::npos) + if(found_2G != std::string::npos) { line += std::string(1, ' '); line += observationType["PSEUDORANGE"]; @@ -4211,7 +4811,6 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& eph out << line << std::endl; } - void Rinex_Printer::rinex_obs_header(std::fstream & out, const Gps_CNAV_Ephemeris & eph, const double d_TOW_first_observation) { std::string line; @@ -5197,6 +5796,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps } + void Rinex_Printer::update_obs_header(std::fstream& out, const Glonass_Gnav_Utc_Model& utc_model) { if(utc_model.d_N_4) @@ -5408,6 +6008,7 @@ void Rinex_Printer::update_obs_header(std::fstream& out, const Galileo_Utc_Model } + void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, const double obs_time, const std::map& observables, const std::string glonass_band) { // RINEX observations timestamps are GPS timestamps. @@ -5416,7 +6017,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri // Avoid compiler warning if(glonass_band.size()){} - boost::posix_time::ptime p_glonass_time = Rinex_Printer::compute_GLONASS_time(eph, obs_time); + boost::posix_time::ptime p_glonass_time = Rinex_Printer::compute_UTC_time(eph, obs_time); std::string timestring = boost::posix_time::to_iso_string(p_glonass_time); //double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); //double gps_t = eph.sv_clock_correction(obs_time); @@ -5499,7 +6100,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri std::string lineObs; lineObs.clear(); line.clear(); - // GPS L1 PSEUDORANGE + // GLONASS L1 PSEUDORANGE line += std::string(2, ' '); lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); @@ -5517,8 +6118,8 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri // Signal Strength Indicator (SSI) int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // GPS L1 CA PHASE - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GPS_TWO_PI, 3), 14); + // GLONASS L1 CA PHASE + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GLONASS_TWO_PI, 3), 14); if (lli == 0) { lineObs += std::string(1, ' '); @@ -5528,7 +6129,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // GPS L1 CA DOPPLER + // GLONASS L1 CA DOPPLER lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); if (lli == 0) { @@ -5539,7 +6140,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); } lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - //GPS L1 SIGNAL STRENGTH + //GLONASS L1 SIGNAL STRENGTH lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); out << lineObs << std::endl; @@ -5653,14 +6254,329 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeri } - - - void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double gps_obs_time, const std::map& observables) { if(glonass_gnav_eph.d_m){} // avoid warning, not needed std::string line; + // -------- EPOCH record + boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, gps_obs_time); + std::string timestring = boost::posix_time::to_iso_string(p_gps_time); + //double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); + //double gps_t = eph.sv_clock_correction(obs_time); + double gps_t = gps_obs_time; + + std::string month (timestring, 4, 2); + std::string day (timestring, 6, 2); + std::string hour (timestring, 9, 2); + std::string minutes (timestring, 11, 2); + + if (version == 2) + { + line.clear(); + std::string year (timestring, 2, 2); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + if (month.compare(0, 1 , "0") == 0) + { + line += std::string(1, ' '); + line += month.substr(1, 1); + } + else + { + line += month; + } + line += std::string(1, ' '); + if (day.compare(0, 1 , "0") == 0) + { + line += std::string(1, ' '); + line += day.substr(1, 1); + } + else + { + line += day; + } + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + line += std::string(1, ' '); + double second_ = fmod(gps_t, 60); + if (second_ < 10) + { + line += std::string(1, ' '); + } + line += Rinex_Printer::asString(second_, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + } + if (version == 3) + { + std::string year (timestring, 0, 4); + line += std::string(1, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; + + line += std::string(1, ' '); + double seconds = fmod(gps_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line +=std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); + + } + //Number of satellites observed in current epoch + //Get maps with observations + std::map observablesG1C; + std::map observablesR1C; + std::map observablesR2C; + std::map::const_iterator observables_iter; + + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) + { + observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) + { + observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) + { + observablesG1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } + + std::multimap total_glo_map; + std::set available_glo_prns; + std::set::iterator it; + for(observables_iter = observablesR1C.begin(); + observables_iter != observablesR1C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } + + for(observables_iter = observablesR2C.begin(); + observables_iter != observablesR2C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } + + int numGloSatellitesObserved = available_glo_prns.size(); + int numGpsSatellitesObserved = observablesG1C.size(); + int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + if(version == 2) + { + // Add list of GPS satellites + for(observables_iter = observablesG1C.begin(); + observables_iter != observablesG1C.end(); + observables_iter++) + { + line += satelliteSystem["GPS"]; + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + // Add list of GLONASS L1 satellites + for(observables_iter = observablesR1C.begin(); + observables_iter != observablesR1C.end(); + observables_iter++) + { + line += satelliteSystem["GLONASS"]; + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + // Add list of GLONASS L2 satellites + for(observables_iter = observablesR2C.begin(); + observables_iter != observablesR2C.end(); + observables_iter++) + { + line += satelliteSystem["GLONASS"]; + if (static_cast(observables_iter->second.PRN) < 10) line += std::string(1, '0'); + line += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + } + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; + + // -------- OBSERVATION record + std::string s; + std::string lineObs; + for(observables_iter = observablesG1C.begin(); + observables_iter != observablesG1C.end(); + observables_iter++) + { + lineObs.clear(); + + s.assign(1, observables_iter->second.System); + if(version == 3) + { + // Specify system only if in version 3 + if(s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; + if(s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); + } + + // Pseudorange Measurements + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } + + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // PHASE + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GPS_TWO_PI, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); + + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } + + std::pair ::iterator, std::multimap::iterator> ret; + for(it = available_glo_prns.begin(); + it != available_glo_prns.end(); + it++) + { + lineObs.clear(); + if(version == 3) + { + lineObs += satelliteSystem["GLONASS"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); + } + ret = total_glo_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + /// \todo Need to account for pseudorange correction for glonass + double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } + + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } + +} + + +void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_CNAV_Ephemeris& gps_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double gps_obs_time, const std::map& observables) +{ + if(glonass_gnav_eph.d_m){} // avoid warning, not needed + std::string line; + + // -------- EPOCH record boost::posix_time::ptime p_gps_time = Rinex_Printer::compute_GPS_time(gps_eph, gps_obs_time); std::string timestring = boost::posix_time::to_iso_string(p_gps_time); //double utc_t = nav_msg.utc_time(nav_msg.sv_clock_correction(obs_time)); @@ -5673,223 +6589,228 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep std::string minutes (timestring, 11, 2); std::string year (timestring, 0, 4); - line += std::string(1, '>'); - line += std::string(1, ' '); - line += year; - line += std::string(1, ' '); - line += month; - line += std::string(1, ' '); - line += day; - line += std::string(1, ' '); - line += hour; - line += std::string(1, ' '); - line += minutes; + line += std::string(1, '>'); + line += std::string(1, ' '); + line += year; + line += std::string(1, ' '); + line += month; + line += std::string(1, ' '); + line += day; + line += std::string(1, ' '); + line += hour; + line += std::string(1, ' '); + line += minutes; - line += std::string(1, ' '); - double seconds = fmod(gps_t, 60); - // Add extra 0 if seconds are < 10 - if (seconds < 10) - { - line +=std::string(1, '0'); - } - line += Rinex_Printer::asString(seconds, 7); - line += std::string(2, ' '); - // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event - line += std::string(1, '0'); + line += std::string(1, ' '); + double seconds = fmod(gps_t, 60); + // Add extra 0 if seconds are < 10 + if (seconds < 10) + { + line +=std::string(1, '0'); + } + line += Rinex_Printer::asString(seconds, 7); + line += std::string(2, ' '); + // Epoch flag 0: OK 1: power failure between previous and current epoch <1: Special event + line += std::string(1, '0'); - //Number of satellites observed in current epoch - //Get maps with observations - std::map observablesG1C; - std::map observablesR1C; - std::map observablesR2C; - std::map::const_iterator observables_iter; + //Number of satellites observed in current epoch + //Get maps with observations + std::map observablesG2S; + std::map observablesR1C; + std::map observablesR2C; + std::map::const_iterator observables_iter; - for(observables_iter = observables.begin(); - observables_iter != observables.end(); - observables_iter++) - { - std::string system_(&observables_iter->second.System, 1); - std::string sig_(observables_iter->second.Signal); - if((system_.compare("R") == 0) && (sig_.compare("1C") == 0)) - { - observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); - } - if((system_.compare("R") == 0) && (sig_.compare("1C") == 0)) - { - observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); - } - if((system_.compare("G") == 0) && (sig_.compare("1C") == 0)) - { - observablesG1C.insert(std::pair(observables_iter->first, observables_iter->second)); - } - } + for(observables_iter = observables.begin(); + observables_iter != observables.end(); + observables_iter++) + { + std::string system_(&observables_iter->second.System, 1); + std::string sig_(observables_iter->second.Signal); + if((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) + { + observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) + { + observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); + } + if((system_.compare("G") == 0) && (sig_.compare("2S") == 0)) + { + observablesG2S.insert(std::pair(observables_iter->first, observables_iter->second)); + } + } - std::multimap total_glo_map; - std::set available_glo_prns; - std::set::iterator it; - for(observables_iter = observablesR1C.begin(); - observables_iter != observablesR1C.end(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); - it = available_glo_prns.find(prn_); - if(it == available_glo_prns.end()) - { - available_glo_prns.insert(prn_); - } - } + std::multimap total_glo_map; + std::set available_glo_prns; + std::set::iterator it; + for(observables_iter = observablesR1C.begin(); + observables_iter != observablesR1C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } - for(observables_iter = observablesR2C.begin(); - observables_iter != observablesR2C.end(); - observables_iter++) - { - unsigned int prn_ = observables_iter->second.PRN; - total_glo_map.insert(std::pair(prn_, observables_iter->second)); - it = available_glo_prns.find(prn_); - if(it == available_glo_prns.end()) - { - available_glo_prns.insert(prn_); - } - } + for(observables_iter = observablesR2C.begin(); + observables_iter != observablesR2C.end(); + observables_iter++) + { + unsigned int prn_ = observables_iter->second.PRN; + total_glo_map.insert(std::pair(prn_, observables_iter->second)); + it = available_glo_prns.find(prn_); + if(it == available_glo_prns.end()) + { + available_glo_prns.insert(prn_); + } + } - int numGloSatellitesObserved = available_glo_prns.size(); - int numGpsSatellitesObserved = observablesG1C.size(); - int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; - line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); + int numGloSatellitesObserved = available_glo_prns.size(); + int numGpsSatellitesObserved = observablesG2S.size(); + int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved; + line += Rinex_Printer::rightJustify(boost::lexical_cast(numSatellitesObserved), 3); - // Receiver clock offset (optional) - //line += rightJustify(asString(clockOffset, 12), 15); + line += std::string(80 - line.size(), ' '); + Rinex_Printer::lengthCheck(line); + out << line << std::endl; - line += std::string(80 - line.size(), ' '); - Rinex_Printer::lengthCheck(line); - out << line << std::endl; + // -------- OBSERVATION record + std::string s; + std::string lineObs; + for(observables_iter = observablesG2S.begin(); + observables_iter != observablesG2S.end(); + observables_iter++) + { + lineObs.clear(); - std::string s; - std::string lineObs; - for(observables_iter = observablesG1C.begin(); - observables_iter != observablesG1C.end(); - observables_iter++) - { - lineObs.clear(); + s.assign(1, observables_iter->second.System); + // Specify system only if in version 3 + if(s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; + if(s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen + if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); - s.assign(1, observables_iter->second.System); - if(s.compare("G") == 0) lineObs += satelliteSystem["GPS"]; - if(s.compare("R") == 0) lineObs += satelliteSystem["GLONASS"]; // should not happen - if (static_cast(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(observables_iter->second.PRN)); - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); - //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + // Pseudorange Measurements + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Pseudorange_m, 3), 14); - // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } - // PHASE - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GPS_TWO_PI, 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // DOPPLER - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // PHASE + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_phase_rads/GPS_TWO_PI, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // SIGNAL STRENGTH - lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); + // DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); - out << lineObs << std::endl; - } + // SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(observables_iter->second.CN0_dB_hz, 3), 14); - std::pair ::iterator, std::multimap::iterator> ret; - for(it = available_glo_prns.begin(); - it != available_glo_prns.end(); - it++) - { - lineObs.clear(); - lineObs += satelliteSystem["GLONASS"]; - if (static_cast(*it) < 10) lineObs += std::string(1, '0'); - lineObs += boost::lexical_cast(static_cast(*it)); - ret = total_glo_map.equal_range(*it); - for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) - { - lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } - //Loss of lock indicator (LLI) - int lli = 0; // Include in the observation!! - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } + std::pair ::iterator, std::multimap::iterator> ret; + for(it = available_glo_prns.begin(); + it != available_glo_prns.end(); + it++) + { + lineObs.clear(); + lineObs += satelliteSystem["GLONASS"]; + if (static_cast(*it) < 10) lineObs += std::string(1, '0'); + lineObs += boost::lexical_cast(static_cast(*it)); - // Signal Strength Indicator (SSI) - int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + ret = total_glo_map.equal_range(*it); + for (std::multimap::iterator iter = ret.first; iter != ret.second; ++iter) + { + /// \todo Need to account for pseudorange correction for glonass + double leap_seconds = Rinex_Printer::get_leap_second(glonass_gnav_eph, gps_obs_time); + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14); - // GLONASS CARRIER PHASE - lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GALILEO_TWO_PI), 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + //Loss of lock indicator (LLI) + int lli = 0; // Include in the observation!! + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } - // GLONASS DOPPLER - lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); - if (lli == 0) - { - lineObs += std::string(1, ' '); - } - else - { - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); - } - lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + // Signal Strength Indicator (SSI) + int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz); + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); - // GLONASS SIGNAL STRENGTH - lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); - } + // GLONASS CARRIER PHASE + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (GLONASS_TWO_PI), 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS DOPPLER + lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14); + if (lli == 0) + { + lineObs += std::string(1, ' '); + } + else + { + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(lli), 1); + } + lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString(ssi), 1); + + // GLONASS SIGNAL STRENGTH + lineObs += Rinex_Printer::rightJustify(asString(iter->second.CN0_dB_hz, 3), 14); + } + + if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); + out << lineObs << std::endl; + } - if (lineObs.size() < 80) lineObs += std::string(80 - lineObs.size(), ' '); - out << lineObs << std::endl; - } } - void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double galileo_obs_time, const std::map& observables) { if(glonass_gnav_eph.d_m){} // avoid warning, not needed @@ -5945,11 +6866,11 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& ga { std::string system_(&observables_iter->second.System, 1); std::string sig_(observables_iter->second.Signal); - if((system_.compare("R") == 0) && (sig_.compare("1C") == 0)) + if((system_.compare("R") == 0) && (sig_.compare("1G") == 0)) { observablesR1C.insert(std::pair(observables_iter->first, observables_iter->second)); } - if((system_.compare("R") == 0) && (sig_.compare("2C") == 0)) + if((system_.compare("R") == 0) && (sig_.compare("2G") == 0)) { observablesR2C.insert(std::pair(observables_iter->first, observables_iter->second)); } @@ -7171,6 +8092,7 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep } + void Rinex_Printer::to_date_time(int gps_week, int gps_tow, int &year, int &month, int &day, int &hour, int &minute, int &second) { // represents GPS time (week, TOW) in the date time format of the Gregorian calendar. @@ -7381,10 +8303,85 @@ boost::posix_time::ptime Rinex_Printer::compute_Galileo_time(const Galileo_Ephem } -boost::posix_time::ptime Rinex_Printer::compute_GLONASS_time(const Glonass_Gnav_Ephemeris& eph, const double obs_time) +boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephemeris& eph, const double obs_time) { - boost::posix_time::ptime p_time = eph.compute_GLONASS_time(obs_time); - return p_time; + double tod = 0.0; + double glot2utc = 3*3600; + double obs_time_utc = 0.0, obs_time_glot = 0.0; + int i = 0; + + // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end + obs_time_glot = obs_time + glot2utc; + + // Get seconds of day in glonass time + tod = fmod (obs_time_glot, 86400); + + // Form date and time duration types + boost::posix_time::time_duration t1(0, 0, tod); + boost::gregorian::date d1(eph.d_yr, 1, 1); + boost::gregorian::days d2(eph.d_N_T-1); + boost::posix_time::ptime glo_time(d1 + d2, t1); + + // Convert to utc + boost::posix_time::time_duration t2(0, 0, glot2utc); + boost::posix_time::ptime utc_time = glo_time - t2; + + // Adjust for leap second correction + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + boost::posix_time::ptime ls_time(d3, t3); + if (utc_time >= ls_time) + { + // We subtract the leap second when going from gpst to utc + utc_time = utc_time - boost::posix_time::time_duration(0,0,fabs(GLONASS_LEAP_SECONDS[i][6])); + break; + } + } + + return utc_time; +} + +double Rinex_Printer::get_leap_second(const Glonass_Gnav_Ephemeris& eph, const double gps_obs_time) +{ + double tod = 0.0; + double glot2utc = 3*3600; + double obs_time_utc = 0.0, obs_time_glot = 0.0; + int i = 0; + double leap_second = 0; + + // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end + obs_time_glot = gps_obs_time + glot2utc; + + // Get seconds of day in glonass time + tod = fmod (obs_time_glot, 86400); + + // Form date and time duration types + boost::posix_time::time_duration t1(0, 0, tod); + boost::gregorian::date d1(eph.d_yr, 1, 1); + boost::gregorian::days d2(eph.d_N_T-1); + boost::posix_time::ptime glo_time(d1 + d2, t1); + + // Convert to utc + boost::posix_time::time_duration t2(0, 0, glot2utc); + boost::posix_time::ptime utc_time = glo_time - t2; + + // Adjust for leap second correction + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + boost::posix_time::ptime ls_time(d3, t3); + if (utc_time >= ls_time) + { + // We subtract the leap second when going from gpst to utc + leap_second = fabs(GLONASS_LEAP_SECONDS[i][6]); + break; + } + } + + return leap_second; } /* diff --git a/src/algorithms/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index 901fd0a60..ee90ef3a4 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -116,7 +116,7 @@ public: /*! * \brief Generates the GLONASS L1, L2 C/A Navigation Data header */ - void rinex_nav_header(std::fstream & out, const Glonass_Gnav_Utc_Model & utc_model, const Glonass_Gnav_Almanac & glonass_gnav_almanac); + void rinex_nav_header(std::fstream & out, const Glonass_Gnav_Utc_Model & utc_model, const Glonass_Gnav_Ephemeris & glonass_gnav_eph); /*! * \brief Generates the Mixed (Galileo/GLONASS) Navigation Data header @@ -128,6 +128,11 @@ public: */ void rinex_nav_header(std::fstream & out, const Gps_Iono & gps_iono, const Gps_Utc_Model & gps_utc_model, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model, const Glonass_Gnav_Almanac & glonass_gnav_almanac); + /*! + * \brief Generates the Mixed (GPS L2C C/A/GLONASS L1, L2) Navigation Data header + */ + void rinex_nav_header(std::fstream & out, const Gps_CNAV_Iono & gps_iono, const Gps_CNAV_Utc_Model & gps_utc_model, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model, const Glonass_Gnav_Almanac & glonass_gnav_almanac); + /*! * \brief Generates the GPS Observation data header */ @@ -156,7 +161,7 @@ public: /*! * \brief Generates the GLONASS GNAV Observation data header. Example: bands("1C"), bands("1C 2C"), bands("2C"), ... Default: "1C". */ - void rinex_obs_header(std::fstream & out, const Glonass_Gnav_Ephemeris & eph, const double d_TOW_first_observation, const std::string bands = "1C"); + void rinex_obs_header(std::fstream & out, const Glonass_Gnav_Ephemeris & eph, const double d_TOW_first_observation, const std::string bands = "1G"); /*! * \brief Generates the Mixed (GPS L1 C/A /GLONASS) Observation data header. Example: galileo_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". @@ -168,6 +173,11 @@ public: */ void rinex_obs_header(std::fstream & out, const Galileo_Ephemeris & galileo_eph, const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const double d_TOW_first_observation, const std::string galileo_bands = "1B", const std::string glo_bands = "1C"); + /*! + * \brief Generates the Mixed (GPS L2C/GLONASS) Observation data header. Example: galileo_bands("1G")... Default: "1G". + */ + void rinex_obs_header(std::fstream & out, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const double d_TOW_first_observation, const std::string glo_bands = "1G"); + /*! * \brief Generates the SBAS raw data header */ @@ -194,9 +204,20 @@ public: boost::posix_time::ptime compute_Galileo_time(const Galileo_Ephemeris & eph, const double obs_time); /*! - * \brief Computes the GLONASS System Time and returns a boost::posix_time::ptime object - */ - boost::posix_time::ptime compute_GLONASS_time(const Glonass_Gnav_Ephemeris & eph, const double obs_time); + * \brief Computes the UTC Time and returns a boost::posix_time::ptime object + * \details Function used as a method to convert the observation time into UTC time which is used + * as the default time for RINEX files + * \param eph GLONASS GNAV Ephemeris object + * \param obs_time Observation time in GPS seconds of week + */ + boost::posix_time::ptime compute_UTC_time(const Glonass_Gnav_Ephemeris & eph, const double obs_time); + + /*! + * \brief Computes number of leap seconds of GPS relative to UTC + * \param eph GLONASS GNAV Ephemeris object + * \param gps_obs_time Observation time in GPS seconds of week + */ + double get_leap_second(const Glonass_Gnav_Ephemeris& eph, const double gps_obs_time); /*! * \brief Writes data from the GPS L1 C/A navigation message into the RINEX file @@ -228,6 +249,11 @@ public: */ void log_rinex_nav(std::fstream & out, const std::map & gps_eph_map, const std::map & glonass_gnav_eph_map); + /*! + * \brief Writes data from the Mixed (GPS/GLONASS GNAV) navigation message into the RINEX file + */ + void log_rinex_nav(std::fstream & out, const std::map & gps_cnav_eph_map, const std::map & glonass_gnav_eph_map); + /*! * \brief Writes data from the Mixed (Galileo/ GLONASS GNAV) navigation message into the RINEX file */ @@ -268,6 +294,11 @@ public: */ void log_rinex_obs(std::fstream & out, const Gps_Ephemeris & gps_eph, const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const double gps_obs_time, const std::map & observables); + /*! + * \brief Writes Mixed GPS L2C - GLONASS observables into the RINEX file + */ + void log_rinex_obs(std::fstream & out, const Gps_CNAV_Ephemeris & gps_cnav_eph, const Glonass_Gnav_Ephemeris & glonass_gnav_eph, const double gps_obs_time, const std::map & observables); + /*! * \brief Writes Mixed Galileo/GLONASS observables into the RINEX file */ @@ -295,6 +326,8 @@ public: void update_nav_header(std::fstream & out, const Gps_Iono & gps_iono, const Gps_Utc_Model & gps_utc, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model, const Glonass_Gnav_Almanac & glonass_gnav_almanac); + void update_nav_header(std::fstream & out, const Gps_CNAV_Iono & gps_cnav_iono, const Gps_CNAV_Utc_Model & gps_cnav_utc, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model, const Glonass_Gnav_Almanac & glonass_gnav_almanac); + void update_nav_header(std::fstream & out, const Galileo_Iono & galileo_iono, const Galileo_Utc_Model & galileo_utc_model, const Galileo_Almanac& galileo_almanac, const Glonass_Gnav_Utc_Model & glonass_gnav_utc_model, const Glonass_Gnav_Almanac & glonass_gnav_almanac); void update_obs_header(std::fstream & out, const Gps_Utc_Model & utc_model); diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc index 800d1d4bd..2322626e8 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.cc @@ -1,5 +1,5 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h + * \file glonass_l1_ca_dll_pll_c_aid_tracking.cc * \brief Interface of an adapter of a DLL+PLL tracking loop block * for Glonass L1 C/A to a TrackingInterface * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com diff --git a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h index 4cdd59ce6..b62729a5f 100644 --- a/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h +++ b/src/algorithms/tracking/adapters/glonass_l1_ca_dll_pll_c_aid_tracking.h @@ -1,5 +1,5 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h + * \file glonass_l1_ca_dll_pll_c_aid_tracking.h * \brief Interface of an adapter of a DLL+PLL tracking loop block * for Glonass L1 C/A to a TrackingInterface * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc index d6569fb81..3fd0e74cd 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -1,7 +1,6 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \file glonass_l1_ca_dll_pll_c_aid_tracking_cc.h + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com @@ -218,6 +217,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc d_preamble_timestamp_s = 0.0; d_carrier_frequency_hz = 0.0; + d_carrier_doppler_old_hz = 0.0; //set_min_output_buffer((long int)300); } @@ -270,13 +270,13 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking() // d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); // d_carrier_doppler_hz = d_acq_carrier_doppler_hz; // d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); - d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); + d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * static_cast(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN))); d_carrier_doppler_hz = d_acq_carrier_doppler_hz; d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); // DLL/PLL filter initialization - d_carrier_loop_filter.initialize(d_acq_carrier_doppler_hz); // The carrier loop filter implements the Doppler accumulator + d_carrier_loop_filter.initialize(d_carrier_frequency_hz); // The carrier loop filter implements the Doppler accumulator d_code_loop_filter.initialize(); // initialize the code filter // generate local reference ALWAYS starting at chip 1 (1 sample per chip) @@ -709,6 +709,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items __a // ################## PLL ########################################################## // Update PLL discriminator [rads/Ti -> Secs/Ti] d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / GLONASS_TWO_PI; // prompt output + d_carrier_doppler_old_hz = d_carrier_doppler_hz; // Carrier discriminator filter // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan // Input [s/Ti] -> output [Hz] @@ -716,7 +717,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work (int noutput_items __a // PLL to DLL assistance [Secs/Ti] d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch; // code Doppler frequency update - d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); + d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); // ################## DLL ########################################################## // DLL discriminator diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h index 1aa7b72bd..d928beb29 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.h @@ -1,7 +1,6 @@ /*! * \file glonass_l1_ca_dll_pll_c_aid_tracking_cc.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com @@ -158,6 +157,7 @@ private: double d_code_phase_step_chips; double d_carrier_doppler_hz; double d_carrier_frequency_hz; + double d_carrier_doppler_old_hz; double d_carrier_phase_step_rad; double d_acc_carrier_phase_cycles; double d_code_phase_samples; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc index 197e46379..9619167f4 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -1,7 +1,6 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \file glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com @@ -217,6 +216,10 @@ glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc d_code_error_filt_chips_Ti = 0.0; d_preamble_timestamp_s = 0.0; d_carr_phase_error_secs_Ti = 0.0; + + d_carrier_frequency_hz = 0.0; + d_carrier_doppler_old_hz = 0.0; + //set_min_output_buffer((long int)300); } @@ -265,13 +268,13 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_sc::start_tracking() d_acq_code_phase_samples = corrected_acq_phase_samples; - d_carrier_doppler_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); - // d_carrier_doppler_hz = d_acq_carrier_doppler_hz; + d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * static_cast(GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)));; + d_carrier_doppler_hz = d_acq_carrier_doppler_hz; - d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); + d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); // DLL/PLL filter initialization - d_carrier_loop_filter.initialize(d_acq_carrier_doppler_hz); // The carrier loop filter implements the Doppler accumulator + d_carrier_loop_filter.initialize(d_carrier_frequency_hz); // The carrier loop filter implements the Doppler accumulator d_code_loop_filter.initialize(); // initialize the code filter // generate local reference ALWAYS starting at chip 1 (1 sample per chip) @@ -700,7 +703,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work (int noutput_items __a // ################## PLL ########################################################## // Update PLL discriminator [rads/Ti -> Secs/Ti] d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(std::complex(d_correlator_outs_16sc[1].real(),d_correlator_outs_16sc[1].imag())) / GLONASS_TWO_PI; //prompt output - + d_carrier_doppler_old_hz = d_carrier_doppler_hz; // Carrier discriminator filter // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan // Input [s/Ti] -> output [Hz] @@ -708,7 +711,7 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work (int noutput_items __a // PLL to DLL assistance [Secs/Ti] d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch; // code Doppler frequency update - d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); + d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); // ################## DLL ########################################################## // DLL discriminator diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h index 6f83bac0d..e9424f9c7 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.h @@ -1,7 +1,6 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \file glonass_l1_ca_dll_pll_c_aid_tracking_sc.h + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com @@ -160,6 +159,8 @@ private: double d_code_freq_chips; double d_code_phase_step_chips; double d_carrier_doppler_hz; + double d_carrier_frequency_hz; + double d_carrier_doppler_old_hz; double d_carrier_phase_step_rad; double d_acc_carrier_phase_cycles; double d_code_phase_samples; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc index 89c6b5cfe..c2b22a832 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc @@ -1,7 +1,6 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \file glonass_l1_ca_dll_pll_tracking_cc.cc + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com @@ -54,9 +53,6 @@ #include "control_message_factory.h" -/*! - * \todo Include in definition header file - */ #define CN0_ESTIMATION_SAMPLES 10 #define MINIMUM_VALID_CN0 25 #define MAXIMUM_LOCK_FAIL_COUNTER 50 @@ -175,6 +171,7 @@ Glonass_L1_Ca_Dll_Pll_Tracking_cc::Glonass_L1_Ca_Dll_Pll_Tracking_cc( d_acq_code_phase_samples = 0.0; d_acq_carrier_doppler_hz = 0.0; d_carrier_doppler_hz = 0.0; + d_carrier_doppler_phase_step_rad = 0.0; d_carrier_frequency_hz = 0.0; d_acc_carrier_phase_rad = 0.0; d_code_phase_samples = 0.0; @@ -235,6 +232,7 @@ void Glonass_L1_Ca_Dll_Pll_Tracking_cc::start_tracking() d_carrier_frequency_hz = d_acq_carrier_doppler_hz + d_if_freq + (DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN)); d_carrier_doppler_hz = d_acq_carrier_doppler_hz; d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); + d_carrier_doppler_phase_step_rad = GLONASS_TWO_PI * (d_carrier_doppler_hz) / static_cast(d_fs_in); // DLL/PLL filter initialization d_carrier_loop_filter.initialize(); // initialize the carrier filter @@ -554,9 +552,9 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribu d_sample_counter = d_sample_counter + samples_offset; // count for the processed samples d_pull_in = false; // take into account the carrier cycles accumulated in the pull in signal alignment - d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * samples_offset; + d_acc_carrier_phase_rad -= d_carrier_doppler_phase_step_rad * samples_offset; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; - current_synchro_data.Carrier_Doppler_hz = d_carrier_frequency_hz; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; current_synchro_data.fs = d_fs_in; current_synchro_data.correlation_length_ms = 1; *out[0] = current_synchro_data; @@ -581,7 +579,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribu carr_error_filt_hz = d_carrier_loop_filter.get_carrier_nco(carr_error_hz); // New carrier Doppler frequency estimation d_carrier_frequency_hz += carr_error_filt_hz; - d_carrier_doppler_hz = d_acq_carrier_doppler_hz + carr_error_filt_hz; + d_carrier_doppler_hz += carr_error_filt_hz; d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_HZ + ((d_carrier_doppler_hz * GLONASS_L1_CA_CODE_RATE_HZ) / d_glonass_freq_ch); // ################## DLL ########################################################## @@ -605,12 +603,13 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribu //################### PLL COMMANDS ################################################# // carrier phase step (NCO phase increment per sample) [rads/sample] + d_carrier_doppler_phase_step_rad = GLONASS_TWO_PI * d_carrier_doppler_hz / static_cast(d_fs_in); d_carrier_phase_step_rad = GLONASS_TWO_PI * d_carrier_frequency_hz / static_cast(d_fs_in); // remnant carrier phase to prevent overflow in the code NCO d_rem_carr_phase_rad = d_rem_carr_phase_rad + d_carrier_phase_step_rad * d_current_prn_length_samples; d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, GLONASS_TWO_PI); // carrier phase accumulator - d_acc_carrier_phase_rad -= d_carrier_phase_step_rad * d_current_prn_length_samples; + d_acc_carrier_phase_rad -= d_carrier_doppler_phase_step_rad * d_current_prn_length_samples; //################### DLL COMMANDS ################################################# // code phase step (Code resampler phase increment per sample) [chips/sample] @@ -657,7 +656,7 @@ int Glonass_L1_Ca_Dll_Pll_Tracking_cc::general_work (int noutput_items __attribu current_synchro_data.Tracking_sample_counter = d_sample_counter + d_current_prn_length_samples; current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; - current_synchro_data.Carrier_Doppler_hz = d_carrier_frequency_hz; + current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; current_synchro_data.Flag_valid_symbol_output = true; current_synchro_data.correlation_length_ms = 1; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h index 4e080fae2..641c6f04e 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.h @@ -1,7 +1,6 @@ /*! - * \file glonass_l1_ca_dll_pll_tracking.h - * \brief Interface of an adapter of a DLL+PLL tracking loop block - * for Glonass L1 C/A to a TrackingInterface + * \file glonass_l1_ca_dll_pll_tracking_cc.h + * \brief Implementation of a code DLL + carrier PLL tracking block * \author Gabriel Araujo, 2017. gabriel.araujo.5000(at)gmail.com * \author Luis Esteve, 2017. luis(at)epsilon-formacion.com * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com @@ -140,6 +139,7 @@ private: double d_code_freq_chips; double d_code_phase_step_chips; double d_carrier_doppler_hz; + double d_carrier_doppler_phase_step_rad; double d_carrier_frequency_hz; double d_carrier_phase_step_rad; double d_acc_carrier_phase_rad; diff --git a/src/core/system_parameters/GLONASS_L1_CA.h b/src/core/system_parameters/GLONASS_L1_CA.h index 4e97fe121..06f1112f3 100644 --- a/src/core/system_parameters/GLONASS_L1_CA.h +++ b/src/core/system_parameters/GLONASS_L1_CA.h @@ -50,7 +50,7 @@ const double GLONASS_FLATTENING = 1/29825784; //!< Flatten const double GLONASS_GRAVITY = 97803284; //!< Equatorial acceleration of gravity [mGal] const double GLONASS_GRAVITY_CORRECTION = 0.87; //!< Correction to acceleration of gravity at sea-level due to Atmosphere[мGal] const double GLONASS_J2 = 1082625.75e-9; //!< Second zonal harmonic of the geopotential -const double GLONASS_J4 = -2370.89e-9; //! GLONASS_PRN = {{ 0, 8,}, //For test { 1, 1,}, //Plane 1 @@ -134,7 +138,7 @@ const std::map GLONASS_PRN = {17, 4,}, //Plane 3 {18,-3,}, //Plane 3 {19, 3,}, //Plane 3 - {20, -5,}, //Plane 3 + {20,-5,}, //Plane 3 {21, 4,}, //Plane 3 {22,-3,}, //Plane 3 {23, 3,}, //Plane 3 diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.cc b/src/core/system_parameters/glonass_gnav_ephemeris.cc index c557c6a6f..6cd530c59 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.cc +++ b/src/core/system_parameters/glonass_gnav_ephemeris.cc @@ -82,7 +82,6 @@ Glonass_Gnav_Ephemeris::Glonass_Gnav_Ephemeris() d_tod = 0.0; } - boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(const double offset_time) const { boost::posix_time::time_duration t(0, 0, offset_time + d_tau_c + d_tau_n); @@ -93,68 +92,71 @@ boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(const doub return glonass_time; } - boost::posix_time::ptime Glonass_Gnav_Ephemeris::glot_to_utc(const double offset_time, const double glot2utc_corr) const { - double tod = 0.0; - double glot2utc = 3*3600; + double tod = 0.0; + double glot2utc = 3*3600; - tod = offset_time - glot2utc + glot2utc_corr + d_tau_n; - boost::posix_time::time_duration t(0, 0, tod); - boost::gregorian::date d1(d_yr, 1, 1); - boost::gregorian::days d2(d_N_T - 1); - boost::posix_time::ptime utc_time(d1+d2, t); + tod = offset_time - glot2utc + glot2utc_corr + d_tau_n; + boost::posix_time::time_duration t(0, 0, tod); + boost::gregorian::date d1(d_yr, 1, 1); + boost::gregorian::days d2(d_N_T - 1); + boost::posix_time::ptime utc_time(d1+d2, t); - return utc_time; + return utc_time; } void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_corr, double glot2gpst_corr, double * wn, double * tow) const { - double tod = 0.0; - double glot2utc = 3*3600; - double days = 0.0; - double total_sec = 0.0, sec_of_day = 0.0; - int i = 0; + double tod = 0.0; + double glot2utc = 3*3600; + double days = 0.0; + double total_sec = 0.0, sec_of_day = 0.0; + int i = 0; - boost::gregorian::date gps_epoch { 1980, 1, 6 }; + boost::gregorian::date gps_epoch { 1980, 1, 6 }; - // tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections - // tk plus 10 sec is the true tod since get_TOW is called when in str5 - tod = tod_offset - glot2utc ; + // tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections + // tk plus 10 sec is the true tod since get_TOW is called when in str5 + tod = tod_offset - glot2utc ; - boost::posix_time::time_duration t(0, 0, tod); - boost::gregorian::date d1(d_yr, 1, 1); - boost::gregorian::days d2(d_N_T-1); - boost::posix_time::ptime glonass_time(d1+d2, t); - boost::gregorian::date utc_date = glonass_time.date(); + boost::posix_time::time_duration t(0, 0, tod); + boost::gregorian::date d1(d_yr, 1, 1); + boost::gregorian::days d2(d_N_T-1); + boost::posix_time::ptime utc_time(d1+d2, t); + boost::gregorian::date utc_date = utc_time.date(); + boost::posix_time::ptime gps_time; - // Total number of days - std::string fdat = boost::posix_time::to_simple_string(glonass_time); - days = static_cast((utc_date - gps_epoch).days()); + // Adjust for leap second correction + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + boost::posix_time::ptime ls_time(d3, t3); + if (utc_time >= ls_time) + { + // We add the leap second when going from utc to gpst + gps_time = utc_time + boost::posix_time::time_duration(0,0,fabs(GLONASS_LEAP_SECONDS[i][6])); + break; + } + } - // Total number of seconds - sec_of_day = static_cast((glonass_time.time_of_day()).total_seconds()); - total_sec = days*86400 + sec_of_day; + // Total number of days + std::string fdat = boost::posix_time::to_simple_string(gps_time); + days = static_cast((utc_date - gps_epoch).days()); - // GLONASST already includes leap second addition or deletion - for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) - { - if (d_yr >= GLONASS_LEAP_SECONDS[i][0]) - { - // We add the leap second when going from utc to gpst - total_sec += fabs(GLONASS_LEAP_SECONDS[i][6]); - break; - } - } + // Total number of seconds + sec_of_day = static_cast((gps_time.time_of_day()).total_seconds()); + total_sec = days*86400 + sec_of_day; - // Compute Week number - *wn = floor(total_sec/604800); + // Compute Week number + *wn = floor(total_sec/604800); - // Compute the arithmetic modules to wrap around range - *tow = total_sec - 604800*floor(total_sec/604800); - // Perform corrections from fractional seconds - *tow += glot2utc_corr + glot2gpst_corr; + // Compute the arithmetic modules to wrap around range + *tow = total_sec - 604800*floor(total_sec/604800); + // Perform corrections from fractional seconds + *tow += glot2utc_corr + glot2gpst_corr; } diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc index 33ed3965c..ceb2d8373 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc @@ -95,8 +95,9 @@ TEST(RinexPrinterTest, GlonassObsHeader) const Glonass_Gnav_Ephemeris eph = Glonass_Gnav_Ephemeris(); std::shared_ptr rp1; - rp1 = std::make_shared(); - rp1->rinex_obs_header(rp1->obsFile, eph, 0.0); + rp1 = std::make_shared(3); + const std::string bands = "1G"; + rp1->rinex_obs_header(rp1->obsFile, eph, 0.0, bands); rp1->obsFile.seekp(0); while(!rp1->obsFile.eof()) diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc index da5571399..7026903e2 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc @@ -130,7 +130,7 @@ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT3) double tow = 0.0; double true_leap_sec = 17; double true_week = 1886; - double true_tow = 259200+true_leap_sec; + double true_tow = 259200+true_leap_sec+tod; gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc index 5fabb4676..595b1fa2f 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc @@ -172,6 +172,7 @@ TEST(GlonassGnavNavigationMessageTest, String3Decoder) gnav_ephemeris.d_Zn = 19929.2377929688; // Call target test method + gnav_nav_message.flag_ephemeris_str_2 = true; gnav_nav_message.string_decoder(str3); // Perform assertions of decoded fields @@ -209,6 +210,7 @@ TEST(GlonassGnavNavigationMessageTest, String4Decoder) gnav_ephemeris.d_M = 1; // Call target test method + gnav_nav_message.flag_ephemeris_str_3 = true; gnav_nav_message.string_decoder(str4); // Perform assertions of decoded fields @@ -243,6 +245,7 @@ TEST(GlonassGnavNavigationMessageTest, String5Decoder) gnav_utc_model.d_tau_gps = 9.313225746154785e-08; // Call target test method + gnav_nav_message.flag_ephemeris_str_4 = true; gnav_nav_message.string_decoder(str5); // Perform assertions of decoded fields