mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 07:13:03 +00:00 
			
		
		
		
	unit-test: Adds and fixes unit test for system-parameters block
Adding unit test for system-parameters block, testing string decoding logic for GLONASS GNAV messages. Bug fixes the code after several errors were detected while debugging
This commit is contained in:
		 Damian Miralles
					Damian Miralles
				
			
				
					committed by
					
						 Damian Miralles
						Damian Miralles
					
				
			
			
				
	
			
			
			 Damian Miralles
						Damian Miralles
					
				
			
						parent
						
							3f87223f35
						
					
				
				
					commit
					eb33715cb9
				
			| @@ -3299,8 +3299,7 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Glonass_Gnav_Ephem | |||||||
|     line += std::string(1, ' '); |     line += std::string(1, ' '); | ||||||
|     line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(0), 2); // Frequency Number |     line += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(0), 2); // Frequency Number | ||||||
|     line += std::string(1, ' '); |     line += std::string(1, ' '); | ||||||
|  |     line += std::string(60-line.size(), ' '); | ||||||
|  |  | ||||||
|     line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); |     line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); | ||||||
|     Rinex_Printer::lengthCheck(line); |     Rinex_Printer::lengthCheck(line); | ||||||
|     out << line << std::endl; |     out << line << std::endl; | ||||||
| @@ -3328,7 +3327,8 @@ void Rinex_Printer::rinex_obs_header(std::fstream& out, const Glonass_Gnav_Ephem | |||||||
|     line += observationCode["GLONASS_G2_P"]; |     line += observationCode["GLONASS_G2_P"]; | ||||||
|     line += std::string(1, ' '); |     line += std::string(1, ' '); | ||||||
|     line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); |     line += Rinex_Printer::rightJustify(asString(0.0, 3), 8); | ||||||
|     line += Rinex_Printer::leftJustify("GLONASS SLOT / FRQ #", 20); |     line += std::string(60-line.size(), ' '); | ||||||
|  |     line += Rinex_Printer::leftJustify("GLONASS COD/PHS/BIS", 20); | ||||||
|     Rinex_Printer::lengthCheck(line); |     Rinex_Printer::lengthCheck(line); | ||||||
|     out << line << std::endl; |     out << line << std::endl; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -127,8 +127,8 @@ const std::vector<std::pair<int,int>> KX({{78,8}}); | |||||||
| //STRING 1 | //STRING 1 | ||||||
| const std::vector<std::pair<int,int>> P1({{8,2}}); | const std::vector<std::pair<int,int>> P1({{8,2}}); | ||||||
| const std::vector<std::pair<int,int>> T_K_HR({{10,5}}); | const std::vector<std::pair<int,int>> T_K_HR({{10,5}}); | ||||||
| const std::vector<std::pair<int,int>> T_K_MIN({{10,6}}); | const std::vector<std::pair<int,int>> T_K_MIN({{15,6}}); | ||||||
| const std::vector<std::pair<int,int>> T_K_SEC({{10,1}}); | const std::vector<std::pair<int,int>> T_K_SEC({{21,1}}); | ||||||
| const std::vector<std::pair<int,int>> X_N_DOT ({{22,24}}); | const std::vector<std::pair<int,int>> X_N_DOT ({{22,24}}); | ||||||
| const std::vector<std::pair<int,int>> X_N_DOT_DOT ({{46,5}}); | const std::vector<std::pair<int,int>> X_N_DOT_DOT ({{46,5}}); | ||||||
| const std::vector<std::pair<int,int>> X_N({{51,27}}); | const std::vector<std::pair<int,int>> X_N({{51,27}}); | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
| /*! | /*! | ||||||
|  * \file glonass_gnav_almanac.h |  * \file glonass_gnav_almanac.h | ||||||
|  * \brief  Interface of a GLONASS GNAV ALMANAC storage |  * \brief  Interface of a GLONASS GNAV ALMANAC storage | ||||||
|  * \author Damian Miralles, 2017. dmiralles2009@gmail.com |  * \note Code added as part of GSoC 2017 program | ||||||
|  |  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com | ||||||
|  |  * \see <a href="http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD_GLONASS_eng_v5.1.pdf">GLONASS ICD</a> | ||||||
|  * |  * | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  * |  * | ||||||
|   | |||||||
| @@ -39,13 +39,48 @@ | |||||||
|  |  | ||||||
| Glonass_Gnav_Ephemeris::Glonass_Gnav_Ephemeris() | Glonass_Gnav_Ephemeris::Glonass_Gnav_Ephemeris() | ||||||
| { | { | ||||||
|     i_satellite_freq_channel = 0; |  | ||||||
| 	d_m = 0.0;             //!< String number within frame [dimensionless] | 	d_m = 0.0;             //!< String number within frame [dimensionless] | ||||||
|     d_t_k = 0.0;             //!< Time referenced to the beginning of the frame within the current day [hours, minutes, seconds] | 	d_t_k = 0.0;           //!< GLONASS Time (UTC(SU) + 3 h) referenced to the beginning of the frame within the current day [s] | ||||||
|     d_t_b = 0.0;             //!< Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. [minutes] | 	d_t_b = 0.0;           //!< Reference ephemeris relative time in GLONASS Time (UTC(SU) + 3 h). Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. [s] | ||||||
| 	d_M = 0.0;             //!< Type of satellite transmitting navigation signal [dimensionless] | 	d_M = 0.0;             //!< Type of satellite transmitting navigation signal [dimensionless] | ||||||
| 	d_gamma_n = 0.0;       //!< Relative deviation of predicted carrier frequency value of n- satellite from nominal value at the instant tb [dimensionless] | 	d_gamma_n = 0.0;       //!< Relative deviation of predicted carrier frequency value of n- satellite from nominal value at the instant tb [dimensionless] | ||||||
| 	d_tau_n = 0.0;         //!< Correction to the nth satellite time (tn) relative to GLONASS time (te), | 	d_tau_n = 0.0;         //!< Correction to the nth satellite time (tn) relative to GLONASS time (te), | ||||||
|  | 	d_Xn = 0.0;            //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km]. | ||||||
|  | 	d_Yn = 0.0;            //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km] | ||||||
|  | 	d_Zn = 0.0;            //!< Earth-fixed coordinate z of the satellite in PZ-90.02 coordinate system [km] | ||||||
|  | 	d_VXn = 0.0;           //!< Earth-fixed velocity coordinate x of the satellite in PZ-90.02 coordinate system [km/s] | ||||||
|  | 	d_VYn = 0.0;           //!< Earth-fixed velocity coordinate y of the satellite in PZ-90.02 coordinate system [km/s] | ||||||
|  | 	d_VZn = 0.0;           //!< Earth-fixed velocity coordinate z of the satellite in PZ-90.02 coordinate system [km/s] | ||||||
|  | 	d_AXn = 0.0;           //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2] | ||||||
|  | 	d_AYn = 0.0;           //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2] | ||||||
|  | 	d_AZn = 0.0;           //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2] | ||||||
|  | 	d_B_n = 0.0;           //!< Health flag [dimensionless] | ||||||
|  | 	d_P = 0.0;             //!< Technological parameter of control segment, indication the satellite operation mode in respect of time parameters [dimensionless] | ||||||
|  | 	d_N_T = 0.0;           //!< Current date, calendar number of day within four-year interval starting from the 1-st of January in a leap year [days] | ||||||
|  | 	d_F_T = 0.0;           //!< Parameter that provides the predicted satellite user range accuracy at time tb [dimensionless] | ||||||
|  | 	d_n = 0.0;             //!< Index of the satellite transmitting given navigation signal. It corresponds to a slot number within GLONASS constellation | ||||||
|  | 	d_Delta_tau_n = 0.0;   //!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless] | ||||||
|  | 	d_E_n = 0.0;           //!< Characterises "age" of a current information [days] | ||||||
|  | 	d_P_1 = 0.0;           //!< Flag of the immediate data updating [minutes] | ||||||
|  | 	d_P_2 = 0.0;           //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless] | ||||||
|  | 	d_P_3 = 0.0;           //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless] | ||||||
|  | 	d_P_4 = 0.0;           //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless] | ||||||
|  | 	d_l3rd_n = 0.0;        //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] | ||||||
|  | 	d_l5th_n = 0.0;        //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] | ||||||
|  |  | ||||||
|  | 	// Satellite Identification Information | ||||||
|  | 	i_satellite_freq_channel = 0;  			//!< SV Frequency Channel Number | ||||||
|  | 	i_satellite_PRN = 0;           			//!< SV PRN Number, equivalent to slot number for compatibility with GPS | ||||||
|  | 	i_satellite_slot_number = 0;			//!< SV Slot Number | ||||||
|  | 	d_TOD = 0.0;                           //!< Time of Day of the ephemeris set based in start of frame [s] | ||||||
|  | 	d_D4Y = 0.0;                           //!< Day of Year after latest leap year (4 year interval) | ||||||
|  | 	d_yr = 1972;                           //!< Current year, defaults to 1972 (UTC Epoch with leap seconds) | ||||||
|  | 	d_satClkDrift = 0.0;                   //!< GLONASS clock error | ||||||
|  | 	d_dtr = 0.0;                           //!< relativistic clock correction term | ||||||
|  | 	d_iode = 0.0;                          //!< Issue of data, ephemeris (Bit 0-6 of tb) | ||||||
|  | 	d_tau_c = 0.0; | ||||||
|  | 	d_TOW = 0.0; // tow of the start of frame | ||||||
|  | 	d_WN = 0.0; //  week number of the start of frame | ||||||
|     // satellite positions |     // satellite positions | ||||||
|     d_satpos_X = 0.0;        //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km]. |     d_satpos_X = 0.0;        //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km]. | ||||||
|     d_satpos_Y = 0.0;        //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km] |     d_satpos_Y = 0.0;        //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km] | ||||||
| @@ -58,31 +93,15 @@ Glonass_Gnav_Ephemeris::Glonass_Gnav_Ephemeris() | |||||||
|     d_satacc_X = 0.0;        //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2] |     d_satacc_X = 0.0;        //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2] | ||||||
|     d_satacc_Y = 0.0;        //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2] |     d_satacc_Y = 0.0;        //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2] | ||||||
|     d_satacc_Z = 0.0;        //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2] |     d_satacc_Z = 0.0;        //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2] | ||||||
|     d_B_n = 0.0;             //!< Health flag [dimensionless] |  | ||||||
|     d_P = 0.0;               //!< Technological parameter of control segment, indication the satellite operation mode in respect of time parameters [dimensionless] |  | ||||||
|     d_N_T = 0.0;             //!< Current date, calendar number of day within four-year interval starting from the 1-st of January in a leap year [days] |  | ||||||
|     d_F_T = 0.0;             //!< Parameter that provides the predicted satellite user range accuracy at time tb [dimensionless] |  | ||||||
|     d_n = 0.0;               //!< Index of the satellite transmitting given navigation signal. It corresponds to a slot number within GLONASS constellation |  | ||||||
|     d_Delta_tau_n = 0.0;     //!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless] |  | ||||||
|     d_E_n = 0.0;             //!< Characterises "age" of a current information [days] |  | ||||||
|     d_P_1 = 0.0;             //!< Flag of the immediate data updating. |  | ||||||
|     d_P_2 = 0.0;             //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless] |  | ||||||
|     d_P_3 = 0.0;             //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless] |  | ||||||
|     d_P_4 = 0.0;             //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless] |  | ||||||
|     d_l3rd_n = 0.0;          //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] |  | ||||||
|     d_l5th_n = 0.0;             //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] |  | ||||||
|  |  | ||||||
|     // clock terms derived from ephemeris data |  | ||||||
|     d_satClkDrift = 0.0;    //!< GLONASS clock error |  | ||||||
|     d_dtr = 0.0; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(const double offset_time) const | boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(const double offset_time) const | ||||||
| { | { | ||||||
|     boost::posix_time::time_duration t(0, 0, offset_time); |     boost::posix_time::time_duration t(0, 0, offset_time); | ||||||
|     boost::gregorian::date d(d_yr, 1, d_N_T); |     boost::gregorian::date d1(d_yr, 1, 1); | ||||||
|     boost::posix_time::ptime glonass_time(d, t); |     boost::gregorian::days d2(d_N_T); | ||||||
|  |     boost::posix_time::ptime glonass_time(d1+d2, t); | ||||||
|  |  | ||||||
|     return glonass_time; |     return glonass_time; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
| /*! | /*! | ||||||
|  * \file glonass_gnav_ephemeris.h |  * \file glonass_gnav_ephemeris.h | ||||||
|  * \brief  Interface of a GLONASS EPHEMERIS storage |  * \brief  Interface of a GLONASS EPHEMERIS storage | ||||||
|  |  * \note Code added as part of GSoC 2017 program | ||||||
|  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com |  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com | ||||||
|  |  * \see <a href="http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD_GLONASS_eng_v5.1.pdf">GLONASS ICD</a> | ||||||
|  * |  * | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  * |  * | ||||||
| @@ -99,7 +101,6 @@ public: | |||||||
|     double d_l5th_n;        //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] |     double d_l5th_n;        //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless] | ||||||
|  |  | ||||||
|     // Inmediate deliverables of ephemeris information |     // Inmediate deliverables of ephemeris information | ||||||
|     //TODO check how freq channel is managed in gnav message. I think it is a number greater thn 0 |  | ||||||
|     // Satellite Identification Information |     // Satellite Identification Information | ||||||
|     int i_satellite_freq_channel;  			//!< SV Frequency Channel Number |     int i_satellite_freq_channel;  			//!< SV Frequency Channel Number | ||||||
|     unsigned int i_satellite_PRN;           //!< SV PRN Number, equivalent to slot number for compatibility with GPS |     unsigned int i_satellite_PRN;           //!< SV PRN Number, equivalent to slot number for compatibility with GPS | ||||||
| @@ -114,8 +115,6 @@ public: | |||||||
|     double d_TOW; // tow of the start of frame |     double d_TOW; // tow of the start of frame | ||||||
|     double d_WN; //  week number of the start of frame |     double d_WN; //  week number of the start of frame | ||||||
|  |  | ||||||
|     // Need to add a way to compute the GPS week number and GPS TIME OF WEEK from GLONASS ephemeris |  | ||||||
|  |  | ||||||
|     // satellite positions after RK4 Integration |     // satellite positions after RK4 Integration | ||||||
|     double d_satpos_X;        //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km]. |     double d_satpos_X;        //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km]. | ||||||
|     double d_satpos_Y;        //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km] |     double d_satpos_Y;        //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km] | ||||||
|   | |||||||
| @@ -31,6 +31,8 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "glonass_gnav_navigation_message.h" | #include "glonass_gnav_navigation_message.h" | ||||||
|  | #include <boost/crc.hpp> | ||||||
|  | #include <boost/dynamic_bitset.hpp> | ||||||
| #include <cmath> | #include <cmath> | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <sstream> | #include <sstream> | ||||||
| @@ -107,8 +109,8 @@ Glonass_Gnav_Navigation_Message::Glonass_Gnav_Navigation_Message() | |||||||
|  |  | ||||||
| bool Glonass_Gnav_Navigation_Message::CRC_test(std::bitset<GLONASS_GNAV_STRING_BITS> bits) | bool Glonass_Gnav_Navigation_Message::CRC_test(std::bitset<GLONASS_GNAV_STRING_BITS> bits) | ||||||
| { | { | ||||||
|     int sum_bits; |     int sum_bits = 0; | ||||||
|     int sum_hamming; |     int sum_hamming = 0; | ||||||
|     int C1 = 0; |     int C1 = 0; | ||||||
|     int C2 = 0; |     int C2 = 0; | ||||||
|     int C3 = 0; |     int C3 = 0; | ||||||
| @@ -117,85 +119,84 @@ bool Glonass_Gnav_Navigation_Message::CRC_test(std::bitset<GLONASS_GNAV_STRING_B | |||||||
|     int C6 = 0; |     int C6 = 0; | ||||||
|     int C7 = 0; |     int C7 = 0; | ||||||
|     int C_Sigma = 0; |     int C_Sigma = 0; | ||||||
|  |     std::vector<int> string_bits(GLONASS_GNAV_STRING_BITS); | ||||||
|  |  | ||||||
|     std::bitset<GLONASS_GNAV_STRING_BITS> data = std::bitset<GLONASS_GNAV_STRING_BITS>(bits.to_string(), 0, 77); | 	//!< Populate data and hamming code vectors | ||||||
|     std::bitset<GLONASS_GNAV_HAMMING_CODE_BITS> hamming_code = std::bitset<GLONASS_GNAV_HAMMING_CODE_BITS>(bits.to_string(), 77, 8); | 	for(int i = 0; i < static_cast<int>(GLONASS_GNAV_STRING_BITS); i++) | ||||||
|  | 		{ | ||||||
|  | 			string_bits[i] = static_cast<int>(bits[i]); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|     std::istringstream dsb = std::istringstream( data.to_string() ); |  | ||||||
|     std::istringstream hcb = std::istringstream( hamming_code.to_string() ); |  | ||||||
|     std::vector<int> data_bits = std::vector<int>( std::istream_iterator<int>( dsb ), std::istream_iterator<int>() ); |  | ||||||
|     std::vector<int> hamming_code_bits = std::vector<int>( std::istream_iterator<int>( dsb ), std::istream_iterator<int>() ); |  | ||||||
|  |  | ||||||
|     //!< Compute C1 term |     //!< Compute C1 term | ||||||
|     sum_bits = 0; |     sum_bits = 0; | ||||||
|     for(int i = 0; i < static_cast<int>(GLONASS_GNAV_CRC_I_INDEX.size()); i++) |     for(int i = 0; i < static_cast<int>(GLONASS_GNAV_CRC_I_INDEX.size()); i++) | ||||||
|         { |         { | ||||||
|             sum_bits += data_bits[GLONASS_GNAV_CRC_I_INDEX[i]]; |             sum_bits += string_bits[GLONASS_GNAV_CRC_I_INDEX[i]]; | ||||||
|         } |         } | ||||||
|     C1 = hamming_code_bits[0]^(sum_bits%2); |     C1 = string_bits[0]^(sum_bits%2); | ||||||
|  |  | ||||||
|     //!< Compute C2 term |     //!< Compute C2 term | ||||||
|     sum_bits = 0; |     sum_bits = 0; | ||||||
|     for(int j = 0; j < static_cast<int>(GLONASS_GNAV_CRC_J_INDEX.size()); j++) |     for(int j = 0; j < static_cast<int>(GLONASS_GNAV_CRC_J_INDEX.size()); j++) | ||||||
|         { |         { | ||||||
|             sum_bits += data_bits[GLONASS_GNAV_CRC_J_INDEX[j]]; |             sum_bits += string_bits[GLONASS_GNAV_CRC_J_INDEX[j]]; | ||||||
|         } |         } | ||||||
|     C2 = (hamming_code_bits[1])^(sum_bits%2); |     C2 = (string_bits[1])^(sum_bits%2); | ||||||
|  |  | ||||||
|     //!< Compute C3 term |     //!< Compute C3 term | ||||||
|     sum_bits = 0; |     sum_bits = 0; | ||||||
|     for(int k = 0; k < static_cast<int>(GLONASS_GNAV_CRC_K_INDEX.size()); k++) |     for(int k = 0; k < static_cast<int>(GLONASS_GNAV_CRC_K_INDEX.size()); k++) | ||||||
|         { |         { | ||||||
|             sum_bits += data_bits[GLONASS_GNAV_CRC_K_INDEX[k]]; |             sum_bits += string_bits[GLONASS_GNAV_CRC_K_INDEX[k]]; | ||||||
|         } |         } | ||||||
|     C3 = hamming_code_bits[2]^(sum_bits%2); |     C3 = string_bits[2]^(sum_bits%2); | ||||||
|  |  | ||||||
|     //!< Compute C4 term |     //!< Compute C4 term | ||||||
|     sum_bits = 0; |     sum_bits = 0; | ||||||
|     for(int l = 0; l < static_cast<int>(GLONASS_GNAV_CRC_L_INDEX.size()); l++) |     for(int l = 0; l < static_cast<int>(GLONASS_GNAV_CRC_L_INDEX.size()); l++) | ||||||
|         { |         { | ||||||
|             sum_bits += data_bits[GLONASS_GNAV_CRC_L_INDEX[l]]; |             sum_bits += string_bits[GLONASS_GNAV_CRC_L_INDEX[l]]; | ||||||
|         } |         } | ||||||
|     C4 = hamming_code_bits[3]^(sum_bits%2); |     C4 = string_bits[3]^(sum_bits%2); | ||||||
|  |  | ||||||
|     //!< Compute C5 term |     //!< Compute C5 term | ||||||
|     sum_bits = 0; |     sum_bits = 0; | ||||||
|     for(int m = 0; m < static_cast<int>(GLONASS_GNAV_CRC_M_INDEX.size()); m++) |     for(int m = 0; m < static_cast<int>(GLONASS_GNAV_CRC_M_INDEX.size()); m++) | ||||||
|         { |         { | ||||||
|             sum_bits += data_bits[GLONASS_GNAV_CRC_M_INDEX[m]]; |             sum_bits += string_bits[GLONASS_GNAV_CRC_M_INDEX[m]]; | ||||||
|         } |         } | ||||||
|     C5 = hamming_code_bits[4]^(sum_bits%2); |     C5 = string_bits[4]^(sum_bits%2); | ||||||
|  |  | ||||||
|     //!< Compute C6 term |     //!< Compute C6 term | ||||||
|     sum_bits = 0; |     sum_bits = 0; | ||||||
|     for(int n = 0; n < static_cast<int>(GLONASS_GNAV_CRC_N_INDEX.size()); n++) |     for(int n = 0; n < static_cast<int>(GLONASS_GNAV_CRC_N_INDEX.size()); n++) | ||||||
|         { |         { | ||||||
|             sum_bits += data_bits[GLONASS_GNAV_CRC_N_INDEX[n]]; |             sum_bits += string_bits[GLONASS_GNAV_CRC_N_INDEX[n]]; | ||||||
|         } |         } | ||||||
|     C6 = hamming_code_bits[5]^(sum_bits%2); |     C6 = string_bits[5]^(sum_bits%2); | ||||||
|  |  | ||||||
|     //!< Compute C7 term |     //!< Compute C7 term | ||||||
|     sum_bits = 0; |     sum_bits = 0; | ||||||
|     for(int p = 0; p < static_cast<int>(GLONASS_GNAV_CRC_P_INDEX.size()); p++) |     for(int p = 0; p < static_cast<int>(GLONASS_GNAV_CRC_P_INDEX.size()); p++) | ||||||
|         { |         { | ||||||
|             sum_bits += data_bits[GLONASS_GNAV_CRC_P_INDEX[p]]; |             sum_bits += string_bits[GLONASS_GNAV_CRC_P_INDEX[p]]; | ||||||
|         } |         } | ||||||
|     C7 = hamming_code_bits[6]^(sum_bits%2); |     C7 = string_bits[6]^(sum_bits%2); | ||||||
|  |  | ||||||
|     //!< Compute C_Sigma term |     //!< Compute C_Sigma term | ||||||
|     sum_bits = 0; |     sum_bits = 0; | ||||||
|     sum_hamming = 0; |     sum_hamming = 0; | ||||||
|     for(int q = 0; q < static_cast<int>(GLONASS_GNAV_CRC_Q_INDEX.size()); q++) |     for(int q = 0; q < static_cast<int>(GLONASS_GNAV_CRC_Q_INDEX.size()); q++) | ||||||
|         { |         { | ||||||
|             sum_bits += data_bits[GLONASS_GNAV_CRC_Q_INDEX[q]]; |             sum_bits += string_bits[GLONASS_GNAV_CRC_Q_INDEX[q]]; | ||||||
|         } |         } | ||||||
|     for(int q = 0; q < 8; q++) |     for(int q = 0; q < 8; q++) | ||||||
|         { |         { | ||||||
|             sum_hamming += hamming_code_bits[q]; |             sum_hamming += string_bits[q]; | ||||||
|         } |         } | ||||||
|     C_Sigma = (sum_hamming%2)^(sum_bits%2); |     C_Sigma = (sum_hamming%2)^(sum_bits%2); | ||||||
|  |  | ||||||
|  |  | ||||||
|     //!< Verification of the data |     //!< Verification of the data | ||||||
|     // All of the checksums are equal to zero |     // All of the checksums are equal to zero | ||||||
|     if((C1 & C2 & C3 & C4 & C5 & C6 & C7 & C_Sigma) == 0 ) |     if((C1 & C2 & C3 & C4 & C5 & C6 & C7 & C_Sigma) == 0 ) | ||||||
| @@ -252,60 +253,29 @@ unsigned long int Glonass_Gnav_Navigation_Message::read_navigation_unsigned(std: | |||||||
| signed long int Glonass_Gnav_Navigation_Message::read_navigation_signed(std::bitset<GLONASS_GNAV_STRING_BITS> bits, const std::vector<std::pair<int,int>> parameter) | signed long int Glonass_Gnav_Navigation_Message::read_navigation_signed(std::bitset<GLONASS_GNAV_STRING_BITS> bits, const std::vector<std::pair<int,int>> parameter) | ||||||
| { | { | ||||||
|     signed long int value = 0; |     signed long int value = 0; | ||||||
|  |     signed long int sign = 0; | ||||||
|     int num_of_slices = parameter.size(); |     int num_of_slices = parameter.size(); | ||||||
|     // Discriminate between 64 bits and 32 bits compiler |  | ||||||
|     int long_int_size_bytes = sizeof(signed long int); |  | ||||||
|     if (long_int_size_bytes == 8) // if a long int takes 8 bytes, we are in a 64 bits system |  | ||||||
|         { |  | ||||||
|     // read the MSB and perform the sign extension |     // read the MSB and perform the sign extension | ||||||
| 	if (bits[GLONASS_GNAV_STRING_BITS - parameter[0].first] == 1) | 	if (bits[GLONASS_GNAV_STRING_BITS - parameter[0].first] == 1) | ||||||
| 		{ | 		{ | ||||||
|                     value ^= 0xFFFFFFFFFFFFFFFF; //64 bits variable | 			sign = -1; | ||||||
| 		} | 		} | ||||||
| 	else | 	else | ||||||
| 		{ | 		{ | ||||||
|                     value &= 0; | 			sign = 1; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|     for (int i = 0; i < num_of_slices; i++) |     for (int i = 0; i < num_of_slices; i++) | ||||||
|         { |         { | ||||||
|                     for (int j = 0; j < parameter[i].second; j++) |             for (int j = 1; j < parameter[i].second; j++) | ||||||
|                 { |                 { | ||||||
|                     value <<= 1; //shift left |                     value <<= 1; //shift left | ||||||
|                             value &= 0xFFFFFFFFFFFFFFFE; //reset the corresponding bit (for the 64 bits variable) |  | ||||||
|                     if (bits[GLONASS_GNAV_STRING_BITS - parameter[i].first - j] == 1) |                     if (bits[GLONASS_GNAV_STRING_BITS - parameter[i].first - j] == 1) | ||||||
|                         { |                         { | ||||||
|                             value += 1; // insert the bit |                             value += 1; // insert the bit | ||||||
|                         } |                         } | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
|         } |     return (sign*value); | ||||||
|     else  // we assume we are in a 32 bits system |  | ||||||
|         { |  | ||||||
|             // read the MSB and perform the sign extension |  | ||||||
|             if (bits[GLONASS_GNAV_STRING_BITS - parameter[0].first] == 1) |  | ||||||
|                 { |  | ||||||
|                     value ^= 0xFFFFFFFF; |  | ||||||
|                 } |  | ||||||
|             else |  | ||||||
|                 { |  | ||||||
|                     value &= 0; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|             for (int i = 0; i < num_of_slices; i++) |  | ||||||
|                 { |  | ||||||
|                     for (int j = 0; j < parameter[i].second; j++) |  | ||||||
|                         { |  | ||||||
|                             value <<= 1; //shift left |  | ||||||
|                             value &= 0xFFFFFFFE; //reset the corresponding bit |  | ||||||
|                             if (bits[GLONASS_GNAV_STRING_BITS - parameter[i].first - j] == 1) |  | ||||||
|                                 { |  | ||||||
|                                     value += 1; // insert the bit |  | ||||||
|                                 } |  | ||||||
|                         } |  | ||||||
|                 } |  | ||||||
|         } |  | ||||||
|     return value; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -393,7 +363,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(char * frame_string) | |||||||
|         case 3: |         case 3: | ||||||
|             // --- It is string 3 ---------------------------------------------- |             // --- It is string 3 ---------------------------------------------- | ||||||
|             gnav_ephemeris.d_P_3 = static_cast<double>(read_navigation_unsigned(string_bits, P3)); |             gnav_ephemeris.d_P_3 = static_cast<double>(read_navigation_unsigned(string_bits, P3)); | ||||||
|             gnav_ephemeris.d_gamma_n = static_cast<double>(read_navigation_signed(string_bits, GAMMA_N)) * TWO_N30; |             gnav_ephemeris.d_gamma_n = static_cast<double>(read_navigation_signed(string_bits, GAMMA_N)) * TWO_N40; | ||||||
|             gnav_ephemeris.d_P = static_cast<double>(read_navigation_unsigned(string_bits, P)); |             gnav_ephemeris.d_P = static_cast<double>(read_navigation_unsigned(string_bits, P)); | ||||||
|             gnav_ephemeris.d_l3rd_n = static_cast<double>(read_navigation_unsigned(string_bits, EPH_L_N)); |             gnav_ephemeris.d_l3rd_n = static_cast<double>(read_navigation_unsigned(string_bits, EPH_L_N)); | ||||||
|             gnav_ephemeris.d_VZn = static_cast<double>(read_navigation_signed(string_bits, Z_N_DOT)) * TWO_N20; |             gnav_ephemeris.d_VZn = static_cast<double>(read_navigation_signed(string_bits, Z_N_DOT)) * TWO_N20; | ||||||
| @@ -541,6 +511,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(char * frame_string) | |||||||
|  |  | ||||||
|                 flag_almanac_str_9 = true; |                 flag_almanac_str_9 = true; | ||||||
|               } |               } | ||||||
|  |             break; | ||||||
|         case 10: |         case 10: | ||||||
|             // --- It is string 10 --------------------------------------------- |             // --- It is string 10 --------------------------------------------- | ||||||
|             i_satellite_slot_number = static_cast<double>(read_navigation_unsigned(string_bits, n_A)); |             i_satellite_slot_number = static_cast<double>(read_navigation_unsigned(string_bits, n_A)); | ||||||
| @@ -618,6 +589,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(char * frame_string) | |||||||
|  |  | ||||||
|                 flag_almanac_str_13 = true; |                 flag_almanac_str_13 = true; | ||||||
|               } |               } | ||||||
|  |             break; | ||||||
|         case 14: |         case 14: | ||||||
|             // --- It is string 14 --------------------------------------------- |             // --- It is string 14 --------------------------------------------- | ||||||
|             if( frame_ID == 5) |             if( frame_ID == 5) | ||||||
| @@ -665,6 +637,7 @@ int Glonass_Gnav_Navigation_Message::string_decoder(char * frame_string) | |||||||
|  |  | ||||||
|                 flag_almanac_str_15 = true; |                 flag_almanac_str_15 = true; | ||||||
|               } |               } | ||||||
|  |             break; | ||||||
|         default: |         default: | ||||||
|             break; |             break; | ||||||
|         } // switch subframeID ... |         } // switch subframeID ... | ||||||
|   | |||||||
| @@ -1,8 +1,9 @@ | |||||||
| /*! | /*! | ||||||
|  * \file glonass_gnav_navigation_message.h |  * \file glonass_gnav_navigation_message.h | ||||||
|  * \brief  Interface of a GLONASS GNAV Data message decoder as described in GLONASS ICD (Edition 5.1) |  * \brief  Interface of a GLONASS GNAV Data message decoder as described in GLONASS ICD (Edition 5.1) | ||||||
|  * See http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD_GLONASS_eng_v5.1.pdf |  * \note Code added as part of GSoC 2017 program | ||||||
|  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com |  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com | ||||||
|  |  * \see <a href="http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD_GLONASS_eng_v5.1.pdf">GLONASS ICD</a> | ||||||
|  * |  * | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
|  * |  * | ||||||
|   | |||||||
| @@ -145,6 +145,7 @@ DECLARE_string(log_dir); | |||||||
|  |  | ||||||
| #include "unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc" | #include "unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc" | ||||||
| #include "unit-tests/system-parameters/glonass_gnav_almanac_test.cc" | #include "unit-tests/system-parameters/glonass_gnav_almanac_test.cc" | ||||||
|  | #include "unit-tests/system-parameters/glonass_gnav_nav_message_test.cc" | ||||||
|  |  | ||||||
| // For GPS NAVIGATION (L1) | // For GPS NAVIGATION (L1) | ||||||
| concurrent_queue<Gps_Acq_Assist> global_gps_acq_assist_queue; | concurrent_queue<Gps_Acq_Assist> global_gps_acq_assist_queue; | ||||||
|   | |||||||
| @@ -281,20 +281,49 @@ TEST(RtcmTest, MT1020) | |||||||
|     auto rtcm = std::make_shared<Rtcm>(); |     auto rtcm = std::make_shared<Rtcm>(); | ||||||
|     bool expected_true = true; |     bool expected_true = true; | ||||||
|  |  | ||||||
|     Glonass_Gnav_Ephemeris glonass_gnav_eph = Glonass_Gnav_Ephemeris(); |     // Objects to populate the ephemeris and utc fields | ||||||
|     Glonass_Gnav_Utc_Model glonass_gnav_utc_model = Glonass_Gnav_Utc_Model(); |     Glonass_Gnav_Ephemeris gnav_eph = Glonass_Gnav_Ephemeris(); | ||||||
|     Glonass_Gnav_Ephemeris glonass_gnav_eph_read = Glonass_Gnav_Ephemeris(); |     Glonass_Gnav_Utc_Model gnav_utc_model = Glonass_Gnav_Utc_Model(); | ||||||
|     Glonass_Gnav_Utc_Model glonass_gnav_utc_model_read = Glonass_Gnav_Utc_Model(); |     // Objects read, used for comparison | ||||||
|  |     Glonass_Gnav_Ephemeris gnav_eph_read = Glonass_Gnav_Ephemeris(); | ||||||
|  |     Glonass_Gnav_Utc_Model gnav_utc_model_read = Glonass_Gnav_Utc_Model(); | ||||||
|  |  | ||||||
|  |     glonass_gnav_eph.i_satellite_slot_number    = 3; | ||||||
|  |     gnav_ephemeris.d_P_1        = 0; | ||||||
|  |     gnav_ephemeris.d_t_k        = 7560; | ||||||
|  |     gnav_ephemeris.d_VXn        = -0.490900039672852; | ||||||
|  |     gnav_ephemeris.d_AXn        = 0; | ||||||
|  |     gnav_ephemeris.d_Xn         = -11025.6669921875; | ||||||
|  |     gnav_ephemeris.d_B_n        = 0; | ||||||
|  |     gnav_ephemeris.d_P_2        = 1; | ||||||
|  |     gnav_ephemeris.d_t_b        = 8100; | ||||||
|  |     gnav_ephemeris.d_VYn        = -2.69022750854492; | ||||||
|  |     gnav_ephemeris.d_AYn        = 0; | ||||||
|  |     gnav_ephemeris.d_Yn         = -11456.7348632812; | ||||||
|  |     gnav_ephemeris.d_P_3        = 1; | ||||||
|  |     gnav_ephemeris.d_gamma_n    = 1.81898940354586e-12; | ||||||
|  |     gnav_ephemeris.d_P          = 3; | ||||||
|  |     gnav_ephemeris.d_l3rd_n     = 0; | ||||||
|  |     gnav_ephemeris.d_VZn        = -1.82016849517822; | ||||||
|  |     gnav_ephemeris.d_AZn        = -2.79396772384644e-09; | ||||||
|  |     gnav_ephemeris.d_Zn         = 19929.2377929688; | ||||||
|  |     gnav_ephemeris.d_tau_n      = -8.30907374620438e-05; | ||||||
|  |     gnav_ephemeris.d_Delta_tau_n = 9.31322574615479e-10; | ||||||
|  |     gnav_ephemeris.d_E_n        = 0; | ||||||
|  |     gnav_ephemeris.d_P_4        = 0; | ||||||
|  |     gnav_ephemeris.d_F_T        = 6; | ||||||
|  |     gnav_ephemeris.d_N_T        = 268; | ||||||
|  |     gnav_ephemeris.d_n          = 21; | ||||||
|  |     gnav_ephemeris.d_M          = 1; | ||||||
|  |     gnav_utc_model.d_N_A        = 268; | ||||||
|  |     gnav_utc_model.d_tau_c      = 9.6391886472702e-08; | ||||||
|  |     gnav_utc_model.d_N_4        = 6; | ||||||
|  |     gnav_utc_model.d_tau_gps    = 9.313225746154785e-08; | ||||||
|  |  | ||||||
|     glonass_gnav_eph.i_satellite_PRN    = 3; |  | ||||||
|     glonass_gnav_eph.d_t_b              = 4; |  | ||||||
|     glonass_gnav_eph.d_E_n              = 2.0 * E_LSB; |  | ||||||
|     glonass_gnav_eph.d_l3rd_n           = true; |  | ||||||
|     glonass_gnav_utc_model.d_tau_gps    = 5; |  | ||||||
|     std::string tx_msg = rtcm->print_MT1020(glonass_gnav_eph, glonass_gnav_utc_model); |     std::string tx_msg = rtcm->print_MT1020(glonass_gnav_eph, glonass_gnav_utc_model); | ||||||
|  |  | ||||||
|     EXPECT_EQ(0, rtcm->read_MT1020(tx_msg, glonass_gnav_eph_read, glonass_gnav_utc_model_read)); |     EXPECT_EQ(0, rtcm->read_MT1020(tx_msg, glonass_gnav_eph_read, glonass_gnav_utc_model_read)); | ||||||
|     EXPECT_EQ(3, glonass_gnav_eph_read.i_satellite_PRN); |     EXPECT_EQ(3, glonass_gnav_eph_read.i_satellite_slot_number); | ||||||
|     EXPECT_DOUBLE_EQ(4, glonass_gnav_eph_read.d_t_b); |     EXPECT_DOUBLE_EQ(4, glonass_gnav_eph_read.d_t_b); | ||||||
|     EXPECT_DOUBLE_EQ( 2.0 * E_LSB, glonass_gnav_eph_read.d_E_n); |     EXPECT_DOUBLE_EQ( 2.0 * E_LSB, glonass_gnav_eph_read.d_E_n); | ||||||
|     EXPECT_DOUBLE_EQ( 5, glonass_gnav_utc_model_read.d_tau_gps); |     EXPECT_DOUBLE_EQ( 5, glonass_gnav_utc_model_read.d_tau_gps); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /*! | /*! | ||||||
|  * \file gps_l1_ca_dll_pll_tracking_test.cc |  * \file gps_l1_ca_dll_pll_tracking_test.cc | ||||||
|  * \brief  This class implements a tracking test for Galileo_E5a_DLL_PLL_Tracking |  * \brief  This class implements a telemetry decoder test for GPS_L1_CA_Telemetry_Decoder | ||||||
|  *  implementation based on some input parameters. |  *  implementation based on some input parameters. | ||||||
|  * \author Javier Arribas, 2015. jarribas(at)cttc.es |  * \author Javier Arribas, 2015. jarribas(at)cttc.es | ||||||
|  * |  * | ||||||
| @@ -477,4 +477,3 @@ TEST_F(GpsL1CATelemetryDecoderTest, ValidationOfResults) | |||||||
|  |  | ||||||
|     std::cout <<  "Test completed in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; |     std::cout <<  "Test completed in " << elapsed_seconds.count() * 1e6 << " microseconds" << std::endl; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
| /*! | /*! | ||||||
|  * \file code_generation_test.cc |  * \file code_generation_test.cc | ||||||
|  * \brief  This file implements tests for the generation of complex exponentials. |  * \note Code added as part of GSoC 2017 program | ||||||
|  * \author Carles Fernandez-Prades, 2014. cfernandez(at)cttc.es |  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com | ||||||
|  |  * \see <a href="http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD_GLONASS_eng_v5.1.pdf">GLONASS ICD</a> | ||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
| @@ -35,8 +36,6 @@ | |||||||
| #include "gps_sdr_signal_processing.h" | #include "gps_sdr_signal_processing.h" | ||||||
| #include "gnss_signal_processing.h" | #include "gnss_signal_processing.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #include <complex> | #include <complex> | ||||||
| #include <ctime> | #include <ctime> | ||||||
| #include "gnss_signal_processing.h" | #include "gnss_signal_processing.h" | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
| /*! | /*! | ||||||
|  * \file code_generation_test.cc |  * \file code_generation_test.cc | ||||||
|  * \brief  This file implements tests for the generation of complex exponentials. |  * \note Code added as part of GSoC 2017 program | ||||||
|  * \author Carles Fernandez-Prades, 2014. cfernandez(at)cttc.es |  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com | ||||||
|  |  * \see <a href="http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD_GLONASS_eng_v5.1.pdf">GLONASS ICD</a> | ||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
| @@ -32,23 +33,33 @@ | |||||||
|  |  | ||||||
| #include <complex> | #include <complex> | ||||||
| #include <ctime> | #include <ctime> | ||||||
|  | #include <iostream> | ||||||
| #include "gnss_signal_processing.h" | #include "gnss_signal_processing.h" | ||||||
| #include "glonass_gnav_ephemeris.h" | #include "glonass_gnav_ephemeris.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| TEST(GlonassGnavEphemerisTest, SatellitePosition) | TEST(GlonassGnavEphemerisTest, ComputeGlonassTime) | ||||||
| { | { | ||||||
|     Glonass_Gnav_Ephemeris gnav_eph; |     Glonass_Gnav_Ephemeris gnav_eph; | ||||||
|  |     gnav_eph.d_yr = 2016; | ||||||
|  |     gnav_eph.d_N_T = 367; | ||||||
|  |     boost::posix_time::time_duration t(0, 0, 7560); | ||||||
|  |     boost::gregorian::date d(gnav_eph.d_yr, 1, 1); | ||||||
|  |     boost::gregorian::days d2(gnav_eph.d_N_T); | ||||||
|  |     d = d + d2; | ||||||
|  |  | ||||||
|     gnav_eph.d_Xn = 12317.934082000; |     boost::gregorian::date expected_gdate; | ||||||
|     gnav_eph.d_Yn = -2245.13232422; | 	boost::posix_time::time_duration expected_gtime; | ||||||
|     gnav_eph.d_Zn = 22212.8173828; |  | ||||||
|     gnav_eph.d_VXn = -1.25356674194; |  | ||||||
|     gnav_eph.d_VYn = 2.774200439450; |  | ||||||
|     gnav_eph.d_VZn = 0.9808206558230000; |  | ||||||
|     gnav_eph.d_AXn = -0.931322574616e-9; |  | ||||||
|     gnav_eph.d_AYn = 0.0000000000000000; |  | ||||||
|     gnav_eph.d_AZn =  -0.186264514923e-8; |  | ||||||
|  |  | ||||||
|     gnav_eph.simplified_satellite_position(60); | 	boost::posix_time::ptime gtime = gnav_eph.compute_GLONASS_time(7560); | ||||||
|  | 	expected_gdate = gtime.date(); | ||||||
|  | 	expected_gtime = gtime.time_of_day(); | ||||||
|  |  | ||||||
|  |     // Perform assertions of decoded fields | ||||||
|  | 	ASSERT_TRUE(expected_gdate.year() - d.year() < FLT_EPSILON ); | ||||||
|  | 	ASSERT_TRUE(expected_gdate.month() - d.month() < FLT_EPSILON ); | ||||||
|  | 	ASSERT_TRUE(expected_gdate.day() - d.day() < FLT_EPSILON ); | ||||||
|  | 	ASSERT_TRUE(expected_gtime.hours() -  t.hours() < FLT_EPSILON ); | ||||||
|  | 	ASSERT_TRUE(expected_gtime.minutes() -  t.minutes() < FLT_EPSILON ); | ||||||
|  | 	ASSERT_TRUE(expected_gtime.seconds() -  t.seconds() < FLT_EPSILON ); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
| /*! | /*! | ||||||
|  * \file glonass_gnav_navigation_message_test.cc |  * \file glonass_gnav_navigation_message_test.cc | ||||||
|  * \brief  This file implements tests for the decoding of the GLONASS GNAV navigation message |  * \brief  This file implements tests for the decoding of the GLONASS GNAV navigation message | ||||||
|  |  * \note Code added as part of GSoC 2017 program | ||||||
|  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com |  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com | ||||||
|  |  * \see <a href="http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD_GLONASS_eng_v5.1.pdf">GLONASS ICD</a> | ||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * ------------------------------------------------------------------------- |  * ------------------------------------------------------------------------- | ||||||
| @@ -46,12 +48,12 @@ TEST(GlonassGnavNavigationMessageTest, CRCTest) | |||||||
| { | { | ||||||
|     // Variables declarations in code |     // Variables declarations in code | ||||||
|     bool test_result; |     bool test_result; | ||||||
|     std::string str5("0010100100001100000000000000000000000000110011110001100000000000000001100100011000000"); |     std::bitset<GLONASS_GNAV_STRING_BITS> string_bits (std::string ("0010100100001100000000000000000000000000110011110001100000000000000001100100011000000")); | ||||||
|     Glonass_Gnav_Navigation_Message gnav_nav_message; |     Glonass_Gnav_Navigation_Message gnav_nav_message; | ||||||
|     gnav_nav_message.reset(); |     gnav_nav_message.reset(); | ||||||
|  |  | ||||||
|     // Call function to test |     // Call function to test | ||||||
|     test_result = gnav_nav_message.CRC_test(std::bitset<GLONASS_GNAV_STRING_BITS> (str5)); |     test_result = gnav_nav_message.CRC_test(string_bits); | ||||||
|  |  | ||||||
|     // Check results in unit test assetions |     // Check results in unit test assetions | ||||||
|     ASSERT_TRUE(test_result); |     ASSERT_TRUE(test_result); | ||||||
| @@ -72,20 +74,21 @@ TEST(GlonassGnavNavigationMessageTest, String1Decoder) | |||||||
|     Glonass_Gnav_Ephemeris gnav_ephemeris; |     Glonass_Gnav_Ephemeris gnav_ephemeris; | ||||||
|  |  | ||||||
|     // Fill out ephemeris values for truth |     // Fill out ephemeris values for truth | ||||||
|     gnav_ephemeris.d_P_1    = static_cast<double>(read_navigation_unsigned(string_bits, P1)); |     gnav_ephemeris.d_P_1    = 0; | ||||||
|     gnav_ephemeris.d_t_k    =  static_cast<double>(read_navigation_unsigned(string_bits, T_K_HR)) * 3600 + |     gnav_ephemeris.d_t_k    = 7560; | ||||||
|     gnav_ephemeris.d_VXn    = static_cast<double>(read_navigation_signed(string_bits, X_N_DOT)) * 2e-20; |     gnav_ephemeris.d_VXn    = -0.490900039672852; | ||||||
|     gnav_ephemeris.d_AXn    = static_cast<double>(read_navigation_signed(string_bits, X_N_DOT_DOT)) * 2e-30; |     gnav_ephemeris.d_AXn    = 0; | ||||||
|     gnav_ephemeris.d_Xn     = static_cast<double>(read_navigation_signed(string_bits, X_N)) * 2e-11; |     gnav_ephemeris.d_Xn     = -11025.6669921875; | ||||||
|  |  | ||||||
|     // Call target test method |     // Call target test method | ||||||
|     gnav_nav_message.string_decoder(str1.c_str()); |     gnav_nav_message.string_decoder(const_cast<char*> (str1.c_str())); | ||||||
|  |  | ||||||
|     // Perform assertions of decoded fields |     // Perform assertions of decoded fields | ||||||
|     ASSERT_TRUE(gnav_ephemeris.d_t_k - gnav_nav_message.gnav_ephemeris.d_t_k < DBL_EPSILON ); |     ASSERT_TRUE(gnav_ephemeris.d_P_1 - gnav_nav_message.gnav_ephemeris.d_P_1 < FLT_EPSILON ); | ||||||
|     ASSERT_TRUE(gnav_ephemeris.d_VXn - gnav_nav_message.gnav_ephemeris.d_VXn < DBL_EPSILON ); |     ASSERT_TRUE(gnav_ephemeris.d_t_k - gnav_nav_message.gnav_ephemeris.d_t_k < FLT_EPSILON ); | ||||||
|     ASSERT_TRUE(gnav_ephemeris.d_AXn - gnav_nav_message.gnav_ephemeris.d_AXn < DBL_EPSILON ); |     ASSERT_TRUE(gnav_ephemeris.d_VXn - gnav_nav_message.gnav_ephemeris.d_VXn < FLT_EPSILON ); | ||||||
|     ASSERT_TRUE(gnav_ephemeris.d_Xn -  gnav_nav_message.gnav_ephemeris.d_Xn < DBL_EPSILON ); |     ASSERT_TRUE(gnav_ephemeris.d_AXn - gnav_nav_message.gnav_ephemeris.d_AXn < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_Xn -  gnav_nav_message.gnav_ephemeris.d_Xn < FLT_EPSILON ); | ||||||
| } | } | ||||||
|  |  | ||||||
| /*! | /*! | ||||||
| @@ -103,29 +106,129 @@ TEST(GlonassGnavNavigationMessageTest, String2Decoder) | |||||||
|     Glonass_Gnav_Ephemeris gnav_ephemeris; |     Glonass_Gnav_Ephemeris gnav_ephemeris; | ||||||
|  |  | ||||||
|     // Fill out ephemeris values for truth |     // Fill out ephemeris values for truth | ||||||
|     gnav_ephemeris.d_B_n = static_cast<double>(read_navigation_unsigned(string_bits, B_N)); |     gnav_ephemeris.d_B_n = 0; | ||||||
|     gnav_ephemeris.d_P_2 = static_cast<double>(read_navigation_unsigned(string_bits, P2)); |     gnav_ephemeris.d_P_2 = 1; | ||||||
|     gnav_ephemeris.d_t_b = static_cast<double>(read_navigation_unsigned(string_bits, T_B))*15*60; |     gnav_ephemeris.d_t_b = 8100; | ||||||
|     gnav_ephemeris.d_VYn = static_cast<double>(read_navigation_signed(string_bits, Y_N_DOT))* 2e-20; |     gnav_ephemeris.d_VYn = -2.69022750854492; | ||||||
|     gnav_ephemeris.d_AYn = static_cast<double>(read_navigation_signed(string_bits, Y_N_DOT_DOT)) * 2e-30; |     gnav_ephemeris.d_AYn = 0; | ||||||
|     gnav_ephemeris.d_Yn  = static_cast<double>(read_navigation_signed(string_bits, X_N)) * 2e-11; |     gnav_ephemeris.d_Yn  = -11456.7348632812; | ||||||
|  |  | ||||||
|     // Call target test method |     // Call target test method | ||||||
|     gnav_nav_message.string_decoder(str2.c_str()) |     gnav_nav_message.string_decoder(const_cast<char*> (str2.c_str())); | ||||||
|  |  | ||||||
|     // Perform assertions of decoded fields |     // Perform assertions of decoded fields | ||||||
|     ASSERT_TRUE(gnav_ephemeris.d_B_n - gnav_nav_message.gnav_ephemeris.d_B_n < DBL_EPSILON ); |     ASSERT_TRUE(gnav_ephemeris.d_B_n - gnav_nav_message.gnav_ephemeris.d_B_n < FLT_EPSILON ); | ||||||
|     ASSERT_TRUE(gnav_ephemeris.d_P_2 - gnav_nav_message.gnav_ephemeris.d_P_2 < DBL_EPSILON ); |     ASSERT_TRUE(gnav_ephemeris.d_P_2 - gnav_nav_message.gnav_ephemeris.d_P_2 < FLT_EPSILON ); | ||||||
|     ASSERT_TRUE(gnav_ephemeris.d_t_b - gnav_nav_message.gnav_ephemeris.d_t_b < DBL_EPSILON ); |     ASSERT_TRUE(gnav_ephemeris.d_t_b - gnav_nav_message.gnav_ephemeris.d_t_b < FLT_EPSILON ); | ||||||
|     ASSERT_TRUE(gnav_ephemeris.d_VYn -  gnav_nav_message.gnav_ephemeris.d_VYn < DBL_EPSILON ); |     ASSERT_TRUE(gnav_ephemeris.d_VYn -  gnav_nav_message.gnav_ephemeris.d_VYn < FLT_EPSILON ); | ||||||
|     ASSERT_TRUE(gnav_ephemeris.d_AYn - gnav_nav_message.gnav_ephemeris.d_AYn < DBL_EPSILON ); |     ASSERT_TRUE(gnav_ephemeris.d_AYn - gnav_nav_message.gnav_ephemeris.d_AYn < FLT_EPSILON ); | ||||||
|     ASSERT_TRUE(gnav_ephemeris.d_Yn -  gnav_nav_message.gnav_ephemeris.d_Yn < DBL_EPSILON ); |     ASSERT_TRUE(gnav_ephemeris.d_Yn -  gnav_nav_message.gnav_ephemeris.d_Yn < FLT_EPSILON ); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::string str2("0001000010001001000001010101100001011001011000000010101100110000001011110000110011110"); | /*! | ||||||
|  |  * \brief Testing string decoding for GLONASS GNAV messages | ||||||
|  |  * \test The provided string (str1.....str15) was generated with a version of | ||||||
|  |  * MATLAB GNSS-SDR that the author coded to perform proper decoding of GLONASS | ||||||
|  |  * GNAV signals. The same assumption is to be applied for ephemeris and almanac | ||||||
|  |  * data provided. | ||||||
|  |  */ | ||||||
|  | TEST(GlonassGnavNavigationMessageTest, String3Decoder) | ||||||
|  | { | ||||||
|  |     // Variable declarations | ||||||
|     std::string str3("0001110000000001001101001110100011111011010011001101001101110110010011110011100100011"); |     std::string str3("0001110000000001001101001110100011111011010011001101001101110110010011110011100100011"); | ||||||
|  |     Glonass_Gnav_Navigation_Message gnav_nav_message; | ||||||
|  |     Glonass_Gnav_Ephemeris gnav_ephemeris; | ||||||
|  |  | ||||||
|  |     // Fill out ephemeris values for truth | ||||||
|  |     gnav_ephemeris.d_P_3        = 1; | ||||||
|  |     gnav_ephemeris.d_gamma_n    = 1.81898940354586e-12; | ||||||
|  |     gnav_ephemeris.d_P          = 3; | ||||||
|  |     gnav_ephemeris.d_l3rd_n     = 0; | ||||||
|  |     gnav_ephemeris.d_VZn        = -1.82016849517822; | ||||||
|  |     gnav_ephemeris.d_AZn        = -2.79396772384644e-09; | ||||||
|  |     gnav_ephemeris.d_Zn         = 19929.2377929688; | ||||||
|  |  | ||||||
|  |     // Call target test method | ||||||
|  |     gnav_nav_message.string_decoder(const_cast<char*> (str3.c_str())); | ||||||
|  |  | ||||||
|  |     // Perform assertions of decoded fields | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_P_3 - gnav_nav_message.gnav_ephemeris.d_P_3 < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_gamma_n - gnav_nav_message.gnav_ephemeris.d_gamma_n < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_P - gnav_nav_message.gnav_ephemeris.d_P < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_l3rd_n -  gnav_nav_message.gnav_ephemeris.d_l3rd_n < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_VZn - gnav_nav_message.gnav_ephemeris.d_VZn < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_AZn -  gnav_nav_message.gnav_ephemeris.d_AZn < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_Zn -  gnav_nav_message.gnav_ephemeris.d_Zn < FLT_EPSILON ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief Testing string decoding for GLONASS GNAV messages | ||||||
|  |  * \test The provided string (str1.....str15) was generated with a version of | ||||||
|  |  * MATLAB GNSS-SDR that the author coded to perform proper decoding of GLONASS | ||||||
|  |  * GNAV signals. The same assumption is to be applied for ephemeris and almanac | ||||||
|  |  * data provided. | ||||||
|  |  */ | ||||||
|  | TEST(GlonassGnavNavigationMessageTest, String4Decoder) | ||||||
|  | { | ||||||
|  |     // Variable declarations | ||||||
|     std::string str4("0010010000101011100100000100000100000000000000000000011000100100001100101010100011101"); |     std::string str4("0010010000101011100100000100000100000000000000000000011000100100001100101010100011101"); | ||||||
|  |     Glonass_Gnav_Navigation_Message gnav_nav_message; | ||||||
|  |     Glonass_Gnav_Ephemeris gnav_ephemeris; | ||||||
|  |  | ||||||
|  |     // Fill out ephemeris values for truth | ||||||
|  |     gnav_ephemeris.d_tau_n = -8.30907374620438e-05; | ||||||
|  |     gnav_ephemeris.d_Delta_tau_n = 9.31322574615479e-10; | ||||||
|  |     gnav_ephemeris.d_E_n = 0; | ||||||
|  |     gnav_ephemeris.d_P_4 = 0; | ||||||
|  |     gnav_ephemeris.d_F_T = 6; | ||||||
|  |     gnav_ephemeris.d_N_T = 268; | ||||||
|  |     gnav_ephemeris.d_n = 21; | ||||||
|  |     gnav_ephemeris.d_M = 1; | ||||||
|  |  | ||||||
|  |     // Call target test method | ||||||
|  |     gnav_nav_message.string_decoder(const_cast<char*> (str4.c_str())); | ||||||
|  |  | ||||||
|  |     // Perform assertions of decoded fields | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_tau_n - gnav_nav_message.gnav_ephemeris.d_tau_n < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_Delta_tau_n - gnav_nav_message.gnav_ephemeris.d_Delta_tau_n < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_E_n - gnav_nav_message.gnav_ephemeris.d_E_n < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_P_4 -  gnav_nav_message.gnav_ephemeris.d_P_4 < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_F_T - gnav_nav_message.gnav_ephemeris.d_F_T < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_N_T -  gnav_nav_message.gnav_ephemeris.d_N_T < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_n -  gnav_nav_message.gnav_ephemeris.d_n < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_ephemeris.d_M -  gnav_nav_message.gnav_ephemeris.d_M < FLT_EPSILON ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief Testing string decoding for GLONASS GNAV messages | ||||||
|  |  * \test The provided string (str1.....str15) was generated with a version of | ||||||
|  |  * MATLAB GNSS-SDR that the author coded to perform proper decoding of GLONASS | ||||||
|  |  * GNAV signals. The same assumption is to be applied for ephemeris and almanac | ||||||
|  |  * data provided. | ||||||
|  |  */ | ||||||
|  | TEST(GlonassGnavNavigationMessageTest, String5Decoder) | ||||||
|  | { | ||||||
|  |     // Variable declarations | ||||||
|     std::string str5("0010100100001100000000000000000000000000110011110001100000000000000001100100011000000"); |     std::string str5("0010100100001100000000000000000000000000110011110001100000000000000001100100011000000"); | ||||||
|  |     Glonass_Gnav_Navigation_Message gnav_nav_message; | ||||||
|  |     Glonass_Gnav_Utc_Model gnav_utc_model; | ||||||
|  |  | ||||||
|  |     // Fill out ephemeris values for truth | ||||||
|  |     gnav_utc_model.d_N_A        = 268; | ||||||
|  |     gnav_utc_model.d_tau_c      = 9.6391886472702e-08; | ||||||
|  |     gnav_utc_model.d_N_4        = 6; | ||||||
|  |     gnav_utc_model.d_tau_gps    = 9.313225746154785e-08; | ||||||
|  |  | ||||||
|  |     // Call target test method | ||||||
|  |     gnav_nav_message.string_decoder(const_cast<char*> (str5.c_str())); | ||||||
|  |  | ||||||
|  |     // Perform assertions of decoded fields | ||||||
|  |     ASSERT_TRUE(gnav_utc_model.d_N_A - gnav_nav_message.gnav_utc_model.d_N_A < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_utc_model.d_tau_c - gnav_nav_message.gnav_utc_model.d_tau_c < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_utc_model.d_N_4 - gnav_nav_message.gnav_utc_model.d_N_4 < FLT_EPSILON ); | ||||||
|  |     ASSERT_TRUE(gnav_utc_model.d_tau_gps -  gnav_nav_message.gnav_utc_model.d_tau_gps < FLT_EPSILON ); | ||||||
|  | } | ||||||
|  |  | ||||||
| std::string str6("0011010100110100001100111100011100001101011000000110101111001000000101100011111011001"); | std::string str6("0011010100110100001100111100011100001101011000000110101111001000000101100011111011001"); | ||||||
| std::string str7("0011101101010001000010000110101111110000101101001011111110101110100010111100010001101"); | std::string str7("0011101101010001000010000110101111110000101101001011111110101110100010111100010001101"); | ||||||
| std::string str8("0100010100111000000001111110001101000000110000001000100111011100001010101111010011010"); | std::string str8("0100010100111000000001111110001101000000110000001000100111011100001010101111010011010"); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user