mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	Adding code for telemetry decoder algorithms
This commit is contained in:
		 Damian Miralles
					Damian Miralles
				
			
				
					committed by
					
						 Damian Miralles
						Damian Miralles
					
				
			
			
				
	
			
			
			 Damian Miralles
						Damian Miralles
					
				
			
						parent
						
							6c8a29d3d4
						
					
				
				
					commit
					b34a82a949
				
			| @@ -0,0 +1,102 @@ | |||||||
|  | /*! | ||||||
|  |  * \file glonass_l1_ca_telemetry_decoder.cc | ||||||
|  |  * \brief Implementation of an adapter of a GLONASS L1 C/A NAV data decoder block | ||||||
|  |  * to a TelemetryDecoderInterface | ||||||
|  |  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "glonass_l1_ca_telemetry_decoder.h" | ||||||
|  | #include <gnuradio/io_signature.h> | ||||||
|  | #include <glog/logging.h> | ||||||
|  | #include "concurrent_queue.h" | ||||||
|  | #include "glonass_gnav_ephemeris.h" | ||||||
|  | #include "glonass_gnav_almanac.h" | ||||||
|  | #include "glonass_gnav_iono.h" | ||||||
|  | #include "glonass_gnav_utc_model.h" | ||||||
|  | #include "configuration_interface.h" | ||||||
|  |  | ||||||
|  | using google::LogMessage; | ||||||
|  |  | ||||||
|  | GlonassL1CaTelemetryDecoder::GlonassL1CaTelemetryDecoder(ConfigurationInterface* configuration, | ||||||
|  |         std::string role, | ||||||
|  |         unsigned int in_streams, | ||||||
|  |         unsigned int out_streams) : | ||||||
|  |         role_(role), | ||||||
|  |         in_streams_(in_streams), | ||||||
|  |         out_streams_(out_streams) | ||||||
|  | { | ||||||
|  |     std::string default_dump_filename = "./navigation.dat"; | ||||||
|  |     DLOG(INFO) << "role " << role; | ||||||
|  |     dump_ = configuration->property(role + ".dump", false); | ||||||
|  |     dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); | ||||||
|  |     // make telemetry decoder object | ||||||
|  |     telemetry_decoder_ = glonass_l1_ca_make_telemetry_decoder_cc(satellite_, dump_); // TODO fix me | ||||||
|  |     DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; | ||||||
|  |  | ||||||
|  |     DLOG(INFO) << "global navigation message queue assigned to telemetry_decoder ("<< telemetry_decoder_->unique_id() << ")"; | ||||||
|  |     channel_ = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | GlonassL1CaTelemetryDecoder::~GlonassL1CaTelemetryDecoder() | ||||||
|  | {} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void GlonassL1CaTelemetryDecoder::set_satellite(Gnss_Satellite satellite) | ||||||
|  | { | ||||||
|  |     satellite_ = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); | ||||||
|  |     telemetry_decoder_->set_satellite(satellite_); | ||||||
|  |     DLOG(INFO) << "TELEMETRY DECODER: satellite set to " << satellite_; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void GlonassL1CaTelemetryDecoder::connect(gr::top_block_sptr top_block) | ||||||
|  | { | ||||||
|  |     if(top_block) { /* top_block is not null */}; | ||||||
|  |     // Nothing to connect internally | ||||||
|  |     DLOG(INFO) << "nothing to connect internally"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void GlonassL1CaTelemetryDecoder::disconnect(gr::top_block_sptr top_block) | ||||||
|  | { | ||||||
|  |     if(top_block) { /* top_block is not null */}; | ||||||
|  |     // Nothing to disconnect | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | gr::basic_block_sptr GlonassL1CaTelemetryDecoder::get_left_block() | ||||||
|  | { | ||||||
|  |     return telemetry_decoder_; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | gr::basic_block_sptr GlonassL1CaTelemetryDecoder::get_right_block() | ||||||
|  | { | ||||||
|  |     return telemetry_decoder_; | ||||||
|  | } | ||||||
| @@ -0,0 +1,91 @@ | |||||||
|  | /*! | ||||||
|  |  * \file glonass_l1_ca_telemetry_decoder.h | ||||||
|  |  * \brief Interface of an adapter of a GLONASS L1 C/A NAV data decoder block | ||||||
|  |  * to a TelemetryDecoderInterface | ||||||
|  |  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifndef GNSS_SDR_GLONASS_L1_CA_TELEMETRY_DECODER_H_ | ||||||
|  | #define GNSS_SDR_GLONASS_L1_CA_TELEMETRY_DECODER_H_ | ||||||
|  |  | ||||||
|  | #include <string> | ||||||
|  | #include "telemetry_decoder_interface.h" | ||||||
|  | #include "glonass_l1_ca_telemetry_decoder_cc.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ConfigurationInterface; | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief This class implements a NAV data decoder for GLONASS L1 C/A | ||||||
|  |  */ | ||||||
|  | class GlonassL1CaTelemetryDecoder : public TelemetryDecoderInterface | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     GlonassL1CaTelemetryDecoder(ConfigurationInterface* configuration, | ||||||
|  |             std::string role, | ||||||
|  |             unsigned int in_streams, | ||||||
|  |             unsigned int out_streams); | ||||||
|  |  | ||||||
|  |     virtual ~GlonassL1CaTelemetryDecoder(); | ||||||
|  |     std::string role() | ||||||
|  |     { | ||||||
|  |         return role_; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     //! Returns "GLONASS_L1_CA_Telemetry_Decoder" | ||||||
|  |     std::string implementation() | ||||||
|  |     { | ||||||
|  |         return "GLONASS_L1_CA_Telemetry_Decoder"; | ||||||
|  |     } | ||||||
|  |     void connect(gr::top_block_sptr top_block); | ||||||
|  |     void disconnect(gr::top_block_sptr top_block); | ||||||
|  |     gr::basic_block_sptr get_left_block(); | ||||||
|  |     gr::basic_block_sptr get_right_block(); | ||||||
|  |     void set_satellite(Gnss_Satellite satellite); | ||||||
|  |     void set_channel(int channel){telemetry_decoder_->set_channel(channel);} | ||||||
|  |     void reset() | ||||||
|  |     { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     size_t item_size() | ||||||
|  |     { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     glonass_l1_ca_telemetry_decoder_cc_sptr telemetry_decoder_; | ||||||
|  |     Gnss_Satellite satellite_; | ||||||
|  |     int channel_; | ||||||
|  |     bool dump_; | ||||||
|  |     std::string dump_filename_; | ||||||
|  |     std::string role_; | ||||||
|  |     unsigned int in_streams_; | ||||||
|  |     unsigned int out_streams_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @@ -0,0 +1,441 @@ | |||||||
|  | /*! | ||||||
|  |  * \file galileo_e1b_telemetry_decoder_cc.cc | ||||||
|  |  * \brief Implementation of a Galileo INAV message demodulator block | ||||||
|  |  * \author Mara Branzanti 2013. mara.branzanti(at)gmail.com | ||||||
|  |  * \author Javier Arribas 2013. jarribas(at)cttc.es | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "galileo_e1b_telemetry_decoder_cc.h" | ||||||
|  | #include <cstdio> | ||||||
|  | #include <cstdlib> | ||||||
|  | #include <iostream> | ||||||
|  | #include <boost/lexical_cast.hpp> | ||||||
|  | #include <gnuradio/io_signature.h> | ||||||
|  | #include <glog/logging.h> | ||||||
|  | #include "control_message_factory.h" | ||||||
|  | #include "gnss_synchro.h" | ||||||
|  | #include "convolutional.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #define CRC_ERROR_LIMIT 6 | ||||||
|  |  | ||||||
|  | using google::LogMessage; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | glonass_l1_ca_telemetry_decoder_cc_sptr | ||||||
|  | glonass_l1_ca_make_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump) | ||||||
|  | { | ||||||
|  |     return glonass_l1_ca_telemetry_decoder_cc_sptr(new glonass_l1_ca_telemetry_decoder_cc(satellite, dump)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | glonass_l1_ca_telemetry_decoder_cc::glonass_l1_ca_telemetry_decoder_cc( | ||||||
|  |         Gnss_Satellite satellite, | ||||||
|  |         bool dump) : | ||||||
|  |                    gr::block("glonass_l1_ca_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), | ||||||
|  |                            gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) | ||||||
|  | { | ||||||
|  |     // Telemetry Bit transition synchronization port out | ||||||
|  |     this->message_port_register_out(pmt::mp("preamble_timestamp_s")); | ||||||
|  |     // Ephemeris data port out | ||||||
|  |     this->message_port_register_out(pmt::mp("telemetry")); | ||||||
|  |     // initialize internal vars | ||||||
|  |     d_dump = dump; | ||||||
|  |     d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); | ||||||
|  |     LOG(INFO) << "Initializing GLONASS L1CA TELEMETRY PROCESSING"; | ||||||
|  |     // TODO. WHAT IS THIS? | ||||||
|  |     d_samples_per_symbol = ( GLONASS_L1_CODE_CHIP_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS ) / GLONASS_L1_CA_SYMBOL_RATE_BPS; | ||||||
|  |  | ||||||
|  |     // set the preamble | ||||||
|  |     unsigned short int preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS] = GLONASS_GNAV_PREAMBLE; | ||||||
|  |     d_symbols_per_preamble = GLONASS_GNAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol; | ||||||
|  |  | ||||||
|  |     memcpy((unsigned short int*)this->d_preambles_bits, (unsigned short int*)preambles_bits, GLONASS_GNAV_PREAMBLE_LENGTH_BITS*sizeof(unsigned short int)); | ||||||
|  |  | ||||||
|  |     // preamble bits to sampled symbols | ||||||
|  |     d_preambles_symbols = (signed int*)malloc(sizeof(signed int) * d_symbols_per_preamble); | ||||||
|  |     int n = 0; | ||||||
|  |     for (int i = 0; i < GLONASS_GNAV_PREAMBLE_LENGTH_BITS; i++) | ||||||
|  |         { | ||||||
|  |             for (unsigned int j = 0; j < d_samples_per_symbol; j++) | ||||||
|  |                 { | ||||||
|  |                     if (d_preambles_bits[i] == 1) | ||||||
|  |                         { | ||||||
|  |                             d_preambles_symbols[n] = 1; | ||||||
|  |                         } | ||||||
|  |                     else | ||||||
|  |                         { | ||||||
|  |                             d_preambles_symbols[n] = -1; | ||||||
|  |                         } | ||||||
|  |                     n++; | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     d_sample_counter = 0; | ||||||
|  |     d_stat = 0; | ||||||
|  |     d_preamble_index = 0; | ||||||
|  |  | ||||||
|  |     d_flag_frame_sync = false; | ||||||
|  |  | ||||||
|  |     d_flag_parity = false; | ||||||
|  |     d_TOW_at_current_symbol = 0; | ||||||
|  |     delta_t = 0; | ||||||
|  |     d_CRC_error_counter = 0; | ||||||
|  |     flag_even_word_arrived = 0; | ||||||
|  |     d_flag_preamble = false; | ||||||
|  |     d_channel = 0; | ||||||
|  |     flag_TOW_set = false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | glonass_l1_ca_telemetry_decoder_cc::~glonass_l1_ca_telemetry_decoder_cc() | ||||||
|  | { | ||||||
|  |     delete d_preambles_symbols; | ||||||
|  |     d_dump_file.close(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *page_part_symbols,int frame_length) | ||||||
|  | { | ||||||
|  |     double page_part_symbols_deint[frame_length]; | ||||||
|  |  | ||||||
|  |     // 2. Viterbi decoder | ||||||
|  |     // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) | ||||||
|  |     // 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180<38> | ||||||
|  |     for (int i = 0; i < frame_length; i++) | ||||||
|  |         { | ||||||
|  |             if ((i + 1) % 2 == 0) | ||||||
|  |                 { | ||||||
|  |                     page_part_symbols_deint[i] = -page_part_symbols_deint[i]; | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     int page_part_bits[frame_length/2]; | ||||||
|  |     viterbi_decoder(page_part_symbols_deint, page_part_bits); | ||||||
|  |  | ||||||
|  |     // 3. Call the Galileo page decoder | ||||||
|  |     std::string page_String; | ||||||
|  |     for(int i = 0; i < (frame_length/2); i++) | ||||||
|  |         { | ||||||
|  |             if (page_part_bits[i] > 0) | ||||||
|  |                 { | ||||||
|  |                     page_String.push_back('1'); | ||||||
|  |                 } | ||||||
|  |             else | ||||||
|  |                 { | ||||||
|  |                     page_String.push_back('0'); | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     d_nav.decode_string(page_String); | ||||||
|  |  | ||||||
|  |     if(d_nav.flag_CRC_test == true) | ||||||
|  |         { | ||||||
|  |             LOG(INFO) << "GLONASS GNAV CRC correct on channel " << d_channel << " from satellite " << d_satellite; | ||||||
|  |             std::cout << "GLONASS GNAV CRC correct on channel " << d_channel << " from satellite " << d_satellite << std::endl; | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             std::cout << "GLONASS GNAV CRC error on channel " << d_channel <<  " from satellite " << d_satellite << std::endl; | ||||||
|  |             LOG(INFO) << "GLONASS GNAV CRC error on channel " << d_channel <<  " from satellite " << d_satellite; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     // 4. Push the new navigation data to the queues | ||||||
|  |     if (d_nav.have_new_ephemeris() == true) | ||||||
|  |         { | ||||||
|  |             // get object for this SV (mandatory) | ||||||
|  |             std::shared_ptr<Glonass_Gnav_Ephemeris> tmp_obj = std::make_shared<Glonass_Gnav_Ephemeris>(d_nav.get_ephemeris()); | ||||||
|  |  | ||||||
|  |             this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |     if (d_nav.have_new_utc_model() == true) | ||||||
|  |         { | ||||||
|  |             // get object for this SV (mandatory) | ||||||
|  |             std::shared_ptr<Glonass_Gnav_Utc_Model> tmp_obj = std::make_shared<Glonass_Gnav_Utc_Model>(d_nav.get_utc_model()); | ||||||
|  |             this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); | ||||||
|  |         } | ||||||
|  |     if (d_nav.have_new_almanac() == true) | ||||||
|  |         { | ||||||
|  |             std::shared_ptr<Glonass_Gnav_Almanac> tmp_obj= std::make_shared<Glonass_Gnav_Almanac>(d_nav.get_almanac()); | ||||||
|  |             this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); | ||||||
|  |             //debug | ||||||
|  |             std::cout << "GLONASS GNAV almanac received!" << std::endl; | ||||||
|  |             DLOG(INFO) << "Current parameters:"; | ||||||
|  |             DLOG(INFO) << "d_TOW_at_current_symbol=" << d_TOW_at_current_symbol; | ||||||
|  |             DLOG(INFO) << "d_nav.WN_0=" << d_nav.WN_0; | ||||||
|  |             delta_t = tmp_obj->A_0G_10 + tmp_obj->A_1G_10 * (d_TOW_at_current_symbol - tmp_obj->t_0G_10 + 604800 * (fmod((d_nav.WN_0 - tmp_obj->WN_0G_10), 64))); | ||||||
|  |             DLOG(INFO) << "delta_t=" << delta_t << "[s]"; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), | ||||||
|  |         gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) | ||||||
|  | { | ||||||
|  |     int corr_value = 0; | ||||||
|  |     int preamble_diff = 0; | ||||||
|  |  | ||||||
|  |     Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0]; | ||||||
|  |     const Gnss_Synchro **in = (const Gnss_Synchro **)  &input_items[0]; //Get the input samples pointer | ||||||
|  |  | ||||||
|  |     Gnss_Synchro current_symbol; //structure to save the synchronization information and send the output object to the next block | ||||||
|  |     //1. Copy the current tracking output | ||||||
|  |     current_symbol = in[0][0]; | ||||||
|  |     d_symbol_history.push_back(current_symbol); //add new symbol to the symbol queue | ||||||
|  |     d_sample_counter++; //count for the processed samples | ||||||
|  |     consume_each(1); | ||||||
|  |  | ||||||
|  |     d_flag_preamble = false; | ||||||
|  |     unsigned int required_symbols=GLONASS_GNAV_PAGE_SYMBOLS+d_symbols_per_preamble; | ||||||
|  |  | ||||||
|  |     if (d_symbol_history.size()>required_symbols) | ||||||
|  |     { | ||||||
|  |         //******* preamble correlation ******** | ||||||
|  |         for (int i = 0; i < d_symbols_per_preamble; i++) | ||||||
|  |             { | ||||||
|  |                 if (d_symbol_history.at(i).Prompt_I < 0)    // symbols clipping | ||||||
|  |                     { | ||||||
|  |                         corr_value -= d_preambles_symbols[i]; | ||||||
|  |                     } | ||||||
|  |                 else | ||||||
|  |                     { | ||||||
|  |                         corr_value += d_preambles_symbols[i]; | ||||||
|  |                     } | ||||||
|  |             } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     //******* frame sync ****************** | ||||||
|  |     if (d_stat == 0) //no preamble information | ||||||
|  |         { | ||||||
|  |             if (abs(corr_value) >= d_symbols_per_preamble) | ||||||
|  |                 { | ||||||
|  |                     d_preamble_index = d_sample_counter;//record the preamble sample stamp | ||||||
|  |                     LOG(INFO) << "Preamble detection for GLONASS L1 C/A SAT " << this->d_satellite; | ||||||
|  |                     d_stat = 1; // enter into frame pre-detection status | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else if (d_stat == 1) // posible preamble lock | ||||||
|  |         { | ||||||
|  |             if (abs(corr_value) >= d_symbols_per_preamble) | ||||||
|  |                 { | ||||||
|  |                     //check preamble separation | ||||||
|  |                     preamble_diff = d_sample_counter - d_preamble_index; | ||||||
|  |                     if (abs(preamble_diff - GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) == 0) | ||||||
|  |                         { | ||||||
|  |                             //try to decode frame | ||||||
|  |                             LOG(INFO) << "Starting page decoder for GLONASS L1 C/A SAT " << this->d_satellite; | ||||||
|  |                             d_preamble_index = d_sample_counter; //record the preamble sample stamp | ||||||
|  |                             d_stat = 2; | ||||||
|  |                         } | ||||||
|  |                     else | ||||||
|  |                         { | ||||||
|  |                             if (preamble_diff > GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) | ||||||
|  |                                 { | ||||||
|  |                                     d_stat = 0; // start again | ||||||
|  |                                 } | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else if (d_stat == 2) | ||||||
|  |         { | ||||||
|  |             if (d_sample_counter == d_preamble_index + GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) | ||||||
|  |                 { | ||||||
|  |                     // NEW GLONASS string received | ||||||
|  |                     // 0. fetch the symbols into an array | ||||||
|  |                     int frame_length = GLONASS_GNAV_STRING_SYMBOLS - d_symbols_per_preamble; | ||||||
|  |                     double page_part_symbols[frame_length]; | ||||||
|  |  | ||||||
|  |                     //******* SYMBOL TO BIT ******* | ||||||
|  |                     if (d_symbol_history.at(0).Flag_valid_symbol_output == true) | ||||||
|  |                         { | ||||||
|  |                             // extended correlation to bit period is enabled in tracking! | ||||||
|  |                             d_symbol_accumulator += d_symbol_history.at(0).Prompt_I; // accumulate the input value in d_symbol_accumulator | ||||||
|  |                             d_symbol_accumulator_counter += d_symbol_history.at(0).correlation_length_ms; | ||||||
|  |                         } | ||||||
|  |                     if (d_symbol_accumulator_counter >= 20) | ||||||
|  |                          { | ||||||
|  |                          } | ||||||
|  |  | ||||||
|  |                     for (int i = 0; i < frame_length; i++) | ||||||
|  |                         { | ||||||
|  |                             if (corr_value > 0) | ||||||
|  |                                 { | ||||||
|  |                                     page_part_symbols[i] = d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now! | ||||||
|  |  | ||||||
|  |                                 } | ||||||
|  |                             else | ||||||
|  |                                 { | ||||||
|  |                                     page_part_symbols[i] = -d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now! | ||||||
|  |                                 } | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                     //call the decoder | ||||||
|  |                     decode_string(page_part_symbols); | ||||||
|  |                     if (d_nav.flag_CRC_test == true) | ||||||
|  |                         { | ||||||
|  |                             d_CRC_error_counter = 0; | ||||||
|  |                             d_flag_preamble = true; //valid preamble indicator (initialized to false every work()) | ||||||
|  |                             d_preamble_index = d_sample_counter;  //record the preamble sample stamp (t_P) | ||||||
|  |                             if (!d_flag_frame_sync) | ||||||
|  |                                 { | ||||||
|  |                                     d_flag_frame_sync = true; | ||||||
|  |                                     DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " | ||||||
|  |                                             << d_symbol_history.at(0).Tracking_sample_counter << " [samples]"; | ||||||
|  |                                 } | ||||||
|  |                         } | ||||||
|  |                     else | ||||||
|  |                         { | ||||||
|  |                             d_CRC_error_counter++; | ||||||
|  |                             d_preamble_index = d_sample_counter;  //record the preamble sample stamp | ||||||
|  |                             if (d_CRC_error_counter > CRC_ERROR_LIMIT) | ||||||
|  |                                 { | ||||||
|  |                                     LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite; | ||||||
|  |                                     d_flag_frame_sync = false; | ||||||
|  |                                     d_stat = 0; | ||||||
|  |                                 } | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     // UPDATE GNSS SYNCHRO DATA | ||||||
|  |     //2. Add the telemetry decoder information | ||||||
|  |     if (this->d_flag_preamble == true and d_nav.flag_TOW_set == true) | ||||||
|  |         //update TOW at the preamble instant | ||||||
|  |         { | ||||||
|  |             if(d_nav.flag_TOW_5 == true) //page 5 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec) | ||||||
|  |                 { | ||||||
|  |                 //TOW_5 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay | ||||||
|  |                     d_TOW_at_current_symbol = d_nav.TOW_5  + GALILEO_INAV_PAGE_PART_SECONDS+((double)required_symbols)*GALILEO_E1_CODE_PERIOD; //-GALILEO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND; | ||||||
|  |                     d_nav.flag_TOW_5 = false; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             else if(d_nav.flag_TOW_6 == true) //page 6 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec) | ||||||
|  |                 { | ||||||
|  |                     //TOW_6 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay | ||||||
|  |                     d_TOW_at_current_symbol = d_nav.TOW_6 + GALILEO_INAV_PAGE_PART_SECONDS+((double)required_symbols)*GALILEO_E1_CODE_PERIOD;//-GALILEO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND; | ||||||
|  |                     d_nav.flag_TOW_6 = false; | ||||||
|  |                 } | ||||||
|  |             else | ||||||
|  |                 { | ||||||
|  |                     //this page has no timing information | ||||||
|  |                     d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E1_CODE_PERIOD;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALILEO_E1_CODE_PERIOD; | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else //if there is not a new preamble, we define the TOW of the current symbol | ||||||
|  |         { | ||||||
|  |             d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E1_CODE_PERIOD; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     //if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true) | ||||||
|  |  | ||||||
|  |     if(d_nav.flag_GGTO_1 == true  and  d_nav.flag_GGTO_2 == true and  d_nav.flag_GGTO_3 == true and  d_nav.flag_GGTO_4 == true) //all GGTO parameters arrived | ||||||
|  |         { | ||||||
|  |             delta_t = d_nav.A_0G_10 + d_nav.A_1G_10 * (d_TOW_at_current_symbol - d_nav.t_0G_10 + 604800.0 * (fmod((d_nav.WN_0 - d_nav.WN_0G_10), 64))); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     if (d_flag_frame_sync == true and d_nav.flag_TOW_set == true) | ||||||
|  |         { | ||||||
|  |             current_symbol.Flag_valid_word = true; | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             current_symbol.Flag_valid_word = false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     current_symbol.TOW_at_current_symbol_s = floor(d_TOW_at_current_symbol*1000.0)/1000.0; | ||||||
|  |     current_symbol.TOW_at_current_symbol_s -=delta_t; //Galileo to GPS TOW | ||||||
|  |  | ||||||
|  |     if(d_dump == true) | ||||||
|  |         { | ||||||
|  |             // MULTIPLEXED FILE RECORDING - Record results to file | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 double tmp_double; | ||||||
|  |                 unsigned long int tmp_ulong_int; | ||||||
|  |                 tmp_double = d_TOW_at_current_symbol; | ||||||
|  |                 d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  |                 tmp_ulong_int = current_symbol.Tracking_sample_counter; | ||||||
|  |                 d_dump_file.write((char*)&tmp_ulong_int, sizeof(unsigned long int)); | ||||||
|  |                 tmp_double = 0; | ||||||
|  |                 d_dump_file.write((char*)&tmp_double, sizeof(double)); | ||||||
|  |             } | ||||||
|  |             catch (const std::ifstream::failure & e) | ||||||
|  |             { | ||||||
|  |                     LOG(WARNING) << "Exception writing observables dump file " << e.what(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     // remove used symbols from history | ||||||
|  |     if (d_symbol_history.size()>required_symbols) | ||||||
|  |     { | ||||||
|  |         d_symbol_history.pop_front(); | ||||||
|  |     } | ||||||
|  |     //3. Make the output (copy the object contents to the GNURadio reserved memory) | ||||||
|  |     *out[0] = current_symbol; | ||||||
|  |  | ||||||
|  |     return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void glonass_l1_ca_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite) | ||||||
|  | { | ||||||
|  |     d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); | ||||||
|  |     DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite; | ||||||
|  |     DLOG(INFO) << "Navigation Satellite set to " << d_satellite; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void glonass_l1_ca_telemetry_decoder_cc::set_channel(int channel) | ||||||
|  | { | ||||||
|  |     d_channel = channel; | ||||||
|  |     LOG(INFO) << "Navigation channel set to " << channel; | ||||||
|  |     // ############# ENABLE DATA FILE LOG ################# | ||||||
|  |     if (d_dump == true) | ||||||
|  |         { | ||||||
|  |             if (d_dump_file.is_open() == false) | ||||||
|  |                 { | ||||||
|  |                     try | ||||||
|  |                     { | ||||||
|  |                             d_dump_filename = "telemetry"; | ||||||
|  |                             d_dump_filename.append(boost::lexical_cast<std::string>(d_channel)); | ||||||
|  |                             d_dump_filename.append(".dat"); | ||||||
|  |                             d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit ); | ||||||
|  |                             d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary); | ||||||
|  |                             LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str(); | ||||||
|  |                     } | ||||||
|  |                     catch (const std::ifstream::failure& e) | ||||||
|  |                     { | ||||||
|  |                             LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  | } | ||||||
| @@ -0,0 +1,114 @@ | |||||||
|  | /*! | ||||||
|  |  * \file glonass_l1_ca_telemetry_decoder_cc.h | ||||||
|  |  * \brief Interface of a GLONASS GNAV message demodulator block | ||||||
|  |  * \author Damian Miralles, 2017. dmiralles2009(at)gmail.com | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors) | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is a software defined Global Navigation | ||||||
|  |  *          Satellite Systems receiver | ||||||
|  |  * | ||||||
|  |  * This file is part of GNSS-SDR. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * GNSS-SDR is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ------------------------------------------------------------------------- | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef GNSS_SDR_GLONASS_L1_CA_TELEMETRY_DECODER_CC_H | ||||||
|  | #define GNSS_SDR_GLONASS_L1_CA_TELEMETRY_DECODER_CC_H | ||||||
|  |  | ||||||
|  | #include <fstream> | ||||||
|  | #include <string> | ||||||
|  | #include <gnuradio/block.h> | ||||||
|  | #include "GLONASS_L1_CA.h" | ||||||
|  | #include "concurrent_queue.h" | ||||||
|  | #include "gnss_satellite.h" | ||||||
|  | #include "glonass_gnav_navigation_message.h" | ||||||
|  | #include "glonass_gnav_ephemeris.h" | ||||||
|  | #include "glonass_gnav_almanac.h" | ||||||
|  | #include "glonass_gnav_iono.h" | ||||||
|  | #include "glonass_gnav_utc_model.h" | ||||||
|  | #include "gnss_synchro.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class glonass_l1_ca_telemetry_decoder_cc; | ||||||
|  |  | ||||||
|  | typedef boost::shared_ptr<glonass_l1_ca_telemetry_decoder_cc> glonass_l1_ca_telemetry_decoder_cc_sptr; | ||||||
|  |  | ||||||
|  | glonass_l1_ca_telemetry_decoder_cc_sptr glonass_l1_ca_make_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump); | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |  * \brief This class implements a block that decodes the GNAV data defined in GLONASS ICD | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | class glonass_l1_ca_telemetry_decoder_cc : public gr::block | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     ~glonass_l1_ca_telemetry_decoder_cc(); | ||||||
|  |     void set_satellite(Gnss_Satellite satellite);  //!< Set satellite PRN | ||||||
|  |     void set_channel(int channel);                 //!< Set receiver's channel | ||||||
|  |  | ||||||
|  |     /*! | ||||||
|  |      * \brief This is where all signal processing takes place | ||||||
|  |      */ | ||||||
|  |     int general_work (int noutput_items, gr_vector_int &ninput_items, | ||||||
|  |             gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     friend glonass_l1_ca_telemetry_decoder_cc_sptr | ||||||
|  |     glonass_l1_ca_make_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump); | ||||||
|  |     glonass_l1_ca_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump); | ||||||
|  |  | ||||||
|  |     void decode_word(double *symbols,int frame_length); | ||||||
|  |  | ||||||
|  |     //!< Preamble decoding | ||||||
|  |     unsigned short int d_preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS]; | ||||||
|  |     int *d_preambles_symbols; | ||||||
|  |     unsigned int d_samples_per_symbol; | ||||||
|  |     int d_symbols_per_preamble; | ||||||
|  |  | ||||||
|  |     //!< Storage for incoming data | ||||||
|  |     std::deque<Gnss_Synchro> d_symbol_history; | ||||||
|  |  | ||||||
|  |     //!< Variables for internal functionality | ||||||
|  |     long unsigned int d_sample_counter;     //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed | ||||||
|  |     long unsigned int d_preamble_index;     //!< Index of sample number where preamble was found | ||||||
|  |     unsigned int d_stat;                    //!< Status of decoder | ||||||
|  |     bool d_flag_frame_sync;                 //!< Indicate when a frame sync is achieved | ||||||
|  |     bool d_flag_parity;                     //!< Flag indicating when parity check was achieved (crc check) | ||||||
|  |     bool d_flag_preamble; | ||||||
|  |     int d_CRC_error_counter; | ||||||
|  |     bool flag_TOW_set;      //!< | ||||||
|  |     double delta_t;         //!< GPS-GLONASS time offset | ||||||
|  |      | ||||||
|  |     //!< Navigation Message variable | ||||||
|  |     Glonass_Gnav_Navigation_Message d_nav; | ||||||
|  |  | ||||||
|  |     //!< Values to populate gnss synchronization structure | ||||||
|  |     double d_TOW_at_current_symbol; | ||||||
|  |     bool Flag_valid_word; | ||||||
|  |  | ||||||
|  |     //!< Satellite Information and logging capacity | ||||||
|  |     Gnss_Satellite d_satellite; | ||||||
|  |     int d_channel; | ||||||
|  |     bool d_dump; | ||||||
|  |     std::string d_dump_filename; | ||||||
|  |     std::ofstream d_dump_file; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @@ -84,6 +84,7 @@ const double GLONASS_L1_CA_CODE_RATE_HZ      = 0.511e6;       //!< GLONASS L1 C/ | |||||||
| const double GLONASS_L1_CA_CODE_LENGTH_CHIPS = 511.0;         //!< GLONASS L1 C/A code length [chips] | const double GLONASS_L1_CA_CODE_LENGTH_CHIPS = 511.0;         //!< GLONASS L1 C/A code length [chips] | ||||||
| const double GLONASS_L1_CA_CODE_PERIOD       = 0.001;         //!< GLONASS L1 C/A code period [seconds] | const double GLONASS_L1_CA_CODE_PERIOD       = 0.001;         //!< GLONASS L1 C/A code period [seconds] | ||||||
| const double GLONASS_L1_CA_CHIP_PERIOD       = 1.9569e-06;    //!< GLONASS L1 C/A chip period [seconds] | const double GLONASS_L1_CA_CHIP_PERIOD       = 1.9569e-06;    //!< GLONASS L1 C/A chip period [seconds] | ||||||
|  | const double GLONASS_L1_CA_SYMBOL_RATE_BPS   = 1000; | ||||||
|  |  | ||||||
| const double GLONASS_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here) | const double GLONASS_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here) | ||||||
|  |  | ||||||
| @@ -91,7 +92,6 @@ const double GLONASS_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time ( | |||||||
| const int GLONASS_L1_CA_HISTORY_DEEP = 100; | const int GLONASS_L1_CA_HISTORY_DEEP = 100; | ||||||
|  |  | ||||||
| // NAVIGATION MESSAGE DEMODULATION AND DECODING | // NAVIGATION MESSAGE DEMODULATION AND DECODING | ||||||
|  |  | ||||||
| #define GLONASS_CA_PREAMBLE {1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0} | #define GLONASS_CA_PREAMBLE {1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0} | ||||||
| const int GLONASS_CA_PREAMBLE_LENGTH_BITS = 30; | const int GLONASS_CA_PREAMBLE_LENGTH_BITS = 30; | ||||||
| const int GLONASS_CA_PREAMBLE_LENGTH_SYMBOLS = 300; | const int GLONASS_CA_PREAMBLE_LENGTH_SYMBOLS = 300; | ||||||
| @@ -99,9 +99,7 @@ const double GLONASS_CA_PREAMBLE_DURATION_S = 0.3; | |||||||
| const int GLONASS_CA_TELEMETRY_RATE_BITS_SECOND = 50;   //!< NAV message bit rate [bits/s] | const int GLONASS_CA_TELEMETRY_RATE_BITS_SECOND = 50;   //!< NAV message bit rate [bits/s] | ||||||
| const int GLONASS_CA_TELEMETRY_SYMBOLS_PER_BIT = 10; | const int GLONASS_CA_TELEMETRY_SYMBOLS_PER_BIT = 10; | ||||||
| const int GLONASS_CA_TELEMETRY_RATE_SYMBOLS_SECOND = GLONASS_CA_TELEMETRY_RATE_BITS_SECOND*GLONASS_CA_TELEMETRY_SYMBOLS_PER_BIT;   //!< NAV message bit rate [symbols/s] | const int GLONASS_CA_TELEMETRY_RATE_SYMBOLS_SECOND = GLONASS_CA_TELEMETRY_RATE_BITS_SECOND*GLONASS_CA_TELEMETRY_SYMBOLS_PER_BIT;   //!< NAV message bit rate [symbols/s] | ||||||
|  | const int GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS = 1700; | ||||||
| const int GLONASS_GNAV_WORD_LENGTH = 4;         //!< \TODO cHECK this, size is not integer bte size |  | ||||||
| const int GLONASS_GNAV_FRAME_LENGTH = 40;       //!< \TODO GPS_WORD_LENGTH x 10 = 40 bytes |  | ||||||
| const int GLONASS_GNAV_FRAME_BITS = 1725;       //!< Number of chips per frame in the GNAV message  15 strings*(85 data bits + 30 time mark bits)[bits] | const int GLONASS_GNAV_FRAME_BITS = 1725;       //!< Number of chips per frame in the GNAV message  15 strings*(85 data bits + 30 time mark bits)[bits] | ||||||
| const int GLONASS_GNAV_FRAME_SECONDS = 30;      //!< Subframe duration [seconds] | const int GLONASS_GNAV_FRAME_SECONDS = 30;      //!< Subframe duration [seconds] | ||||||
| const int GLONASS_GNAV_FRAME_MS = 30000;        //!< Subframe duration [seconds] | const int GLONASS_GNAV_FRAME_MS = 30000;        //!< Subframe duration [seconds] | ||||||
|   | |||||||
| @@ -37,98 +37,55 @@ m * \file glonass_gnav_navigation_message.cc | |||||||
|  |  | ||||||
| void Glonass_Gnav_Navigation_Message::reset() | void Glonass_Gnav_Navigation_Message::reset() | ||||||
| { | { | ||||||
|     b_valid_ephemeris_set_flag = false; |     //!< Satellite Identification | ||||||
|     double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s] |     i_channel_ID = 0;               //!< Channel ID assigned by the receiver | ||||||
|     d_TOW_SF1 = 0;            //!< Time of GPS Week from HOW word of Subframe 1 [s] |     i_satellite_freq_channel = 0;   //!< SV Frequency Slot Number | ||||||
|     d_TOW_SF2 = 0;            //!< Time of GPS Week from HOW word of Subframe 2 [s] |     i_satellite_slot_number = 0;    //!< SV Orbit Slot Number | ||||||
|     d_TOW_SF3 = 0;            //!< Time of GPS Week from HOW word of Subframe 3 [s] |  | ||||||
|     d_TOW_SF4 = 0;            //!< Time of GPS Week from HOW word of Subframe 4 [s] |  | ||||||
|     d_TOW_SF5 = 0;            //!< Time of GPS Week from HOW word of Subframe 5 [s] |  | ||||||
|  |  | ||||||
|     d_m = 0.0;               //!< String number within frame [dimensionless] |     //!< Ephmeris Flags | ||||||
|     d_t_k = 0.0;             //!< Time referenced to the beginning of the frame within the current day [hours, minutes, seconds] |     flag_all_ephemeris = false; | ||||||
|     d_t_b = 0.0;             //!< Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. [minutes] |     flag_ephemeris_str_1 = false; | ||||||
|     d_M = 0.0;               //!< Type of satellite transmitting navigation signal [dimensionless] |     flag_ephemeris_str_2 = false; | ||||||
|     d_gamma_n = 0.0;         //!< Relative deviation of predicted carrier frequency value of n- satellite from nominal value at the instant tb [dimensionless] |     flag_ephemeris_str_3 = false; | ||||||
|     d_tau_n = 0.0;           //!< Correction to the nth satellite time (tn) relative to GLONASS time (te), |     flag_ephemeris_str_4 = false; | ||||||
|     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_l_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] |  | ||||||
|  |  | ||||||
|     // Almanac and Not Inmediate Information |     //!< Almanac Flags | ||||||
|     d_tau_c = 0.0;             //!< GLONASS time scale correction to UTC(SU) time. [s] |     flag_all_almanac = false; | ||||||
|     d_tau_gps = 0.0;           //!< Correction to GPS time to GLONASS time [day] |     flag_almanac_str_6  = false; | ||||||
|     d_N_4 = 0.0;               //!< Four year interval number starting from 1996 [4 year interval] |     flag_almanac_str_7  = false; | ||||||
|     d_N_A = 0.0;               //!< Calendar day number within the four-year period beginning since the leap year [days] |     flag_almanac_str_8  = false; | ||||||
|     d_n_A = 0.0;               //!< Conventional number of satellite within GLONASS space segment [dimensionless] |     flag_almanac_str_9  = false; | ||||||
|     d_H_n_A = 0.0;             //!< Carrier frequency number of navigation RF signal transmitted by d_nA satellite [dimensionless] |     flag_almanac_str_10 = false; | ||||||
|     d_lambda_n_A = 0.0;        //!< Longitude of the first (within the d_NA day) ascending node of d_nA  [semi-circles] |     flag_almanac_str_11 = false; | ||||||
|     d_t_lambda_n_A = 0.0;      //!< Time of first ascending node passage [s] |     flag_almanac_str_12 = false; | ||||||
|     d_Delta_i_n_A = 0.0;        //!< Correction of the mean value of inclination of d_n_A satellite at instant t_lambda_n_A [semi-circles] |     flag_almanac_str_13 = false; | ||||||
|     d_Delta_T_n_A = 0.0;       //!< Correction to the mean value of Draconian period of d_n_A satellite at instant t_lambda_n_A[s / orbital period] |     flag_almanac_str_14 = false; | ||||||
|     d_Delta_T_n_A_dot = 0.0;   //!< Rate of change of Draconian period of d_n_A satellite at instant t_lambda_n_A [s / orbital period^2] |     flag_almanac_str_15 = false; | ||||||
|     d_epsilon_n_A = 0.0;       //!< Eccentricity of d_n_A satellite at instant t_lambda_n_A [dimensionless] |  | ||||||
|     d_omega_n_A = 0.0;         //!< Argument of preigree of d_n_A satellite at instant t_lambdan_A [semi-circles] |  | ||||||
|     d_M_n_A = 0.0;             //!< Type of satellite n_A [dimensionless] |  | ||||||
|     d_B1 = 0.0;                //!< Coefficient  to  determine DeltaUT1 [s] |  | ||||||
|     d_B2 = 0.0;                //!< Coefficient  to  determine DeltaUT1 [s/msd] |  | ||||||
|     d_KP = 0.0;                //!< Notification on forthcoming leap second correction of UTC [dimensionless] |  | ||||||
|     d_tau_n_A = 0.0;           //!< Coarse value of d_n_A satellite time correction to GLONASS time at instant  t_lambdan_A[s] |  | ||||||
|     d_C_n_A = 0.0;             //!< Generalized “unhealthy flag” of n_A satellite at instant of almanac upload [dimensionless] |  | ||||||
|  |  | ||||||
|     std::map<int,std::string> satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus |     //!< UTC and System Clocks Flags | ||||||
|  |     flag_utc_model_valid;      //!< If set, it indicates that the UTC model parameters are filled | ||||||
|  |     flag_utc_model_str_5;      //!< Clock info send in string 5 of navigation data | ||||||
|  |     flag_utc_model_str_15;     //!< Clock info send in string 15 of frame 5 of navigation data | ||||||
|  |     flag_TOW_5; | ||||||
|  |     flag_TOW_6; | ||||||
|  |     flag_TOW_set;              //!< it is true when page 5 or page 6 arrives | ||||||
|  |  | ||||||
|  |     //broadcast orbit 1 | ||||||
|     /*! \brief If true, enhanced level of integrity assurance. |     //TODO Need to send the information regarding the frame number | ||||||
|      * |     double d_TOW;           //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s] | ||||||
|      *  If false, indicates that the conveying signal is provided with the legacy level of integrity assurance. |     double d_TOW_F1;        //!< Time of GPS Week from HOW word of Subframe 1 [s] | ||||||
|      *  That is, the probability that the instantaneous URE of the conveying signal exceeds 4.42 times the upper bound |     double d_TOW_F2;        //!< Time of GPS Week from HOW word of Subframe 2 [s] | ||||||
|      *  value of the current broadcast URA index, for more than 5.2 seconds, without an accompanying alert, is less |     double d_TOW_F3;        //!< Time of GPS Week from HOW word of Subframe 3 [s] | ||||||
|      *  than 1E-5 per hour. If true, indicates that the conveying signal is provided with an enhanced level of |     double d_TOW_F4;        //!< Time of GPS Week from HOW word of Subframe 4 [s] | ||||||
|      *  integrity assurance. That is, the probability that the instantaneous URE of the conveying signal exceeds 5.73 |     double d_TOW_F5;        //!< Time of GPS Week from HOW word of Subframe 5 [s] | ||||||
|      *  times the upper bound value of the current broadcast URA index, for more than 5.2 seconds, without an |  | ||||||
|      *  accompanying alert, is less than 1E-8 per hour. |  | ||||||
|      */ |  | ||||||
|     b_integrity_status_flag = false; |  | ||||||
|     b_alert_flag = false;      //!< If true, indicates  that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk. |  | ||||||
|     b_antispoofing_flag = false;  //!<  If true, the AntiSpoofing mode is ON in that SV |  | ||||||
|  |  | ||||||
|     // Clock terms |     // Clock terms | ||||||
|     d_satClkCorr = 0.0;     // Satellite clock error |     d_satClkCorr = 0.0; | ||||||
|     d_dtr = 0.0;            // Relativistic clock correction term |     d_dtr = 0.0; | ||||||
|     d_satClkDrift = 0.0;    // Satellite clock drift |     d_satClkDrift = 0.0; | ||||||
|  |  | ||||||
|     // satellite identification info |  | ||||||
|     int i_channel_ID = 0; |  | ||||||
|     int i_satellite_freq_channel = 0; //!< SV PRN NUMBER |  | ||||||
|  |  | ||||||
|     // time synchro |     std::map<int,std::string> satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus | ||||||
|     d_subframe_timestamp_ms = 0; //[ms] |  | ||||||
|  |  | ||||||
|     // UTC parameters |  | ||||||
|     bool flag_utc_model_valid = false; //!< If set, it indicates that the UTC model parameters are filled |  | ||||||
|  |  | ||||||
|     // satellite positions |  | ||||||
|     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_Z = 0.0;        //!< Earth-fixed coordinate z of the satellite in PZ-90.02 coordinate system [km] |  | ||||||
|     // Satellite velocity |  | ||||||
|     d_satvel_X = 0.0;        //!< Earth-fixed velocity coordinate x of the satellite in PZ-90.02 coordinate system [km/s] |  | ||||||
|     d_satvel_Y = 0.0;        //!< Earth-fixed velocity coordinate y of the satellite in PZ-90.02 coordinate system [km/s] |  | ||||||
|     d_satvel_Z = 0.0;        //!< Earth-fixed velocity coordinate z of the satellite in PZ-90.02 coordinate system [km/s] |  | ||||||
|     // Satellite acceleration |  | ||||||
|     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_Z = 0.0;        //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2] |  | ||||||
|  |  | ||||||
|     auto gnss_sat = Gnss_Satellite(); |     auto gnss_sat = Gnss_Satellite(); | ||||||
|     std::string _system ("GLONASS"); |     std::string _system ("GLONASS"); | ||||||
| @@ -145,79 +102,97 @@ Glonass_Gnav_Navigation_Message::Glonass_Gnav_Navigation_Message() | |||||||
|     reset(); |     reset(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| bool Glonass_Gnav_Navigation_Message::_CRC_test(std::bitset<GLONASS_GNAV_STRING_BITS> data_bits, std::bitset<GLONASS_GNAV_STRING_BITS> hamming_code_bits ) | bool Glonass_Gnav_Navigation_Message::_CRC_test(std::bitset<GLONASS_GNAV_STRING_BITS> data_bits, std::bitset<GLONASS_GNAV_STRING_BITS> hamming_code_bits ) | ||||||
| { | { | ||||||
|     int sum; |     int sum_bits; | ||||||
|  |     int sum_hamming; | ||||||
|  |  | ||||||
|     //!< Compute C1 term |     //!< Compute C1 term | ||||||
|     sum = 0; |     sum_bits = 0; | ||||||
|     for(int i = 0; i < GLONASS_GNAV_CRC_I_INDEX.size; i++) |     for(int i = 0; i < GLONASS_GNAV_CRC_I_INDEX.size; i++) | ||||||
|         { |         { | ||||||
|             sum += data_bits[GLONASS_GNAV_CRC_I_INDEX[i]] |             sum_bits += data_bits[GLONASS_GNAV_CRC_I_INDEX[i]]; | ||||||
|         } |         } | ||||||
|     C1 = hamming_code_bits[0]^fmod(sum,2); |     C1 = hamming_code_bits[0]^fmod(sum_bits,2); | ||||||
|  |  | ||||||
|     //!< Compute C2 term |     //!< Compute C2 term | ||||||
|     sum = 0; |     sum_bits = 0; | ||||||
|     for(int j = 0; j < GLONASS_GNAV_CRC_J_INDEX.size; j++) |     for(int j = 0; j < GLONASS_GNAV_CRC_J_INDEX.size; j++) | ||||||
|         { |         { | ||||||
|             sum += data_bits[GLONASS_GNAV_CRC_J_INDEX[j]] |             sum_bits += data_bits[GLONASS_GNAV_CRC_J_INDEX[j]]; | ||||||
|         } |         } | ||||||
|     C2 = hamming_code_bits[1]^fmod(sum,2); |     C2 = hamming_code_bits[1]^fmod(sum_bits,2); | ||||||
|  |  | ||||||
|     //!< Compute C3 term |     //!< Compute C3 term | ||||||
|     sum = 0; |     sum_bits = 0; | ||||||
|     for(int k = 0; k < GLONASS_GNAV_CRC_K_INDEX.size; k++) |     for(int k = 0; k < GLONASS_GNAV_CRC_K_INDEX.size; k++) | ||||||
|         { |         { | ||||||
|             sum += data_bits[GLONASS_GNAV_CRC_K_INDEX[k]] |             sum_bits += data_bits[GLONASS_GNAV_CRC_K_INDEX[k]]; | ||||||
|         } |         } | ||||||
|     C3 = hamming_code_bits[2]^fmod(sum,2); |     C3 = hamming_code_bits[2]^fmod(sum_bits,2); | ||||||
|  |  | ||||||
|     //!< Compute C4 term |     //!< Compute C4 term | ||||||
|     sum = 0; |     sum_bits = 0; | ||||||
|     for(int l = 0; l < GLONASS_GNAV_CRC_L_INDEX.size; l++) |     for(int l = 0; l < GLONASS_GNAV_CRC_L_INDEX.size; l++) | ||||||
|         { |         { | ||||||
|             sum += data_bits[GLONASS_GNAV_CRC_L_INDEX[l]] |             sum_bits += data_bits[GLONASS_GNAV_CRC_L_INDEX[l]]; | ||||||
|         } |         } | ||||||
|     C4 = hamming_code_bits[3]^fmod(sum,2); |     C4 = hamming_code_bits[3]^fmod(sum_bits,2); | ||||||
|  |  | ||||||
|     //!< Compute C5 term |     //!< Compute C5 term | ||||||
|     sum = 0; |     sum_bits = 0; | ||||||
|     for(int m = 0; m < GLONASS_GNAV_CRC_M_INDEX.size; m++) |     for(int m = 0; m < GLONASS_GNAV_CRC_M_INDEX.size; m++) | ||||||
|         { |         { | ||||||
|             sum += data_bits[GLONASS_GNAV_CRC_M_INDEX[m]] |             sum_bits += data_bits[GLONASS_GNAV_CRC_M_INDEX[m]]; | ||||||
|         } |         } | ||||||
|     C5 = hamming_code_bits[4]^fmod(sum,2); |     C5 = hamming_code_bits[4]^fmod(sum_bits,2); | ||||||
|  |  | ||||||
|     //!< Compute C6 term |     //!< Compute C6 term | ||||||
|     sum = 0; |     sum_bits = 0; | ||||||
|     for(int n = 0; n < GLONASS_GNAV_CRC_N_INDEX.size; n++) |     for(int n = 0; n < GLONASS_GNAV_CRC_N_INDEX.size; n++) | ||||||
|         { |         { | ||||||
|             sum += data_bits[GLONASS_GNAV_CRC_N_INDEX[n]] |             sum_bits += data_bits[GLONASS_GNAV_CRC_N_INDEX[n]]; | ||||||
|         } |         } | ||||||
|     C6 = hamming_code_bits[5]^fmod(sum,2); |     C6 = hamming_code_bits[5]^fmod(sum_bits,2); | ||||||
|  |  | ||||||
|     //!< Compute C7 term |     //!< Compute C7 term | ||||||
|     sum = 0; |     sum_bits = 0; | ||||||
|     for(int p = 0; p < GLONASS_GNAV_CRC_P_INDEX.size; p++) |     for(int p = 0; p < GLONASS_GNAV_CRC_P_INDEX.size; p++) | ||||||
|         { |         { | ||||||
|             sum += data_bits[GLONASS_GNAV_CRC_P_INDEX[p]] |             sum_bits += data_bits[GLONASS_GNAV_CRC_P_INDEX[p]]; | ||||||
|         } |         } | ||||||
|     C7 = hamming_code_bits[6]^fmod(sum,2); |     C7 = hamming_code_bits[6]^fmod(sum_bits,2); | ||||||
|  |  | ||||||
|     //!< Compute C8 term |     //!< Compute C_Sigma term | ||||||
|     sum = 0; |     sum_bits = 0; | ||||||
|  |     sum_hamming = 0; | ||||||
|     for(int q = 0; q < GLONASS_GNAV_CRC_Q_INDEX.size; q++) |     for(int q = 0; q < GLONASS_GNAV_CRC_Q_INDEX.size; q++) | ||||||
|         { |         { | ||||||
|             sum += data_bits[GLONASS_GNAV_CRC_Q_INDEX[q]] |             sum_bits += data_bits[GLONASS_GNAV_CRC_Q_INDEX[q]]; | ||||||
|         } |         } | ||||||
|     C8 = hamming_code_bits[7]^fmod(sum,2); |     for(int q = 0; q < 8; q++) | ||||||
|  |         { | ||||||
|  |             sum_hamming += hamming_code_bits[q]; | ||||||
|  |         } | ||||||
|  |     C_Sigma = fmod(sum_bits, 2)^fmod(sum_bits,2); | ||||||
|  |  | ||||||
|     if isempty(find(C,1)) || (length(find(C(1,1:7))) == 1 && C(1,8) == 1) |  | ||||||
|          status = 1; |     //!< Verification of the data | ||||||
|      else |     // All of the checksums are equal to zero | ||||||
|          status = 0; |     if((C1 & C2 & C3 & C4 & C5 & C6 & C7 & C_Sigma) == 0 ) | ||||||
|      end |         { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |     // only one of the checksums (C1,...,C7) is equal to zero but C_Sigma = 1 | ||||||
|  |     else if(C_Sigma == 1 && C1+C2+C3+C4+C5+C6+C7 == 6) | ||||||
|  |         { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -315,6 +290,7 @@ signed long int Glonass_Gnav_Navigation_Message::read_navigation_signed(std::bit | |||||||
|     return value; |     return value; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| unsigned int Glonass_Gnav_Navigation_Message::get_frame_number(unsigned int satellite_slot_number) | unsigned int Glonass_Gnav_Navigation_Message::get_frame_number(unsigned int satellite_slot_number) | ||||||
| { | { | ||||||
|     unsigned int frame_ID = 0; |     unsigned int frame_ID = 0; | ||||||
| @@ -346,6 +322,7 @@ unsigned int Glonass_Gnav_Navigation_Message::get_frame_number(unsigned int sate | |||||||
|         } |         } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| int Glonass_Gnav_Navigation_Message::string_decoder(char * frame_string) | int Glonass_Gnav_Navigation_Message::string_decoder(char * frame_string) | ||||||
| { | { | ||||||
|     int string_ID = 0; |     int string_ID = 0; | ||||||
| @@ -591,8 +568,6 @@ int Glonass_Gnav_Navigation_Message::string_decoder(char * frame_string) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| double Glonass_Gnav_Navigation_Message::utc_time(const double glonass_time_corrected) const | double Glonass_Gnav_Navigation_Message::utc_time(const double glonass_time_corrected) const | ||||||
| { | { | ||||||
|     double t_utc; |     double t_utc; | ||||||
| @@ -602,71 +577,25 @@ double Glonass_Gnav_Navigation_Message::utc_time(const double glonass_time_corre | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Glonass_Gnav_Ephemeris Glonass_Gnav_Navigation_Message::get_ephemeris() | Glonass_Gnav_Ephemeris Glonass_Gnav_Navigation_Message::get_ephemeris() | ||||||
| { | { | ||||||
|     Glonass_Gnav_Ephemeris ephemeris; |     return gnav_ephemeris; | ||||||
|  |  | ||||||
|     ephemeris.i_satellite_freq_channel = i_satellite_freq_channel; |  | ||||||
|     ephemeris.d_m = d_m; |  | ||||||
|     ephemeris.d_t_k = d_t_k; |  | ||||||
|     ephemeris.d_t_b = d_t_b; |  | ||||||
|     ephemeris.d_M = d_M; |  | ||||||
|     ephemeris.d_gamma_n = d_gamma_n; |  | ||||||
|     ephemeris.d_tau_n = d_tau_n; |  | ||||||
|     // satellite positions |  | ||||||
|     ephemeris.d_satpos_X = d_satpos_X; |  | ||||||
|     ephemeris.d_satpos_Y = d_satpos_Y; |  | ||||||
|     ephemeris.d_satpos_Z = d_satpos_Z; |  | ||||||
|     // Satellite velocity |  | ||||||
|     ephemeris.d_satvel_X = d_satvel_X; |  | ||||||
|     ephemeris.d_satvel_Y = d_satvel_Y; |  | ||||||
|     ephemeris.d_satvel_Z = d_satvel_Z; |  | ||||||
|     // Satellite acceleration |  | ||||||
|     ephemeris.d_satacc_X = d_satacc_X; |  | ||||||
|     ephemeris.d_satacc_Y = d_satacc_Y; |  | ||||||
|     ephemeris.d_satacc_Z = d_satacc_Z; |  | ||||||
|     ephemeris.d_B_n = d_B_n; |  | ||||||
|     ephemeris.d_P = d_P; |  | ||||||
|     ephemeris.d_N_T = d_N_T; |  | ||||||
|     ephemeris.d_F_T = d_F_T; |  | ||||||
|     ephemeris.d_n = d_n; |  | ||||||
|     ephemeris.d_Delta_tau_n = d_Delta_tau_n; |  | ||||||
|     ephemeris.d_E_n = d_E_n; |  | ||||||
|     ephemeris.d_P_1 = d_P_1; |  | ||||||
|     ephemeris.d_P_2 = d_P_2; |  | ||||||
|     ephemeris.d_P_3 = d_P_3; |  | ||||||
|     ephemeris.d_P_4 = d_P_4; |  | ||||||
|     ephemeris.d_l_n = d_l_n; |  | ||||||
|  |  | ||||||
|     // clock terms derived from ephemeris data |  | ||||||
|     ephemeris.d_satClkDrift = d_satClkDrift; |  | ||||||
|     ephemeris.d_dtr = d_dtr; |  | ||||||
|  |  | ||||||
|     return ephemeris; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| Glonass_Gnav_Utc_Model Glonass_Gnav_Navigation_Message::get_utc_model() | Glonass_Gnav_Utc_Model Glonass_Gnav_Navigation_Message::get_utc_model() | ||||||
| { | { | ||||||
|     Gps_Utc_Model utc_model; |     return gnav_utc_model; | ||||||
|     utc_model.valid = flag_utc_model_valid; |  | ||||||
|     // UTC parameters |  | ||||||
|     utc_model.d_A1 = d_A1; |  | ||||||
|     utc_model.d_A0 = d_A0; |  | ||||||
|     utc_model.d_t_OT = d_t_OT; |  | ||||||
|     utc_model.i_WN_T = i_WN_T; |  | ||||||
|     utc_model.d_DeltaT_LS = d_DeltaT_LS; |  | ||||||
|     utc_model.i_WN_LSF = i_WN_LSF; |  | ||||||
|     utc_model.i_DN = i_DN; |  | ||||||
|     utc_model.d_DeltaT_LSF = d_DeltaT_LSF; |  | ||||||
|     // warning: We clear flag_utc_model_valid in order to not re-send the same information to the ionospheric parameters queue |  | ||||||
|     flag_utc_model_valid = false; |  | ||||||
|     return utc_model; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| bool Glonass_Gnav_Navigation_Message::satellite_validation() | Glonass_Gnav_Almanac get_almanac() | ||||||
|  | { | ||||||
|  |     return gnav_almanac; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool Glonass_Gnav_Navigation_Message::have_new_ephemeris() //Check if we have a new ephemeris stored in the galileo navigation class | ||||||
| { | { | ||||||
|     bool flag_data_valid = false; |     bool flag_data_valid = false; | ||||||
|     b_valid_ephemeris_set_flag = false; |     b_valid_ephemeris_set_flag = false; | ||||||
| @@ -674,7 +603,7 @@ bool Glonass_Gnav_Navigation_Message::satellite_validation() | |||||||
|     // First Step: |     // First Step: | ||||||
|     // check Issue Of Ephemeris Data (IODE IODC..) to find a possible interrupted reception |     // check Issue Of Ephemeris Data (IODE IODC..) to find a possible interrupted reception | ||||||
|     // and check if the data have been filled (!=0) |     // and check if the data have been filled (!=0) | ||||||
|     if (d_TOW_SF1 != 0 and d_TOW_SF2 != 0 and d_TOW_SF3 != 0) |     if (d_TOW_F1 != 0 and d_TOW_F2 != 0 and d_TOW_F3 != 0) | ||||||
|         { |         { | ||||||
|             if (d_IODE_SF2 == d_IODE_SF3 and d_IODC == d_IODE_SF2 and d_IODC!= -1) |             if (d_IODE_SF2 == d_IODE_SF3 and d_IODC == d_IODE_SF2 and d_IODC!= -1) | ||||||
|                 { |                 { | ||||||
| @@ -682,5 +611,67 @@ bool Glonass_Gnav_Navigation_Message::satellite_validation() | |||||||
|                     b_valid_ephemeris_set_flag = true; |                     b_valid_ephemeris_set_flag = true; | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
|     return flag_data_valid; |  | ||||||
|  |  | ||||||
|  |     if ((flag_ephemeris_str_1 == true) and (flag_ephemeris_str_2 == true) and (flag_ephemeris_str_3 == true) and (flag_ephemeris_str_4 == true) and (flag_iono_and_GST == true)) | ||||||
|  |         { | ||||||
|  |             //if all ephemeris pages have the same IOD, then they belong to the same block | ||||||
|  |             if ((gnav_ephemeris.d_t_b== IOD_nav_2) and (IOD_nav_3 == IOD_nav_4) and (IOD_nav_1 == IOD_nav_3)) | ||||||
|  |                 { | ||||||
|  |                     std::cout << "Ephemeris (1, 2, 3, 4) have been received and belong to the same batch" << std::endl; | ||||||
|  |                     flag_ephemeris_1 = false;// clear the flag | ||||||
|  |                     flag_ephemeris_2 = false;// clear the flag | ||||||
|  |                     flag_ephemeris_3 = false;// clear the flag | ||||||
|  |                     flag_ephemeris_4 = false;// clear the flag | ||||||
|  |                     flag_all_ephemeris = true; | ||||||
|  |                     IOD_ephemeris = IOD_nav_1; | ||||||
|  |                     std::cout << "Batch number: "<< IOD_ephemeris << std::endl; | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  |             else | ||||||
|  |                 { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool Glonass_Gnav_Navigation_Message::have_new_utc_model() // Check if we have a new utc data set stored in the galileo navigation class | ||||||
|  | { | ||||||
|  |     if (flag_utc_model == true) | ||||||
|  |         { | ||||||
|  |             flag_utc_model = false; // clear the flag | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool Glonass_Gnav_Navigation_Message::have_new_almanac() //Check if we have a new almanac data set stored in the galileo navigation class | ||||||
|  | { | ||||||
|  |     if ((flag_almanac_str_6 == true) and (flag_almanac_str_7 == true) and | ||||||
|  |         (flag_almanac_str_8 == true) and (flag_almanac_str_9 == true) and | ||||||
|  |         (flag_almanac_str_10 == true) and (flag_almanac_str_11 == true) and | ||||||
|  |         (flag_almanac_str_12 == true) and (flag_almanac_str_13 == true) and | ||||||
|  |         (flag_almanac_str_14 == true) and (flag_almanac_str_15 == true)) | ||||||
|  |         { | ||||||
|  |             //All almanac have been received | ||||||
|  |             flag_almanac_str_6 = false; | ||||||
|  |             flag_almanac_str_7 = false; | ||||||
|  |             flag_almanac_str_8 = false; | ||||||
|  |             flag_almanac_str_9 = false; | ||||||
|  |             flag_almanac_str_10 = false; | ||||||
|  |             flag_almanac_str_11 = false; | ||||||
|  |             flag_almanac_str_12 = false; | ||||||
|  |             flag_almanac_str_13 = false; | ||||||
|  |             flag_almanac_str_14 = false; | ||||||
|  |             flag_almanac_str_15 = false; | ||||||
|  |             flag_all_almanac = true; | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |     else | ||||||
|  |         return false; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -64,78 +64,61 @@ private: | |||||||
|     unsigned int get_frame_number(unsigned int satellite_slot_number); |     unsigned int get_frame_number(unsigned int satellite_slot_number); | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     bool b_valid_ephemeris_set_flag; // flag indicating that this ephemeris set have passed the validation check |  | ||||||
|     int Page_type_time_stamp; |  | ||||||
|     int flag_even_word; |  | ||||||
|     std::string page_Even; |  | ||||||
|     bool flag_CRC_test; |     bool flag_CRC_test; | ||||||
|  |     unsigned int u_frame_number; | ||||||
|  |  | ||||||
|     Glonass_Gnav_Ephemeris gnav_ephemeris;      //!< Ephemeris information decoded |     Glonass_Gnav_Ephemeris gnav_ephemeris;      //!< Ephemeris information decoded | ||||||
|     Glonass_Gnav_Iono gnav_iono;                //!< Iono corrections information |     //Glonass_Gnav_Iono gnav_iono;                //!< Iono corrections information | ||||||
|     Glonass_Gnav_Utc_Model gnav_utc_model;      //!< UTC model information |     Glonass_Gnav_Utc_Model gnav_utc_model;      //!< UTC model information | ||||||
|     Glonass_Gnav_Almanac gnav_almanac[24];      //!< Almanac information for all 24 satellites |     Glonass_Gnav_Almanac gnav_almanac[24];      //!< Almanac information for all 24 satellites | ||||||
|  |  | ||||||
|  |     //!< Satellite Identification | ||||||
|  |     int i_channel_ID;               //!< Channel ID assigned by the receiver | ||||||
|  |     int i_satellite_freq_channel;   //!< SV Frequency Slot Number | ||||||
|  |     int i_satellite_slot_number;    //!< SV Orbit Slot Number | ||||||
|  |  | ||||||
|     //!< Ephmeris Flags |     //!< Ephmeris Flags | ||||||
|     bool flag_all_ephemeris;  //!< Flag indicating that all strings containing ephemeris have been received |     bool flag_all_ephemeris;  //!< Flag indicating that all strings containing ephemeris have been received | ||||||
|     bool flag_ephemeris_str_1;    //!< Flag indicating that ephemeris 1/4 (word 1) have been received |     bool flag_ephemeris_str_1;    //!< Flag indicating that ephemeris 1/4 (string 1) have been received | ||||||
|     bool flag_ephemeris_str_2;    //!< Flag indicating that ephemeris 2/4 (word 2) have been received |     bool flag_ephemeris_str_2;    //!< Flag indicating that ephemeris 2/4 (string 2) have been received | ||||||
|     bool flag_ephemeris_str_3;    //!< Flag indicating that ephemeris 3/4 (word 3) have been received |     bool flag_ephemeris_str_3;    //!< Flag indicating that ephemeris 3/4 (string 3) have been received | ||||||
|     bool flag_ephemeris_str_4;    //!< Flag indicating that ephemeris 4/4 (word 4) have been received |     bool flag_ephemeris_str_4;    //!< Flag indicating that ephemeris 4/4 (string 4) have been received | ||||||
|  |  | ||||||
|     bool flag_iono_and_GST;   //!< Flag indicating that ionospheric and GST parameters (word 5) have been received |     //!< Almanac Flags | ||||||
|  |     bool flag_all_almanac;        //!< Flag indicating that all almanac have been received | ||||||
|  |     bool flag_almanac_str_6;      //!< Flag indicating that almanac of string 6 have been received | ||||||
|  |     bool flag_almanac_str_7;      //!< Flag indicating that almanac of string 7 have been received | ||||||
|  |     bool flag_almanac_str_8;      //!< Flag indicating that almanac of string 8 have been received | ||||||
|  |     bool flag_almanac_str_9;      //!< Flag indicating that almanac of string 9 have been received | ||||||
|  |     bool flag_almanac_str_10;     //!< Flag indicating that almanac of string 10 have been received | ||||||
|  |     bool flag_almanac_str_11;     //!< Flag indicating that almanac of string 11 have been received | ||||||
|  |     bool flag_almanac_str_12;     //!< Flag indicating that almanac of string 12 have been received | ||||||
|  |     bool flag_almanac_str_13;     //!< Flag indicating that almanac of string 13 have been received | ||||||
|  |     bool flag_almanac_str_14;     //!< Flag indicating that almanac of string 14 have been received | ||||||
|  |     bool flag_almanac_str_15;     //!< Flag indicating that almanac of string 15 have been received | ||||||
|  |  | ||||||
|  |     //!< UTC and System Clocks Flags | ||||||
|  |     bool flag_utc_model_valid;      //!< If set, it indicates that the UTC model parameters are filled | ||||||
|  |     bool flag_utc_model_str_5;      //!< Clock info send in string 5 of navigation data | ||||||
|  |     bool flag_utc_model_str_15;     //!< Clock info send in string 15 of frame 5 of navigation data | ||||||
|     bool flag_TOW_5; |     bool flag_TOW_5; | ||||||
|     bool flag_TOW_6; |     bool flag_TOW_6; | ||||||
|     bool flag_TOW_set;        //!< it is true when page 5 or page 6 arrives |     bool flag_TOW_set;              //!< it is true when page 5 or page 6 arrives | ||||||
|     bool flag_utc_model;      //!< Flag indicating that utc model parameters (word 6) have been received |  | ||||||
|  |  | ||||||
|     bool flag_all_almanac;        //!< Flag indicating that all almanac have been received |  | ||||||
|     bool flag_almanac_str_6;      //!< Flag indicating that almanac 1/4 (word 7) have been received |  | ||||||
|     bool flag_almanac_str_7;      //!< Flag indicating that almanac 2/4 (word 8) have been received |  | ||||||
|     bool flag_almanac_str_8;      //!< Flag indicating that almanac 3/4 (word 9) have been received |  | ||||||
|     bool flag_almanac_str_9;      //!< Flag indicating that almanac 4/4 (word 10) have been received |  | ||||||
|     bool flag_almanac_str_10;     //!< Flag indicating that almanac 4/4 (word 10) have been received |  | ||||||
|     bool flag_almanac_str_11;     //!< Flag indicating that almanac 4/4 (word 10) have been received |  | ||||||
|     bool flag_almanac_str_12;     //!< Flag indicating that almanac 4/4 (word 10) have been received |  | ||||||
|     bool flag_almanac_str_13;     //!< Flag indicating that almanac 4/4 (word 10) have been received |  | ||||||
|     bool flag_almanac_str_14;     //!< Flag indicating that almanac 4/4 (word 10) have been received |  | ||||||
|     bool flag_almanac_str_15;     //!< Flag indicating that almanac 4/4 (word 10) have been received |  | ||||||
|  |  | ||||||
|     //broadcast orbit 1 |     //broadcast orbit 1 | ||||||
|     //TODO Need to send the information regarding the frame number |     //TODO Need to send the information regarding the frame number | ||||||
|     double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s] |     double d_TOW;           //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s] | ||||||
|     double d_TOW_F1;            //!< Time of GPS Week from HOW word of Subframe 1 [s] |     double d_TOW_F1;        //!< Time of GPS Week from HOW word of Subframe 1 [s] | ||||||
|     double d_TOW_F2;            //!< Time of GPS Week from HOW word of Subframe 2 [s] |     double d_TOW_F2;        //!< Time of GPS Week from HOW word of Subframe 2 [s] | ||||||
|     double d_TOW_F3;            //!< Time of GPS Week from HOW word of Subframe 3 [s] |     double d_TOW_F3;        //!< Time of GPS Week from HOW word of Subframe 3 [s] | ||||||
|     double d_TOW_F4;            //!< Time of GPS Week from HOW word of Subframe 4 [s] |     double d_TOW_F4;        //!< Time of GPS Week from HOW word of Subframe 4 [s] | ||||||
|     double d_TOW_F5;            //!< Time of GPS Week from HOW word of Subframe 5 [s] |     double d_TOW_F5;        //!< Time of GPS Week from HOW word of Subframe 5 [s] | ||||||
|  |  | ||||||
|     // Clock terms |     // Clock terms | ||||||
|     double d_satClkCorr;     // Satellite clock error |     double d_satClkCorr;     // Satellite clock error | ||||||
|     double d_dtr;            // Relativistic clock correction term |     double d_dtr;            // Relativistic clock correction term | ||||||
|     double d_satClkDrift;    // Satellite clock drift |     double d_satClkDrift;    // Satellite clock drift | ||||||
|  |  | ||||||
|     // satellite identification info |  | ||||||
|     int i_channel_ID; |  | ||||||
|     unsigned int i_satellite_PRN;   //!< SV PRN Number |  | ||||||
|     int i_satellite_freq_channel;   //!< SV Frequency Slot Number |  | ||||||
|     int i_satellite_slot_number;    //!< SV Orbit Slot Number |  | ||||||
|  |  | ||||||
|     // UTC parameters |  | ||||||
|     bool flag_utc_model_valid; //!< If set, it indicates that the UTC model parameters are filled |  | ||||||
|  |  | ||||||
|     // satellite positions |  | ||||||
|     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_Z;        //!< Earth-fixed coordinate z of the satellite in PZ-90.02 coordinate system [km] |  | ||||||
|     // Satellite velocity |  | ||||||
|     double d_satvel_X;        //!< Earth-fixed velocity coordinate x of the satellite in PZ-90.02 coordinate system [km/s] |  | ||||||
|     double d_satvel_Y;        //!< Earth-fixed velocity coordinate y of the satellite in PZ-90.02 coordinate system [km/s] |  | ||||||
|     double d_satvel_Z;        //!< Earth-fixed velocity coordinate z of the satellite in PZ-90.02 coordinate system [km/s] |  | ||||||
|     // Satellite acceleration |  | ||||||
|     double d_satacc_X;        //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2] |  | ||||||
|     double d_satacc_Y;        //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2] |  | ||||||
|     double d_satacc_Z;        //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2] |  | ||||||
|  |  | ||||||
|     /*! |     /*! | ||||||
|      * \brief Reset GLONASS GNAV Navigation Information |      * \brief Reset GLONASS GNAV Navigation Information | ||||||
|      */ |      */ | ||||||
| @@ -182,12 +165,10 @@ public: | |||||||
|      */ |      */ | ||||||
|     bool have_new_almanac(); |     bool have_new_almanac(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     /*! |     /*! | ||||||
|      * \brief Decodes the GLONASS GNAV frame |      * \brief Decodes the GLONASS GNAV string | ||||||
|      */ |      */ | ||||||
|     int string_decoder(char *string, int frame_ID); |     int string_decoder(char *string); | ||||||
|  |  | ||||||
|     /*! |     /*! | ||||||
|      * \brief Computes the Coordinated Universal Time (UTC) and returns it in [s] |      * \brief Computes the Coordinated Universal Time (UTC) and returns it in [s] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user