1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-06-14 09:16:51 +00:00

bds b1i: Adds B1I RINEX support

Adds RINEX support for B1I only signals. It also fixes a couple of bugs
with the code. This was not properly developed during GSoC
This commit is contained in:
Damian Miralles 2018-11-30 09:25:48 -06:00
parent 8db3f21070
commit 287c93e5b8
6 changed files with 904 additions and 192 deletions

View File

@ -1,92 +0,0 @@
; This is a GNSS-SDR configuration file
; The configuration API is described at https://gnss-sdr.org/docs/sp-blocks/
; You can define your own receiver and invoke it by doing
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
;
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second].
GNSS-SDR.internal_fs_sps=25000000
;######### CONTROL_THREAD CONFIG ############
ControlThread.wait_for_flowgraph=false
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=File_Signal_Source
SignalSource.filename=/media/dmiralles/Seagate Backup Plus Drive/GNSS Data/USRP_BDS_B1I_201805171123_fs_25e6_if0e3_ishort.bin
SignalSource.item_type=ishort
SignalSource.sampling_frequency=25000000
SignalSource.samples=0
SignalSource.repeat=false
SignalSource.dump=false
SignalSource.enable_throttle_control=false
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Signal_Conditioner
DataTypeAdapter.implementation=Ishort_To_Complex
InputFilter.implementation=Pass_Through
InputFilter.item_type=gr_complex
Resampler.implementation=Direct_Resampler
Resampler.sample_freq_in=25000000
Resampler.sample_freq_out=25000000
Resampler.item_type=gr_complex
;######### CHANNELS GLOBAL CONFIG ############
Channels_B1.count=2
Channels.in_acquisition=1
Channel.signal=B1
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_B1.implementation=BEIDOU_B1I_PCPS_Acquisition
Acquisition_B1.item_type=gr_complex
Acquisition_B1.coherent_integration_time_ms=1
Acquisition_B1.threshold=20
;Acquisition_B1.pfa=0.000001
Acquisition_B1.doppler_max=10000
Acquisition_B1.doppler_step=2500
Acquisition_B1.dump=true
Acquisition_B1.dump_filename=./acq_dump.dat
Acquisition_B1.blocking=false;
Acquisition_B1.use_CFAR_algorithm=false
;######### TRACKING GLOBAL CONFIG ############
Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking
Tracking_B1.item_type=gr_complex
Tracking_B1.pll_bw_hz=40.0;
Tracking_B1.dll_bw_hz=8.0;
Tracking_B1.order=3;
Tracking_B1.dump=true;
Tracking_B1.dump_filename=./epl_tracking_ch_
;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_B1.implementation=BEIDOU_B1I_Telemetry_Decoder
TelemetryDecoder_B1.dump=true
;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=true
Observables.dump_filename=./observables.dat
;######### PVT CONFIG ############
PVT.implementation=RTKLIB_PVT
PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic
PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX
PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad
PVT.output_rate_ms=100
PVT.display_rate_ms=500
PVT.dump_filename=./PVT
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
PVT.flag_nmea_tty_port=false;
PVT.nmea_dump_devname=/dev/pts/4
PVT.flag_rtcm_server=false
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1
PVT.dump=false

View File

@ -1,94 +0,0 @@
; This is a GNSS-SDR configuration file
; The configuration API is described at https://gnss-sdr.org/docs/sp-blocks/
; You can define your own receiver and invoke it by doing
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
;
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second].
GNSS-SDR.internal_fs_sps=5000000
;######### CONTROL_THREAD CONFIG ############
ControlThread.wait_for_flowgraph=false
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=File_Signal_Source
SignalSource.filename=/home/sergi/gnss/gnss-sdr/data/stereo_l1_b1.datz
SignalSource.item_type=ishort
SignalSource.sampling_frequency=5000000
SignalSource.samples=0
SignalSource.repeat=false
SignalSource.dump=false
;SignalSource.dump_filename=../data/signal_source.dat
SignalSource.enable_throttle_control=false
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Signal_Conditioner
DataTypeAdapter.implementation=Ishort_To_Complex
InputFilter.implementation=Pass_Through
InputFilter.item_type=gr_complex
Resampler.implementation=Direct_Resampler
Resampler.sample_freq_in=5000000
Resampler.sample_freq_out=5000000
Resampler.item_type=gr_complex
;######### CHANNELS GLOBAL CONFIG ############
Channels_B1.count=5
Channels.in_acquisition=1
Channel.signal=B1
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_B1.implementation=BEIDOU_B1I_PCPS_Acquisition
Acquisition_B1.item_type=gr_complex
Acquisition_B1.coherent_integration_time_ms=1
Acquisition_B1.threshold=20
;Acquisition_B1.pfa=0.000001
Acquisition_B1.doppler_max=10000
Acquisition_B1.doppler_step=50
Acquisition_B1.dump=true
Acquisition_B1.dump_filename=./acq_dump.dat
Acquisition_B1.blocking=false;
Acquisition_B1.use_CFAR_algorithm=false
;######### TRACKING GLOBAL CONFIG ############
Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking
Tracking_B1.item_type=gr_complex
Tracking_B1.pll_bw_hz=40.0;
Tracking_B1.dll_bw_hz=8.0;
Tracking_B1.order=3;
Tracking_B1.dump=true;
Tracking_B1.dump_filename=./epl_tracking_ch_
;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_B1.implementation=BEIDOU_B1I_Telemetry_Decoder
TelemetryDecoder_B1.dump=true
;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=true
Observables.dump_filename=./observables.dat
;######### PVT CONFIG ############
PVT.implementation=RTKLIB_PVT
PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic
PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX
PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad
PVT.output_rate_ms=100
PVT.display_rate_ms=500
PVT.dump_filename=./PVT
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
PVT.flag_nmea_tty_port=false;
PVT.nmea_dump_devname=/dev/pts/4
PVT.flag_rtcm_server=false
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1
PVT.dump=false

View File

@ -953,15 +953,15 @@ rtklib_pvt_cc::~rtklib_pvt_cc()
// Save BeiDou UTC model parameters
file_name = xml_base_path + "bds_dnav_utc_model.xml";
if (d_pvt_solver->bds_dnav_utc_model.valid)
if (d_pvt_solver->beidou_dnav_utc_model.valid)
{
std::ofstream ofs;
try
{
ofs.open(file_name.c_str(), std::ofstream::trunc | std::ofstream::out);
boost::archive::xml_oarchive xml(ofs);
xml << boost::serialization::make_nvp("GNSS-SDR_bds_dnav_utc_model", d_pvt_solver->bds_dnav_utc_model);
LOG(INFO) << "Saved GPS UTC model parameters";
xml << boost::serialization::make_nvp("GNSS-SDR_bds_dnav_utc_model", d_pvt_solver->beidou_dnav_utc_model);
LOG(INFO) << "Saved BeiDou DNAV UTC model parameters";
}
catch (std::exception& e)
{
@ -1555,7 +1555,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
case 50: // BDS B1I only
if (beidou_dnav_ephemeris_iter != d_pvt_solver->beidou_dnav_ephemeris_map.cend())
{
rp->rinex_obs_header(rp->obsFile, beidou_dnav_ephemeris_iter->second, d_rx_time);
rp->rinex_obs_header(rp->obsFile, beidou_dnav_ephemeris_iter->second, d_rx_time, "B1");
rp->rinex_nav_header(rp->navFile, d_pvt_solver->beidou_dnav_iono, d_pvt_solver->beidou_dnav_utc_model);
b_rinex_header_written = true; // do not write header anymore
}
@ -1942,7 +1942,7 @@ int rtklib_pvt_cc::work(int noutput_items, gr_vector_const_void_star& input_item
case 50: // BDS B1I only
if (beidou_dnav_ephemeris_iter != d_pvt_solver->beidou_dnav_ephemeris_map.cend())
{
rp->log_rinex_obs(rp->obsFile, beidou_dnav_ephemeris_iter->second, d_rx_time, gnss_observables_map);
rp->log_rinex_obs(rp->obsFile, beidou_dnav_ephemeris_iter->second, d_rx_time, gnss_observables_map, "B1");
}
if (!b_rinex_header_updated and (d_pvt_solver->beidou_dnav_utc_model.d_A0 != 0))
{

View File

@ -89,6 +89,7 @@ Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path)
navGalfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_GAL_NAV");
navMixfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_MIXED_NAV");
navGlofilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_GLO_NAV");
navBdsfilename = base_rinex_path + boost::filesystem::path::preferred_separator + Rinex_Printer::createFilename("RINEX_FILE_TYPE_BDS_NAV");
Rinex_Printer::navFile.open(navfilename, std::ios::out | std::ios::in | std::ios::app);
Rinex_Printer::obsFile.open(obsfilename, std::ios::out | std::ios::in | std::ios::app);
@ -96,6 +97,8 @@ Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path)
Rinex_Printer::navGalFile.open(navGalfilename, std::ios::out | std::ios::in | std::ios::app);
Rinex_Printer::navMixFile.open(navMixfilename, std::ios::out | std::ios::in | std::ios::app);
Rinex_Printer::navGloFile.open(navGlofilename, std::ios::out | std::ios::in | std::ios::app);
Rinex_Printer::navBdsFile.open(navBdsfilename, std::ios::out | std::ios::in | std::ios::app);
if (!Rinex_Printer::navFile.is_open() or !Rinex_Printer::obsFile.is_open() or
!Rinex_Printer::sbsFile.is_open() or !Rinex_Printer::navGalFile.is_open() or
@ -167,6 +170,8 @@ Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path)
observationCode["COMPASS_E6_I"] = "6I";
observationCode["COMPASS_E6_Q"] = "6Q";
observationCode["COMPASS_E6_IQ"] = "6X";
observationCode["BEIDOU_B1_I"] = "1I";
observationCode["BEIDOU_B1_Q"] = "1Q";
observationType["PSEUDORANGE"] = "C";
observationType["CARRIER_PHASE"] = "L";
@ -201,19 +206,21 @@ Rinex_Printer::Rinex_Printer(int32_t conf_version, const std::string& base_path)
Rinex_Printer::~Rinex_Printer()
{
// close RINEX files
int64_t posn, poso, poss, posng, posmn, posnr;
int64_t posn, poso, poss, posng, posmn, posnr, posnc;
posn = navFile.tellp();
poso = obsFile.tellp();
poss = sbsFile.tellp();
posng = navGalFile.tellp();
posmn = navMixFile.tellp();
posnr = navGloFile.tellp();
posnc = navBdsFile.tellp();
Rinex_Printer::navFile.close();
Rinex_Printer::obsFile.close();
Rinex_Printer::sbsFile.close();
Rinex_Printer::navGalFile.close();
Rinex_Printer::navGloFile.close();
Rinex_Printer::navBdsFile.close();
// If nothing written, erase the files.
if (posn == 0)
{
@ -239,6 +246,10 @@ Rinex_Printer::~Rinex_Printer()
{
if (remove(navGlofilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file";
}
if (posnc == 0)
{
if (remove(navBdsfilename.c_str()) != 0) LOG(INFO) << "Error deleting temporary file";
}
}
@ -276,6 +287,8 @@ std::string Rinex_Printer::createFilename(std::string type)
fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_SBAS", "B")); // B - SBAS broadcast data file.
fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_CLK", "C")); // C - Clock file.
fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_SUMMARY", "S")); // S - Summary file (used e.g., by IGS, not a standard!).
fileType.insert(std::pair<std::string, std::string>("RINEX_FILE_TYPE_BDS_NAV", "F")); // G - GLONASS navigation file.
boost::posix_time::ptime pt = boost::posix_time::second_clock::local_time();
tm pt_tm = boost::posix_time::to_tm(pt);
@ -1542,6 +1555,121 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono
}
void Rinex_Printer::rinex_nav_header(std::fstream& out, const Beidou_Dnav_Iono& iono, const Beidou_Dnav_Utc_Model& utc_model)
{
std::string line;
// -------- Line 1
line = std::string(5, ' ');
line += stringVersion;
line += std::string(11, ' ');
if (version == 3)
{
line += std::string("N: GNSS NAV DATA");
line += std::string(4, ' ');
//! \todo Add here other systems...
line += std::string("F: BDS");
line += std::string(14, ' ');
// ...
}
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 3
line.clear();
line += Rinex_Printer::leftJustify("BDS 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 https://gnss-sdr.org", 60);
line += Rinex_Printer::leftJustify("COMMENT", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line ionospheric info 1, only version 3 supported
line.clear();
line += std::string("BDSA");
line += std::string(1, ' ');
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha0, 10, 2), 12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha1, 10, 2), 12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha2, 10, 2), 12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(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 ionospheric info 2
line.clear();
line += std::string("BDSB");
line += std::string(1, ' ');
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta0, 10, 2), 12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta1, 10, 2), 12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta2, 10, 2), 12);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta3, 10, 2), 12);
line += std::string(7, ' ');
line += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- Line 5 system time correction
line += std::string("BDUT");
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0, 16, 2), 18);
line += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1, 15, 2), 16);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_t_OT), 7);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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>(utc_model.d_DeltaT_LS), 6);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_DeltaT_LSF), 6);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.i_WN_LSF), 6);
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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_sbs_header(std::fstream& out)
{
std::string line;
@ -2643,6 +2771,101 @@ void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& gal
}
void Rinex_Printer::update_nav_header(std::fstream& out, const Beidou_Dnav_Utc_Model& utc_model, const Beidou_Dnav_Iono& iono)
{
std::vector<std::string> data;
std::string line_aux;
int64_t 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("BDSA", 0) != std::string::npos)
{
line_aux += std::string("GPSA");
line_aux += std::string(1, ' ');
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha0, 10, 2), 12);
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha1, 10, 2), 12);
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_alpha2, 10, 2), 12);
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(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("BDSB", 0) != std::string::npos)
{
line_aux += std::string("GPSB");
line_aux += std::string(1, ' ');
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta0, 10, 2), 12);
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta1, 10, 2), 12);
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta2, 10, 2), 12);
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(iono.d_beta3, 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("BDUT", 0) != std::string::npos)
{
line_aux += std::string("GPUT");
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A0, 16, 2), 18);
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.d_A1, 15, 2), 16);
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_t_OT), 7);
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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("LEAP SECONDS", 59) != std::string::npos)
{
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_DeltaT_LS), 6);
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_DeltaT_LSF), 6);
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.i_WN_LSF), 6);
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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(navfilename, std::ios::out | std::ios::trunc);
out.seekp(0);
for (int32_t i = 0; i < static_cast<int32_t>(data.size()) - 1; i++)
{
out << data[i] << std::endl;
}
out.close();
out.open(navfilename, 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::log_rinex_nav(std::fstream& out, const std::map<int32_t, Gps_Ephemeris>& eph_map)
{
std::string line;
@ -3529,6 +3752,146 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map<int32_t, Gal
}
void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map<int32_t, Beidou_Dnav_Ephemeris>& eph_map)
{
std::string line;
std::map<int32_t, Beidou_Dnav_Ephemeris>::const_iterator bds_ephemeris_iter;
for (bds_ephemeris_iter = eph_map.cbegin();
bds_ephemeris_iter != eph_map.cend();
bds_ephemeris_iter++)
{
// -------- SV / EPOCH / SV CLK
boost::posix_time::ptime p_utc_time = Rinex_Printer::compute_BDS_time(bds_ephemeris_iter->second, bds_ephemeris_iter->second.d_Toc);
std::string timestring = boost::posix_time::to_iso_string(p_utc_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 seconds(timestring, 13, 2);
line += satelliteSystem["BDS"];
if (bds_ephemeris_iter->second.i_satellite_PRN < 10) line += std::string("0");
line += boost::lexical_cast<std::string>(bds_ephemeris_iter->second.i_satellite_PRN);
std::string year(timestring, 0, 4);
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 += seconds;
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_A_f0, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_A_f1, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_A_f2, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 1
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_AODE, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Crs, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Delta_n, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_M_0, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 2
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Cuc, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_e_eccentricity, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Cus, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_sqrt_A, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 3
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Toe, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Cic, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_OMEGA0, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Cis, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 4
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_i_0, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_Crc, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_OMEGA, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_OMEGA_DOT, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 5
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_IDOT, 18, 2);
line += std::string(1, ' ');
line += std::string(18, ' '); // spare
line += std::string(1, ' ');
double BDS_week_continuous_number = static_cast<double>(bds_ephemeris_iter->second.i_BEIDOU_week);
line += Rinex_Printer::doub2for(BDS_week_continuous_number, 18, 2);
line += std::string(1, ' ');
line += std::string(18, ' '); // spare
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 6
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(static_cast<double>(bds_ephemeris_iter->second.i_SV_accuracy), 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(static_cast<double>(bds_ephemeris_iter->second.i_SV_health), 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_TGD1, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_TGD2, 18, 2);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- BROADCAST ORBIT - 7
line.clear();
line += std::string(5, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_TOW, 18, 2);
line += std::string(1, ' ');
line += Rinex_Printer::doub2for(bds_ephemeris_iter->second.d_AODC, 18, 2);
line += std::string(1, ' ');
line += std::string(18, ' '); // spare
line += std::string(1, ' ');
line += std::string(18, ' '); // spare
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
line.clear();
}
}
void Rinex_Printer::rinex_obs_header(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, const double d_TOW_first_observation, const std::string glonass_bands)
{
if (eph.d_m)
@ -6841,6 +7204,235 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Gps_Ephemeris& gps
}
void Rinex_Printer::Rinex_Printer::rinex_obs_header(std::fstream& out, const Beidou_Dnav_Ephemeris& eph, const double d_TOW_first_observation, const std::string bands)
{
std::string line;
version = 3;
// -------- Line 1
line = std::string(5, ' ');
line += "3.02";
line += std::string(11, ' ');
line += Rinex_Printer::leftJustify("OBSERVATION DATA", 20);
line += satelliteSystem["BeiDou "];
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 C = BEIDOU 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("BEIDOU 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 https://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 OBSERVER / AGENCY
line.clear();
std::string username;
char c_username[20] = {0};
int32_t 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
uint32_t number_of_observations = 0;
std::string signal_("B1");
std::size_t found_B1 = bands.find(signal_);
if (found_B1 != std::string::npos)
{
number_of_observations = number_of_observations + 4;
}
signal_ = "B3";
std::size_t found_B3 = bands.find(signal_);
if (found_B3 != std::string::npos)
{
number_of_observations = number_of_observations + 4;
}
line.clear();
line += satelliteSystem["Beidou"];
line += std::string(2, ' ');
line += Rinex_Printer::rightJustify(std::to_string(number_of_observations), 3);
if (found_B1 != std::string::npos)
{
line += std::string(1, ' ');
line += observationType["PSEUDORANGE"];
line += observationCode["BEIDOU_B1_I"];
line += std::string(1, ' ');
line += observationType["CARRIER_PHASE"];
line += observationCode["BEIDOU_B1_I"];
line += std::string(1, ' ');
line += observationType["DOPPLER"];
line += observationCode["BEIDOU_B1_I"];
line += std::string(1, ' ');
line += observationType["SIGNAL_STRENGTH"];
line += observationCode["BEIDOU_B1_I"];
}
if (found_B3 != std::string::npos)
{
line += std::string(1, ' ');
line += observationType["PSEUDORANGE"];
line += observationCode["BEIDOU_B3_I"];
line += std::string(1, ' ');
line += observationType["CARRIER_PHASE"];
line += observationCode["BEIDOU_B3_I"];
line += std::string(1, ' ');
line += observationType["DOPPLER"];
line += observationCode["BEIDOU_B3_I"];
line += std::string(1, ' ');
line += observationType["SIGNAL_STRENGTH"];
line += observationCode["BEIDOU_B3_I"];
}
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();
boost::posix_time::ptime p_bds_time = Rinex_Printer::compute_BDS_time(eph, d_TOW_first_observation);
std::string timestring = boost::posix_time::to_iso_string(p_bds_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 beidou_t = d_TOW_first_observation;
double seconds = fmod(beidou_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("BDT"), 8);
line += std::string(9, ' ');
line += Rinex_Printer::leftJustify("TIME OF FIRST OBS", 20);
Rinex_Printer::lengthCheck(line);
out << line << std::endl;
// -------- SYS /PHASE SHIFTS
// -------- 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::update_obs_header(std::fstream& out __attribute__((unused)), const Glonass_Gnav_Utc_Model& utc_model)
{
if (utc_model.d_N_4)
@ -7050,6 +7642,66 @@ void Rinex_Printer::update_obs_header(std::fstream& out, const Galileo_Utc_Model
}
void Rinex_Printer::update_obs_header(std::fstream& out, const Beidou_Dnav_Utc_Model& utc_model)
{
std::vector<std::string> data;
std::string line_aux;
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("TIME OF FIRST OBS", 59) != std::string::npos)
{
data.push_back(line_str);
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_DeltaT_LS), 6);
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.d_DeltaT_LSF), 6);
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.i_WN_LSF), 6);
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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(obsfilename, std::ios::out | std::ios::trunc);
out.seekp(0);
for (int32_t i = 0; i < static_cast<int32_t>(data.size()) - 1; i++)
{
out << data[i] << std::endl;
}
out.close();
out.open(obsfilename, std::ios::out | std::ios::in | std::ios::app);
out.seekp(0, std::ios_base::end);
}
void Rinex_Printer::log_rinex_obs(std::fstream& out, const Glonass_Gnav_Ephemeris& eph, const double obs_time, const std::map<int32_t, Gnss_Synchro>& observables, const std::string glonass_band)
{
// RINEX observations timestamps are GPS timestamps.
@ -9760,6 +10412,178 @@ void Rinex_Printer::log_rinex_obs(std::fstream& out, const Gps_Ephemeris& gps_ep
}
void Rinex_Printer::log_rinex_obs(std::fstream& out, const Beidou_Dnav_Ephemeris& eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables, const std::string bds_bands)
{
// RINEX observations timestamps are Galileo timestamps.
// See http://gage14.upc.es/gLAB/HTML/Observation_Rinex_v3.01.html
std::string line;
boost::posix_time::ptime p_bds_time = Rinex_Printer::compute_BDS_time(eph, obs_time);
std::string timestring = boost::posix_time::to_iso_string(p_bds_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 bds_t = 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(bds_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 BeiDou observations
std::map<int32_t, Gnss_Synchro> observablesB1I;
std::map<int32_t, Gnss_Synchro> observablesB3I;
std::map<int32_t, Gnss_Synchro>::const_iterator observables_iter;
for (observables_iter = observables.cbegin();
observables_iter != observables.cend();
observables_iter++)
{
std::string system_(&observables_iter->second.System, 1);
std::string sig_(observables_iter->second.Signal);
if ((system_.compare("C") == 0) && (sig_.compare("B1") == 0))
{
observablesB1I.insert(std::pair<int32_t, Gnss_Synchro>(observables_iter->first, observables_iter->second));
}
if ((system_.compare("C") == 0) && (sig_.compare("B3") == 0))
{
observablesB3I.insert(std::pair<int32_t, Gnss_Synchro>(observables_iter->first, observables_iter->second));
}
}
std::size_t found_B1 = bds_bands.find("B1");
std::size_t found_B3 = bds_bands.find("B3");
std::multimap<uint32_t, Gnss_Synchro> total_map;
std::set<uint32_t> available_prns;
std::set<uint32_t>::iterator it;
if (found_B1 != std::string::npos)
{
for (observables_iter = observablesB1I.cbegin();
observables_iter != observablesB1I.cend();
observables_iter++)
{
uint32_t prn_ = observables_iter->second.PRN;
total_map.insert(std::pair<uint32_t, Gnss_Synchro>(prn_, observables_iter->second));
it = available_prns.find(prn_);
if (it == available_prns.end())
{
available_prns.insert(prn_);
}
}
}
if (found_B3 != std::string::npos)
{
for (observables_iter = observablesB3I.cbegin();
observables_iter != observablesB3I.cend();
observables_iter++)
{
uint32_t prn_ = observables_iter->second.PRN;
it = available_prns.find(prn_);
if (it == available_prns.end())
{
available_prns.insert(prn_);
if (found_B1 != std::string::npos)
{
Gnss_Synchro gs = Gnss_Synchro();
std::string sys = "C";
gs.System = *sys.c_str();
std::string sig = "B1";
std::memcpy(static_cast<void*>(gs.Signal), sig.c_str(), 3);
gs.PRN = prn_;
total_map.insert(std::pair<uint32_t, Gnss_Synchro>(prn_, gs));
}
}
total_map.insert(std::pair<uint32_t, Gnss_Synchro>(prn_, observables_iter->second));
}
}
int32_t numSatellitesObserved = available_prns.size();
line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(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;
std::string lineObs;
std::pair<std::multimap<uint32_t, Gnss_Synchro>::iterator, std::multimap<uint32_t, Gnss_Synchro>::iterator> ret;
for (it = available_prns.begin();
it != available_prns.end();
it++)
{
lineObs.clear();
lineObs += satelliteSystem["Beidou"];
if (static_cast<int32_t>(*it) < 10) lineObs += std::string(1, '0');
lineObs += boost::lexical_cast<std::string>(static_cast<int32_t>(*it));
ret = total_map.equal_range(*it);
for (std::multimap<uint32_t, Gnss_Synchro>::iterator iter = ret.first; iter != ret.second; ++iter)
{
lineObs += Rinex_Printer::rightJustify(asString(iter->second.Pseudorange_m, 3), 14);
//Loss of lock indicator (LLI)
int32_t lli = 0; // Include in the observation!!
if (lli == 0)
{
lineObs += std::string(1, ' ');
}
// Signal Strength Indicator (SSI)
int32_t ssi = Rinex_Printer::signalStrength(iter->second.CN0_dB_hz);
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int32_t>(ssi), 1);
// CARRIER PHASE
lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_phase_rads / (BEIDOU_TWO_PI), 3), 14);
if (lli == 0)
{
lineObs += std::string(1, ' ');
}
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int32_t>(ssi), 1);
// DOPPLER
lineObs += Rinex_Printer::rightJustify(asString(iter->second.Carrier_Doppler_hz, 3), 14);
if (lli == 0)
{
lineObs += std::string(1, ' ');
}
lineObs += Rinex_Printer::rightJustify(Rinex_Printer::asString<int32_t>(ssi), 1);
// 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::to_date_time(int32_t gps_week, int32_t 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.
@ -9932,6 +10756,19 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Gps_Navigation_Me
}
boost::posix_time::ptime Rinex_Printer::compute_BDS_time(const Beidou_Dnav_Ephemeris& eph, const double obs_time)
{
// The RINEX v2.11 v3.00 format uses GPS time for the observations epoch, not UTC time, thus, no leap seconds needed here.
// (see Section 3 in http://igscb.jpl.nasa.gov/igscb/data/format/rinex211.txt)
// (see Pag. 17 in http://igscb.jpl.nasa.gov/igscb/data/format/rinex300.pdf)
// --??? No time correction here, since it will be done in the RINEX processor
const double bds_t = obs_time;
boost::posix_time::time_duration t = boost::posix_time::milliseconds(static_cast<int64_t>((bds_t + 604800 * static_cast<double>(eph.i_BEIDOU_week % 8192)) * 1000));
boost::posix_time::ptime p_time(boost::gregorian::date(2006, 1, 1), t);
return p_time;
}
boost::posix_time::ptime Rinex_Printer::compute_GPS_time(const Gps_Ephemeris& eph, const double obs_time)
{
// The RINEX v2.11 v3.00 format uses GPS time for the observations epoch, not UTC time, thus, no leap seconds needed here.

View File

@ -55,9 +55,11 @@
#include "gps_cnav_navigation_message.h"
#include "galileo_navigation_message.h"
#include "glonass_gnav_navigation_message.h"
#include "beidou_dnav_navigation_message.h"
#include "GPS_L1_CA.h"
#include "Galileo_E1.h"
#include "GLONASS_L1_L2_CA.h"
#include "Beidou_B1I.h"
#include "gnss_synchro.h"
#include <boost/date_time/posix_time/posix_time.hpp>
#include <cstdint>
@ -91,6 +93,7 @@ public:
std::fstream sbsFile; //<! Output file stream for RINEX SBAS raw data file
std::fstream navGalFile; //<! Output file stream for RINEX Galileo navigation data file
std::fstream navGloFile; //<! Output file stream for RINEX GLONASS navigation data file
std::fstream navBdsFile; //<! Output file stream for RINEX Galileo navigation data file
std::fstream navMixFile; //<! Output file stream for RINEX Mixed navigation data file
/*!
@ -138,6 +141,8 @@ public:
*/
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);
void rinex_nav_header(std::fstream& out, const Beidou_Dnav_Iono& iono, const Beidou_Dnav_Utc_Model& utc_model);
/*!
* \brief Generates the GPS Observation data header
*/
@ -193,11 +198,25 @@ public:
*/
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 a Beidou B1I Observation data header. Example: beidou_bands("B1")
*/
void rinex_obs_header(std::fstream& out, const Beidou_Dnav_Ephemeris& eph, const double d_TOW_first_observation, const std::string bands);
/*!
* \brief Generates the SBAS raw data header
*/
void rinex_sbs_header(std::fstream& out);
/*!
* \brief Computes the BDS Time and returns a boost::posix_time::ptime object
* \details Function used to convert the observation time into BDT time which is used
* as the default time for RINEX files
* \param eph BeiDou DNAV Ephemeris object
* \param obs_time Observation time in BDT seconds of week
*/
boost::posix_time::ptime compute_BDS_time(const Beidou_Dnav_Ephemeris& eph, const double obs_time);
/*!
* \brief Computes the UTC time and returns a boost::posix_time::ptime object
*/
@ -279,6 +298,11 @@ public:
*/
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Galileo_Ephemeris>& galileo_eph_map, const std::map<int32_t, Glonass_Gnav_Ephemeris>& glonass_gnav_eph_map);
/*!
* \brief Writes data from the Beidou B1I navigation message into the RINEX file
*/
void log_rinex_nav(std::fstream& out, const std::map<int32_t, Beidou_Dnav_Ephemeris>& eph_map);
/*!
* \brief Writes GPS L1 observables into the RINEX file
*/
@ -334,6 +358,12 @@ public:
*/
void log_rinex_obs(std::fstream& out, const Galileo_Ephemeris& galileo_eph, const Glonass_Gnav_Ephemeris& glonass_gnav_eph, const double gps_obs_time, const std::map<int32_t, Gnss_Synchro>& observables);
/*!
* \brief Writes BDS B1I observables into the RINEX file
*/
void log_rinex_obs(std::fstream& out, const Beidou_Dnav_Ephemeris& eph, double obs_time, const std::map<int32_t, Gnss_Synchro>& observables, const std::string bds_bands);
/*!
* \brief Represents GPS time in the date time format. Leap years are considered, but leap seconds are not.
*/
@ -362,6 +392,8 @@ public:
void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model, const Glonass_Gnav_Almanac& glonass_gnav_almanac);
void update_nav_header(std::fstream& out, const Beidou_Dnav_Utc_Model& beidou_dnav_utc, const Beidou_Dnav_Iono& beidou_dnav_iono);
void update_obs_header(std::fstream& out, const Gps_Utc_Model& utc_model);
void update_obs_header(std::fstream& out, const Gps_CNAV_Utc_Model& utc_model);
@ -370,6 +402,8 @@ public:
void update_obs_header(std::fstream& out, const Glonass_Gnav_Utc_Model& glonass_gnav_utc_model);
void update_obs_header(std::fstream& out, const Beidou_Dnav_Utc_Model& utc_model);
std::map<std::string, std::string> satelliteSystem; //<! GPS, GLONASS, SBAS payload, Galileo or Compass
std::map<std::string, std::string> observationType; //<! PSEUDORANGE, CARRIER_PHASE, DOPPLER, SIGNAL_STRENGTH
std::map<std::string, std::string> observationCode; //<! GNSS observation descriptors
@ -380,6 +414,7 @@ public:
std::string sbsfilename;
std::string navGalfilename;
std::string navGlofilename;
std::string navBdsfilename;
std::string navMixfilename;
private:

View File

@ -34,6 +34,9 @@
#ifndef GNSS_SDR_BEIDOU_DNAV_ALMANAC_H_
#define GNSS_SDR_BEIDOU_DNAV_ALMANAC_H_
#include <boost/serialization/nvp.hpp>
#include <cstdint>
/*!
* \brief This class is a storage for the GPS SV ALMANAC data as described in IS-GPS-200E
@ -60,6 +63,29 @@ public:
* Default constructor
*/
Beidou_Dnav_Almanac();
template <class Archive>
void serialize(Archive& ar, const unsigned int version)
{
if (version)
{
};
ar& BOOST_SERIALIZATION_NVP(i_satellite_PRN);
ar& BOOST_SERIALIZATION_NVP(d_Delta_i);
ar& BOOST_SERIALIZATION_NVP(d_Toa);
//ar& BOOST_SERIALIZATION_NVP(i_WNa);
ar& BOOST_SERIALIZATION_NVP(d_M_0);
ar& BOOST_SERIALIZATION_NVP(d_e_eccentricity);
ar& BOOST_SERIALIZATION_NVP(d_sqrt_A);
ar& BOOST_SERIALIZATION_NVP(d_OMEGA0);
ar& BOOST_SERIALIZATION_NVP(d_OMEGA);
ar& BOOST_SERIALIZATION_NVP(d_OMEGA_DOT);
ar& BOOST_SERIALIZATION_NVP(i_SV_health);
//ar& BOOST_SERIALIZATION_NVP(i_AS_status);
ar& BOOST_SERIALIZATION_NVP(d_A_f0);
ar& BOOST_SERIALIZATION_NVP(d_A_f1);
}
};
#endif