bds_b1i: Adding support for d2 nav decoding

This commit is contained in:
Damian Miralles
2018-12-26 12:54:23 -06:00
parent 7cdd2ee477
commit 7cef679744
12 changed files with 637 additions and 1222 deletions
@@ -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<int32_t *>(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<int32_t *>(volk_gnsssdr_malloc(BEIDOU_B1I_SECONDARY_CODE_LENGTH * sizeof(int32_t), volk_gnsssdr_get_alignment()));
d_preamble_samples = static_cast<int32_t *>(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<double *>(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<int32_t *>(volk_gnsssdr_malloc(BEIDOU_B1I_SECONDARY_CODE_LENGTH * sizeof(int32_t), volk_gnsssdr_get_alignment()));
d_preamble_samples = static_cast<int32_t *>(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<double *>(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<double *>(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<float>(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<float>(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<float>(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<float>(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;
@@ -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 <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "beidou_b1i_telemetry_decoder_cc_old.h"
#include "control_message_factory.h"
#include <boost/lexical_cast.hpp>
#include <glog/logging.h>
#include <gnuradio/io_signature.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
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<int *>(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<uint32_t>(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<std::string>(d_channel));
d_dump_filename.append(".dat");
d_dump_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel
<< " Log file: " << d_dump_filename.c_str();
}
catch (const std::ifstream::failure &e)
{
LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what();
}
}
}
}
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<signed int> *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<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer
const Gnss_Synchro **in = reinterpret_cast<const Gnss_Synchro **>(&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<double>(current_time_samples) - d_preamble_time_samples) / static_cast<double>(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<double>(d_preamble_time_samples) / static_cast<double>(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<double>(current_time_samples) - static_cast<double>(d_preamble_time_samples)) / static_cast<double>(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<Beidou_Dnav_Ephemeris> tmp_obj = std::make_shared<Beidou_Dnav_Ephemeris>(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<Beidou_Dnav_Iono> tmp_obj = std::make_shared<Beidou_Dnav_Iono>(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<Beidou_Dnav_Utc_Model> tmp_obj = std::make_shared<Beidou_Dnav_Utc_Model>(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<unsigned int>(d_BEIDOU_FSM.d_nav.d_SOW +14) * 1000 ;
d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((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<double>(d_TOW_at_current_symbol_ms) / 1000.0;
d_dump_file.write(reinterpret_cast<char *>(&tmp_double), sizeof(double));
tmp_ulong_int = current_symbol.Tracking_sample_counter;
d_dump_file.write(reinterpret_cast<char *>(&tmp_ulong_int), sizeof(unsigned long int));
tmp_double = static_cast<double>(d_TOW_at_Preamble_ms) * 1000.0;
d_dump_file.write(reinterpret_cast<char *>(&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;
}
@@ -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 <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#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 <gnuradio/block.h>
#include <fstream>
#include <string>
#include <boost/circular_buffer.hpp>
#include "Beidou_B1I.h"
class beidou_b1i_telemetry_decoder_cc;
typedef boost::shared_ptr<beidou_b1i_telemetry_decoder_cc> 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<signed int> *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<signed int> d_symbol_history;
boost::circular_buffer<signed int> d_symbol_nh_history;
boost::circular_buffer<signed int> 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