diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc index ccd794943..fa231eb29 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc @@ -34,10 +34,10 @@ #include "configuration_interface.h" #include #include -#include "../../../core/system_parameters/beidou_dnav_almanac.h" -#include "../../../core/system_parameters/beidou_dnav_ephemeris.h" -#include "../../../core/system_parameters/beidou_dnav_iono.h" -#include "../../../core/system_parameters/beidou_dnav_utc_model.h" +#include "beidou_dnav_almanac.h" +#include "beidou_dnav_ephemeris.h" +#include "beidou_dnav_iono.h" +#include "beidou_dnav_utc_model.h" using google::LogMessage; diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h index e22bddc53..cfca5768f 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h @@ -35,12 +35,12 @@ #include "telemetry_decoder_interface.h" #include -#include "../gnuradio_blocks/beidou_b1i_telemetry_decoder_cc_old.h" +#include "beidou_b1i_telemetry_decoder_cc.h" class ConfigurationInterface; /*! - * \brief This class implements a NAV data decoder for GPS L1 C/A + * \brief This class implements a NAV data decoder for BEIDOU B1I */ class BeidouB1iTelemetryDecoder : public TelemetryDecoderInterface { @@ -57,7 +57,7 @@ public: return role_; } - //! Returns "GPS_L1_CA_Telemetry_Decoder" + //! Returns "BEIDOU_B1I_Telemetry_Decoder" inline std::string implementation() override { return "BEIDOU_B1I_Telemetry_Decoder"; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.cc index 067a99b41..ce4797c97 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.cc @@ -66,69 +66,105 @@ beidou_b1i_telemetry_decoder_cc::beidou_b1i_telemetry_decoder_cc( // initialize internal vars d_dump = dump; d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); - LOG(INFO) << "Initializing BeiDou B2a Telemetry Decoding"; - // Define the number of sampes per symbol. Notice that BEIDOU has 2 rates, !!!Change - //one for the navigation data and the other for the preamble information - d_samples_per_symbol = (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS) / BEIDOU_B1I_SYMBOL_RATE_SPS; - d_symbols_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS; + LOG(INFO) << "Initializing BeiDou B1i Telemetry Decoding for satellite "<< this->d_satellite; - // set the preamble - d_samples_per_preamble = BEIDOU_DNAV_PREAMBLE_LENGTH_SYMBOLS * d_samples_per_symbol; + // GEO Satellites (PRN 1 to 5) use D2 NAV message + if ( d_satellite.get_PRN() > 0 and d_satellite.get_PRN() < 6 ) + { + d_samples_per_symbol = (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_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; + d_subframe_length_symbols = BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS; - // preamble symbols to samples - d_secondary_code_symbols = static_cast(volk_gnsssdr_malloc(BEIDOU_B1I_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_subframe_length_symbols = BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS; + // 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] = 1; + n++; + } + } + else + { + for (uint32_t j = 0; j < d_samples_per_symbol; j++) + { + d_preamble_samples[n] = -1; + n++; + } + } + } - // Setting samples of secondary code - for (int32_t i = 0; i < BEIDOU_B1I_SECONDARY_CODE_LENGTH; i++) + d_subframe_symbols = static_cast(volk_gnsssdr_malloc(d_subframe_length_symbols * sizeof(double), volk_gnsssdr_get_alignment())); + d_required_symbols = BEIDOU_DNAV_SUBFRAME_SYMBOLS*d_samples_per_symbol + d_samples_per_preamble; + } + else // MEO/IGSO Satellites (PRN 6 to 37) use D1 NAV message { - if (BEIDOU_B1I_SECONDARY_CODE.at(i) == '1') + d_samples_per_symbol = (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_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_B1I_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_subframe_length_symbols = BEIDOU_DNAV_PREAMBLE_PERIOD_SYMBOLS; + + // Setting samples of secondary code + for (int32_t i = 0; i < BEIDOU_B1I_SECONDARY_CODE_LENGTH; i++) { - d_secondary_code_symbols[i] = 1; + if (BEIDOU_B1I_SECONDARY_CODE.at(i) == '1') + { + d_secondary_code_symbols[i] = 1; + } + else + { + d_secondary_code_symbols[i] = -1; + } } - else + + // Setting samples of preamble code + int32_t n = 0; + for (int32_t i = 0; i < d_symbols_per_preamble; i++) { - d_secondary_code_symbols[i] = -1; + 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_B1I_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_B1I_SECONDARY_CODE_LENGTH; + } + } } + + d_subframe_symbols = static_cast(volk_gnsssdr_malloc(d_subframe_length_symbols * sizeof(double), volk_gnsssdr_get_alignment())); + d_required_symbols = BEIDOU_DNAV_SUBFRAME_SYMBOLS*d_samples_per_symbol + d_samples_per_preamble; } - // 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_B1I_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_B1I_SECONDARY_CODE_LENGTH; - } - } - } - d_subframe_symbols = static_cast(volk_gnsssdr_malloc(d_subframe_length_symbols * sizeof(double), volk_gnsssdr_get_alignment())); - d_required_symbols = BEIDOU_DNAV_SUBFRAME_SYMBOLS*d_samples_per_symbol + d_samples_per_preamble; + // 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; @@ -136,8 +172,6 @@ beidou_b1i_telemetry_decoder_cc::beidou_b1i_telemetry_decoder_cc( d_channel = 0; flag_SOW_set = false; - - } @@ -252,7 +286,15 @@ void beidou_b1i_telemetry_decoder_cc::decode_subframe(double *frame_symbols, int } } - d_nav.subframe_decoder(data_bits); + 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) @@ -418,10 +460,18 @@ int beidou_b1i_telemetry_decoder_cc::general_work(int noutput_items __attribute_ //integrate samples into symbols for (uint32_t m = 0; m < d_samples_per_symbol; m++) { - // 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_B1I_SECONDARY_CODE_LENGTH; + 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_B1I_SECONDARY_CODE_LENGTH; + } } } } @@ -434,16 +484,25 @@ int beidou_b1i_telemetry_decoder_cc::general_work(int noutput_items __attribute_ //integrate samples into symbols for (uint32_t m = 0; m < d_samples_per_symbol; m++) { - // 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_B1I_SECONDARY_CODE_LENGTH; + 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_B1I_SECONDARY_CODE_LENGTH; + } } } } //call the decoder decode_subframe(d_subframe_symbols, d_subframe_length_symbols); + if (d_nav.flag_crc_test == true) { d_CRC_error_counter = 0; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc_old.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc_old.cc deleted file mode 100644 index e72bb2f52..000000000 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc_old.cc +++ /dev/null @@ -1,550 +0,0 @@ -/*! - * \file beidou_b1i_telemetry_decoder_cc.cc - * \brief Implementation of a NAV message demodulator block based on - * Kay Borre book MATLAB-based GPS receiver - * \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.es - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (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 . - * - * ------------------------------------------------------------------------- - */ - -#include "beidou_b1i_telemetry_decoder_cc_old.h" - -#include "control_message_factory.h" -#include -#include -#include -#include - -using google::LogMessage; - -beidou_b1i_telemetry_decoder_cc_sptr -beidou_b1i_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump) -{ - return beidou_b1i_telemetry_decoder_cc_sptr(new beidou_b1i_telemetry_decoder_cc(satellite, dump)); -} - - -beidou_b1i_telemetry_decoder_cc::beidou_b1i_telemetry_decoder_cc( - const Gnss_Satellite &satellite, - bool dump) : gr::block("beidou_navigation_cc", 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()); - - // set the preamble - unsigned short int preambles_bits[BEIDOU_B1I_PREAMBLE_LENGTH_BITS] = BEIDOU_DNAV_PREAMBLE; - - // preamble bits to sampled symbols - d_preambles_symbols = static_cast(volk_gnsssdr_malloc(BEIDOU_B1I_PREAMBLE_LENGTH_SYMBOLS * sizeof(int), volk_gnsssdr_get_alignment())); - int n = 0; - for (int i = 0; i < BEIDOU_B1I_PREAMBLE_LENGTH_BITS; i++) - { - - if (preambles_bits[i] == 1) - { - d_preambles_symbols[n] = 1; - } - else - { - d_preambles_symbols[n] = -1; - } - n++; - } - - d_samples_per_symbol = 20; - d_bits_per_preamble = 11; - d_samples_per_preamble = 11 * d_samples_per_symbol; - d_required_symbols = static_cast(6000) * d_samples_per_symbol + d_samples_per_preamble; - - d_stat = 0; - d_symbol_accumulator = 0; - d_symbol_accumulator_counter = 0; - d_frame_bit_index = 0; - d_flag_frame_sync = false; - d_BEIDOU_frame_4bytes = 0; - d_prev_BEIDOU_frame_4bytes = 0; - d_flag_parity = false; - d_TOW_at_Preamble_ms = 0; - flag_TOW_set = false; - d_flag_preamble = false; - d_flag_new_tow_available = false; - word_number = 0; - d_channel = 0; - flag_PLL_180_deg_phase_locked = false; - d_preamble_time_samples = 0; - d_TOW_at_current_symbol_ms = 0; - d_symbol_history.resize(BEIDOU_B1I_PREAMBLE_LENGTH_BITS); // Change fixed buffer size - d_symbol_nh_history.resize(BEIDOU_B1I_SECONDARY_CODE_LENGTH); // Change fixed buffer size - d_bit_buffer.resize(30); // Change fixed buffer size - d_symbol_history.clear(); // Clear all the elements in the buffer - d_symbol_nh_history.clear(); - d_bit_buffer.clear(); - d_make_correlation = true; - d_symbol_counter_corr = 0; - for (int aux = 0; aux < BEIDOU_B1I_SECONDARY_CODE_LENGTH; aux++) - { - if (BEIDOU_B1I_SECONDARY_CODE[aux] == 0) - { - bits_NH[aux] = -1.0; - } - else - { - bits_NH[aux] = 1.0; - } - } - sync_NH = false; - new_sym = false; - -} - - -beidou_b1i_telemetry_decoder_cc::~beidou_b1i_telemetry_decoder_cc() -{ - volk_gnsssdr_free(d_preambles_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(); - } - } -} - -void beidou_b1i_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite) -{ - d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); - DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite; - d_BEIDOU_FSM.i_satellite_PRN = d_satellite.get_PRN(); - DLOG(INFO) << "Navigation Satellite set to " << d_satellite; -} - - -void beidou_b1i_telemetry_decoder_cc::set_channel(int channel) -{ - d_channel = channel; - d_BEIDOU_FSM.i_channel_ID = channel; - DLOG(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(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(); - } - } - } -} - -void beidou_b1i_telemetry_decoder_cc::decodebch_bi1(int *bits, int *decbits) -{ - int bit, err, reg[4] = {1, 1, 1, 1}; - int errind[15] = {14, 13, 10, 12, 6, 9, 4, 11, 0, 5, 7, 8, 1, 3, 2}; - - for (unsigned int i = 0; i < 15; i++) - { - decbits[i] = bits[i]; - } - - for (unsigned int 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_b1i_telemetry_decoder_cc::decode_word(int word_counter, boost::circular_buffer *d_bit_buffer, unsigned int& d_BEIDOU_frame_4bytes) -{ - d_BEIDOU_frame_4bytes = 0; - int bitsdec[30], bitsbch[30], first_branch[15], second_branch[15]; - - if (word_counter == 1) - { - for (unsigned int j = 0; j < 30; j++) - { - bitsdec[j] = d_bit_buffer->at(j); - } - } - else - { - for (unsigned int r = 0; r < 2; r++) - { - for (unsigned int c = 0; c < 15; c++) - { - bitsbch[r*15 + c] = d_bit_buffer->at(c*2 + r); - } - } - - decodebch_bi1(&bitsbch[0], first_branch); - decodebch_bi1(&bitsbch[15], second_branch); - - for (unsigned int j = 0; j < 11; j++) - { - bitsdec[j] = first_branch[j]; - bitsdec[j + 11] = second_branch[j]; - } - - for (unsigned int j = 0; j < 4; j++) - { - bitsdec[j + 22] = first_branch[11 + j]; - bitsdec[j + 26] = second_branch[11 + j]; - } - } - - for (unsigned int k = 0; k < 30 ; k++) - { - if (bitsdec[k] == 1) - { - d_BEIDOU_frame_4bytes++; - } - - d_BEIDOU_frame_4bytes <<= 1; - } - - d_BEIDOU_frame_4bytes >>= 1; -} - - - -int beidou_b1i_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_ms = 0; - int corr_NH = 0; - Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer - const Gnss_Synchro **in = reinterpret_cast(&input_items[0]); // Get the input buffer pointer - new_sym = false; - 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]; - double current_time_samples = current_symbol.Tracking_sample_counter; - double current_samples_fs = current_symbol.fs; - int symbol_value = 0; - d_symbol_nh_history.push_back(current_symbol.Prompt_I); //add new symbol to the symbol queue - consume_each(1); - - if (d_symbol_nh_history.size() == BEIDOU_B1I_SECONDARY_CODE_LENGTH) - { - for (int i = 0; i < BEIDOU_B1I_SECONDARY_CODE_LENGTH; i++) - { - if ((bits_NH[i] * d_symbol_nh_history.at(i)) > 0.0) - { - corr_NH += 1; - } - else - { - corr_NH -= 1; - } - } - if (abs(corr_NH) == BEIDOU_B1I_SECONDARY_CODE_LENGTH) - { - sync_NH = true; - if (corr_NH > 0) - { - symbol_value = 1; - } - else - { - symbol_value = -1; - } -//std::cout << symbol_value << std::endl; - - d_symbol_history.push_back(symbol_value); - new_sym = true; - d_symbol_nh_history.clear(); - } - else - { - d_symbol_nh_history.pop_front(); - sync_NH = false; - new_sym = false; - } - } - - if ((d_symbol_history.size() >= BEIDOU_B1I_PREAMBLE_LENGTH_BITS) and (d_make_correlation or !d_flag_frame_sync)) - { - //******* preamble correlation ******** - for (unsigned int i = 0; i < BEIDOU_B1I_PREAMBLE_LENGTH_BITS; i++) - { - if (d_symbol_history.at(i) < 0) // symbols clipping - { - corr_value -= d_preambles_symbols[i]; - } - else - { - corr_value += d_preambles_symbols[i]; - } - } - //std::cout << corr_value << std::endl; - - if (std::abs(corr_value) >= BEIDOU_B1I_PREAMBLE_LENGTH_BITS) - { -/* for (unsigned int i = 0; i < d_symbol_history.size() ; i++) - { - std::cout << d_symbol_history.at(i); - } - - std::cout << std::endl; -*/ -// std::cout << "SUCCESSFUL PREAMBLE CORRELATION" << std::endl; - - d_symbol_history.clear(); - d_symbol_counter_corr++; - } - } - - /*if (new_sym and ) - { - flag_new_cnav_frame = beidou_nav_msg_decoder_add_symbol(&d_cnav_decoder, symbol_clip, &msg, &delay); - new_sym = false; - }*/ - - d_flag_preamble = false; - - - //******* frame sync ****************** - if (std::abs(corr_value) == BEIDOU_B1I_PREAMBLE_LENGTH_BITS) - { -// std::cout << "FRAME SYNC" << std::endl; - - //TODO: Rewrite with state machine - if (d_stat == 0) - { -// std::cout << "STATE MACHINE" << std::endl; - - d_BEIDOU_FSM.Event_beidou_word_preamble(); - //record the preamble sample stamp - d_preamble_time_samples = current_time_samples; // record the preamble sample stamp - DLOG(INFO) << "Preamble detection for SAT " << this->d_satellite << "current_time_samples=" << current_time_samples; - //sync the symbol to bits integrator - d_symbol_accumulator = 0; - d_symbol_accumulator_counter = 0; - d_stat = 1; // enter into frame pre-detection status - } - else if (d_stat == 1) //check 6 seconds of preamble separation - { - // std::cout << "6 SECONDS" << std::endl; - - preamble_diff_ms = std::round(((static_cast(current_time_samples) - d_preamble_time_samples) / static_cast(current_samples_fs)) * 1000.0); - if (std::abs(preamble_diff_ms - BEIDOU_SUBFRAME_MS) < 1) - { - std::cout << "Preamble confirmation for SAT" << std::endl; - - DLOG(INFO) << "Preamble confirmation for SAT " << this->d_satellite; - d_BEIDOU_FSM.Event_beidou_word_preamble(); - d_flag_preamble = true; - d_make_correlation = false; - d_symbol_counter_corr = 0; - d_preamble_time_samples = current_time_samples; // record the PRN start sample index associated to the preamble - if (!d_flag_frame_sync) - { - d_flag_frame_sync = true; - if (corr_value < 0) - { - flag_PLL_180_deg_phase_locked = true; // PLL is locked to opposite phase! - DLOG(INFO) << " PLL in opposite phase for Sat " << this->d_satellite.get_PRN(); - } - else - { - flag_PLL_180_deg_phase_locked = false; - } - DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " - << static_cast(d_preamble_time_samples) / static_cast(current_samples_fs) << " [s]"; - } - } - d_frame_bit_index = 10; - d_symbol_history.clear(); - for (int i = 0; i < BEIDOU_B1I_PREAMBLE_LENGTH_BITS; i++) - { - d_bit_buffer.push_back(d_preambles_symbols[i]); - } - word_number = 0; - } - } - else - { - d_symbol_counter_corr++; - if (d_symbol_counter_corr > (BEIDOU_SUBFRAME_MS - BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT)) - { - d_make_correlation = true; - } - if (d_stat == 1) - { - preamble_diff_ms = round(((static_cast(current_time_samples) - static_cast(d_preamble_time_samples)) / static_cast(current_samples_fs)) * 1000.0); - if (preamble_diff_ms > BEIDOU_SUBFRAME_MS + 1) - { - DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms; - d_stat = 0; //lost of frame sync - d_flag_frame_sync = false; - flag_TOW_set = false; - d_make_correlation = true; - d_symbol_counter_corr = 0; - } - } - } - if (d_flag_frame_sync and new_sym) - { -// std::cout << symbol_value << std::endl; - if (flag_PLL_180_deg_phase_locked) - { - d_bit_buffer.push_back(-symbol_value); - } - else - { - d_bit_buffer.push_back(symbol_value); - } - //******* bits to words ****** - d_frame_bit_index++; - if (d_frame_bit_index == 30) - { - word_number++; - beidou_b1i_telemetry_decoder_cc::decode_word(word_number, &d_bit_buffer, d_BEIDOU_frame_4bytes); -// std::cout << d_BEIDOU_frame_4bytes << std::endl; - - d_bit_buffer.clear(); - d_frame_bit_index = 0; - memcpy(&d_BEIDOU_FSM.d_BEIDOU_frame_4bytes, &d_BEIDOU_frame_4bytes, sizeof(char) * 4); - //d_BEIDOU_FSM.d_preamble_time_ms = d_preamble_time_seconds * 1000.0; - d_BEIDOU_FSM.Event_beidou_word_valid(); - // send TLM data to PVT using asynchronous message queues - if (d_BEIDOU_FSM.d_flag_new_subframe == true) - { -/* switch (d_BEIDOU_FSM.d_subframe_ID) - { - case 3: //we have a new set of ephemeris data for the current SV -*/ if (d_BEIDOU_FSM.d_nav.satellite_validation() == true) - { - - // get ephemeris object for this SV (mandatory) - std::shared_ptr tmp_obj = std::make_shared(d_BEIDOU_FSM.d_nav.get_ephemeris()); - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } -/* break; - case 4: // Possible IONOSPHERE and UTC model update (page 18) - */ if (d_BEIDOU_FSM.d_nav.flag_iono_valid == true) - { - - std::shared_ptr tmp_obj = std::make_shared(d_BEIDOU_FSM.d_nav.get_iono()); - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } - if (d_BEIDOU_FSM.d_nav.flag_utc_model_valid == true) - { -std::cout << " we have a new set of utc data for the current SV "<< std::endl; - - std::shared_ptr tmp_obj = std::make_shared(d_BEIDOU_FSM.d_nav.get_utc_model()); - this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); - } -/* break; - case 5: - // get almanac (if available) - //TODO: implement almanac reader in navigation_message - break; - default: - break; - } -*/ d_BEIDOU_FSM.clear_flag_new_subframe(); - d_flag_new_tow_available = true; - } - } - } - //2. Add the telemetry decoder information - if (this->d_flag_preamble == true and d_flag_new_tow_available == true) - { - d_TOW_at_Preamble_ms = static_cast(d_BEIDOU_FSM.d_nav.d_SOW +14) * 1000 ; - d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast((d_required_symbols + 1) * BEIDOU_B1I_CODE_PERIOD_MS); - flag_TOW_set = true; - d_flag_new_tow_available = false; - } - else - { - d_TOW_at_current_symbol_ms += BEIDOU_B1I_CODE_PERIOD_MS; - } - - current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; - current_symbol.Flag_valid_word = flag_TOW_set; - - if (flag_PLL_180_deg_phase_locked == true) - { - //correct the accumulated phase for the Costas loop phase shift, if required - current_symbol.Carrier_phase_rads += BEIDOU_PI; - } - - if (d_dump == true) - { - // MULTIPLEXED FILE RECORDING - Record results to file - try - { - double tmp_double; - unsigned long int tmp_ulong_int; - tmp_double = static_cast(d_TOW_at_current_symbol_ms) / 1000.0; - 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(unsigned long int)); - tmp_double = static_cast(d_TOW_at_Preamble_ms) * 1000.0; - d_dump_file.write(reinterpret_cast(&tmp_double), sizeof(double)); - } - 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_b1i_telemetry_decoder_cc_old.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc_old.h deleted file mode 100644 index 9cec4d4be..000000000 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc_old.h +++ /dev/null @@ -1,135 +0,0 @@ -/*! - * \file beidou_b1i_telemetry_decoder_cc.h - * \brief Interface of a NAV message demodulator block based on - * Kay Borre book MATLAB-based GPS receiver - * \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (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 . - * - * ------------------------------------------------------------------------- - */ - -#ifndef GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_CC_H -#define GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_CC_H - -#include "beidou_b1i_subframe_fsm.h" -#include "gnss_satellite.h" -#include "gnss_synchro.h" -#include -#include -#include -#include -#include "Beidou_B1I.h" - -class beidou_b1i_telemetry_decoder_cc; - -typedef boost::shared_ptr beidou_b1i_telemetry_decoder_cc_sptr; - -beidou_b1i_telemetry_decoder_cc_sptr -beidou_b1i_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - -/*! - * \brief This class implements a block that decodes the NAV data defined in IS-GPS-200E - * - */ -class beidou_b1i_telemetry_decoder_cc : public gr::block -{ -public: - ~beidou_b1i_telemetry_decoder_cc(); - void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN - void set_channel(int channel); - void decode_word(int word_counter, boost::circular_buffer *d_bit_buffer, unsigned int& d_BEIDOU_frame_4bytes); - void decodebch_bi1(int *bits, int *decbits); - unsigned int getbitu(const unsigned char *buff, int pos, int len); - void bits2byte(int *bits, int nbits, int nbin, int right, uint8_t *bin); - - /*! - * \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_b1i_telemetry_decoder_cc_sptr - beidou_b1i_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - - beidou_b1i_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); - - bool beidou_word_parityCheck(unsigned int beidouword); - - // class private vars - - int *d_preambles_symbols; - unsigned int d_stat; - bool d_flag_frame_sync; - - // symbols - boost::circular_buffer d_symbol_history; - boost::circular_buffer d_symbol_nh_history; - boost::circular_buffer d_bit_buffer; - - double d_symbol_accumulator; - short int d_symbol_accumulator_counter; - - // symbol counting - bool d_make_correlation; - unsigned int d_symbol_counter_corr; - - //bits and frame - unsigned short int d_frame_bit_index; - double bits_NH[BEIDOU_B1I_SECONDARY_CODE_LENGTH]; - unsigned int d_BEIDOU_frame_4bytes; - unsigned int d_prev_BEIDOU_frame_4bytes; - bool d_flag_parity; - bool d_flag_preamble; - bool d_flag_new_tow_available; - int d_word_number; - - uint32_t d_samples_per_symbol; - int32_t d_bits_per_preamble; - int32_t d_samples_per_preamble; - uint32_t d_required_symbols; - - // navigation message vars - Beidou_Dnav_Navigation_Message d_nav; - BeidouB1iSubframeFsm d_BEIDOU_FSM; - - bool d_dump; - Gnss_Satellite d_satellite; - int d_channel; - - unsigned long int d_preamble_time_samples; - - unsigned int d_TOW_at_Preamble_ms; - unsigned int d_TOW_at_current_symbol_ms; - unsigned int word_number; - bool flag_TOW_set; - bool flag_PLL_180_deg_phase_locked; - - std::string d_dump_filename; - std::ofstream d_dump_file; - bool sync_NH; - bool new_sym; - -}; - -#endif diff --git a/src/algorithms/telemetry_decoder/libs/CMakeLists.txt b/src/algorithms/telemetry_decoder/libs/CMakeLists.txt index 760ed7eac..e62abe66a 100644 --- a/src/algorithms/telemetry_decoder/libs/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/libs/CMakeLists.txt @@ -20,14 +20,12 @@ add_subdirectory(libswiftcnav) set(TELEMETRY_DECODER_LIB_SOURCES - beidou_b1i_subframe_fsm.cc viterbi_decoder.cc ) set(TELEMETRY_DECODER_LIB_HEADERS viterbi_decoder.h convolutional.h - beidou_b1i_subframe_fsm.h ) include_directories( diff --git a/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.cc b/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.cc deleted file mode 100644 index 48ccd8bbe..000000000 --- a/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.cc +++ /dev/null @@ -1,289 +0,0 @@ -/*! - * \file beidou_b1i_subframe_fsm.cc - * \brief Implementation of a BEIDOU NAV message word-to-subframe decoder state machine - * \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (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 . - * - * ------------------------------------------------------------------------- - */ - -#include "beidou_b1i_subframe_fsm.h" -#include "gnss_satellite.h" -#include -#include -#include -#include -#include -#include -#include - -//************ GPS WORD TO SUBFRAME DECODER STATE MACHINE ********** -struct Ev_beidou_word_valid : sc::event -{ -}; - - -struct Ev_beidou_word_invalid : sc::event -{ -}; - - -struct Ev_beidou_word_preamble : sc::event -{ -}; - - -struct beidou_subframe_fsm_S0 : public sc::state -{ -public: - // sc::transition(event,next_status) - typedef sc::transition reactions; - beidou_subframe_fsm_S0(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S0 "< -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - beidou_subframe_fsm_S1(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S1 "< -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - beidou_subframe_fsm_S2(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S2 "<().beidou_word_to_subframe(0); - } -}; - - -struct beidou_subframe_fsm_S3 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - beidou_subframe_fsm_S3(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S3 "<().beidou_word_to_subframe(1); - } -}; - - -struct beidou_subframe_fsm_S4 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - beidou_subframe_fsm_S4(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S4 "<().beidou_word_to_subframe(2); - } -}; - - -struct beidou_subframe_fsm_S5 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - beidou_subframe_fsm_S5(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S5 "<().beidou_word_to_subframe(3); - } -}; - - -struct beidou_subframe_fsm_S6 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - beidou_subframe_fsm_S6(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S6 "<().beidou_word_to_subframe(4); - } -}; - - -struct beidou_subframe_fsm_S7 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - beidou_subframe_fsm_S7(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S7 "<().beidou_word_to_subframe(5); - } -}; - - -struct beidou_subframe_fsm_S8 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - beidou_subframe_fsm_S8(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S8 "<().beidou_word_to_subframe(6); - } -}; - - -struct beidou_subframe_fsm_S9 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - beidou_subframe_fsm_S9(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S9 "<().beidou_word_to_subframe(7); - } -}; - - -struct beidou_subframe_fsm_S10 : public sc::state -{ -public: - typedef mpl::list, - sc::transition > - reactions; - - beidou_subframe_fsm_S10(my_context ctx) : my_base(ctx) - { - //std::cout<<"Enter S10 "<().beidou_word_to_subframe(8); - } -}; - - -struct beidou_subframe_fsm_S11 : public sc::state -{ -public: - typedef sc::transition reactions; - - beidou_subframe_fsm_S11(my_context ctx) : my_base(ctx) - { - //std::cout<<"Completed GPS Subframe!"<().beidou_word_to_subframe(9); - context().beidou_subframe_to_nav_msg(); //decode the subframe - // DECODE SUBFRAME - //std::cout<<"Enter S11"<d_subframe); //decode the subframe - std::cout << "New BEIDOU NAV message received in channel " << i_channel_ID << ": " - << "subframe " - << d_subframe_ID << " from satellite " - << Gnss_Satellite(std::string("Beidou"), i_satellite_PRN) << std::endl; - d_nav.i_satellite_PRN = i_satellite_PRN; - d_nav.i_channel_ID = i_channel_ID; - - d_flag_new_subframe = true; -} - - -void BeidouB1iSubframeFsm::Event_beidou_word_valid() -{ - this->process_event(Ev_beidou_word_valid()); -} - - -void BeidouB1iSubframeFsm::Event_beidou_word_invalid() -{ - this->process_event(Ev_beidou_word_invalid()); -} - - -void BeidouB1iSubframeFsm::Event_beidou_word_preamble() -{ - this->process_event(Ev_beidou_word_preamble()); -} diff --git a/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.h b/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.h deleted file mode 100644 index 012558a68..000000000 --- a/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.h +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * \file beidou_b1i_subframe_fsm.h - * \brief Interface of a BEIDOU NAV message word-to-subframe decoder state machine - * \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com - * - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (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 . - * - * ------------------------------------------------------------------------- - */ - - -#ifndef GNSS_SDR_BEIDOU_B1I_SUBFRAME_FSM_H_ -#define GNSS_SDR_BEIDOU_B1I_SUBFRAME_FSM_H_ - -#include -#include "beidou_dnav_almanac.h" -#include "beidou_dnav_ephemeris.h" -#include "beidou_dnav_iono.h" -#include "beidou_dnav_navigation_message.h" -#include "beidou_dnav_utc_model.h" -#include "Beidou_B1I.h" - -namespace sc = boost::statechart; -namespace mpl = boost::mpl; - -struct beidou_subframe_fsm_S0; -struct beidou_subframe_fsm_S1; -struct beidou_subframe_fsm_S2; -struct beidou_subframe_fsm_S3; -struct beidou_subframe_fsm_S4; -struct beidou_subframe_fsm_S5; -struct beidou_subframe_fsm_S6; -struct beidou_subframe_fsm_S7; -struct beidou_subframe_fsm_S8; -struct beidou_subframe_fsm_S9; -struct beidou_subframe_fsm_S10; -struct beidou_subframe_fsm_S11; - - -/*! - * \brief This class implements a Finite State Machine that handles the decoding - * of the GPS L1 C/A NAV message - */ -class BeidouB1iSubframeFsm : public sc::state_machine -{ -public: - BeidouB1iSubframeFsm(); //!< The constructor starts the Finite State Machine - void clear_flag_new_subframe(); - // channel and satellite info - int i_channel_ID; //!< Channel id - unsigned int i_satellite_PRN; //!< Satellite PRN number - - Beidou_Dnav_Navigation_Message d_nav; //!< GPS L1 C/A navigation message object - - // GPS SV and System parameters - Beidou_Dnav_Ephemeris ephemeris; //!< Object that handles GPS ephemeris parameters - Beidou_Dnav_Almanac almanac; //!< Object that handles GPS almanac data - Beidou_Dnav_Utc_Model utc_model; //!< Object that handles UTM model parameters - Beidou_Dnav_Iono iono; //!< Object that handles ionospheric parameters - - char d_subframe[BEIDOU_SUBFRAME_LENGTH]; - int d_subframe_ID; - bool d_flag_new_subframe; - char d_BEIDOU_frame_4bytes[BEIDOU_WORD_LENGTH]; - //double d_preamble_time_ms; - - void beidou_word_to_subframe(int position); //!< inserts the word in the correct position of the subframe - - /*! - * \brief This function decodes a NAv message subframe and pushes the information to the right queues - */ - void beidou_subframe_to_nav_msg(); - - //FSM EVENTS - void Event_beidou_word_valid(); //!< FSM event: the received word is valid - void Event_beidou_word_invalid(); //!< FSM event: the received word is not valid - void Event_beidou_word_preamble(); //!< FSM event: word preamble detected -}; - -#endif diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index 055355ba7..2f0c5c583 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -1492,6 +1492,8 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) next_state = acquire_secondary(); if (next_state) { + LOG(INFO) << systemName << " " << signal_pretty_name << " secondary code locked in channel " << d_channel + << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; std::cout << systemName << " " << signal_pretty_name << " secondary code locked in channel " << d_channel << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; } @@ -1523,7 +1525,8 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) } if (corr_value == d_preamble_length_symbols) { - //std::cout << "Preamble detected at tracking!" << std::endl; + LOG(INFO) << systemName << " " << signal_pretty_name << " tracking preamble detected in channel " << d_channel + << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; next_state = true; } else diff --git a/src/core/system_parameters/Beidou_B1I.h b/src/core/system_parameters/Beidou_B1I.h index ca9d4b989..f7ff788ca 100644 --- a/src/core/system_parameters/Beidou_B1I.h +++ b/src/core/system_parameters/Beidou_B1I.h @@ -100,7 +100,8 @@ const double BEIDOU_DNAV_DATA_BITS = 300; const double BEIDOU_DNAV_WORDS_SUBFRAME = 10; const double BEIDOU_DNAV_WORD_LENGTH_BITS = 30; -const double BEIDOU_B1I_SYMBOL_RATE_SPS = 50; //BEIDOU symbol rate +const double BEIDOU_D1NAV_SYMBOL_RATE_SPS = 50; +const double BEIDOU_D2NAV_SYMBOL_RATE_SPS = 500; const double BEIDOU_B1I_PREAMBLE_PERIOD_SYMBOLS = 300; // BEIDOU D1 NAVIGATION MESSAGE STRUCTURE @@ -110,99 +111,111 @@ const std::vector > D1_FRAID( { {16,3} } ); const std::vector > D1_SOW( { {19,8},{31,12} } ); const std::vector > D1_PNUM( { {44,7} } ); +// DNAV SCALE FACTORS +// EPH +const double D1_TOC_LSB = TWO_P3; +const double D1_TGD1_LSB = 0.1; +const double D1_TGD2_LSB = 0.1; +const double D1_ALPHA0_LSB = TWO_N30; +const double D1_ALPHA1_LSB = TWO_N27; +const double D1_ALPHA2_LSB = TWO_N24; +const double D1_ALPHA3_LSB = TWO_N24; +const double D1_BETA0_LSB = TWO_P11; +const double D1_BETA1_LSB = TWO_P14; +const double D1_BETA2_LSB = TWO_P16; +const double D1_BETA3_LSB = TWO_P16; +const double D1_A2_LSB = TWO_N66; +const double D1_A0_LSB = TWO_N33; +const double D1_A1_LSB = TWO_N50; +const double D1_DELTA_N_LSB = PI_TWO_N43; +const double D1_CUC_LSB = TWO_N31; +const double D1_M0_LSB = PI_TWO_N31; +const double D1_E_LSB = TWO_N33; +const double D1_CUS_LSB = TWO_N31; +const double D1_CRC_LSB = TWO_N6; +const double D1_CRS_LSB = TWO_N6; +const double D1_SQRT_A_LSB = TWO_N19; +const double D1_TOE_LSB = TWO_P3; +const double D1_I0_LSB = PI_TWO_N31; +const double D1_CIC_LSB = TWO_N31; +const double D1_OMEGA_DOT_LSB = PI_TWO_N43; +const double D1_CIS_LSB = TWO_N31; +const double D1_IDOT_LSB = PI_TWO_N43; +const double D1_OMEGA0_LSB = PI_TWO_N31; +const double D1_OMEGA_LSB = PI_TWO_N31; +//ALM +const double D1_SQRT_A_ALMANAC_LSB = TWO_N11; +const double D1_A1_ALMANAC_LSB = TWO_N38; +const double D1_A0_ALMANAC_LSB = TWO_N20; +const double D1_OMEGA0_ALMANAC_LSB = PI_TWO_N23; +const double D1_E_ALMANAC_LSB = TWO_N21; +const double D1_DELTA_I_LSB = PI_TWO_N19; +const double D1_TOA_LSB = TWO_P12; +const double D1_OMEGA_DOT_ALMANAC_LSB = PI_TWO_N38; +const double D1_OMEGA_ALMANAC_LSB = PI_TWO_N23; +const double D1_M0_ALMANAC_LSB = PI_TWO_N23; +const double D1_A0GPS_LSB = 0.1; +const double D1_A1GPS_LSB = 0.1; +const double D1_A0GAL_LSB = 0.1; +const double D1_A1GAL_LSB = 0.1; +const double D1_A0GLO_LSB = 0.1; +const double D1_A1GLO_LSB = 0.1; +const double D1_A0UTC_LSB = TWO_N30; +const double D1_A1UTC_LSB = TWO_N50; + // SUBFRAME 1 const std::vector > D1_SAT_H1( { {43,1} } ); const std::vector > D1_AODC( { {44,5} } ); const std::vector > D1_URAI( { {49,4} } ); const std::vector > D1_WN( { {61,13} } ); const std::vector > D1_TOC( { {74,9},{91,8} } ); -const double D1_TOC_LSB = TWO_P3; const std::vector > D1_TGD1( { {99,10} } ); -const double D1_TGD1_LSB = 0.1; const std::vector > D1_TGD2( { {121,6} } ); -const double D1_TGD2_LSB = 0.1; const std::vector > D1_ALPHA0( { {127,8} } ); -const double D1_ALPHA0_LSB = TWO_N30; const std::vector > D1_ALPHA1( { {135,8} } ); -const double D1_ALPHA1_LSB = TWO_N27; const std::vector > D1_ALPHA2( { {151,8} } ); -const double D1_ALPHA2_LSB = TWO_N24; const std::vector > D1_ALPHA3( { {159,8} } ); -const double D1_ALPHA3_LSB = TWO_N24; const std::vector > D1_BETA0( { {167,6}, {181,2} } ); -const double D1_BETA0_LSB = TWO_P11; const std::vector > D1_BETA1( { {183,8} } ); -const double D1_BETA1_LSB = TWO_P14; const std::vector > D1_BETA2( { {191,8} } ); -const double D1_BETA2_LSB = TWO_P16; const std::vector > D1_BETA3( { {199,4},{211,4} } ); -const double D1_BETA3_LSB = TWO_P16; const std::vector > D1_A2( { {215,11} } ); -const double D1_A2_LSB = TWO_N66; const std::vector > D1_A0( { {226,7},{241,17} } ); -const double D1_A0_LSB = TWO_N33; const std::vector > D1_A1( { {258,5},{271,17} } ); -const double D1_A1_LSB = TWO_N50; const std::vector > D1_AODE( { {288,5} } ); //SUBFRAME 2 const std::vector > D1_DELTA_N( { {43,10},{61,6} } ); -const double D1_DELTA_N_LSB = PI_TWO_N43; const std::vector > D1_CUC( { {67,16},{91,2} } ); -const double D1_CUC_LSB = TWO_N31; const std::vector > D1_M0( { {93,20}, {121,12} } ); -const double D1_M0_LSB = PI_TWO_N31; const std::vector > D1_E( { {133,10},{151,22} } ); -const double D1_E_LSB = TWO_N33; const std::vector > D1_CUS( { {181,18} } ); -const double D1_CUS_LSB = TWO_N31; const std::vector > D1_CRC( { {199,4},{211,14} } ); -const double D1_CRC_LSB = TWO_N6; const std::vector > D1_CRS( { {225,8},{241,10} } ); -const double D1_CRS_LSB = TWO_N6; const std::vector > D1_SQRT_A( { {251,12},{271,20} } ); -const double D1_SQRT_A_LSB = TWO_N19; const std::vector > D1_TOE_SF2( { {291,2} } ); -const double D1_TOE_LSB = TWO_P3; //SUBFRAME 3 const std::vector > D1_TOE_SF3( { {43,10},{61,5} } ); const std::vector > D1_I0( { {66,17},{91,15} } ); -const double D1_I0_LSB = PI_TWO_N31; const std::vector > D1_CIC( { {106,7},{121,11} } ); -const double D1_CIC_LSB = TWO_N31; const std::vector > D1_OMEGA_DOT( { {132,11},{151,13} } ); -const double D1_OMEGA_DOT_LSB = PI_TWO_N43; const std::vector > D1_CIS( { {164,9},{181,9} } ); -const double D1_CIS_LSB = TWO_N31; const std::vector > D1_IDOT( { {190,13},{211,1} } ); -const double D1_IDOT_LSB = PI_TWO_N43; const std::vector > D1_OMEGA0( { {212,21},{241,11} } ); -const double D1_OMEGA0_LSB = PI_TWO_N31; const std::vector > D1_OMEGA( { {252,11},{271,21} } ); -const double D1_OMEGA_LSB = PI_TWO_N31; //SUBFRAME 4 AND PAGES 1 THROUGH 6 IN SUBFRAME 5 const std::vector > D1_SQRT_A_ALMANAC( { {51,2},{61,22} } ); -const double D1_SQRT_A_ALMANAC_LSB = TWO_N11; const std::vector > D1_A1_ALMANAC( { {91,11} } ); -const double D1_A1_ALMANAC_LSB = TWO_N38; const std::vector > D1_A0_ALMANAC( { {102,11} } ); -const double D1_A0_ALMANAC_LSB = TWO_N20; const std::vector > D1_OMEGA0_ALMANAC( { {121,22},{151,2} } ); -const double D1_OMEGA0_ALMANAC_LSB = PI_TWO_N23; const std::vector > D1_E_ALMANAC( { {153,17} } ); -const double D1_E_ALMANAC_LSB = TWO_N21; const std::vector > D1_DELTA_I( { {170,3},{181,13} } ); -const double D1_DELTA_I_LSB = PI_TWO_N19; const std::vector > D1_TOA( { {194,8} } ); -const double D1_TOA_LSB = TWO_P12; const std::vector > D1_OMEGA_DOT_ALMANAC( { {202,1}, {211,16} } ); -const double D1_OMEGA_DOT_ALMANAC_LSB = PI_TWO_N38; const std::vector > D1_OMEGA_ALMANAC( { {227,6},{241,18} } ); -const double D1_OMEGA_ALMANAC_LSB = PI_TWO_N23; const std::vector > D1_M0_ALMANAC( { {259,4},{271,20} } ); -const double D1_M0_ALMANAC_LSB = PI_TWO_N23; //SUBFRAME 5 PAGE 7 const std::vector > D1_HEA1( { {51,2},{61,7} } ); @@ -225,8 +238,6 @@ const std::vector > D1_HEA17( { {251,9} } ); const std::vector > D1_HEA18( { {260,3},{271,6} } ); const std::vector > D1_HEA19( { {277,9} } ); - - //SUBFRAME 5 PAGE 8 const std::vector > D1_HEA20( { {51,2},{61,7} } ); const std::vector > D1_HEA21( { {68,9} } ); @@ -244,26 +255,86 @@ const std::vector > D1_TOA2( { {198,5},{211,3} } ); //SUBFRAME 5 PAGE 9 const std::vector > D1_A0GPS( { {97,14} } ); -const double D1_A0GPS_LSB = 0.1; const std::vector > D1_A1GPS( { {111,2},{121,14} } ); -const double D1_A1GPS_LSB = 0.1; const std::vector > D1_A0GAL( { {135,8},{151,6} } ); -const double D1_A0GAL_LSB = 0.1; const std::vector > D1_A1GAL( { {157,16} } ); -const double D1_A1GAL_LSB = 0.1; const std::vector > D1_A0GLO( { {181,14} } ); -const double D1_A0GLO_LSB = 0.1; const std::vector > D1_A1GLO( { {195,8},{211,8} } ); -const double D1_A1GLO_LSB = 0.1; //SUBFRAME 5 PAGE 10 const std::vector > D1_DELTA_T_LS( { {51,2},{61,6} } ); const std::vector > D1_DELTA_T_LSF( { {67,8} } ); const std::vector > D1_WN_LSF( { {75,8} } ); const std::vector > D1_A0UTC( { {91,22},{121,10} } ); -const double D1_A0UTC_LSB = TWO_N30; const std::vector > D1_A1UTC( { {131,12},{151,12} } ); -const double D1_A1UTC_LSB = TWO_N50; const std::vector > D1_DN( { {163,8} } ); +// D2 NAV Message Decoding Information +const std::vector > D2_PRE( { {1,11} } ); +const std::vector > D2_FRAID( { {16,3} } ); +const std::vector > D2_SOW( { {19,8},{31,12} } ); +const std::vector > D2_PNUM( { {43,4} } ); + +// D2 NAV, SUBFRAME 1, PAGE 1 +const std::vector > D2_SAT_H1( { {47,1} } ); +const std::vector > D2_AODC( { {48,5} } ); +const std::vector > D2_URAI( { {61,4} } ); +const std::vector > D2_WN( { {65,13} } ); +const std::vector > D2_TOC( { {78,5},{91,12} } ); +const std::vector > D2_TGD1( { {103,10} } ); +const std::vector > D2_TGD2( { {121,10} } ); + +// D2 NAV, SUBFRAME 1, PAGE 2 +const std::vector > D2_ALPHA0( { {47,6}, {61,2} } ); +const std::vector > D2_ALPHA1( { {63,8} } ); +const std::vector > D2_ALPHA2( { {71,8} } ); +const std::vector > D2_ALPHA3( { {79,4}, {91,4} } ); +const std::vector > D2_BETA0( { {95,8} } ); +const std::vector > D2_BETA1( { {103,8} } ); +const std::vector > D2_BETA2( { {111,2}, {121,6} } ); +const std::vector > D2_BETA3( { {127,8} } ); + +// D2 NAV, SUBFRAME 1, PAGE 3 +const std::vector > D2_A0( { {101,12},{121,12} } ); +const std::vector > D2_A1_MSB( { {133,4} } ); + +// D2 NAV, SUBFRAME 1, PAGE 4 +const std::vector > D2_A1_LSB( { {47,6}, {121, 12} } ); +const std::vector > D2_A2( { {73,10}, {91,1} } ); +const std::vector > D2_AODE( { {92,5} } ); +const std::vector > D2_DELTA_N( { {97,16} } ); +const std::vector > D2_CUC_MSB( { {121,14} } ); + +// D2 NAV, SUBFRAME 1, PAGE 5 +const std::vector > D2_CUC_LSB( { {47,4} } ); +const std::vector > D2_M0( { {51,2}, {61,22}, {91,8} } ); +const std::vector > D2_CUS( { {99,14}, {121, 4} } ); +const std::vector > D2_E_MSB( { {125,10} } ); + +// D2 NAV, SUBFRAME 1, PAGE 6 +const std::vector > D2_E_LSB( { {47,6}, {61, 16} } ); +const std::vector > D2_SQRT_A( { {77,6},{91,22}, {121,4} } ); +const std::vector > D2_CIC_MSB( { {125,10} } ); + +// D2 NAV, SUBFRAME 1, PAGE 7 +const std::vector > D2_CIC_LSB( { {47,6}, {61,2} } ); +const std::vector > D2_CIS( { {63,18} } ); +const std::vector > D2_TOE( { {81,2},{91,15} } ); +const std::vector > D2_I0_MSB( { {106,7},{121,14} } ); + +// D2 NAV, SUBFRAME 1, PAGE 8 +const std::vector > D2_I0_LSB( { {47,6},{61,5} } ); +const std::vector > D2_CRC( { {66,17},{91,1} } ); +const std::vector > D2_CRS( { {92,18} } ); +const std::vector > D2_OMEGA_DOT_MSB( { {110,3},{121,16} } ); + +// D2 NAV, SUBFRAME 1, PAGE 9 +const std::vector > D2_OMEGA_DOT_LSB( { {47,5} } ); +const std::vector > D2_OMEGA0( { {52,1},{61,22},{91,9} } ); +const std::vector > D2_OMEGA_MSB( { {100,13},{121,14} } ); + +// D2 NAV, SUBFRAME 1, PAGE 10 +const std::vector > D2_OMEGA_LSB( { {47,5} } ); +const std::vector > D2_IDOT( { {52,1},{61,13} } ); + #endif /* GNSS_SDR_BEIDOU_B1I_H_ */ diff --git a/src/core/system_parameters/beidou_dnav_navigation_message.cc b/src/core/system_parameters/beidou_dnav_navigation_message.cc index 091e7edc9..393939aeb 100644 --- a/src/core/system_parameters/beidou_dnav_navigation_message.cc +++ b/src/core/system_parameters/beidou_dnav_navigation_message.cc @@ -47,6 +47,33 @@ void Beidou_Dnav_Navigation_Message::reset() flag_utc_model_valid = false; flag_crc_test = false; + flag_sf1_p1 = false; + flag_sf1_p2 = false; + flag_sf1_p3 = false; + flag_sf1_p4 = false; + flag_sf1_p5 = false; + flag_sf1_p6 = false; + flag_sf1_p7 = false; + flag_sf1_p8 = false; + flag_sf1_p9 = false; + flag_sf1_p10 = false; + + // D2 NAV Decoding UNique Attributes + d_a1_msb = 0; + d_a1_lsb = 0; + d_Cuc_msb = 0; + d_Cuc_lsb = 0; + d_eccentricity_msb = 0; + d_eccentricity_lsb = 0; + d_Cic_msb = 0; + d_Cic_lsb = 0; + d_i_0_msb = 0; + d_i_0_lsb = 0; + d_OMEGA_msb = 0; + d_OMEGA_lsb = 0; + d_OMEGA_DOT_msb = 0; + d_OMEGA_DOT_lsb = 0; + d_SOW = 0; d_SOW_SF1 = 0; d_SOW_SF2 = 0; @@ -58,7 +85,7 @@ void Beidou_Dnav_Navigation_Message::reset() d_Delta_n = 0; d_M_0 = 0; d_Cuc = 0; - d_e_eccentricity = 0; + d_eccentricity = 0; d_Cus = 0; d_sqrt_A = 0; d_Toe_sf2 = 0; @@ -345,7 +372,7 @@ void Beidou_Dnav_Navigation_Message::satellitePosition(double transmitTime) for (int ii = 1; ii < 20; ii++) { E_old = E; - E = M + d_e_eccentricity * sin(E); + E = M + d_eccentricity * sin(E); dE = fmod(E - E_old, 2 * BEIDOU_PI); if (fabs(dE) < 1e-12) { @@ -355,11 +382,11 @@ void Beidou_Dnav_Navigation_Message::satellitePosition(double transmitTime) } // Compute relativistic correction term - d_dtr = BEIDOU_F * d_e_eccentricity * d_sqrt_A * sin(E); + d_dtr = BEIDOU_F * d_eccentricity * d_sqrt_A * sin(E); // Compute the true anomaly - double tmp_Y = sqrt(1.0 - d_e_eccentricity * d_e_eccentricity) * sin(E); - double tmp_X = cos(E) - d_e_eccentricity; + double tmp_Y = sqrt(1.0 - d_eccentricity * d_eccentricity) * sin(E); + double tmp_X = cos(E) - d_eccentricity; nu = atan2(tmp_Y, tmp_X); // Compute angle phi (argument of Latitude) @@ -372,7 +399,7 @@ void Beidou_Dnav_Navigation_Message::satellitePosition(double transmitTime) u = phi + d_Cuc * cos(2 * phi) + d_Cus * sin(2 * phi); // Correct radius - r = a * (1 - d_e_eccentricity * cos(E)) + d_Crc * cos(2 * phi) + d_Crs * sin(2 * phi); + r = a * (1 - d_eccentricity * cos(E)) + d_Crc * cos(2 * phi) + d_Crs * sin(2 * phi); // Correct inclination i = d_i_0 + d_IDOT * tk + d_Cic * cos(2 * phi) + d_Cis * sin(2 * phi); @@ -395,7 +422,7 @@ void Beidou_Dnav_Navigation_Message::satellitePosition(double transmitTime) d_satvel_Z = d_satpos_Y * sin(i); } -int Beidou_Dnav_Navigation_Message::subframe_decoder(std::string const &subframe) +int Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const &subframe) { int subframe_ID = 0; std::bitset subframe_bits(subframe); @@ -474,7 +501,7 @@ int Beidou_Dnav_Navigation_Message::subframe_decoder(std::string const &subframe d_AODE = static_cast(read_navigation_unsigned(subframe_bits, D1_AODE)); // Set system flags for message reception - flag_sf_1 = true; + flag_sf1 = true; flag_iono_valid = true; flag_utc_model_valid = true; flag_new_SOW_available = true; @@ -493,8 +520,8 @@ int Beidou_Dnav_Navigation_Message::subframe_decoder(std::string const &subframe d_M_0 = static_cast(read_navigation_signed(subframe_bits, D1_M0)); d_M_0 = d_M_0 * D1_M0_LSB; - d_e_eccentricity = static_cast(read_navigation_unsigned(subframe_bits, D1_E)); - d_e_eccentricity = d_e_eccentricity * D1_E_LSB; + d_eccentricity = static_cast(read_navigation_unsigned(subframe_bits, D1_E)); + d_eccentricity = d_eccentricity * D1_E_LSB; d_Cus = static_cast(read_navigation_signed(subframe_bits, D1_CUS)); d_Cus = d_Cus * D1_CUS_LSB; @@ -512,7 +539,7 @@ int Beidou_Dnav_Navigation_Message::subframe_decoder(std::string const &subframe d_Toe_sf2 = static_cast((static_cast(d_Toe_sf2) << 15)); // Set system flags for message reception - flag_sf_2 = true; + flag_sf2 = true; flag_new_SOW_available = true; break; @@ -766,6 +793,304 @@ int Beidou_Dnav_Navigation_Message::subframe_decoder(std::string const &subframe return subframe_ID; } +int Beidou_Dnav_Navigation_Message::d2_subframe_decoder(std::string const &subframe) +{ + int subframe_ID = 0; + int page_ID = 0; + + std::bitset subframe_bits(subframe); + + subframe_ID = static_cast(read_navigation_unsigned(subframe_bits, D2_FRAID)); + page_ID = static_cast(read_navigation_unsigned(subframe_bits, D2_PNUM)); + + // Perform crc computtaion (tbd) + flag_crc_test = true; + + // Decode all 5 sub-frames + switch (subframe_ID) + { + //--- Decode the sub-frame id ------------------------------------------ + case 1: + + switch(page_ID) + { + case 1: + i_SV_health = static_cast(read_navigation_unsigned(subframe_bits, D2_SAT_H1)); + d_AODC = static_cast(read_navigation_unsigned(subframe_bits, D2_AODC)); + i_SV_accuracy = static_cast(read_navigation_unsigned(subframe_bits, D2_URAI)); // (20.3.3.3.1.3) + i_BEIDOU_week = static_cast(read_navigation_unsigned(subframe_bits, D2_WN)); + d_Toc = static_cast(read_navigation_unsigned(subframe_bits, D2_TOC)) * D1_TOC_LSB; + d_TGD1 = static_cast(read_navigation_signed(subframe_bits, D2_TGD1)) * D1_TGD1_LSB; + + // Set system flags for message reception + flag_sf1_p1 = true; + + break; + case 2: + d_alpha0 = static_cast(read_navigation_signed(subframe_bits, D2_ALPHA0))*D1_ALPHA0_LSB; + d_alpha1 = static_cast(read_navigation_signed(subframe_bits, D2_ALPHA1))*D1_ALPHA1_LSB; + d_alpha2 = static_cast(read_navigation_signed(subframe_bits, D2_ALPHA2))*D1_ALPHA2_LSB; + d_alpha3 = static_cast(read_navigation_signed(subframe_bits, D1_ALPHA3))*D1_ALPHA3_LSB; + + d_beta0 = static_cast(read_navigation_signed(subframe_bits, D2_BETA0))*D1_BETA0_LSB; + d_beta1 = static_cast(read_navigation_signed(subframe_bits, D2_BETA1))*D1_BETA1_LSB; + d_beta2 = static_cast(read_navigation_signed(subframe_bits, D2_BETA2))*D1_BETA2_LSB; + d_beta3 = static_cast(read_navigation_signed(subframe_bits, D2_BETA3))*D1_BETA3_LSB; + + // Set system flags for message reception + flag_sf1_p2 = true; + + break; + case 3: + d_a0 = static_cast(read_navigation_signed(subframe_bits, D2_A0))*D1_A0_LSB; + d_a1_msb = static_cast(read_navigation_signed(subframe_bits, D2_A1_MSB)); + + // Set system flags for message reception + flag_sf1_p3 = true; + + break; + case 4: + d_a1_lsb = static_cast(read_navigation_signed(subframe_bits, D2_A1_LSB)); + d_a2 = static_cast(read_navigation_signed(subframe_bits, D1_A2))*D1_A2_LSB; + d_AODE = static_cast(read_navigation_unsigned(subframe_bits, D2_AODE)); + d_Delta_n = static_cast(read_navigation_unsigned(subframe_bits, D2_DELTA_N))*D1_DELTA_N_LSB; + d_Cuc_msb = static_cast(read_navigation_signed(subframe_bits, D2_CUC_MSB)); + + // Set system flags for message reception + flag_sf1_p4 = true; + break; + case 5: + d_Cuc_lsb = static_cast(read_navigation_signed(subframe_bits, D2_CUC_LSB)); + d_M_0 = static_cast(read_navigation_signed(subframe_bits, D2_M0))*D1_M0_LSB; + d_Cus = static_cast(read_navigation_signed(subframe_bits, D2_CUS))*D1_CUS_LSB; + d_eccentricity_msb = static_cast(read_navigation_unsigned(subframe_bits, D2_E_MSB)); + + // Set system flags for message reception + flag_sf1_p5 = true; + break; + case 6: + d_eccentricity_lsb = static_cast(read_navigation_unsigned(subframe_bits, D2_E_LSB)); + d_sqrt_A = static_cast(read_navigation_unsigned(subframe_bits, D2_SQRT_A))*D1_SQRT_A_LSB; + d_Cic_msb = static_cast(read_navigation_signed(subframe_bits, D2_CIC_MSB)); + + // Set system flags for message reception + flag_sf1_p6 = true; + break; + case 7: + d_Cic_lsb = static_cast(read_navigation_signed(subframe_bits, D2_CIC_LSB)); + d_Cis = static_cast(read_navigation_signed(subframe_bits, D2_CIS))*D1_CIS_LSB; + d_Toe = static_cast(read_navigation_unsigned(subframe_bits, D2_TOE))*D1_TOE_LSB; + d_i_0_msb = static_cast(read_navigation_signed(subframe_bits, D2_I0_MSB)); + + // Set system flags for message reception + flag_sf1_p7 = true; + break; + case 8: + d_i_0_lsb = static_cast(read_navigation_signed(subframe_bits, D2_I0_LSB)); + d_Crc = static_cast(read_navigation_signed(subframe_bits, D2_CRC))*D1_CRC_LSB; + d_Crs = static_cast(read_navigation_signed(subframe_bits, D2_CRS))*D1_CRS_LSB; + d_OMEGA_DOT_msb = static_cast(read_navigation_signed(subframe_bits, D2_OMEGA_DOT_MSB)); + + // Set system flags for message reception + flag_sf1_p8 = true; + break; + case 9: + d_OMEGA_DOT_lsb = static_cast(read_navigation_signed(subframe_bits, D2_OMEGA_DOT_LSB)); + d_OMEGA0 = static_cast(read_navigation_signed(subframe_bits, D2_OMEGA0))*D1_OMEGA0_LSB; + d_OMEGA_msb = static_cast(read_navigation_signed(subframe_bits, D2_OMEGA_MSB)); + + // Set system flags for message reception + flag_sf1_p9 = true; + break; + case 10: + d_OMEGA_lsb = static_cast(read_navigation_signed(subframe_bits, D2_OMEGA_LSB)); + d_IDOT = static_cast(read_navigation_signed(subframe_bits, D1_IDOT))*D1_IDOT_LSB; + + // Set system flags for message reception + flag_sf1_p10 = true; + break; + default: + break; + } + + break; + + case 2: //--- It is subframe 2 ------------------- + + break; + + case 3: // --- It is subframe 3 ------------------------------------- + + + break; + + case 4: // --- It is subframe 4 ---------- Almanac, ionospheric model, UTC parameters, SV health (PRN: 25-32) + d_SOW_SF4 = static_cast(read_navigation_unsigned(subframe_bits, D1_SOW)); + d_SOW = d_SOW_SF4; // Set transmission time + + d_SQRT_A_ALMANAC = static_cast(read_navigation_unsigned(subframe_bits, D1_SQRT_A_ALMANAC)); + d_SQRT_A_ALMANAC = d_SQRT_A_ALMANAC * D1_SQRT_A_ALMANAC_LSB; + + d_A1_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_A1_ALMANAC)); + d_A1_ALMANAC = d_A1_ALMANAC * D1_A1_ALMANAC_LSB; + + d_A0_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_A0_ALMANAC)); + d_A0_ALMANAC = d_A0_ALMANAC * D1_A0_ALMANAC_LSB; + + d_OMEGA0_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA0_ALMANAC)); + d_OMEGA0_ALMANAC = d_OMEGA0_ALMANAC * D1_OMEGA0_ALMANAC_LSB; + + d_E_ALMANAC = static_cast(read_navigation_unsigned(subframe_bits, D1_E)); + d_E_ALMANAC = d_E_ALMANAC * D1_E_ALMANAC_LSB; + + d_DELTA_I = static_cast(read_navigation_signed(subframe_bits, D1_DELTA_I)); + d_DELTA_I = D1_DELTA_I_LSB; + + d_TOA = static_cast(read_navigation_unsigned(subframe_bits, D1_TOA)); + d_TOA = d_TOA * D1_TOA_LSB; + + d_OMEGA_DOT_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA_DOT_ALMANAC)); + d_OMEGA_DOT_ALMANAC = D1_OMEGA_DOT_ALMANAC_LSB; + + d_OMEGA_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA_ALMANAC)); + d_OMEGA_ALMANAC = d_OMEGA_ALMANAC * D1_OMEGA_ALMANAC_LSB; + + d_M0_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_M0)); + d_M0_ALMANAC = d_M0_ALMANAC * D1_M0_ALMANAC_LSB; + + // Set system flags for message reception + flag_sf_4 = true; + flag_new_SOW_available = true; + + break; + + case 5://--- It is subframe 5 -----------------almanac health (PRN: 1-24) and Almanac reference week number and time. + int SV_page_5; + d_SOW_SF5 = static_cast(read_navigation_unsigned(subframe_bits, D1_SOW)); + d_SOW = d_SOW_SF5; // Set transmission time + + SV_page_5 = static_cast(read_navigation_unsigned(subframe_bits, D1_PNUM)); + + if (SV_page_5 < 7) + { + d_SOW_SF4 = static_cast(read_navigation_unsigned(subframe_bits, D1_SOW)); + d_SQRT_A_ALMANAC = static_cast(read_navigation_unsigned(subframe_bits, D1_SQRT_A_ALMANAC)); + d_SQRT_A_ALMANAC = d_SQRT_A_ALMANAC * D1_SQRT_A_ALMANAC_LSB; + + d_A1_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_A1_ALMANAC)); + d_A1_ALMANAC = d_A1_ALMANAC * D1_A1_ALMANAC_LSB; + + d_A0_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_A0_ALMANAC)); + d_A0_ALMANAC = d_A0_ALMANAC * D1_A0_ALMANAC_LSB; + + d_OMEGA0_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA0_ALMANAC)); + d_OMEGA0_ALMANAC = d_OMEGA0_ALMANAC * D1_OMEGA0_ALMANAC_LSB; + + d_E_ALMANAC = static_cast(read_navigation_unsigned(subframe_bits, D1_E)); + d_E_ALMANAC = d_E_ALMANAC * D1_E_ALMANAC_LSB; + + d_DELTA_I = static_cast(read_navigation_signed(subframe_bits, D1_DELTA_I)); + d_DELTA_I = D1_DELTA_I_LSB; + + d_TOA = static_cast(read_navigation_unsigned(subframe_bits, D1_TOA)); + d_TOA = d_TOA * D1_TOA_LSB; + + d_OMEGA_DOT_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA_DOT_ALMANAC)); + d_OMEGA_DOT_ALMANAC = D1_OMEGA_DOT_ALMANAC_LSB; + + d_OMEGA_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA_ALMANAC)); + d_OMEGA_ALMANAC = d_OMEGA_ALMANAC * D1_OMEGA_ALMANAC_LSB; + + d_M0_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_M0)); + d_M0_ALMANAC = d_M0_ALMANAC * D1_M0_ALMANAC_LSB; + + } + + if (SV_page_5 == 7) + { + //! \TODO read almanac + almanacHealth[1] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA1)); + almanacHealth[2] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA2)); + almanacHealth[3] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA3)); + almanacHealth[4] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA4)); + almanacHealth[5] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA5)); + almanacHealth[6] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA6)); + almanacHealth[7] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA7)); + almanacHealth[8] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA8)); + almanacHealth[9] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA9)); + almanacHealth[10] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA10)); + almanacHealth[11] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA11)); + almanacHealth[12] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA12)); + almanacHealth[13] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA13)); + almanacHealth[14] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA14)); + almanacHealth[15] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA15)); + almanacHealth[16] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA16)); + almanacHealth[17] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA17)); + almanacHealth[18] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA18)); + almanacHealth[19] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA19)); + } + if (SV_page_5 == 8) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110) + { + almanacHealth[20] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA20)); + almanacHealth[21] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA21)); + almanacHealth[22] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA22)); + almanacHealth[23] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA23)); + almanacHealth[24] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA24)); + almanacHealth[25] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA25)); + almanacHealth[26] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA26)); + almanacHealth[27] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA27)); + almanacHealth[28] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA28)); + almanacHealth[29] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA29)); + almanacHealth[30] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA30)); + almanac_WN = static_cast(read_navigation_unsigned(subframe_bits, D1_WNA)); + d_toa2 = static_cast(read_navigation_unsigned(subframe_bits, D1_TOA2)); + + } + + if (SV_page_5 == 9) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110) + { + d_A0GPS = static_cast(read_navigation_signed(subframe_bits, D1_A0GPS)); + d_A0GPS = d_A0GPS * D1_A0GPS_LSB; + + d_A1GPS = static_cast(read_navigation_signed(subframe_bits, D1_A1GPS)); + d_A1GPS = d_A1GPS * D1_A1GPS_LSB; + + d_A0GAL = static_cast(read_navigation_signed(subframe_bits, D1_A0GAL)); + d_A0GAL = d_A0GAL * D1_A0GAL_LSB; + + d_A1GAL = static_cast(read_navigation_signed(subframe_bits, D1_A1GAL)); + d_A1GAL = d_A1GAL* D1_A1GAL_LSB; + + d_A0GLO = static_cast(read_navigation_signed(subframe_bits, D1_A0GLO)); + d_A0GLO = d_A0GLO * D1_A0GLO_LSB; + + d_A1GLO = static_cast(read_navigation_signed(subframe_bits, D1_A1GLO)); + d_A1GLO = d_A1GLO* D1_A1GLO_LSB; + } + if (SV_page_5 == 10) + { + d_DeltaT_LS = static_cast(read_navigation_signed(subframe_bits, D1_DELTA_T_LS)); + d_DeltaT_LSF = static_cast(read_navigation_signed(subframe_bits, D1_DELTA_T_LSF)); + i_WN_LSF = static_cast(read_navigation_signed(subframe_bits, D1_WN_LSF)); + d_A0UTC = static_cast(read_navigation_signed(subframe_bits, D1_A0UTC)); + d_A0UTC = d_A0GPS * D1_A0GPS_LSB; + d_A1UTC = static_cast(read_navigation_signed(subframe_bits, D1_A1UTC)); + d_A1UTC = d_A1UTC * D1_A1UTC_LSB; + } + + // Set system flags for message reception + flag_sf_5 = true; + flag_new_SOW_available = true; + + break; + + default: + break; + } // switch subframeID ... + + return subframe_ID; +} + double Beidou_Dnav_Navigation_Message::utc_time(const double beidoutime_corrected) const { double t_utc; @@ -822,7 +1147,7 @@ Beidou_Dnav_Ephemeris Beidou_Dnav_Navigation_Message::get_ephemeris() ephemeris.d_Delta_n = d_Delta_n; ephemeris.d_M_0 = d_M_0; ephemeris.d_Cuc = d_Cuc; - ephemeris.d_e_eccentricity = d_e_eccentricity; + ephemeris.d_e_eccentricity = d_eccentricity; ephemeris.d_Cus = d_Cus; ephemeris.d_sqrt_A = d_sqrt_A; ephemeris.d_Toe = ((d_Toe_sf2 + d_Toe_sf3) * D1_TOE_LSB) ; @@ -900,13 +1225,13 @@ Beidou_Dnav_Utc_Model Beidou_Dnav_Navigation_Message::get_utc_model() bool Beidou_Dnav_Navigation_Message::have_new_ephemeris() // Check if we have a new ephemeris stored in the galileo navigation class { - if ((flag_sf_1 == true) and (flag_sf_2 == true) and (flag_sf_3 == true)) + if ((flag_sf1 == true) and (flag_sf2 == true) and (flag_sf_3 == true)) { // if all ephemeris pages have the same IOD, then they belong to the same block if (d_previous_aode != d_AODE) { - flag_sf_1 = false; // clear the flag - flag_sf_2 = false; // clear the flag + flag_sf1 = false; // clear the flag + flag_sf2 = false; // clear the flag flag_sf_3 = false; // clear the flag flag_eph_valid = true; // Update the time of ephemeris information diff --git a/src/core/system_parameters/beidou_dnav_navigation_message.h b/src/core/system_parameters/beidou_dnav_navigation_message.h index 6ffdb882a..accd440a6 100644 --- a/src/core/system_parameters/beidou_dnav_navigation_message.h +++ b/src/core/system_parameters/beidou_dnav_navigation_message.h @@ -1,7 +1,8 @@ /*! * \file beidou_navigation_message.h - * \brief Interface of a BeiDou D1 NAV Data message decoder + * \brief Interface of a BeiDou DNAV Data message decoder * \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com + * \author Damian Miralles, 2018. dmiralles2009@gmail.com * * ------------------------------------------------------------------------- * @@ -72,8 +73,8 @@ public: bool flag_eph_valid; bool flag_utc_model_valid; bool flag_iono_valid; - bool flag_sf_1; - bool flag_sf_2; + bool flag_sf1; + bool flag_sf2; bool flag_sf_3; bool flag_sf_4; bool flag_sf_5; @@ -81,6 +82,17 @@ public: bool flag_crc_test; double d_previous_aode; + bool flag_sf1_p1; //!< D2 NAV Message, Subframe 1, Pagge 1 decoded indicator + bool flag_sf1_p2; //!< D2 NAV Message, Subframe 1, Pagge 2 decoded indicator + bool flag_sf1_p3; //!< D2 NAV Message, Subframe 1, Pagge 3 decoded indicator + bool flag_sf1_p4; //!< D2 NAV Message, Subframe 1, Pagge 4 decoded indicator + bool flag_sf1_p5; //!< D2 NAV Message, Subframe 1, Pagge 5 decoded indicator + bool flag_sf1_p6; //!< D2 NAV Message, Subframe 1, Pagge 6 decoded indicator + bool flag_sf1_p7; //!< D2 NAV Message, Subframe 1, Pagge 7 decoded indicator + bool flag_sf1_p8; //!< D2 NAV Message, Subframe 1, Pagge 8 decoded indicator + bool flag_sf1_p9; //!< D2 NAV Message, Subframe 1, Pagge 9 decoded indicator + bool flag_sf1_p10; //!< D2 NAV Message, Subframe 1, Pagge 10 decoded indicator + //broadcast orbit 1 double d_SOW; //!< Time of BeiDou Week of the ephemeris set (taken from subframes SOW) [s] double d_SOW_SF1; //!< Time of BeiDou Week from HOW word of Subframe 1 [s] @@ -95,13 +107,13 @@ public: double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles] //broadcast orbit 2 double d_Cuc; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] - double d_e_eccentricity; //!< Eccentricity [dimensionless] + double d_eccentricity; //!< Eccentricity [dimensionless] double d_Cus; //!< Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad] double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)] //broadcast orbit 3 - double d_Toe_sf2; //!< Ephemeris data reference time of week in subframe 2 - double d_Toe_sf3; //!< Ephemeris data reference time of week in subframe 3 - double d_Toe2; + double d_Toe_sf2; //!< Ephemeris data reference time of week in subframe 2, D1 Message + double d_Toe_sf3; //!< Ephemeris data reference time of week in subframe 3, D1 Message + double d_Toe; //!< Ephemeris data reference time of week in subframe 1, D2 Message double d_Toc; //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s] double d_Cic; //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad] double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] @@ -131,11 +143,27 @@ public: double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s] double d_A_f2; //!< Coefficient 2 of code phase offset model [s/s^2] - double d_a0; - double d_a1; - double d_a2; + double d_a0; //!< Clock correction parameters + double d_a1; //!< Clock correction parameters + double d_a2; //!< Clock correction parameters - // Almanac + // D2 NAV Message Decoding + double d_a1_msb; //!< Clock correction parameters, D2 NAV MSB + double d_a1_lsb; //!< Clock correction parameters, D2 NAV LSB + double d_Cuc_msb; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] + double d_Cuc_lsb; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] + double d_eccentricity_msb; //!< Eccentricity [dimensionless] + double d_eccentricity_lsb; //!< Eccentricity [dimensionless] + double d_Cic_msb; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] + double d_Cic_lsb; //!< Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude [rad] + double d_i_0_msb; //!< Inclination Angle at Reference Time [semi-circles] + double d_i_0_lsb; //!< Inclination Angle at Reference Time [semi-circles] + double d_OMEGA_msb; //!< Argument of Perigee [semi-cicles] + double d_OMEGA_lsb; //!< Argument of Perigee [semi-cicles] + double d_OMEGA_DOT_msb; //!< Rate of Right Ascension [semi-circles/s] + double d_OMEGA_DOT_lsb; //!< Rate of Right Ascension [semi-circles/s] + + // Almanac double d_Toa; //!< Almanac reference time [s] int i_WN_A; //!< Modulo 256 of the GPS week number to which the almanac reference time (d_Toa) is referenced std::map almanacHealth; //!< Map that stores the health information stored in the almanac @@ -242,9 +270,14 @@ public: /*! - * \brief Decodes the GPS NAV message + * \brief Decodes the BDS D1 NAV message */ - int subframe_decoder(std::string const &subframe); + int d1_subframe_decoder(std::string const &subframe); + + /*! + * \brief Decodes the BDS D2 NAV message + */ + int d2_subframe_decoder(std::string const &subframe); /*! * \brief Computes the position of the satellite