1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-06-24 22:13:15 +00:00

Adding generation of MSM2, MSM3, MSM4, MSM5, MSM6 and MSM7

This commit is contained in:
Carles Fernandez 2015-12-09 13:33:28 +01:00
parent 450728dfeb
commit 49523f7f9d
3 changed files with 851 additions and 37 deletions

View File

@ -269,11 +269,11 @@ std::string Rtcm::build_message(std::string data)
// **********************************************
// ********************************************************
//
// MESSAGE TYPE 1001 (GPS L1 OBSERVATIONS)
//
// **********************************************
// ********************************************************
std::bitset<64> Rtcm::get_MT1001_4_header(unsigned int msg_number, const Gps_Ephemeris & gps_eph, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id, unsigned int smooth_int, bool sync_flag, bool divergence_free)
@ -363,11 +363,11 @@ std::string Rtcm::print_MT1001(const Gps_Ephemeris & gps_eph, double obs_time, c
// **********************************************
// ********************************************************
//
// MESSAGE TYPE 1002 (EXTENDED GPS L1 OBSERVATIONS)
//
// **********************************************
// ********************************************************
std::string Rtcm::print_MT1002(const Gps_Ephemeris & gps_eph, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges)
{
@ -430,11 +430,11 @@ std::bitset<74> Rtcm::get_MT1002_sat_content(const Gps_Ephemeris & eph, double o
// **********************************************
// ********************************************************
//
// MESSAGE TYPE 1003 (GPS L1 & L2 OBSERVATIONS)
//
// **********************************************
// ********************************************************
std::string Rtcm::print_MT1003(const Gps_Ephemeris & ephL1, const Gps_CNAV_Ephemeris & ephL2, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges)
{
@ -535,11 +535,11 @@ std::bitset<101> Rtcm::get_MT1003_sat_content(const Gps_Ephemeris & ephL1, const
// **********************************************
// ******************************************************************
//
// MESSAGE TYPE 1004 (EXTENDED GPS L1 & L2 OBSERVATIONS)
//
// **********************************************
// ******************************************************************
std::string Rtcm::print_MT1004(const Gps_Ephemeris & ephL1, const Gps_CNAV_Ephemeris & ephL2, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges)
{
@ -646,11 +646,11 @@ std::bitset<125> Rtcm::get_MT1004_sat_content(const Gps_Ephemeris & ephL1, const
// **********************************************
// ********************************************************
//
// MESSAGE TYPE 1005 (STATION DESCRIPTION)
//
// **********************************************
// ********************************************************
/* Stationary Antenna Reference Point, No Height Information
@ -818,11 +818,11 @@ std::string Rtcm::print_MT1005_test()
// **********************************************
// ********************************************************
//
// MESSAGE TYPE 1019 (GPS EPHEMERIS)
//
// **********************************************
// ********************************************************
std::string Rtcm::print_MT1019(const Gps_Ephemeris & gps_eph)
{
@ -1034,11 +1034,11 @@ int Rtcm::read_MT1019(const std::string & message, Gps_Ephemeris & gps_eph)
// **********************************************
// ********************************************************
//
// MESSAGE TYPE 1045 (GALILEO EPHEMERIS)
//
// **********************************************
// ********************************************************
std::string Rtcm::print_MT1045(const Galileo_Ephemeris & gal_eph)
{
@ -1237,14 +1237,14 @@ int Rtcm::read_MT1045(const std::string & message, Galileo_Ephemeris & gal_eph)
// **********************************************
// **********************************************************************************************
//
// MESSAGE TYPE MSM1 (COMPACT PSEUDORANGES)
//
// **********************************************
// **********************************************************************************************
std::string Rtcm::print_MSM_1( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
@ -1258,8 +1258,9 @@ std::string Rtcm::print_MSM_1( const Gps_Ephemeris & gps_eph,
{
unsigned int msg_number = 0;
if(gps_eph.i_satellite_PRN != 0) msg_number = 1071;
if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1071;
if(gal_eph.i_satellite_PRN != 0) msg_number = 1091;
if((gps_eph.i_satellite_PRN != 0) && (gal_eph.i_satellite_PRN != 0))
if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0))
{
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages?
}
@ -1269,7 +1270,7 @@ std::string Rtcm::print_MSM_1( const Gps_Ephemeris & gps_eph,
msg_number = 1071;
}
std::string header = Rtcm::get_MSM_header(msg_number, gps_eph,
std::string header = Rtcm::get_MSM_header(msg_number, gps_eph, gps_cnav_eph,
gal_eph,
obs_time,
pseudoranges,
@ -1291,6 +1292,7 @@ std::string Rtcm::print_MSM_1( const Gps_Ephemeris & gps_eph,
std::string Rtcm::get_MSM_header(unsigned int msg_number, const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
@ -1308,6 +1310,10 @@ std::string Rtcm::get_MSM_header(unsigned int msg_number, const Gps_Ephemeris &
{
Rtcm::set_DF004(gps_eph, obs_time);
}
else if(gps_cnav_eph.i_satellite_PRN != 0)
{
Rtcm::set_DF004(gps_cnav_eph, obs_time);
}
else
{
Rtcm::set_DF248(gal_eph, obs_time);
@ -1414,21 +1420,681 @@ std::string Rtcm::get_MSM_1_content_signal_data(const std::map<int, Gnss_Synchro
}
// **********************************************
// **********************************************************************************************
//
// MESSAGE TYPE MSM2 (COMPACT PHASERANGES)
//
// **********************************************
// **********************************************************************************************
std::string Rtcm::print_MSM_2( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages)
{
unsigned int msg_number = 0;
if(gps_eph.i_satellite_PRN != 0) msg_number = 1072;
if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1072;
if(gal_eph.i_satellite_PRN != 0) msg_number = 1092;
if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0))
{
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages?
}
if(msg_number == 0)
{
LOG(WARNING) << "Invalid ephemeris provided";
msg_number = 1072;
}
std::string header = Rtcm::get_MSM_header(msg_number, gps_eph, gps_cnav_eph,
gal_eph,
obs_time,
pseudoranges,
ref_id,
clock_steering_indicator,
external_clock_indicator,
smooth_int,
sync_flag,
divergence_free,
more_messages);
std::string sat_data = Rtcm::get_MSM_1_content_sat_data(pseudoranges);
std::string signal_data = Rtcm::get_MSM_2_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, pseudoranges);
std::string message = build_message(header + sat_data + signal_data);
return message;
}
std::string Rtcm::get_MSM_2_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges)
{
std::string signal_data;
std::string first_data_type;
std::string second_data_type;
std::string third_data_type;
unsigned int Ncells = pseudoranges.size();
std::vector<std::pair<int, Gnss_Synchro> > pseudoranges_vector;
std::map<int, Gnss_Synchro>::const_iterator map_iter;
for(map_iter = pseudoranges.begin();
map_iter != pseudoranges.end();
map_iter++)
{
pseudoranges_vector.push_back(*map_iter);
}
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(pseudoranges_vector);
std::reverse(ordered_by_signal.begin(), ordered_by_signal.end());
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal);
for(unsigned int cell = 0; cell < Ncells ; cell++)
{
Rtcm::set_DF401(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second);
first_data_type += DF401.to_string();
second_data_type += DF402.to_string();
third_data_type += DF420.to_string();
}
signal_data = first_data_type + second_data_type + third_data_type;
return signal_data;
}
// **********************************************************************************************
//
// MESSAGE TYPE MSM3 (COMPACT PSEUDORANGES AND PHASERANGES)
//
// **********************************************************************************************
std::string Rtcm::print_MSM_3( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages)
{
unsigned int msg_number = 0;
if(gps_eph.i_satellite_PRN != 0) msg_number = 1073;
if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1073;
if(gal_eph.i_satellite_PRN != 0) msg_number = 1093;
if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0))
{
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages?
}
if(msg_number == 0)
{
LOG(WARNING) << "Invalid ephemeris provided";
msg_number = 1073;
}
std::string header = Rtcm::get_MSM_header(msg_number, gps_eph, gps_cnav_eph,
gal_eph,
obs_time,
pseudoranges,
ref_id,
clock_steering_indicator,
external_clock_indicator,
smooth_int,
sync_flag,
divergence_free,
more_messages);
std::string sat_data = Rtcm::get_MSM_1_content_sat_data(pseudoranges);
std::string signal_data = Rtcm::get_MSM_3_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, pseudoranges);
std::string message = build_message(header + sat_data + signal_data);
return message;
}
std::string Rtcm::get_MSM_3_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges)
{
std::string signal_data;
std::string first_data_type;
std::string second_data_type;
std::string third_data_type;
std::string fourth_data_type;
unsigned int Ncells = pseudoranges.size();
std::vector<std::pair<int, Gnss_Synchro> > pseudoranges_vector;
std::map<int, Gnss_Synchro>::const_iterator map_iter;
for(map_iter = pseudoranges.begin();
map_iter != pseudoranges.end();
map_iter++)
{
pseudoranges_vector.push_back(*map_iter);
}
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(pseudoranges_vector);
std::reverse(ordered_by_signal.begin(), ordered_by_signal.end());
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal);
for(unsigned int cell = 0; cell < Ncells ; cell++)
{
Rtcm::set_DF400(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF401(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second);
first_data_type += DF400.to_string();
second_data_type += DF401.to_string();
third_data_type += DF402.to_string();
fourth_data_type += DF420.to_string();
}
signal_data = first_data_type + second_data_type + third_data_type + fourth_data_type;
return signal_data;
}
// **********************************************************************************************
//
// MESSAGE TYPE MSM4 (FULL PSEUDORANGES AND PHASERANGES PLUS CNR)
//
// **********************************************************************************************
std::string Rtcm::print_MSM_4( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages)
{
unsigned int msg_number = 0;
if(gps_eph.i_satellite_PRN != 0) msg_number = 1074;
if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1074;
if(gal_eph.i_satellite_PRN != 0) msg_number = 1094;
if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0))
{
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages?
}
if(msg_number == 0)
{
LOG(WARNING) << "Invalid ephemeris provided";
msg_number = 1074;
}
std::string header = Rtcm::get_MSM_header(msg_number, gps_eph, gps_cnav_eph,
gal_eph,
obs_time,
pseudoranges,
ref_id,
clock_steering_indicator,
external_clock_indicator,
smooth_int,
sync_flag,
divergence_free,
more_messages);
std::string sat_data = Rtcm::get_MSM_4_content_sat_data(pseudoranges);
std::string signal_data = Rtcm::get_MSM_4_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, pseudoranges);
std::string message = build_message(header + sat_data + signal_data);
return message;
}
std::string Rtcm::get_MSM_4_content_sat_data(const std::map<int, Gnss_Synchro> & pseudoranges)
{
//std::map<int, Gnss_Synchro>::const_iterator gnss_synchro_iter;
std::string data("Not implemented");
return data;
std::string sat_data;
std::string first_data_type;
std::string second_data_type;
Rtcm::set_DF394(pseudoranges);
unsigned int num_satellites = DF394.count();
std::vector<std::pair<int, Gnss_Synchro> > pseudoranges_vector;
std::map<int, Gnss_Synchro>::const_iterator gnss_synchro_iter;
std::vector<unsigned int> pos;
std::vector<unsigned int>::iterator it;
for(gnss_synchro_iter = pseudoranges.begin();
gnss_synchro_iter != pseudoranges.end();
gnss_synchro_iter++)
{
it = std::find(pos.begin(), pos.end(), 65 - gnss_synchro_iter->second.PRN);
if(it == pos.end())
{
pos.push_back(65 - gnss_synchro_iter->second.PRN);
pseudoranges_vector.push_back(*gnss_synchro_iter);
}
}
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(pseudoranges_vector);
for(unsigned int nsat = 0; nsat < num_satellites; nsat++)
{
Rtcm::set_DF397( ordered_by_PRN_pos.at(nsat).second );
Rtcm::set_DF398( ordered_by_PRN_pos.at(nsat).second );
first_data_type += DF397.to_string();
second_data_type += DF398.to_string();
}
sat_data = first_data_type + second_data_type;
return sat_data;
}
std::string Rtcm::get_MSM_4_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges)
{
std::string signal_data;
std::string first_data_type;
std::string second_data_type;
std::string third_data_type;
std::string fourth_data_type;
std::string fifth_data_type;
unsigned int Ncells = pseudoranges.size();
std::vector<std::pair<int, Gnss_Synchro> > pseudoranges_vector;
std::map<int, Gnss_Synchro>::const_iterator map_iter;
for(map_iter = pseudoranges.begin();
map_iter != pseudoranges.end();
map_iter++)
{
pseudoranges_vector.push_back(*map_iter);
}
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(pseudoranges_vector);
std::reverse(ordered_by_signal.begin(), ordered_by_signal.end());
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal);
for(unsigned int cell = 0; cell < Ncells ; cell++)
{
Rtcm::set_DF400(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF401(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF403(ordered_by_PRN_pos.at( cell ).second);
first_data_type += DF400.to_string();
second_data_type += DF401.to_string();
third_data_type += DF402.to_string();
fourth_data_type += DF420.to_string();
fifth_data_type += DF403.to_string();
}
signal_data = first_data_type + second_data_type + third_data_type + fourth_data_type + fifth_data_type;
return signal_data;
}
// **********************************************************************************************
//
// MESSAGE TYPE MSM5 (FULL PSEUDORANGES, PHASERANGES, PHASERANGERATE PLUS CNR)
//
// **********************************************************************************************
std::string Rtcm::print_MSM_5( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages)
{
unsigned int msg_number = 0;
if(gps_eph.i_satellite_PRN != 0) msg_number = 1075;
if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1075;
if(gal_eph.i_satellite_PRN != 0) msg_number = 1095;
if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0))
{
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages?
}
if(msg_number == 0)
{
LOG(WARNING) << "Invalid ephemeris provided";
msg_number = 1075;
}
std::string header = Rtcm::get_MSM_header(msg_number, gps_eph, gps_cnav_eph,
gal_eph,
obs_time,
pseudoranges,
ref_id,
clock_steering_indicator,
external_clock_indicator,
smooth_int,
sync_flag,
divergence_free,
more_messages);
std::string sat_data = Rtcm::get_MSM_5_content_sat_data(pseudoranges);
std::string signal_data = Rtcm::get_MSM_5_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, pseudoranges);
std::string message = build_message(header + sat_data + signal_data);
return message;
}
std::string Rtcm::get_MSM_5_content_sat_data(const std::map<int, Gnss_Synchro> & pseudoranges)
{
std::string sat_data;
std::string first_data_type;
std::string second_data_type;
std::string third_data_type;
std::string fourth_data_type;
Rtcm::set_DF394(pseudoranges);
unsigned int num_satellites = DF394.count();
std::vector<std::pair<int, Gnss_Synchro> > pseudoranges_vector;
std::map<int, Gnss_Synchro>::const_iterator gnss_synchro_iter;
std::vector<unsigned int> pos;
std::vector<unsigned int>::iterator it;
for(gnss_synchro_iter = pseudoranges.begin();
gnss_synchro_iter != pseudoranges.end();
gnss_synchro_iter++)
{
it = std::find(pos.begin(), pos.end(), 65 - gnss_synchro_iter->second.PRN);
if(it == pos.end())
{
pos.push_back(65 - gnss_synchro_iter->second.PRN);
pseudoranges_vector.push_back(*gnss_synchro_iter);
}
}
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(pseudoranges_vector);
for(unsigned int nsat = 0; nsat < num_satellites; nsat++)
{
Rtcm::set_DF397( ordered_by_PRN_pos.at(nsat).second );
Rtcm::set_DF398( ordered_by_PRN_pos.at(nsat).second );
Rtcm::set_DF399( ordered_by_PRN_pos.at(nsat).second );
std::bitset<4> reserved = std::bitset<4>("0000");
first_data_type += DF397.to_string();
second_data_type += reserved.to_string();
third_data_type += DF398.to_string();
fourth_data_type += DF399.to_string();
}
sat_data = first_data_type + second_data_type + third_data_type + fourth_data_type;
return sat_data;
}
std::string Rtcm::get_MSM_5_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges)
{
std::string signal_data;
std::string first_data_type;
std::string second_data_type;
std::string third_data_type;
std::string fourth_data_type;
std::string fifth_data_type;
std::string sixth_data_type;
unsigned int Ncells = pseudoranges.size();
std::vector<std::pair<int, Gnss_Synchro> > pseudoranges_vector;
std::map<int, Gnss_Synchro>::const_iterator map_iter;
for(map_iter = pseudoranges.begin();
map_iter != pseudoranges.end();
map_iter++)
{
pseudoranges_vector.push_back(*map_iter);
}
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(pseudoranges_vector);
std::reverse(ordered_by_signal.begin(), ordered_by_signal.end());
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal);
for(unsigned int cell = 0; cell < Ncells ; cell++)
{
Rtcm::set_DF400(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF401(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF402(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF403(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF404(ordered_by_PRN_pos.at( cell ).second);
first_data_type += DF400.to_string();
second_data_type += DF401.to_string();
third_data_type += DF402.to_string();
fourth_data_type += DF420.to_string();
fifth_data_type += DF403.to_string();
sixth_data_type += DF404.to_string();
}
signal_data = first_data_type + second_data_type + third_data_type + fourth_data_type + fifth_data_type + sixth_data_type;
return signal_data;
}
// **********************************************************************************************
//
// MESSAGE TYPE MSM6 (FULL PSEUDORANGES AND PHASERANGES PLUS CNR, HIGH RESOLUTION)
//
// **********************************************************************************************
std::string Rtcm::print_MSM_6( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages)
{
unsigned int msg_number = 0;
if(gps_eph.i_satellite_PRN != 0) msg_number = 1076;
if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1076;
if(gal_eph.i_satellite_PRN != 0) msg_number = 1096;
if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0))
{
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages?
}
if(msg_number == 0)
{
LOG(WARNING) << "Invalid ephemeris provided";
msg_number = 1076;
}
std::string header = Rtcm::get_MSM_header(msg_number, gps_eph, gps_cnav_eph,
gal_eph,
obs_time,
pseudoranges,
ref_id,
clock_steering_indicator,
external_clock_indicator,
smooth_int,
sync_flag,
divergence_free,
more_messages);
std::string sat_data = Rtcm::get_MSM_4_content_sat_data(pseudoranges);
std::string signal_data = Rtcm::get_MSM_6_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, pseudoranges);
std::string message = build_message(header + sat_data + signal_data);
return message;
}
std::string Rtcm::get_MSM_6_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges)
{
std::string signal_data;
std::string first_data_type;
std::string second_data_type;
std::string third_data_type;
std::string fourth_data_type;
std::string fifth_data_type;
unsigned int Ncells = pseudoranges.size();
std::vector<std::pair<int, Gnss_Synchro> > pseudoranges_vector;
std::map<int, Gnss_Synchro>::const_iterator map_iter;
for(map_iter = pseudoranges.begin();
map_iter != pseudoranges.end();
map_iter++)
{
pseudoranges_vector.push_back(*map_iter);
}
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(pseudoranges_vector);
std::reverse(ordered_by_signal.begin(), ordered_by_signal.end());
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal);
for(unsigned int cell = 0; cell < Ncells ; cell++)
{
Rtcm::set_DF405(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF406(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF407(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF408(ordered_by_PRN_pos.at( cell ).second);
first_data_type += DF405.to_string();
second_data_type += DF406.to_string();
third_data_type += DF407.to_string();
fourth_data_type += DF420.to_string();
fifth_data_type += DF408.to_string();
}
signal_data = first_data_type + second_data_type + third_data_type + fourth_data_type + fifth_data_type;
return signal_data;
}
// **********************************************************************************************
//
// MESSAGE TYPE MSM7 (FULL PSEUDORANGES, PHASERANGES, PHASERANGERATE AND CNR, HIGH RESOLUTION)
//
// **********************************************************************************************
std::string Rtcm::print_MSM_7( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages)
{
unsigned int msg_number = 0;
if(gps_eph.i_satellite_PRN != 0) msg_number = 1077;
if(gps_cnav_eph.i_satellite_PRN != 0) msg_number = 1077;
if(gal_eph.i_satellite_PRN != 0) msg_number = 1097;
if(((gps_eph.i_satellite_PRN != 0) ||(gps_cnav_eph.i_satellite_PRN != 0) ) && (gal_eph.i_satellite_PRN != 0))
{
LOG(WARNING) << "MSM messages for observables from different systems are not defined"; //print two messages?
}
if(msg_number == 0)
{
LOG(WARNING) << "Invalid ephemeris provided";
msg_number = 1076;
}
std::string header = Rtcm::get_MSM_header(msg_number, gps_eph, gps_cnav_eph,
gal_eph,
obs_time,
pseudoranges,
ref_id,
clock_steering_indicator,
external_clock_indicator,
smooth_int,
sync_flag,
divergence_free,
more_messages);
std::string sat_data = Rtcm::get_MSM_5_content_sat_data(pseudoranges);
std::string signal_data = Rtcm::get_MSM_7_content_signal_data(gps_eph, gps_cnav_eph, gal_eph, obs_time, pseudoranges);
std::string message = build_message(header + sat_data + signal_data);
return message;
}
std::string Rtcm::get_MSM_7_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges)
{
std::string signal_data;
std::string first_data_type;
std::string second_data_type;
std::string third_data_type;
std::string fourth_data_type;
std::string fifth_data_type;
std::string sixth_data_type;
unsigned int Ncells = pseudoranges.size();
std::vector<std::pair<int, Gnss_Synchro> > pseudoranges_vector;
std::map<int, Gnss_Synchro>::const_iterator map_iter;
for(map_iter = pseudoranges.begin();
map_iter != pseudoranges.end();
map_iter++)
{
pseudoranges_vector.push_back(*map_iter);
}
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(pseudoranges_vector);
std::reverse(ordered_by_signal.begin(), ordered_by_signal.end());
std::vector<std::pair<int, Gnss_Synchro> > ordered_by_PRN_pos = Rtcm::sort_by_PRN_mask(ordered_by_signal);
for(unsigned int cell = 0; cell < Ncells ; cell++)
{
Rtcm::set_DF405(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF406(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF407(ephNAV, ephCNAV, ephFNAV, obs_time, ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF420(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF408(ordered_by_PRN_pos.at( cell ).second);
Rtcm::set_DF404(ordered_by_PRN_pos.at( cell ).second);
first_data_type += DF405.to_string();
second_data_type += DF406.to_string();
third_data_type += DF407.to_string();
fourth_data_type += DF420.to_string();
fifth_data_type += DF408.to_string();
sixth_data_type += DF404.to_string();
}
signal_data = first_data_type + second_data_type + third_data_type + fourth_data_type + fifth_data_type + sixth_data_type;
return signal_data;
}
// *****************************************************************************************************
// Some utilities
// *****************************************************************************************************
@ -1886,6 +2552,20 @@ int Rtcm::set_DF004(const Gps_Ephemeris & gps_eph, double obs_time)
}
int Rtcm::set_DF004(const Gps_CNAV_Ephemeris & gps_eph, double obs_time)
{
// TOW in milliseconds from the beginning of the GPS week, measured in GPS time
unsigned long int tow = static_cast<unsigned long int>(std::round((obs_time + 604800 * static_cast<double>(gps_eph.i_GPS_week % 1024)) * 1000));
if(tow > 604799999)
{
LOG(WARNING) << "To large TOW! Set to the last millisecond of the week";
tow = 604799999;
}
DF004 = std::bitset<30>(tow);
return 0;
}
int Rtcm::set_DF005(bool sync_flag)
{
// 0 - No further GNSS observables referenced to the same Epoch Time will be transmitted. This enables the receiver to begin processing
@ -2529,7 +3209,6 @@ int Rtcm::set_DF303(const Galileo_Ephemeris & gal_eph)
}
int Rtcm::set_DF304(const Galileo_Ephemeris & gal_eph)
{
unsigned int toe = static_cast<unsigned int>(std::round(gal_eph.t0e_1 / FNAV_t0e_3_LSB));
@ -2844,7 +3523,6 @@ std::string Rtcm::set_DF396(const std::map<int, Gnss_Synchro> & pseudoranges)
}
int Rtcm::set_DF397(const Gnss_Synchro & gnss_synchro)
{
double meters_to_miliseconds = GPS_C_m_s * 0.001;
@ -2870,7 +3548,6 @@ int Rtcm::set_DF397(const Gnss_Synchro & gnss_synchro)
}
int Rtcm::set_DF398(const Gnss_Synchro & gnss_synchro)
{
double meters_to_miliseconds = GPS_C_m_s * 0.001;

View File

@ -47,8 +47,33 @@
/*!
* \brief This class implements the generation and reading of some Message Types
* defined in the RTCM 3.2 Standard.
* This class implements the generation and reading of some Message Types
* defined in the RTCM 3.2 Standard, plus some utilities to handle messages.
*
* Generation of the following Message Types:
* 1001, 1002, 1003, 1004, 1005, 1019, 1045
*
* Decoding of the following Message Types:
* 1019, 1045
*
* Generation of the following Multiple Signal Messages:
* MSM1 (message types 1071, 1091)
* MSM2 (message types 1072, 1092)
* MSM3 (message types 1073, 1093)
* MSM4 (message types 1074, 1094)
* MSM5 (message types 1075, 1095)
* MSM6 (message types 1076, 1096)
* MSM7 (message types 1077, 1097)
*
* RTCM 3 message format (size in bits):
* +----------+--------+-----------+--------------------+----------+
* | preamble | 000000 | length | data message | parity |
* +----------+--------+-----------+--------------------+----------+
* |<-- 8 --->|<- 6 -->|<-- 10 --->|<--- length x 8 --->|<-- 24 -->|
* +----------+--------+-----------+--------------------+----------+
*
*
* (C) Carles Fernandez-Prades, 2015. cfernandez(at)cttc.es
*/
class Rtcm
{
@ -110,6 +135,7 @@ public:
* \brief Prints messages of type MSM1 (Compact GNSS pseudoranges)
*/
std::string print_MSM_1( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
@ -121,6 +147,106 @@ public:
bool divergence_free,
bool more_messages);
/*!
* \brief Prints messages of type MSM2 (Compact GNSS phaseranges)
*/
std::string print_MSM_2( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages);
/*!
* \brief Prints messages of type MSM3 (Compact GNSS pseudoranges and phaseranges)
*/
std::string print_MSM_3( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages);
/*!
* \brief Prints messages of type MSM4 (Full GNSS pseudoranges and phaseranges plus CNR)
*/
std::string print_MSM_4( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages);
/*!
* \brief Prints messages of type MSM5 (Full GNSS pseudoranges, phaseranges, phaserange rate and CNR)
*/
std::string print_MSM_5( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages);
/*!
* \brief Prints messages of type MSM6 (Full GNSS pseudoranges and phaseranges plus CNR, high resolution)
*/
std::string print_MSM_6( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages);
/*!
* \brief Prints messages of type MSM7 (Full GNSS pseudoranges, phaseranges, phaserange rate and CNR, high resolution)
*/
std::string print_MSM_7( const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
unsigned int ref_id,
unsigned int clock_steering_indicator,
unsigned int external_clock_indicator,
int smooth_int,
bool sync_flag,
bool divergence_free,
bool more_messages);
unsigned int lock_time(const Gps_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro); //<! Returns the time period in which GPS L1 signals have been continually tracked.
unsigned int lock_time(const Gps_CNAV_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro); //<! Returns the time period in which GPS L2 signals have been continually tracked.
unsigned int lock_time(const Galileo_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro); //<! Returns the time period in which Galileo signals have been continually tracked.
std::string bin_to_hex(const std::string& s); //<! Returns a string of hexadecimal symbols from a string of binary symbols
std::string hex_to_bin(const std::string& s); //<! Returns a string of binary symbols from a string of hexadecimal symbols
@ -137,7 +263,7 @@ public:
private:
//
// Messages
// Generation of messages content
//
std::bitset<64> get_MT1001_4_header(unsigned int msg_number,
const Gps_Ephemeris & gps_eph,
@ -156,6 +282,7 @@ private:
std::bitset<152> get_MT1005_test();
std::string get_MSM_header(unsigned int msg_number, const Gps_Ephemeris & gps_eph,
const Gps_CNAV_Ephemeris & gps_cnav_eph,
const Galileo_Ephemeris & gal_eph,
double obs_time,
const std::map<int, Gnss_Synchro> & pseudoranges,
@ -168,11 +295,20 @@ private:
bool more_messages);
std::string get_MSM_1_content_sat_data(const std::map<int, Gnss_Synchro> & pseudoranges);
std::string get_MSM_1_content_signal_data(const std::map<int, Gnss_Synchro> & pseudoranges);
std::string get_MSM_4_content_sat_data(const std::map<int, Gnss_Synchro> & pseudoranges);
std::string get_MSM_5_content_sat_data(const std::map<int, Gnss_Synchro> & pseudoranges);
std::string get_MSM_1_content_signal_data(const std::map<int, Gnss_Synchro> & pseudoranges);
std::string get_MSM_2_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges);
std::string get_MSM_3_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges);
std::string get_MSM_4_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges);
std::string get_MSM_5_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges);
std::string get_MSM_6_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges);
std::string get_MSM_7_content_signal_data(const Gps_Ephemeris & ephNAV, const Gps_CNAV_Ephemeris & ephCNAV, const Galileo_Ephemeris & ephFNAV, double obs_time, const std::map<int, Gnss_Synchro> & pseudoranges);
//
// Utilities
//
static std::map<std::string, int> galileo_signal_map;
static std::map<std::string, int> gps_signal_map;
std::vector<std::pair<int, Gnss_Synchro> > sort_by_signal(const std::vector<std::pair<int, Gnss_Synchro> > & synchro_map);
@ -184,9 +320,6 @@ private:
boost::posix_time::ptime gps_L2_last_lock_time[64];
boost::posix_time::ptime gal_E1_last_lock_time[64];
boost::posix_time::ptime gal_E5_last_lock_time[64];
unsigned int lock_time(const Gps_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro);
unsigned int lock_time(const Gps_CNAV_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro);
unsigned int lock_time(const Galileo_Ephemeris & eph, double obs_time, const Gnss_Synchro & gnss_synchro);
unsigned int lock_time_indicator(unsigned int lock_time_period_s);
unsigned int msm_lock_time_indicator(unsigned int lock_time_period_s);
unsigned int msm_extended_lock_time_indicator(unsigned int lock_time_period_s);
@ -215,6 +348,7 @@ private:
std::bitset<30> DF004;
int set_DF004(const Gps_Ephemeris & gps_eph, double obs_time);
int set_DF004(const Gps_CNAV_Ephemeris & gps_eph, double obs_time);
std::bitset<1> DF005;
int set_DF005(bool sync_flag);

View File

@ -332,6 +332,7 @@ TEST(Rtcm_Test, MSMCell)
gal_eph.i_satellite_PRN = gnss_synchro.PRN;
std::string MSM1 = rtcm->print_MSM_1(gps_eph,
{},
gal_eph,
obs_time,
pseudoranges,
@ -357,6 +358,7 @@ TEST(Rtcm_Test, MSMCell)
pseudoranges2.insert(std::pair<int, Gnss_Synchro>(4, gnss_synchro2));
pseudoranges2.insert(std::pair<int, Gnss_Synchro>(5, gnss_synchro));
std::string MSM1_2 = rtcm->print_MSM_1(gps_eph,
{},
gal_eph,
obs_time,
pseudoranges2,
@ -384,6 +386,7 @@ TEST(Rtcm_Test, MSMCell)
pseudoranges3.insert(std::pair<int, Gnss_Synchro>(5, gnss_synchro5));
std::string MSM1_3 = rtcm->print_MSM_1(gps_eph,
{},
gal_eph,
obs_time,
pseudoranges3,
@ -452,7 +455,7 @@ TEST(Rtcm_Test, MSM1)
gps_eph.i_satellite_PRN = gnss_synchro.PRN;
std::string MSM1 = rtcm->print_MSM_1(gps_eph,
{},
{}, {},
obs_time,
pseudoranges,
ref_id,
@ -501,7 +504,7 @@ TEST(Rtcm_Test, MSM1)
pseudoranges2.insert(std::pair<int, Gnss_Synchro>(3, gnss_synchro2));
pseudoranges2.insert(std::pair<int, Gnss_Synchro>(4, gnss_synchro));
std::string MSM1_2 = rtcm->print_MSM_1(gps_eph,
{},
{}, {},
obs_time,
pseudoranges2,
ref_id,