diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc index d946fe064..7b4f9cfb8 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.cc @@ -1,6 +1,6 @@ /*! * \file beidou_b3i_telemetry_decoder.cc - * \brief Implementation of an adapter of a Beidou B1I NAV data decoder block + * \brief Implementation of an adapter of a Beidou B3I NAV data decoder block * to a TelemetryDecoderInterface * \author Damian Miralles, 2019. dmiralles2009@gmail.com * @@ -29,78 +29,56 @@ * ------------------------------------------------------------------------- */ - #include "beidou_b3i_telemetry_decoder.h" #include "configuration_interface.h" -#include #include - -BeidouB3iTelemetryDecoder::BeidouB3iTelemetryDecoder(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_ = beidou_b3i_make_telemetry_decoder_gs(satellite_, dump_); - DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; - channel_ = 0; - if (in_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one input stream"; - } - if (out_streams_ > 1) - { - LOG(ERROR) << "This implementation only supports one output stream"; - } +BeidouB3iTelemetryDecoder::BeidouB3iTelemetryDecoder( + 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_ = beidou_b3i_make_telemetry_decoder_gs(satellite_, dump_); + DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; + channel_ = 0; + if (in_streams_ > 1) { + LOG(ERROR) << "This implementation only supports one input stream"; + } + if (out_streams_ > 1) { + LOG(ERROR) << "This implementation only supports one output stream"; + } } +BeidouB3iTelemetryDecoder::~BeidouB3iTelemetryDecoder() = default; -BeidouB3iTelemetryDecoder::~BeidouB3iTelemetryDecoder() -{ +void BeidouB3iTelemetryDecoder::set_satellite(const 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 BeidouB3iTelemetryDecoder::set_satellite(const 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 BeidouB3iTelemetryDecoder::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 BeidouB3iTelemetryDecoder::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 BeidouB3iTelemetryDecoder::disconnect(gr::top_block_sptr top_block) { + if (top_block) { /* top_block is not null */ + }; + // Nothing to disconnect } - -void BeidouB3iTelemetryDecoder::disconnect(gr::top_block_sptr top_block) -{ - if (top_block) - { /* top_block is not null */ - }; - // Nothing to disconnect +gr::basic_block_sptr BeidouB3iTelemetryDecoder::get_left_block() { + return telemetry_decoder_; } - -gr::basic_block_sptr BeidouB3iTelemetryDecoder::get_left_block() -{ - return telemetry_decoder_; -} - - -gr::basic_block_sptr BeidouB3iTelemetryDecoder::get_right_block() -{ - return telemetry_decoder_; +gr::basic_block_sptr BeidouB3iTelemetryDecoder::get_right_block() { + return telemetry_decoder_; } diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.h index b88631ce5..81f1e1ab3 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b3i_telemetry_decoder.h @@ -29,69 +29,58 @@ * ------------------------------------------------------------------------- */ - #ifndef GNSS_SDR_BEIDOU_B3I_TELEMETRY_DECODER_H_ #define GNSS_SDR_BEIDOU_B3I_TELEMETRY_DECODER_H_ #include "beidou_b3i_telemetry_decoder_gs.h" -#include "gnss_satellite.h" // for Gnss_Satellite +#include "gnss_satellite.h" // for Gnss_Satellite #include "telemetry_decoder_interface.h" -#include // for basic_block_sptr, top_block_sptr -#include // for size_t +#include // for size_t +#include // for basic_block_sptr, top_block_sptr #include class ConfigurationInterface; /*! * \brief This class implements a NAV data decoder for BEIDOU B1I */ -class BeidouB3iTelemetryDecoder : public TelemetryDecoderInterface -{ +class BeidouB3iTelemetryDecoder : public TelemetryDecoderInterface { public: - BeidouB3iTelemetryDecoder(ConfigurationInterface* configuration, - std::string role, - unsigned int in_streams, - unsigned int out_streams); + BeidouB3iTelemetryDecoder(ConfigurationInterface *configuration, + std::string role, unsigned int in_streams, + unsigned int out_streams); - virtual ~BeidouB3iTelemetryDecoder(); + virtual ~BeidouB3iTelemetryDecoder(); - inline std::string role() override - { - return role_; - } + inline std::string role() override { return role_; } - //! Returns "BEIDOU_B3I_Telemetry_Decoder" - inline std::string implementation() override - { - return "BEIDOU_B3I_Telemetry_Decoder"; - } + //! Returns "BEIDOU_B3I_Telemetry_Decoder" + inline std::string implementation() override { + return "BEIDOU_B3I_Telemetry_Decoder"; + } - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; + void connect(gr::top_block_sptr top_block) override; + void disconnect(gr::top_block_sptr top_block) override; + gr::basic_block_sptr get_left_block() override; + gr::basic_block_sptr get_right_block() override; - void set_satellite(const Gnss_Satellite& satellite) override; - inline void set_channel(int channel) override { telemetry_decoder_->set_channel(channel); } + void set_satellite(const Gnss_Satellite &satellite) override; + inline void set_channel(int channel) override { + telemetry_decoder_->set_channel(channel); + } - inline void reset() override - { - return; - } + inline void reset() override { return; } - inline size_t item_size() override - { - return 0; - } + inline size_t item_size() override { return 0; } private: - beidou_b3i_telemetry_decoder_gs_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_; + beidou_b3i_telemetry_decoder_gs_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 diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.cc index 671b8cde7..c54d355c9 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.cc @@ -28,7 +28,6 @@ * ------------------------------------------------------------------------- */ - #include "beidou_b3i_telemetry_decoder_gs.h" #include "Beidou_B3I.h" #include "Beidou_DNAV.h" @@ -37,557 +36,528 @@ #include "beidou_dnav_iono.h" #include "beidou_dnav_utc_model.h" #include "gnss_synchro.h" +#include // for abs +#include // for exception #include #include -#include // for make_any -#include // for mp +#include // for cout +#include // for shared_ptr, make_shared +#include // for make_any +#include // for mp #include -#include // for abs -#include // for exception -#include // for cout -#include // for shared_ptr, make_shared #define CRC_ERROR_LIMIT 8 - beidou_b3i_telemetry_decoder_gs_sptr -beidou_b3i_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump) -{ - return beidou_b3i_telemetry_decoder_gs_sptr(new beidou_b3i_telemetry_decoder_gs(satellite, dump)); +beidou_b3i_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, + bool dump) { + return beidou_b3i_telemetry_decoder_gs_sptr( + new beidou_b3i_telemetry_decoder_gs(satellite, dump)); } - beidou_b3i_telemetry_decoder_gs::beidou_b3i_telemetry_decoder_gs( - const Gnss_Satellite &satellite, - bool dump) : gr::block("beidou_b3i_telemetry_decoder_gs", - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), - gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) -{ - // 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 BeiDou B3I Telemetry Decoding for satellite "<< this->d_satellite; + const Gnss_Satellite &satellite, bool dump) + : gr::block("beidou_b3i_telemetry_decoder_gs", + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), + gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { + // 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 BeiDou B3I Telemetry Decoding for satellite " + << this->d_satellite; - d_samples_per_symbol = (BEIDOU_B3I_CODE_RATE_HZ / BEIDOU_B3I_CODE_LENGTH_CHIPS) / BEIDOU_D1NAV_SYMBOL_RATE_SPS; - d_symbols_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS; - d_samples_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS * d_samples_per_symbol; - d_secondary_code_symbols = static_cast(volk_gnsssdr_malloc(BEIDOU_B3I_SECONDARY_CODE_LENGTH * sizeof(int32_t), volk_gnsssdr_get_alignment())); - d_preamble_samples = static_cast(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); - d_preamble_period_samples = BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS*d_samples_per_symbol; + d_samples_per_symbol = + (BEIDOU_B3I_CODE_RATE_HZ / BEIDOU_B3I_CODE_LENGTH_CHIPS) / + BEIDOU_D1NAV_SYMBOL_RATE_SPS; + d_symbols_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS; + d_samples_per_preamble = + BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS * d_samples_per_symbol; + d_secondary_code_symbols = static_cast( + volk_gnsssdr_malloc(BEIDOU_B3I_SECONDARY_CODE_LENGTH * sizeof(int32_t), + volk_gnsssdr_get_alignment())); + d_preamble_samples = static_cast(volk_gnsssdr_malloc( + d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); + d_preamble_period_samples = + BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS * d_samples_per_symbol; - // Setting samples of secondary code - for (int32_t i = 0; i < BEIDOU_B3I_SECONDARY_CODE_LENGTH; i++) - { - if (BEIDOU_B3I_SECONDARY_CODE.at(i) == '1') - { - d_secondary_code_symbols[i] = 1; - } - else - { - d_secondary_code_symbols[i] = -1; - } - } + // Setting samples of secondary code + for (int32_t i = 0; i < BEIDOU_B3I_SECONDARY_CODE_LENGTH; i++) { + if (BEIDOU_B3I_SECONDARY_CODE.at(i) == '1') { + d_secondary_code_symbols[i] = 1; + } else { + d_secondary_code_symbols[i] = -1; + } + } - // Setting samples of preamble code - int32_t n = 0; - for (int32_t i = 0; i < d_symbols_per_preamble; i++) - { - int32_t m = 0; - if (BEIDOU_DNAV_PREAMBLE.at(i) == '1') - { - for (uint32_t j = 0; j < d_samples_per_symbol; j++) - { - d_preamble_samples[n] = d_secondary_code_symbols[m]; - n++; - m++; - m = m % BEIDOU_B3I_SECONDARY_CODE_LENGTH; - } - } - else - { - for (uint32_t j = 0; j < d_samples_per_symbol; j++) - { - d_preamble_samples[n] = -d_secondary_code_symbols[m]; - n++; - m++; - m = m % BEIDOU_B3I_SECONDARY_CODE_LENGTH; - } - } - } + // Setting samples of preamble code + int32_t n = 0; + for (int32_t i = 0; i < d_symbols_per_preamble; i++) { + int32_t m = 0; + if (BEIDOU_DNAV_PREAMBLE.at(i) == '1') { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) { + d_preamble_samples[n] = d_secondary_code_symbols[m]; + n++; + m++; + m = m % BEIDOU_B3I_SECONDARY_CODE_LENGTH; + } + } else { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) { + d_preamble_samples[n] = -d_secondary_code_symbols[m]; + n++; + m++; + m = m % BEIDOU_B3I_SECONDARY_CODE_LENGTH; + } + } + } - d_subframe_symbols = static_cast(volk_gnsssdr_malloc(BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS * sizeof(double), volk_gnsssdr_get_alignment())); - d_required_symbols = BEIDOU_DNAV_SUBFRAME_SYMBOLS*d_samples_per_symbol + d_samples_per_preamble; - d_symbol_history.set_capacity(d_required_symbols + 1); - - // Generic settings - d_sample_counter = 0; - d_stat = 0; - d_preamble_index = 0; - d_flag_frame_sync = false; - d_TOW_at_current_symbol_ms = 0; - Flag_valid_word = false; - d_CRC_error_counter = 0; - d_flag_preamble = false; - d_channel = 0; - flag_SOW_set = false; + d_subframe_symbols = static_cast( + volk_gnsssdr_malloc(BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS * sizeof(double), + volk_gnsssdr_get_alignment())); + d_required_symbols = BEIDOU_DNAV_SUBFRAME_SYMBOLS * d_samples_per_symbol + + d_samples_per_preamble; + d_symbol_history.set_capacity(d_required_symbols + 1); + // Generic settings + d_sample_counter = 0; + d_stat = 0; + d_preamble_index = 0; + d_flag_frame_sync = false; + d_TOW_at_current_symbol_ms = 0; + Flag_valid_word = false; + d_CRC_error_counter = 0; + d_flag_preamble = false; + d_channel = 0; + flag_SOW_set = false; } +beidou_b3i_telemetry_decoder_gs::~beidou_b3i_telemetry_decoder_gs() { + volk_gnsssdr_free(d_preamble_samples); + volk_gnsssdr_free(d_secondary_code_symbols); + volk_gnsssdr_free(d_subframe_symbols); -beidou_b3i_telemetry_decoder_gs::~beidou_b3i_telemetry_decoder_gs() -{ - volk_gnsssdr_free(d_preamble_samples); + if (d_dump_file.is_open() == true) { + try { + d_dump_file.close(); + } catch (const std::exception &ex) { + LOG(WARNING) << "Exception in destructor closing the dump file " + << ex.what(); + } + } +} + +void beidou_b3i_telemetry_decoder_gs::decode_bch15_11_01(const int32_t *bits, + int32_t *decbits) { + int32_t bit, err, reg[4] = {1, 1, 1, 1}; + int32_t errind[15] = {14, 13, 10, 12, 6, 9, 4, 11, 0, 5, 7, 8, 1, 3, 2}; + + for (uint32_t i = 0; i < 15; i++) { + decbits[i] = bits[i]; + } + + for (uint32_t i = 0; i < 15; i++) { + bit = reg[3]; + reg[3] = reg[2]; + reg[2] = reg[1]; + reg[1] = reg[0]; + reg[0] = bits[i] * bit; + reg[1] *= bit; + } + + err = errind[reg[0] + reg[1] * 2 + reg[2] * 4 + reg[3] * 8]; + + if (err > 0) { + decbits[err - 1] *= -1; + } +} + +void beidou_b3i_telemetry_decoder_gs::decode_word( + int32_t word_counter, const double *enc_word_symbols, + int32_t *dec_word_symbols) { + int32_t bitsbch[30], first_branch[15], second_branch[15]; + + if (word_counter == 1) { + for (uint32_t j = 0; j < 30; j++) { + dec_word_symbols[j] = + static_cast(enc_word_symbols[j] > 0) ? (1) : (-1); + } + } else { + for (uint32_t r = 0; r < 2; r++) { + for (uint32_t c = 0; c < 15; c++) { + bitsbch[r * 15 + c] = + static_cast(enc_word_symbols[c * 2 + r] > 0) ? (1) : (-1); + } + } + + decode_bch15_11_01(&bitsbch[0], first_branch); + decode_bch15_11_01(&bitsbch[15], second_branch); + + for (uint32_t j = 0; j < 11; j++) { + dec_word_symbols[j] = first_branch[j]; + dec_word_symbols[j + 11] = second_branch[j]; + } + + for (uint32_t j = 0; j < 4; j++) { + dec_word_symbols[j + 22] = first_branch[11 + j]; + dec_word_symbols[j + 26] = second_branch[11 + j]; + } + } +} + +void beidou_b3i_telemetry_decoder_gs::decode_subframe(double *frame_symbols) { + // 1. Transform from symbols to bits + std::string data_bits; + int32_t dec_word_bits[30]; + + // Decode each word in subframe + for (uint32_t ii = 0; ii < BEIDOU_DNAV_WORDS_SUBFRAME; ii++) { + // decode the word + decode_word((ii + 1), &frame_symbols[ii * 30], dec_word_bits); + + // Save word to string format + for (uint32_t jj = 0; jj < (BEIDOU_DNAV_WORD_LENGTH_BITS); jj++) { + data_bits.push_back((dec_word_bits[jj] > 0) ? ('1') : ('0')); + } + } + + if (d_satellite.get_PRN() > 0 and d_satellite.get_PRN() < 6) { + d_nav.d2_subframe_decoder(data_bits); + } else { + d_nav.d1_subframe_decoder(data_bits); + } + + // 3. Check operation executed correctly + if (d_nav.flag_crc_test == true) { + LOG(INFO) << "BeiDou DNAV CRC correct in channel " << d_channel + << " from satellite " << d_satellite; + } else { + LOG(INFO) << "BeiDou DNAV CRC error in 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 tmp_obj = + std::make_shared(d_nav.get_ephemeris()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel" + << d_channel << " from satellite " << d_satellite; + std::cout << "New BEIDOU B3I DNAV message received in channel " << d_channel + << ": ephemeris from satellite " << d_satellite << std::endl; + } + if (d_nav.have_new_utc_model() == true) { + // get object for this SV (mandatory) + std::shared_ptr tmp_obj = + std::make_shared(d_nav.get_utc_model()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + LOG(INFO) << "BEIDOU DNAV UTC Model have been received in channel" + << d_channel << " from satellite " << d_satellite; + std::cout << "New BEIDOU B3I DNAV utc model message received in channel " + << d_channel << ": UTC model parameters from satellite " + << d_satellite << std::endl; + } + if (d_nav.have_new_iono() == true) { + // get object for this SV (mandatory) + std::shared_ptr tmp_obj = + std::make_shared(d_nav.get_iono()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + LOG(INFO) << "BEIDOU DNAV Iono have been received in channel" << d_channel + << " from satellite " << d_satellite; + std::cout << "New BEIDOU B3I DNAV Iono message received in channel " + << d_channel << ": Iono model parameters from satellite " + << d_satellite << std::endl; + } + if (d_nav.have_new_almanac() == true) { + // unsigned int slot_nbr = d_nav.i_alm_satellite_PRN; + // std::shared_ptr tmp_obj = + // std::make_shared(d_nav.get_almanac(slot_nbr)); + // this->message_port_pub(pmt::mp("telemetry"), + // pmt::make_any(tmp_obj)); + LOG(INFO) << "BEIDOU DNAV Almanac have been received in channel" + << d_channel << " from satellite " << d_satellite << std::endl; + std::cout << "New BEIDOU B3I DNAV almanac received in channel " << d_channel + << " from satellite " << d_satellite << std::endl; + } +} + +void beidou_b3i_telemetry_decoder_gs::set_satellite( + const Gnss_Satellite &satellite) { + uint32_t sat_prn = 0; + 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; + + // Update satellite information for DNAV decoder + sat_prn = d_satellite.get_PRN(); + d_nav.i_satellite_PRN = sat_prn; + d_nav.i_signal_type = + 5; //!< BDS: data source (0:unknown,1:B1I,2:B1Q,3:B2I,4:B2Q,5:B3I,6:B3Q) + + // Update tel dec parameters for D2 NAV Messages + if (sat_prn > 0 and sat_prn < 6) { + // Clear values from previous declaration + volk_gnsssdr_free(d_preamble_samples); volk_gnsssdr_free(d_secondary_code_symbols); volk_gnsssdr_free(d_subframe_symbols); - if (d_dump_file.is_open() == true) - { - try - { - d_dump_file.close(); - } - catch (const std::exception &ex) - { - LOG(WARNING) << "Exception in destructor closing the dump file " << ex.what(); - } + d_samples_per_symbol = + (BEIDOU_B3I_CODE_RATE_HZ / BEIDOU_B3I_CODE_LENGTH_CHIPS) / + BEIDOU_D2NAV_SYMBOL_RATE_SPS; + d_symbols_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS; + d_samples_per_preamble = + BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS * d_samples_per_symbol; + d_secondary_code_symbols = nullptr; + d_preamble_samples = static_cast( + volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), + volk_gnsssdr_get_alignment())); + d_preamble_period_samples = + BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS * d_samples_per_symbol; + + // Setting samples of preamble code + int32_t n = 0; + for (int32_t i = 0; i < d_symbols_per_preamble; i++) { + if (BEIDOU_DNAV_PREAMBLE.at(i) == '1') { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) { + d_preamble_samples[n] = 1; + n++; } -} - - -void beidou_b3i_telemetry_decoder_gs::decode_bch15_11_01(const int32_t *bits, int32_t *decbits) -{ - int32_t bit, err, reg[4] = {1, 1, 1, 1}; - int32_t errind[15] = {14, 13, 10, 12, 6, 9, 4, 11, 0, 5, 7, 8, 1, 3, 2}; - - for (uint32_t i = 0; i < 15; i++) - { - decbits[i] = bits[i]; + } else { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) { + d_preamble_samples[n] = -1; + n++; } - - for (uint32_t i = 0; i < 15; i++) - { - bit = reg[3]; - reg[3] = reg[2]; - reg[2] = reg[1]; - reg[1] = reg[0]; - reg[0] = bits[i] * bit; - reg[1] *= bit; - } - - err = errind[reg[0] + reg[1]*2 + reg[2]*4 + reg[3]*8]; - - if (err > 0) - { - decbits[err - 1] *= -1; - } -} - - -void beidou_b3i_telemetry_decoder_gs::decode_word( - int32_t word_counter, - const double* enc_word_symbols, - int32_t* dec_word_symbols) -{ - int32_t bitsbch[30], first_branch[15], second_branch[15]; - - if (word_counter == 1) - { - for (uint32_t j = 0; j < 30; j++) - { - dec_word_symbols[j] = static_cast(enc_word_symbols[j] > 0) ? (1) : (-1); - } - } - else - { - for (uint32_t r = 0; r < 2; r++) - { - for (uint32_t c = 0; c < 15; c++) - { - bitsbch[r * 15 + c] = static_cast(enc_word_symbols[c*2 + r] > 0) ? (1) : (-1); - } - } - - decode_bch15_11_01(&bitsbch[0], first_branch); - decode_bch15_11_01(&bitsbch[15], second_branch); - - for (uint32_t j = 0; j < 11; j++) - { - dec_word_symbols[j] = first_branch[j]; - dec_word_symbols[j + 11] = second_branch[j]; - } - - for (uint32_t j = 0; j < 4; j++) - { - dec_word_symbols[j + 22] = first_branch[11 + j]; - dec_word_symbols[j + 26] = second_branch[11 + j]; - } - } -} - - -void beidou_b3i_telemetry_decoder_gs::decode_subframe(double *frame_symbols) -{ - // 1. Transform from symbols to bits - std::string data_bits; - int32_t dec_word_bits[30]; - - // Decode each word in subframe - for(uint32_t ii = 0; ii < BEIDOU_DNAV_WORDS_SUBFRAME; ii++) - { - // decode the word - decode_word((ii+1), &frame_symbols[ii*30], dec_word_bits); - - // Save word to string format - for (uint32_t jj = 0; jj < (BEIDOU_DNAV_WORD_LENGTH_BITS); jj++) - { - data_bits.push_back( (dec_word_bits[jj] > 0) ? ('1') : ('0') ); - } + } } - if ( d_satellite.get_PRN() > 0 and d_satellite.get_PRN() < 6 ) - { - d_nav.d2_subframe_decoder(data_bits); - } - else - { - d_nav.d1_subframe_decoder(data_bits); - } - - // 3. Check operation executed correctly - if (d_nav.flag_crc_test == true) - { - LOG(INFO) << "BeiDou DNAV CRC correct in channel " << d_channel << " from satellite " << d_satellite; - } - else - { - LOG(INFO) << "BeiDou DNAV CRC error in 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 tmp_obj = std::make_shared(d_nav.get_ephemeris()); - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel" << d_channel << " from satellite " << d_satellite; - std::cout << "New BEIDOU B3I DNAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << std::endl; - } - if (d_nav.have_new_utc_model() == true) - { - // get object for this SV (mandatory) - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_utc_model()); - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - LOG(INFO) << "BEIDOU DNAV UTC Model have been received in channel" << d_channel << " from satellite " << d_satellite; - std::cout << "New BEIDOU B3I DNAV utc model message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << std::endl; - } - if (d_nav.have_new_iono() == true) - { - // get object for this SV (mandatory) - std::shared_ptr tmp_obj = std::make_shared(d_nav.get_iono()); - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - LOG(INFO) << "BEIDOU DNAV Iono have been received in channel" << d_channel << " from satellite " << d_satellite; - std::cout << "New BEIDOU B3I DNAV Iono message received in channel " << d_channel << ": Iono model parameters from satellite " << d_satellite << std::endl; - } - if (d_nav.have_new_almanac() == true) - { -// unsigned int slot_nbr = d_nav.i_alm_satellite_PRN; -// std::shared_ptr tmp_obj = std::make_shared(d_nav.get_almanac(slot_nbr)); -// this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - LOG(INFO) << "BEIDOU DNAV Almanac have been received in channel" << d_channel << " from satellite " << d_satellite << std::endl; - std::cout << "New BEIDOU B3I DNAV almanac received in channel " << d_channel << " from satellite " << d_satellite << std::endl; - } + d_subframe_symbols = static_cast(volk_gnsssdr_malloc( + BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS * sizeof(double), + volk_gnsssdr_get_alignment())); + d_required_symbols = BEIDOU_DNAV_SUBFRAME_SYMBOLS * d_samples_per_symbol + + d_samples_per_preamble; + d_symbol_history.set_capacity(d_required_symbols + 1); + } } - -void beidou_b3i_telemetry_decoder_gs::set_satellite(const Gnss_Satellite &satellite) -{ - uint32_t sat_prn = 0; - 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; - - // Update satellite information for DNAV decoder - sat_prn = d_satellite.get_PRN(); - d_nav.i_satellite_PRN = sat_prn; - d_nav.i_signal_type = 5; //!< BDS: data source (0:unknown,1:B1I,2:B1Q,3:B2I,4:B2Q,5:B3I,6:B3Q) - - // Update tel dec parameters for D2 NAV Messages - if ( sat_prn > 0 and sat_prn < 6 ) - { - // Clear values from previous declaration - volk_gnsssdr_free(d_preamble_samples); - volk_gnsssdr_free(d_secondary_code_symbols); - volk_gnsssdr_free(d_subframe_symbols); - - d_samples_per_symbol = (BEIDOU_B3I_CODE_RATE_HZ / BEIDOU_B3I_CODE_LENGTH_CHIPS) / BEIDOU_D2NAV_SYMBOL_RATE_SPS; - d_symbols_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS; - d_samples_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS * d_samples_per_symbol; - d_secondary_code_symbols = nullptr; - d_preamble_samples = static_cast(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); - d_preamble_period_samples = BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS*d_samples_per_symbol; - - // Setting samples of preamble code - int32_t n = 0; - for (int32_t i = 0; i < d_symbols_per_preamble; i++) - { - if (BEIDOU_DNAV_PREAMBLE.at(i) == '1') - { - for (uint32_t j = 0; j < d_samples_per_symbol; j++) - { - d_preamble_samples[n] = 1; - n++; - } - } - else - { - for (uint32_t j = 0; j < d_samples_per_symbol; j++) - { - d_preamble_samples[n] = -1; - n++; - } - } - } - - d_subframe_symbols = static_cast(volk_gnsssdr_malloc(BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS * sizeof(double), volk_gnsssdr_get_alignment())); - d_required_symbols = BEIDOU_DNAV_SUBFRAME_SYMBOLS*d_samples_per_symbol + d_samples_per_preamble; - d_symbol_history.set_capacity(d_required_symbols + 1); - } +void beidou_b3i_telemetry_decoder_gs::set_channel(int32_t 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(std::to_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 Beidou TLM dump file. " + << e.what(); + } + } + } } +int beidou_b3i_telemetry_decoder_gs::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) { + int32_t corr_value = 0; + int32_t preamble_diff = 0; -void beidou_b3i_telemetry_decoder_gs::set_channel(int32_t 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(std::to_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 Beidou TLM dump file. " << e.what(); - } - } + auto **out = reinterpret_cast( + &output_items[0]); // Get the output buffer pointer + const auto **in = reinterpret_cast( + &input_items[0]); // Get the input buffer 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.Prompt_I); // add new symbol to the symbol queue + d_sample_counter++; // count for the processed samples + consume_each(1); + + d_flag_preamble = false; + + if (d_symbol_history.size() > d_required_symbols) { + //******* preamble correlation ******** + for (int32_t i = 0; i < d_samples_per_preamble; i++) { + if (d_symbol_history[i] < 0) // symbols clipping + { + corr_value -= d_preamble_samples[i]; + } else { + corr_value += d_preamble_samples[i]; + } + } + } + + //******* frame sync ****************** + if (d_stat == 0) // no preamble information + { + if (abs(corr_value) >= d_samples_per_preamble) { + // Record the preamble sample stamp + d_preamble_index = d_sample_counter; + LOG(INFO) << "Preamble detection for BEIDOU B3I SAT " + << this->d_satellite; + // Enter into frame pre-detection status + d_stat = 1; + } + } else if (d_stat == 1) // possible preamble lock + { + if (abs(corr_value) >= d_samples_per_preamble) { + // check preamble separation + preamble_diff = static_cast(d_sample_counter - d_preamble_index); + if (abs(preamble_diff - d_preamble_period_samples) == 0) { + // try to decode frame + LOG(INFO) << "Starting BeiDou DNAV frame decoding for BeiDou B3I SAT " + << this->d_satellite; + d_preamble_index = d_sample_counter; // record the preamble sample stamp + d_stat = 2; + } else { + if (preamble_diff > d_preamble_period_samples) { + d_stat = 0; // start again } -} - - -int beidou_b3i_telemetry_decoder_gs::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) -{ - int32_t corr_value = 0; - int32_t preamble_diff = 0; - - auto **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer - const auto **in = reinterpret_cast(&input_items[0]); // Get the input buffer 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.Prompt_I); //add new symbol to the symbol queue - d_sample_counter++; //count for the processed samples - consume_each(1); - - d_flag_preamble = false; - - if (d_symbol_history.size() > d_required_symbols) - { - //******* preamble correlation ******** - for (int32_t i = 0; i < d_samples_per_preamble; i++) - { - if (d_symbol_history[i] < 0) // symbols clipping - { - corr_value -= d_preamble_samples[i]; - } - else - { - corr_value += d_preamble_samples[i]; - } - } - } - - //******* frame sync ****************** - if (d_stat == 0) //no preamble information - { - if (abs(corr_value) >= d_samples_per_preamble) - { - // Record the preamble sample stamp - d_preamble_index = d_sample_counter; - LOG(INFO) << "Preamble detection for BEIDOU B3I SAT " << this->d_satellite; - // Enter into frame pre-detection status - d_stat = 1; - } - } - else if (d_stat == 1) // possible preamble lock - { - if (abs(corr_value) >= d_samples_per_preamble) - { - //check preamble separation - preamble_diff = static_cast(d_sample_counter - d_preamble_index); - if (abs(preamble_diff - d_preamble_period_samples) == 0) - { - //try to decode frame - LOG(INFO) << "Starting BeiDou DNAV frame decoding for BeiDou B3I SAT " << this->d_satellite; - d_preamble_index = d_sample_counter; //record the preamble sample stamp - d_stat = 2; - } - else - { - if (preamble_diff > d_preamble_period_samples) - { - d_stat = 0; // start again - } - DLOG(INFO) << "Failed BeiDou DNAV frame decoding for BeiDou B3I SAT " << this->d_satellite; - } - } - } - else if (d_stat == 2) // preamble acquired - { - if (d_sample_counter == d_preamble_index + static_cast(d_preamble_period_samples)) - { - //******* SAMPLES TO SYMBOLS ******* - if (corr_value > 0) //normal PLL lock - { - int32_t k = 0; - for (uint32_t i = 0; i < BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS; i++) - { - d_subframe_symbols[i] = 0; - //integrate samples into symbols - for (uint32_t m = 0; m < d_samples_per_symbol; m++) - { - if ( d_satellite.get_PRN() > 0 and d_satellite.get_PRN() < 6 ) - { - // because last symbol of the preamble is just received now! - d_subframe_symbols[i] += d_symbol_history.at(i * d_samples_per_symbol + m); - } - else - { - // because last symbol of the preamble is just received now! - d_subframe_symbols[i] += static_cast(d_secondary_code_symbols[k]) * d_symbol_history.at(i * d_samples_per_symbol + m); - k++; - k = k % BEIDOU_B3I_SECONDARY_CODE_LENGTH; - } - } - } - } - else //180 deg. inverted carrier phase PLL lock - { - int32_t k = 0; - for (uint32_t i = 0; i < BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS; i++) - { - d_subframe_symbols[i] = 0; - //integrate samples into symbols - for (uint32_t m = 0; m < d_samples_per_symbol; m++) - { - if ( d_satellite.get_PRN() > 0 and d_satellite.get_PRN() < 6 ) - { - // because last symbol of the preamble is just received now! - d_subframe_symbols[i] -= d_symbol_history.at(i * d_samples_per_symbol + m); - } - else - { - // because last symbol of the preamble is just received now! - d_subframe_symbols[i] -= static_cast(d_secondary_code_symbols[k]) * d_symbol_history.at(i * d_samples_per_symbol + m); - k++; - k = k % BEIDOU_B3I_SECONDARY_CODE_LENGTH; - } - } - } - } - - //call the decoder - decode_subframe(d_subframe_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) << "BeiDou DNAV frame sync found for SAT " << this->d_satellite; - } - } - 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) << "BeiDou DNAV frame sync lost for SAT " << this->d_satellite; - d_flag_frame_sync = false; - d_stat = 0; - flag_SOW_set = false; - } - } - } - } - - // UPDATE GNSS SYNCHRO DATA - //2. Add the telemetry decoder information - if (this->d_flag_preamble == true and d_nav.flag_new_SOW_available == true) - //update TOW at the preamble instant - { - // Reporting sow as gps time of week - d_TOW_at_Preamble_ms = static_cast((d_nav.d_SOW + 14) * 1000.0); - d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((d_required_symbols + 1) * BEIDOU_B3I_CODE_PERIOD_MS); - flag_SOW_set = true; - d_nav.flag_new_SOW_available = false; - } - else //if there is not a new preamble, we define the TOW of the current symbol - { - d_TOW_at_current_symbol_ms += static_cast(BEIDOU_B3I_CODE_PERIOD_MS); - } - - - if (d_flag_frame_sync == true and flag_SOW_set == true) - { - current_symbol.Flag_valid_word = true; - } - else - { - current_symbol.Flag_valid_word = false; - } - - current_symbol.PRN = this->d_satellite.get_PRN(); - current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; - - if (d_dump == true) - { - // MULTIPLEXED FILE RECORDING - Record results to file - try - { - double tmp_double; - uint64_t tmp_ulong_int; - tmp_double = static_cast(d_TOW_at_current_symbol_ms); - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_ulong_int = current_symbol.Tracking_sample_counter; - d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); - tmp_double = d_nav.d_SOW; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - tmp_ulong_int = static_cast(d_required_symbols); - d_dump_file.write(reinterpret_cast(&tmp_ulong_int), sizeof(uint64_t)); - } - catch (const std::ifstream::failure &e) - { - LOG(WARNING) << "Exception writing observables dump file " << e.what(); - } - } - - //3. Make the output (copy the object contents to the GNURadio reserved memory) - *out[0] = current_symbol; - - return 1; + DLOG(INFO) << "Failed BeiDou DNAV frame decoding for BeiDou B3I SAT " + << this->d_satellite; + } + } + } else if (d_stat == 2) // preamble acquired + { + if (d_sample_counter == + d_preamble_index + static_cast(d_preamble_period_samples)) { + //******* SAMPLES TO SYMBOLS ******* + if (corr_value > 0) // normal PLL lock + { + int32_t k = 0; + for (uint32_t i = 0; i < BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS; i++) { + d_subframe_symbols[i] = 0; + // integrate samples into symbols + for (uint32_t m = 0; m < d_samples_per_symbol; m++) { + if (d_satellite.get_PRN() > 0 and d_satellite.get_PRN() < 6) { + // because last symbol of the preamble is just received now! + d_subframe_symbols[i] += + d_symbol_history.at(i * d_samples_per_symbol + m); + } else { + // because last symbol of the preamble is just received now! + d_subframe_symbols[i] += + static_cast(d_secondary_code_symbols[k]) * + d_symbol_history.at(i * d_samples_per_symbol + m); + k++; + k = k % BEIDOU_B3I_SECONDARY_CODE_LENGTH; + } + } + } + } else // 180 deg. inverted carrier phase PLL lock + { + int32_t k = 0; + for (uint32_t i = 0; i < BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS; i++) { + d_subframe_symbols[i] = 0; + // integrate samples into symbols + for (uint32_t m = 0; m < d_samples_per_symbol; m++) { + if (d_satellite.get_PRN() > 0 and d_satellite.get_PRN() < 6) { + // because last symbol of the preamble is just received now! + d_subframe_symbols[i] -= + d_symbol_history.at(i * d_samples_per_symbol + m); + } else { + // because last symbol of the preamble is just received now! + d_subframe_symbols[i] -= + static_cast(d_secondary_code_symbols[k]) * + d_symbol_history.at(i * d_samples_per_symbol + m); + k++; + k = k % BEIDOU_B3I_SECONDARY_CODE_LENGTH; + } + } + } + } + + // call the decoder + decode_subframe(d_subframe_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) << "BeiDou DNAV frame sync found for SAT " + << this->d_satellite; + } + } 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) << "BeiDou DNAV frame sync lost for SAT " + << this->d_satellite; + d_flag_frame_sync = false; + d_stat = 0; + flag_SOW_set = false; + } + } + } + } + + // UPDATE GNSS SYNCHRO DATA + // 2. Add the telemetry decoder information + if (this->d_flag_preamble == true and d_nav.flag_new_SOW_available == true) + // update TOW at the preamble instant + { + // Reporting sow as gps time of week + d_TOW_at_Preamble_ms = static_cast((d_nav.d_SOW + 14) * 1000.0); + d_TOW_at_current_symbol_ms = + d_TOW_at_Preamble_ms + static_cast((d_required_symbols + 1) * + BEIDOU_B3I_CODE_PERIOD_MS); + flag_SOW_set = true; + d_nav.flag_new_SOW_available = false; + } else // if there is not a new preamble, we define the TOW of the current + // symbol + { + d_TOW_at_current_symbol_ms += + static_cast(BEIDOU_B3I_CODE_PERIOD_MS); + } + + if (d_flag_frame_sync == true and flag_SOW_set == true) { + current_symbol.Flag_valid_word = true; + } else { + current_symbol.Flag_valid_word = false; + } + + current_symbol.PRN = this->d_satellite.get_PRN(); + current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; + + if (d_dump == true) { + // MULTIPLEXED FILE RECORDING - Record results to file + try { + double tmp_double; + uint64_t tmp_ulong_int; + tmp_double = static_cast(d_TOW_at_current_symbol_ms); + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_ulong_int = current_symbol.Tracking_sample_counter; + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), + sizeof(uint64_t)); + tmp_double = d_nav.d_SOW; + d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); + tmp_ulong_int = static_cast(d_required_symbols); + d_dump_file.write(reinterpret_cast(&tmp_ulong_int), + sizeof(uint64_t)); + } catch (const std::ifstream::failure &e) { + LOG(WARNING) << "Exception writing observables dump file " << e.what(); + } + } + + // 3. Make the output (copy the object contents to the GNURadio reserved + // memory) + *out[0] = current_symbol; + + return 1; } diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.h index 5027a63ca..5f05b213d 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b3i_telemetry_decoder_gs.h @@ -34,83 +34,87 @@ #include "beidou_dnav_navigation_message.h" #include "gnss_satellite.h" #include -#include // for boost::shared_ptr -#include // for block -#include // for gr_vector_const_void_star +#include // for boost::shared_ptr #include #include +#include // for block +#include // for gr_vector_const_void_star #include - class beidou_b3i_telemetry_decoder_gs; -using beidou_b3i_telemetry_decoder_gs_sptr = boost::shared_ptr; +using beidou_b3i_telemetry_decoder_gs_sptr = + boost::shared_ptr; -beidou_b3i_telemetry_decoder_gs_sptr beidou_b3i_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump); +beidou_b3i_telemetry_decoder_gs_sptr +beidou_b3i_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, + bool dump); /*! * \brief This class implements a block that decodes the BeiDou DNAV data. * */ -class beidou_b3i_telemetry_decoder_gs : public gr::block -{ +class beidou_b3i_telemetry_decoder_gs : public gr::block { public: - ~beidou_b3i_telemetry_decoder_gs(); //!< Class destructor - void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN - void set_channel(int channel); //!< Set receiver's channel + ~beidou_b3i_telemetry_decoder_gs(); //!< Class destructor + void set_satellite(const 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); + /*! + * \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 beidou_b3i_telemetry_decoder_gs_sptr - beidou_b3i_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump); - beidou_b3i_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump); + friend beidou_b3i_telemetry_decoder_gs_sptr + beidou_b3i_make_telemetry_decoder_gs(const Gnss_Satellite &satellite, + bool dump); + beidou_b3i_telemetry_decoder_gs(const Gnss_Satellite &satellite, bool dump); - void decode_subframe(double *symbols); - void decode_word(int32_t word_counter, const double *enc_word_symbols, int32_t* dec_word_symbols); - void decode_bch15_11_01(const int32_t *bits, int32_t *decbits); + void decode_subframe(double *symbols); + void decode_word(int32_t word_counter, const double *enc_word_symbols, + int32_t *dec_word_symbols); + void decode_bch15_11_01(const int32_t *bits, int32_t *decbits); + // Preamble decoding + int32_t *d_preamble_samples; + int32_t *d_secondary_code_symbols; + uint32_t d_samples_per_symbol; + int32_t d_symbols_per_preamble; + int32_t d_samples_per_preamble; + int32_t d_preamble_period_samples; + double *d_subframe_symbols; + uint32_t d_required_symbols; - // Preamble decoding - int32_t *d_preamble_samples; - int32_t *d_secondary_code_symbols; - uint32_t d_samples_per_symbol; - int32_t d_symbols_per_preamble; - int32_t d_samples_per_preamble; - int32_t d_preamble_period_samples; - double *d_subframe_symbols; - uint32_t d_required_symbols; + // Storage for incoming data + boost::circular_buffer d_symbol_history; - // Storage for incoming data - boost::circular_buffer d_symbol_history; + // Variables for internal functionality + uint64_t d_sample_counter; // Sample counter as an index (1,2,3,..etc) + // indicating number of samples processed + uint64_t d_preamble_index; // Index of sample number where preamble was found + uint32_t d_stat; // Status of decoder + bool d_flag_frame_sync; // Indicate when a frame sync is achieved + bool d_flag_preamble; // Flag indicating when preamble was found + int32_t d_CRC_error_counter; // Number of failed CRC operations + bool flag_SOW_set; // Indicates when time of week is set - // Variables for internal functionality - uint64_t d_sample_counter; // Sample counter as an index (1,2,3,..etc) indicating number of samples processed - uint64_t d_preamble_index; // Index of sample number where preamble was found - uint32_t d_stat; // Status of decoder - bool d_flag_frame_sync; // Indicate when a frame sync is achieved - bool d_flag_preamble; // Flag indicating when preamble was found - int32_t d_CRC_error_counter; // Number of failed CRC operations - bool flag_SOW_set; // Indicates when time of week is set + //!< Navigation Message variable + Beidou_Dnav_Navigation_Message d_nav; - //!< Navigation Message variable - Beidou_Dnav_Navigation_Message d_nav; + //!< Values to populate gnss synchronization structure + uint32_t d_TOW_at_Preamble_ms; + uint32_t d_TOW_at_current_symbol_ms; + bool Flag_valid_word; - //!< Values to populate gnss synchronization structure - uint32_t d_TOW_at_Preamble_ms; - uint32_t d_TOW_at_current_symbol_ms; - bool Flag_valid_word; - - //!< Satellite Information and logging capacity - Gnss_Satellite d_satellite; - int32_t d_channel; - bool d_dump; - std::string d_dump_filename; - std::ofstream d_dump_file; + //!< Satellite Information and logging capacity + Gnss_Satellite d_satellite; + int32_t d_channel; + bool d_dump; + std::string d_dump_filename; + std::ofstream d_dump_file; }; #endif