mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-04-09 20:26:46 +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:
parent
8db3f21070
commit
287c93e5b8
@ -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
|
@ -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
|
@ -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))
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user