mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-12 19:20:32 +00:00
glonass: Adding RINEX support for rcv type 28 (GPS L2C + GLO L1 C/A)
Adds RINEX support for receiver type 28 which combines GPS L2C and GLONASS L2C. Fixes a couple of bugs in RINEX file generation and adds new configuration files for L2C processing
This commit is contained in:
parent
78eaa76a60
commit
1cc72b8102
147
conf/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf
Normal file
147
conf/gnss-sdr_GLONASS_L1_CA_GPS_L2C_ibyte.conf
Normal file
@ -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
|
@ -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;
|
||||
|
@ -713,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 #################
|
||||
@ -896,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
|
||||
{
|
||||
@ -944,6 +955,10 @@ int rtklib_pvt_cc::work (int noutput_items, gr_vector_const_void_star &input_ite
|
||||
{
|
||||
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();
|
||||
@ -1136,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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -642,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<std::string>(0.0), 7);
|
||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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<std::string>(0.0), 7);
|
||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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<std::string>(gps_utc_model.d_t_OT), 7);
|
||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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<std::string>(gps_utc_model.d_DeltaT_LS), 6);
|
||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(gps_utc_model.d_DeltaT_LSF), 6);
|
||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(gps_utc_model.i_WN_LSF), 6);
|
||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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)
|
||||
{
|
||||
@ -753,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;
|
||||
@ -862,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;
|
||||
@ -978,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;
|
||||
@ -1157,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;
|
||||
@ -1399,7 +1516,6 @@ void Rinex_Printer::rinex_sbs_header(std::fstream& out)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Rinex_Printer::update_nav_header(std::fstream& out, 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
|
||||
@ -1473,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<std::string> data;
|
||||
@ -1569,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<std::string> data;
|
||||
@ -2054,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<std::string> 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<std::string>(gps_utc_model.d_t_OT), 7);
|
||||
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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<std::string>(0.0), 7);
|
||||
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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<std::string>(0.0), 7);
|
||||
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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<std::string>(gps_utc_model.d_DeltaT_LS), 6);
|
||||
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(gps_utc_model.d_DeltaT_LSF), 6);
|
||||
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(gps_utc_model.i_WN_LSF), 6);
|
||||
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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
|
||||
@ -3042,6 +3262,11 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map<int, Gps_Eph
|
||||
Rinex_Printer::log_rinex_nav(out, glonass_gnav_eph_map);
|
||||
}
|
||||
|
||||
void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map<int, Gps_CNAV_Ephemeris>& gps_eph_map, const std::map<int, Glonass_Gnav_Ephemeris>& 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<int, Galileo_Ephemeris>& galileo_eph_map, const std::map<int, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map)
|
||||
{
|
||||
@ -3211,11 +3436,11 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Glonass_Gnav_Ephem
|
||||
line += Rinex_Printer::rightJustify(strm.str(), 3);
|
||||
|
||||
std::string signal_ = "1G";
|
||||
std::size_t found_1C = glonass_bands.find(signal_);
|
||||
std::size_t found_1G = glonass_bands.find(signal_);
|
||||
signal_ = "2G";
|
||||
std::size_t found_2C = glonass_bands.find(signal_);
|
||||
std::size_t found_2G = glonass_bands.find(signal_);
|
||||
|
||||
if(found_1C != std::string::npos)
|
||||
if(found_1G != std::string::npos)
|
||||
{
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["PSEUDORANGE"];
|
||||
@ -3231,7 +3456,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Glonass_Gnav_Ephem
|
||||
line += observationCode["GLONASS_G1_CA"];
|
||||
}
|
||||
|
||||
if(found_2C != std::string::npos)
|
||||
if(found_2G != std::string::npos)
|
||||
{
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["PSEUDORANGE"];
|
||||
@ -3541,14 +3766,14 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps
|
||||
// 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)
|
||||
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;
|
||||
}
|
||||
@ -3556,7 +3781,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps
|
||||
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)
|
||||
if(found_1G != std::string::npos)
|
||||
{
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["PSEUDORANGE"];
|
||||
@ -3571,7 +3796,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps
|
||||
line += observationType["SIGNAL_STRENGTH"];
|
||||
line += observationCode["GLONASS_G1_CA"];
|
||||
}
|
||||
if(found_2C != std::string::npos)
|
||||
if(found_2G != std::string::npos)
|
||||
{
|
||||
line += std::string(1, ' ');
|
||||
line += observationType["PSEUDORANGE"];
|
||||
@ -3707,6 +3932,310 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
// -------- 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
|
||||
// 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 += 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 #
|
||||
// TODO Need to provide system with list of all satellites and update this accordingly
|
||||
line.clear();
|
||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(0), 3); // Number of satellites in list
|
||||
line += std::string(1, ' ');
|
||||
line += satelliteSystem["GLONASS"];
|
||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(0), 2); // Slot Number
|
||||
line += std::string(1, ' ');
|
||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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 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
|
||||
@ -3929,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;
|
||||
}
|
||||
@ -3945,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"];
|
||||
@ -3961,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"];
|
||||
@ -6042,6 +6571,246 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep
|
||||
}
|
||||
|
||||
|
||||
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<int,Gnss_Synchro>& 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);
|
||||
|
||||
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<int, Gnss_Synchro> observablesG2S;
|
||||
std::map<int, Gnss_Synchro> observablesR1C;
|
||||
std::map<int, Gnss_Synchro> observablesR2C;
|
||||
std::map<int, Gnss_Synchro>::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<int, Gnss_Synchro>(observables_iter->first, observables_iter->second));
|
||||
}
|
||||
if((system_.compare("R") == 0) && (sig_.compare("2G") == 0))
|
||||
{
|
||||
observablesR2C.insert(std::pair<int, Gnss_Synchro>(observables_iter->first, observables_iter->second));
|
||||
}
|
||||
if((system_.compare("G") == 0) && (sig_.compare("2S") == 0))
|
||||
{
|
||||
observablesG2S.insert(std::pair<int, Gnss_Synchro>(observables_iter->first, observables_iter->second));
|
||||
}
|
||||
}
|
||||
|
||||
std::multimap<unsigned int, Gnss_Synchro> total_glo_map;
|
||||
std::set<unsigned int> available_glo_prns;
|
||||
std::set<unsigned int>::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<unsigned int, Gnss_Synchro>(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<unsigned int, Gnss_Synchro>(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 = observablesG2S.size();
|
||||
int numSatellitesObserved = numGloSatellitesObserved + numGpsSatellitesObserved;
|
||||
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(numSatellitesObserved), 3);
|
||||
|
||||
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();
|
||||
|
||||
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<int>(observables_iter->second.PRN) < 10) lineObs += std::string(1, '0');
|
||||
lineObs += boost::lexical_cast<std::string>(static_cast<int>(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<short>(lli), 1);
|
||||
}
|
||||
|
||||
// Signal Strength Indicator (SSI)
|
||||
int ssi = Rinex_Printer::signalStrength(observables_iter->second.CN0_dB_hz);
|
||||
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int>(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<short>(lli), 1);
|
||||
}
|
||||
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int>(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<short>(lli), 1);
|
||||
}
|
||||
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int>(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 <std::multimap<unsigned int, Gnss_Synchro>::iterator, std::multimap<unsigned int, Gnss_Synchro>::iterator> ret;
|
||||
for(it = available_glo_prns.begin();
|
||||
it != available_glo_prns.end();
|
||||
it++)
|
||||
{
|
||||
lineObs.clear();
|
||||
lineObs += satelliteSystem["GLONASS"];
|
||||
if (static_cast<int>(*it) < 10) lineObs += std::string(1, '0');
|
||||
lineObs += boost::lexical_cast<std::string>(static_cast<int>(*it));
|
||||
|
||||
ret = total_glo_map.equal_range(*it);
|
||||
for (std::multimap<unsigned int, Gnss_Synchro>::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<short>(lli), 1);
|
||||
}
|
||||
|
||||
// Signal Strength Indicator (SSI)
|
||||
int ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz);
|
||||
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int>(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<short>(lli), 1);
|
||||
}
|
||||
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int>(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<short>(lli), 1);
|
||||
}
|
||||
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int>(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 Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, double galileo_obs_time, const std::map<int,Gnss_Synchro>& observables)
|
||||
{
|
||||
if(glonass_gnav_eph.d_m){} // avoid warning, not needed
|
||||
|
@ -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
|
||||
*/
|
||||
@ -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
|
||||
*/
|
||||
@ -239,6 +249,11 @@ public:
|
||||
*/
|
||||
void log_rinex_nav(std::fstream & out, const std::map<int, Gps_Ephemeris> & gps_eph_map, const std::map<int, Glonass_Gnav_Ephemeris> & 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<int, Gps_CNAV_Ephemeris> & gps_cnav_eph_map, const std::map<int, Glonass_Gnav_Ephemeris> & glonass_gnav_eph_map);
|
||||
|
||||
/*!
|
||||
* \brief Writes data from the Mixed (Galileo/ GLONASS GNAV) navigation message into the RINEX file
|
||||
*/
|
||||
@ -279,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<int, Gnss_Synchro> & 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<int, Gnss_Synchro> & observables);
|
||||
|
||||
/*!
|
||||
* \brief Writes Mixed Galileo/GLONASS observables into the RINEX file
|
||||
*/
|
||||
@ -306,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);
|
||||
|
Loading…
Reference in New Issue
Block a user