mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-07-07 12:32:57 +00:00
Improving documentation and some code cleaning
git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@446 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
parent
6eabb93de7
commit
a7b1f71566
@ -47,21 +47,21 @@ FirFilter::FirFilter(ConfigurationInterface* configuration, std::string role,
|
|||||||
size_t item_size;
|
size_t item_size;
|
||||||
(*this).init();
|
(*this).init();
|
||||||
if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("gr_complex") == 0)
|
if ((taps_item_type_.compare("float") == 0) && (input_item_type_.compare("gr_complex") == 0)
|
||||||
&& (output_item_type_.compare("gr_complex") == 0))
|
&& (output_item_type_.compare("gr_complex") == 0))
|
||||||
{
|
{
|
||||||
item_size = sizeof(gr_complex);
|
item_size = sizeof(gr_complex);
|
||||||
fir_filter_ccf_ = gr::filter::fir_filter_ccf::make(1, taps_);
|
fir_filter_ccf_ = gr::filter::fir_filter_ccf::make(1, taps_);
|
||||||
DLOG(INFO) << "input_filter(" << fir_filter_ccf_->unique_id() << ")";
|
DLOG(INFO) << "input_filter(" << fir_filter_ccf_->unique_id() << ")";
|
||||||
}
|
if (dump_)
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_AT_LEVEL(ERROR) << taps_item_type_ << " unknown input filter item type";
|
|
||||||
}
|
|
||||||
if (dump_)
|
|
||||||
{
|
{
|
||||||
DLOG(INFO) << "Dumping output into file " << dump_filename_;
|
DLOG(INFO) << "Dumping output into file " << dump_filename_;
|
||||||
file_sink_ = gr::blocks::file_sink::make(item_size, dump_filename_.c_str());
|
file_sink_ = gr::blocks::file_sink::make(item_size, dump_filename_.c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_AT_LEVEL(ERROR) << taps_item_type_ << " unknown input filter item type";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ using google::LogMessage;
|
|||||||
FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration, std::string role,
|
FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration, std::string role,
|
||||||
unsigned int in_streams, unsigned int out_streams,
|
unsigned int in_streams, unsigned int out_streams,
|
||||||
boost::shared_ptr<gr::msg_queue> queue) :
|
boost::shared_ptr<gr::msg_queue> queue) :
|
||||||
config_(configuration), role_(role), in_streams_(in_streams),
|
config_(configuration), role_(role), in_streams_(in_streams),
|
||||||
out_streams_(out_streams), queue_(queue)
|
out_streams_(out_streams), queue_(queue)
|
||||||
{
|
{
|
||||||
size_t item_size;
|
size_t item_size;
|
||||||
(*this).init();
|
(*this).init();
|
||||||
@ -55,7 +55,7 @@ FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration
|
|||||||
&& (output_item_type_.compare("gr_complex") == 0))
|
&& (output_item_type_.compare("gr_complex") == 0))
|
||||||
{
|
{
|
||||||
item_size = sizeof(gr_complex); //output
|
item_size = sizeof(gr_complex); //output
|
||||||
input_size_=sizeof(gr_complex); //input
|
input_size_ = sizeof(gr_complex); //input
|
||||||
freq_xlating_fir_filter_ccf_ = gr::filter::freq_xlating_fir_filter_ccf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_);
|
freq_xlating_fir_filter_ccf_ = gr::filter::freq_xlating_fir_filter_ccf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_);
|
||||||
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_ccf_->unique_id() << ")";
|
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_ccf_->unique_id() << ")";
|
||||||
}
|
}
|
||||||
@ -63,19 +63,20 @@ FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration
|
|||||||
&& (output_item_type_.compare("gr_complex") == 0))
|
&& (output_item_type_.compare("gr_complex") == 0))
|
||||||
{
|
{
|
||||||
item_size = sizeof(gr_complex);
|
item_size = sizeof(gr_complex);
|
||||||
input_size_=sizeof(float); //input
|
input_size_ = sizeof(float); //input
|
||||||
freq_xlating_fir_filter_fcf_ = gr::filter::freq_xlating_fir_filter_fcf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_);
|
freq_xlating_fir_filter_fcf_ = gr::filter::freq_xlating_fir_filter_fcf::make(decimation_factor, taps_, intermediate_freq_, sampling_freq_);
|
||||||
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_fcf_->unique_id() << ")";
|
DLOG(INFO) << "input_filter(" << freq_xlating_fir_filter_fcf_->unique_id() << ")";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_AT_LEVEL(ERROR) << taps_item_type_ << " unknown input filter item type";
|
LOG_AT_LEVEL(ERROR) << taps_item_type_ << " unknown input filter item type";
|
||||||
|
item_size = sizeof(gr_complex); //avoids unitialization
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump_)
|
if (dump_)
|
||||||
{
|
{
|
||||||
DLOG(INFO) << "Dumping output into file " << dump_filename_;
|
DLOG(INFO) << "Dumping output into file " << dump_filename_;
|
||||||
std::cout<<"Dumping output into file " << dump_filename_<<std::endl;
|
std::cout << "Dumping output into file " << dump_filename_ << std::endl;
|
||||||
file_sink_ = gr::blocks::file_sink::make(item_size, dump_filename_.c_str());
|
file_sink_ = gr::blocks::file_sink::make(item_size, dump_filename_.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,12 +92,14 @@ void FreqXlatingFirFilter::connect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (dump_)
|
if (dump_)
|
||||||
{
|
{
|
||||||
if (input_size_==sizeof(float))
|
if (input_size_ == sizeof(float))
|
||||||
{
|
{
|
||||||
top_block->connect(freq_xlating_fir_filter_fcf_, 0, file_sink_, 0);
|
top_block->connect(freq_xlating_fir_filter_fcf_, 0, file_sink_, 0);
|
||||||
}else{
|
}
|
||||||
top_block->connect(freq_xlating_fir_filter_ccf_, 0, file_sink_, 0);
|
else
|
||||||
}
|
{
|
||||||
|
top_block->connect(freq_xlating_fir_filter_ccf_, 0, file_sink_, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -110,12 +113,14 @@ void FreqXlatingFirFilter::disconnect(gr::top_block_sptr top_block)
|
|||||||
{
|
{
|
||||||
if (dump_)
|
if (dump_)
|
||||||
{
|
{
|
||||||
if (input_size_==sizeof(float))
|
if (input_size_ == sizeof(float))
|
||||||
{
|
{
|
||||||
top_block->disconnect(freq_xlating_fir_filter_fcf_, 0, file_sink_, 0);
|
top_block->disconnect(freq_xlating_fir_filter_fcf_, 0, file_sink_, 0);
|
||||||
}else{
|
}
|
||||||
top_block->disconnect(freq_xlating_fir_filter_ccf_, 0, file_sink_, 0);
|
else
|
||||||
}
|
{
|
||||||
|
top_block->disconnect(freq_xlating_fir_filter_ccf_, 0, file_sink_, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -123,24 +128,28 @@ void FreqXlatingFirFilter::disconnect(gr::top_block_sptr top_block)
|
|||||||
|
|
||||||
gr::basic_block_sptr FreqXlatingFirFilter::get_left_block()
|
gr::basic_block_sptr FreqXlatingFirFilter::get_left_block()
|
||||||
{
|
{
|
||||||
if (input_size_==sizeof(float))
|
if (input_size_ == sizeof(float))
|
||||||
{
|
{
|
||||||
return freq_xlating_fir_filter_fcf_;
|
return freq_xlating_fir_filter_fcf_;
|
||||||
}else{
|
}
|
||||||
return freq_xlating_fir_filter_ccf_;
|
else
|
||||||
}
|
{
|
||||||
|
return freq_xlating_fir_filter_ccf_;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gr::basic_block_sptr FreqXlatingFirFilter::get_right_block()
|
gr::basic_block_sptr FreqXlatingFirFilter::get_right_block()
|
||||||
{
|
{
|
||||||
if (input_size_==sizeof(float))
|
if (input_size_ == sizeof(float))
|
||||||
{
|
{
|
||||||
return freq_xlating_fir_filter_fcf_;
|
return freq_xlating_fir_filter_fcf_;
|
||||||
}else{
|
}
|
||||||
return freq_xlating_fir_filter_ccf_;
|
else
|
||||||
}
|
{
|
||||||
|
return freq_xlating_fir_filter_ccf_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file galileo_l1_ca_telemetry_decoder.cc
|
* \file galileo_e1b_telemetry_decoder.cc
|
||||||
* \brief Implementation of an adapter of a Galileo INAV data decoder block
|
* \brief Implementation of an adapter of a Galileo INAV data decoder block
|
||||||
* to a TelemetryDecoderInterface
|
* to a TelemetryDecoderInterface
|
||||||
* \author Javier Arribas 2013. jarribas(at)cttc.es
|
* \author Javier Arribas 2013. jarribas(at)cttc.es,
|
||||||
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
|
* Mara Branzanti 2013. mara.branzanti(at)gmail.com
|
||||||
*
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
|
* Copyright (C) 2010-2013 (see AUTHORS file for a list of contributors)
|
||||||
*
|
*
|
||||||
* GNSS-SDR is a software defined Global Navigation
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
* Satellite Systems receiver
|
* Satellite Systems receiver
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file galileo_l1_ca_telemetry_decoder.h
|
* \file galileo_e1b_telemetry_decoder.h
|
||||||
* \brief Interface of an adapter of a GALILEO E1B NAV data decoder block
|
* \brief Interface of an adapter of a GALILEO E1B NAV data decoder block
|
||||||
* to a TelemetryDecoderInterface
|
* to a TelemetryDecoderInterface
|
||||||
* \author Javier Arribas 2013. jarribas(at)cttc.es * \author Javier Arribas 2013. jarribas(at)cttc.es
|
* \author Javier Arribas 2013 jarribas(at)cttc.es,
|
||||||
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
|
* Mara Branzanti 2013. mara.branzanti(at)gmail.com
|
||||||
*
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
@ -59,6 +59,9 @@ public:
|
|||||||
return role_;
|
return role_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns "Galileo_E1B_Telemetry_Decoder"
|
||||||
|
*/
|
||||||
std::string implementation()
|
std::string implementation()
|
||||||
{
|
{
|
||||||
return "Galileo_E1B_Telemetry_Decoder";
|
return "Galileo_E1B_Telemetry_Decoder";
|
||||||
|
@ -41,9 +41,7 @@
|
|||||||
#include "control_message_factory.h"
|
#include "control_message_factory.h"
|
||||||
#include "galileo_navigation_message.h"
|
#include "galileo_navigation_message.h"
|
||||||
#include "gnss_synchro.h"
|
#include "gnss_synchro.h"
|
||||||
|
|
||||||
#include "convolutional.h"
|
#include "convolutional.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -56,461 +54,489 @@ galileo_e1b_telemetry_decoder_cc_sptr
|
|||||||
galileo_e1b_make_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, long fs_in, unsigned
|
galileo_e1b_make_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, long fs_in, unsigned
|
||||||
int vector_length, boost::shared_ptr<gr::msg_queue> queue, bool dump)
|
int vector_length, boost::shared_ptr<gr::msg_queue> queue, bool dump)
|
||||||
{
|
{
|
||||||
return galileo_e1b_telemetry_decoder_cc_sptr(new galileo_e1b_telemetry_decoder_cc(satellite, if_freq,
|
return galileo_e1b_telemetry_decoder_cc_sptr(new galileo_e1b_telemetry_decoder_cc(satellite, if_freq,
|
||||||
fs_in, vector_length, queue, dump));
|
fs_in, vector_length, queue, dump));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1b_telemetry_decoder_cc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
|
void galileo_e1b_telemetry_decoder_cc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
|
||||||
{
|
{
|
||||||
ninput_items_required[0] = GALILEO_INAV_PAGE_SYMBOLS; //set the required sample history
|
ninput_items_required[0] = GALILEO_INAV_PAGE_SYMBOLS; //set the required sample history
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1b_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int *page_part_bits)
|
void galileo_e1b_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int *page_part_bits)
|
||||||
{
|
{
|
||||||
|
int CodeLength = 240;
|
||||||
|
int DataLength;
|
||||||
|
int nn, KK, mm, max_states;
|
||||||
|
int g_encoder[2];
|
||||||
|
|
||||||
int CodeLength=240;
|
nn = 2; //Coding rate 1/n
|
||||||
int DataLength;
|
KK = 7; //Constraint Length
|
||||||
int nn, KK, mm, max_states;
|
g_encoder[0] = 121; // Polynomial G1
|
||||||
int g_encoder[2];
|
g_encoder[1] = 91; // Polinomial G2
|
||||||
|
|
||||||
nn = 2; //Coding rate 1/n
|
mm = KK - 1;
|
||||||
KK = 7; //Constraint Length
|
max_states = 1 << mm; /* 2^mm */
|
||||||
g_encoder[0]=121; // Polynomial G1
|
DataLength = (CodeLength/nn) - mm;
|
||||||
g_encoder[1]=91; // Polinomial G2
|
|
||||||
|
|
||||||
mm = KK - 1;
|
/* create appropriate transition matrices */
|
||||||
max_states = 1 << mm; /* 2^mm */
|
int *out0, *out1, *state0, *state1;
|
||||||
DataLength = (CodeLength/nn)-mm;
|
out0 = (int*)calloc( max_states, sizeof(int) );
|
||||||
|
out1 = (int*)calloc( max_states, sizeof(int) );
|
||||||
|
state0 = (int*)calloc( max_states, sizeof(int) );
|
||||||
|
state1 = (int*)calloc( max_states, sizeof(int) );
|
||||||
|
|
||||||
/* create appropriate transition matrices */
|
nsc_transit( out0, state0, 0, g_encoder, KK, nn );
|
||||||
int *out0, *out1, *state0, *state1;
|
nsc_transit( out1, state1, 1, g_encoder, KK, nn );
|
||||||
out0 = (int*)calloc( max_states, sizeof(int) );
|
|
||||||
out1 = (int*)calloc( max_states, sizeof(int) );
|
|
||||||
state0 = (int*)calloc( max_states, sizeof(int) );
|
|
||||||
state1 = (int*)calloc( max_states, sizeof(int) );
|
|
||||||
|
|
||||||
nsc_transit( out0, state0, 0, g_encoder, KK, nn );
|
Viterbi( page_part_bits, out0, state0, out1, state1,
|
||||||
nsc_transit( out1, state1, 1, g_encoder, KK, nn );
|
page_part_symbols, KK, nn, DataLength );
|
||||||
|
|
||||||
Viterbi( page_part_bits, out0, state0, out1, state1,
|
|
||||||
page_part_symbols, KK, nn, DataLength );
|
|
||||||
|
|
||||||
|
|
||||||
/* Clean up memory */
|
/* Clean up memory */
|
||||||
free( out0 );
|
free( out0 );
|
||||||
free( out1 );
|
free( out1 );
|
||||||
free( state0 );
|
free( state0 );
|
||||||
free( state1 );
|
free( state1 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1b_telemetry_decoder_cc::deinterleaver(int rows, int cols, double *in, double *out)
|
void galileo_e1b_telemetry_decoder_cc::deinterleaver(int rows, int cols, double *in, double *out)
|
||||||
{
|
{
|
||||||
for (int r=0;r<rows;r++)
|
for (int r = 0; r < rows; r++)
|
||||||
{
|
{
|
||||||
for(int c=0;c<cols;c++)
|
for(int c = 0; c < cols; c++)
|
||||||
{
|
{
|
||||||
out[c*rows+r]=in[r*cols+c];
|
out[c*rows + r] = in[r*cols + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
galileo_e1b_telemetry_decoder_cc::galileo_e1b_telemetry_decoder_cc(
|
galileo_e1b_telemetry_decoder_cc::galileo_e1b_telemetry_decoder_cc(
|
||||||
Gnss_Satellite satellite,
|
Gnss_Satellite satellite,
|
||||||
long if_freq,
|
long if_freq,
|
||||||
long fs_in,
|
long fs_in,
|
||||||
unsigned
|
unsigned
|
||||||
int vector_length,
|
int vector_length,
|
||||||
boost::shared_ptr<gr::msg_queue> queue,
|
boost::shared_ptr<gr::msg_queue> queue,
|
||||||
bool dump) :
|
bool dump) :
|
||||||
gr::block("galileo_e1b_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
|
gr::block("galileo_e1b_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
|
||||||
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
|
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
|
||||||
{
|
{
|
||||||
// initialize internal vars
|
// initialize internal vars
|
||||||
d_queue = queue;
|
d_queue = queue;
|
||||||
d_dump = dump;
|
d_dump = dump;
|
||||||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||||
DLOG(INFO) << "GALILEO E1B TELEMETRY PROCESSING: satellite " << d_satellite;
|
DLOG(INFO) << "GALILEO E1B TELEMETRY PROCESSING: satellite " << d_satellite;
|
||||||
d_vector_length = vector_length;
|
d_vector_length = vector_length;
|
||||||
d_samples_per_symbol = ( Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS ) / Galileo_E1_B_SYMBOL_RATE_BPS;
|
d_samples_per_symbol = ( Galileo_E1_CODE_CHIP_RATE_HZ / Galileo_E1_B_CODE_LENGTH_CHIPS ) / Galileo_E1_B_SYMBOL_RATE_BPS;
|
||||||
d_fs_in = fs_in;
|
d_fs_in = fs_in;
|
||||||
|
|
||||||
// set the preamble
|
// set the preamble
|
||||||
unsigned short int preambles_bits[GALILEO_INAV_PREAMBLE_LENGTH_BITS]=GALILEO_INAV_PREAMBLE;
|
unsigned short int preambles_bits[GALILEO_INAV_PREAMBLE_LENGTH_BITS] = GALILEO_INAV_PREAMBLE;
|
||||||
|
|
||||||
d_symbols_per_preamble=GALILEO_INAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol;
|
d_symbols_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol;
|
||||||
|
|
||||||
memcpy((unsigned short int*)this->d_preambles_bits, (unsigned short int*)preambles_bits, GALILEO_INAV_PREAMBLE_LENGTH_BITS*sizeof(unsigned short int));
|
memcpy((unsigned short int*)this->d_preambles_bits, (unsigned short int*)preambles_bits, GALILEO_INAV_PREAMBLE_LENGTH_BITS*sizeof(unsigned short int));
|
||||||
|
|
||||||
// preamble bits to sampled symbols
|
// preamble bits to sampled symbols
|
||||||
d_preambles_symbols = (signed int*)malloc(sizeof(signed int) * d_symbols_per_preamble);
|
d_preambles_symbols = (signed int*)malloc(sizeof(signed int) * d_symbols_per_preamble);
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (int i=0; i<GALILEO_INAV_PREAMBLE_LENGTH_BITS; i++)
|
for (int i = 0; i < GALILEO_INAV_PREAMBLE_LENGTH_BITS; i++)
|
||||||
{
|
{
|
||||||
for (unsigned int j=0; j<d_samples_per_symbol; j++)
|
for (unsigned int j = 0; j < d_samples_per_symbol; j++)
|
||||||
{
|
{
|
||||||
if (d_preambles_bits[i] == 1)
|
if (d_preambles_bits[i] == 1)
|
||||||
{
|
{
|
||||||
d_preambles_symbols[n] = 1;
|
d_preambles_symbols[n] = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_preambles_symbols[n] = -1;
|
d_preambles_symbols[n] = -1;
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d_sample_counter = 0;
|
d_sample_counter = 0;
|
||||||
d_stat = 0;
|
d_stat = 0;
|
||||||
d_preamble_index = 0;
|
d_preamble_index = 0;
|
||||||
|
|
||||||
d_preamble_time_seconds = 0;
|
d_preamble_time_seconds = 0;
|
||||||
d_flag_frame_sync = false;
|
d_flag_frame_sync = false;
|
||||||
|
|
||||||
d_flag_parity = false;
|
|
||||||
d_TOW_at_Preamble= 0;
|
|
||||||
d_TOW_at_current_symbol = 0;
|
|
||||||
|
|
||||||
d_CRC_error_counter=0;
|
|
||||||
|
|
||||||
|
d_flag_parity = false;
|
||||||
|
d_TOW_at_Preamble = 0;
|
||||||
|
d_TOW_at_current_symbol = 0;
|
||||||
|
|
||||||
|
d_CRC_error_counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
galileo_e1b_telemetry_decoder_cc::~galileo_e1b_telemetry_decoder_cc()
|
galileo_e1b_telemetry_decoder_cc::~galileo_e1b_telemetry_decoder_cc()
|
||||||
{
|
{
|
||||||
delete d_preambles_symbols;
|
delete d_preambles_symbols;
|
||||||
d_dump_file.close();
|
d_dump_file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols,int frame_length)
|
void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols,int frame_length)
|
||||||
{
|
{
|
||||||
double page_part_symbols_deint[frame_length];
|
double page_part_symbols_deint[frame_length];
|
||||||
// 1. De-interleave
|
// 1. De-interleave
|
||||||
deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS,GALILEO_INAV_INTERLEAVER_COLS,page_part_symbols, page_part_symbols_deint);
|
deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS, GALILEO_INAV_INTERLEAVER_COLS, page_part_symbols, page_part_symbols_deint);
|
||||||
|
|
||||||
// 2. Viterbi decoder
|
// 2. Viterbi decoder
|
||||||
// 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder)
|
// 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder)
|
||||||
// 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180º
|
// 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180¼
|
||||||
for (int i=0;i<frame_length;i++)
|
for (int i = 0; i < frame_length; i++)
|
||||||
{
|
{
|
||||||
if ((i+1)%2==0)
|
if ((i + 1) % 2 == 0)
|
||||||
{
|
{
|
||||||
page_part_symbols_deint[i]=-page_part_symbols_deint[i];
|
page_part_symbols_deint[i] = -page_part_symbols_deint[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int page_part_bits[frame_length/2];
|
int page_part_bits[frame_length/2];
|
||||||
viterbi_decoder(page_part_symbols_deint, page_part_bits);
|
viterbi_decoder(page_part_symbols_deint, page_part_bits);
|
||||||
|
|
||||||
// 3. Call the Galileo page decoder
|
// 3. Call the Galileo page decoder
|
||||||
|
|
||||||
std::string page_String;
|
std::string page_String;
|
||||||
|
|
||||||
for(int i=0; i < (frame_length/2); i++)
|
for(int i = 0; i < (frame_length/2); i++)
|
||||||
{
|
{
|
||||||
if (page_part_bits[i]>0)
|
if (page_part_bits[i] > 0)
|
||||||
{
|
{
|
||||||
page_String.push_back('1');
|
page_String.push_back('1');
|
||||||
}else{
|
}
|
||||||
page_String.push_back('0');
|
else
|
||||||
}
|
{
|
||||||
|
page_String.push_back('0');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//std::cout<<"ch["<<d_channel<<"] frame part bits: "<<page_String<<std::endl;
|
//std::cout<<"ch["<<d_channel<<"] frame part bits: "<<page_String<<std::endl;
|
||||||
if (page_part_bits[0]==1)
|
if (page_part_bits[0] == 1)
|
||||||
{
|
{
|
||||||
// DECODE COMPLETE WORD (even + odd) and TEST CRC
|
// DECODE COMPLETE WORD (even + odd) and TEST CRC
|
||||||
d_nav.split_page(page_String, flag_even_word_arrived);
|
d_nav.split_page(page_String, flag_even_word_arrived);
|
||||||
if(d_nav.flag_CRC_test==true)
|
if(d_nav.flag_CRC_test == true)
|
||||||
{
|
{
|
||||||
std::cout<<"Galileo CRC correct on channel "<<d_channel<<std::endl;
|
std::cout << "Galileo CRC correct on channel " << d_channel << std::endl;
|
||||||
}else{
|
}
|
||||||
std::cout<<"Galileo CRC error on channel "<<d_channel<<std::endl;
|
else
|
||||||
}
|
{
|
||||||
flag_even_word_arrived=0;
|
std::cout << "Galileo CRC error on channel " << d_channel << std::endl;
|
||||||
}
|
}
|
||||||
else
|
flag_even_word_arrived = 0;
|
||||||
{
|
}
|
||||||
// STORE HALF WORD (even page)
|
else
|
||||||
d_nav.split_page(page_String.c_str(), flag_even_word_arrived);
|
{
|
||||||
flag_even_word_arrived=1;
|
// STORE HALF WORD (even page)
|
||||||
}
|
d_nav.split_page(page_String.c_str(), flag_even_word_arrived);
|
||||||
|
flag_even_word_arrived = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// 4. Push the new navigation data to the queues
|
// 4. Push the new navigation data to the queues
|
||||||
|
|
||||||
if (d_nav.have_new_ephemeris()==true)
|
if (d_nav.have_new_ephemeris() == true)
|
||||||
{
|
{
|
||||||
// get ephemeris object for this SV
|
// get ephemeris object for this SV
|
||||||
Galileo_Ephemeris ephemeris=d_nav.get_ephemeris();//notice that the read operation will clear the valid flag
|
Galileo_Ephemeris ephemeris = d_nav.get_ephemeris();//notice that the read operation will clear the valid flag
|
||||||
//std::cout<<"New Galileo Ephemeris received for SV "<<d_satellite.get_PRN()<<std::endl;
|
//std::cout<<"New Galileo Ephemeris received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||||
d_ephemeris_queue->push(ephemeris);
|
d_ephemeris_queue->push(ephemeris);
|
||||||
}
|
}
|
||||||
if (d_nav.have_new_iono_and_GST()==true)
|
if (d_nav.have_new_iono_and_GST() == true)
|
||||||
{
|
{
|
||||||
Galileo_Iono iono=d_nav.get_iono(); //notice that the read operation will clear the valid flag
|
Galileo_Iono iono = d_nav.get_iono(); //notice that the read operation will clear the valid flag
|
||||||
//std::cout<<"New Galileo IONO model (and UTC) received for SV "<<d_satellite.get_PRN()<<std::endl;
|
//std::cout<<"New Galileo IONO model (and UTC) received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||||
d_iono_queue->push(iono);
|
d_iono_queue->push(iono);
|
||||||
}
|
}
|
||||||
if (d_nav.have_new_utc_model()==true)
|
if (d_nav.have_new_utc_model() == true)
|
||||||
{
|
{
|
||||||
Galileo_Utc_Model utc_model=d_nav.get_utc_model(); //notice that the read operation will clear the valid flag
|
Galileo_Utc_Model utc_model = d_nav.get_utc_model(); //notice that the read operation will clear the valid flag
|
||||||
//std::cout<<"New Galileo UTC model received for SV "<<d_satellite.get_PRN()<<std::endl;
|
//std::cout<<"New Galileo UTC model received for SV "<<d_satellite.get_PRN()<<std::endl;
|
||||||
d_utc_model_queue->push(utc_model);
|
d_utc_model_queue->push(utc_model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
|
int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
||||||
{
|
{
|
||||||
int corr_value = 0;
|
int corr_value = 0;
|
||||||
int preamble_diff = 0;
|
int preamble_diff = 0;
|
||||||
|
|
||||||
Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0];
|
Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0];
|
||||||
d_sample_counter++; //count for the processed samples
|
d_sample_counter++; //count for the processed samples
|
||||||
|
|
||||||
// ########### Output the tracking data to navigation and PVT ##########
|
// ########### Output the tracking data to navigation and PVT ##########
|
||||||
const Gnss_Synchro **in = (const Gnss_Synchro **) &input_items[0]; //Get the input samples pointer
|
const Gnss_Synchro **in = (const Gnss_Synchro **) &input_items[0]; //Get the input samples pointer
|
||||||
|
|
||||||
// TODO Optimize me!
|
// TODO Optimize me!
|
||||||
//******* preamble correlation ********
|
//******* preamble correlation ********
|
||||||
for (int i=0; i<d_symbols_per_preamble; i++)
|
for (int i = 0; i < d_symbols_per_preamble; i++)
|
||||||
{
|
{
|
||||||
if (in[0][i].Prompt_I < 0) // symbols clipping
|
if (in[0][i].Prompt_I < 0) // symbols clipping
|
||||||
{
|
{
|
||||||
corr_value -= d_preambles_symbols[i];
|
corr_value -= d_preambles_symbols[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
corr_value += d_preambles_symbols[i];
|
corr_value += d_preambles_symbols[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d_flag_preamble = false;
|
d_flag_preamble = false;
|
||||||
|
|
||||||
//******* frame sync ******************
|
//******* frame sync ******************
|
||||||
if (d_stat == 0) //no preamble information
|
if (d_stat == 0) //no preamble information
|
||||||
{
|
{
|
||||||
if (abs(corr_value) >= d_symbols_per_preamble)
|
if (abs(corr_value) >= d_symbols_per_preamble)
|
||||||
{
|
{
|
||||||
d_preamble_index = d_sample_counter;//record the preamble sample stamp
|
d_preamble_index = d_sample_counter;//record the preamble sample stamp
|
||||||
std::cout << "Preamble detection for Galileo SAT " << this->d_satellite << std::endl;
|
std::cout << "Preamble detection for Galileo SAT " << this->d_satellite << std::endl;
|
||||||
d_stat = 1; // enter into frame pre-detection status
|
d_stat = 1; // enter into frame pre-detection status
|
||||||
}
|
}
|
||||||
}else if (d_stat == 1) // posible preamble lock
|
}
|
||||||
{
|
else if (d_stat == 1) // posible preamble lock
|
||||||
if (abs(corr_value) >= d_symbols_per_preamble)
|
{
|
||||||
{
|
if (abs(corr_value) >= d_symbols_per_preamble)
|
||||||
//check preamble separation
|
{
|
||||||
preamble_diff = abs(d_sample_counter - d_preamble_index);
|
//check preamble separation
|
||||||
if (abs(preamble_diff - GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS) == 0)
|
preamble_diff = abs(d_sample_counter - d_preamble_index);
|
||||||
{
|
if (abs(preamble_diff - GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS) == 0)
|
||||||
//try to decode frame
|
{
|
||||||
std::cout<<"Starting page decoder for Galileo SAT " << this->d_satellite<<std::endl;
|
//try to decode frame
|
||||||
d_preamble_index=d_sample_counter;//record the preamble sample stamp
|
std::cout << "Starting page decoder for Galileo SAT " << this->d_satellite << std::endl;
|
||||||
d_stat=2;
|
d_preamble_index = d_sample_counter; //record the preamble sample stamp
|
||||||
}
|
d_stat = 2;
|
||||||
else{
|
}
|
||||||
if (preamble_diff>GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS)
|
else
|
||||||
{
|
{
|
||||||
d_stat=0; // start again
|
if (preamble_diff > GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS)
|
||||||
}
|
{
|
||||||
}
|
d_stat = 0; // start again
|
||||||
}
|
}
|
||||||
}else if (d_stat==2)
|
}
|
||||||
{
|
}
|
||||||
if (d_sample_counter==d_preamble_index+GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS)
|
}
|
||||||
{
|
else if (d_stat == 2)
|
||||||
// NEW Galileo page part is received
|
{
|
||||||
// 0. fetch the symbols into an array
|
if (d_sample_counter == d_preamble_index+GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS)
|
||||||
int frame_length=GALILEO_INAV_PAGE_PART_SYMBOLS-d_symbols_per_preamble;
|
{
|
||||||
double page_part_symbols[frame_length];
|
// NEW Galileo page part is received
|
||||||
|
// 0. fetch the symbols into an array
|
||||||
|
int frame_length = GALILEO_INAV_PAGE_PART_SYMBOLS - d_symbols_per_preamble;
|
||||||
|
double page_part_symbols[frame_length];
|
||||||
|
|
||||||
for (int i=0;i<frame_length;i++)
|
for (int i = 0; i < frame_length; i++)
|
||||||
{
|
{
|
||||||
if (corr_value>0)
|
if (corr_value > 0)
|
||||||
{
|
{
|
||||||
page_part_symbols[i]=in[0][i+d_symbols_per_preamble].Prompt_I; // because last symbol of the preamble is just received now!
|
page_part_symbols[i] = in[0][i + d_symbols_per_preamble].Prompt_I; // because last symbol of the preamble is just received now!
|
||||||
|
|
||||||
}else{
|
}
|
||||||
page_part_symbols[i]=-in[0][i+d_symbols_per_preamble].Prompt_I; // because last symbol of the preamble is just received now!
|
else
|
||||||
}
|
{
|
||||||
}
|
page_part_symbols[i] = -in[0][i + d_symbols_per_preamble].Prompt_I; // because last symbol of the preamble is just received now!
|
||||||
//debug
|
}
|
||||||
//std::cout<<"ch["<<d_channel<<"] Decoder call at preamble index "<<d_sample_counter<<std::endl;
|
}
|
||||||
// std::cout<<"ch["<<d_channel<<"] frame symbols: ";
|
//debug
|
||||||
// for (int j=0;j<frame_length;j++)
|
//std::cout<<"ch["<<d_channel<<"] Decoder call at preamble index "<<d_sample_counter<<std::endl;
|
||||||
// {
|
// std::cout<<"ch["<<d_channel<<"] frame symbols: ";
|
||||||
// if (page_part_symbols[j]>0)
|
// for (int j=0;j<frame_length;j++)
|
||||||
// {
|
// {
|
||||||
// std::cout<<"1";
|
// if (page_part_symbols[j]>0)
|
||||||
// }else{
|
// {
|
||||||
// std::cout<<"0";
|
// std::cout<<"1";
|
||||||
// }
|
// }else{
|
||||||
// }
|
// std::cout<<"0";
|
||||||
// std::cout<<std::endl;
|
// }
|
||||||
//end debug
|
// }
|
||||||
//call the decoder
|
// std::cout<<std::endl;
|
||||||
decode_word(page_part_symbols,frame_length);
|
//end debug
|
||||||
if (d_nav.flag_CRC_test==true)
|
//call the decoder
|
||||||
{
|
decode_word(page_part_symbols, frame_length);
|
||||||
d_CRC_error_counter=0;
|
if (d_nav.flag_CRC_test == true)
|
||||||
d_flag_preamble = true; //valid preamble indicator (initialized to false every work())
|
{
|
||||||
d_preamble_index = d_sample_counter; //record the preamble sample stamp (t_P)
|
d_CRC_error_counter = 0;
|
||||||
d_preamble_time_seconds = in[0][0].Tracking_timestamp_secs;// - d_preamble_duration_seconds; //record the PRN start sample index associated to the preamble
|
d_flag_preamble = true; //valid preamble indicator (initialized to false every work())
|
||||||
if (!d_flag_frame_sync)
|
d_preamble_index = d_sample_counter; //record the preamble sample stamp (t_P)
|
||||||
{
|
d_preamble_time_seconds = in[0][0].Tracking_timestamp_secs; // - d_preamble_duration_seconds; //record the PRN start sample index associated to the preamble
|
||||||
d_flag_frame_sync = true;
|
if (!d_flag_frame_sync)
|
||||||
std::cout <<" Frame sync SAT " << this->d_satellite << " with preamble start at " << d_preamble_time_seconds << " [s]" << std::endl;
|
{
|
||||||
}
|
d_flag_frame_sync = true;
|
||||||
}else{
|
std::cout <<" Frame sync SAT " << this->d_satellite << " with preamble start at " << d_preamble_time_seconds << " [s]" << std::endl;
|
||||||
d_CRC_error_counter++;
|
}
|
||||||
d_preamble_index = d_sample_counter; //record the preamble sample stamp
|
}
|
||||||
if (d_CRC_error_counter>CRC_ERROR_LIMIT)
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Lost of frame sync SAT " << this->d_satellite << std::endl;
|
d_CRC_error_counter++;
|
||||||
d_flag_frame_sync=false;
|
d_preamble_index = d_sample_counter; //record the preamble sample stamp
|
||||||
d_stat=0;
|
if (d_CRC_error_counter > CRC_ERROR_LIMIT)
|
||||||
}
|
{
|
||||||
}
|
std::cout << "Lost of frame sync SAT " << this->d_satellite << std::endl;
|
||||||
}
|
d_flag_frame_sync = false;
|
||||||
}
|
d_stat = 0;
|
||||||
consume_each(1); //one by one
|
}
|
||||||
// UPDATE GNSS SYNCHRO DATA
|
}
|
||||||
Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block
|
}
|
||||||
//1. Copy the current tracking output
|
}
|
||||||
current_synchro_data = in[0][0];
|
consume_each(1); //one by one
|
||||||
//2. Add the telemetry decoder information
|
// UPDATE GNSS SYNCHRO DATA
|
||||||
if (this->d_flag_preamble==true and d_nav.flag_TOW_set==true)
|
Gnss_Synchro current_synchro_data; //structure to save the synchronization information and send the output object to the next block
|
||||||
//update TOW at the preamble instant
|
//1. Copy the current tracking output
|
||||||
//flag preamble is true after the all page (even and odd) is recevived. I/NAV page period is 2 SECONDS
|
current_synchro_data = in[0][0];
|
||||||
{
|
//2. Add the telemetry decoder information
|
||||||
Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
if (this->d_flag_preamble == true and d_nav.flag_TOW_set == true)
|
||||||
if(d_nav.flag_TOW_5 == true) //page 5 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec)
|
//update TOW at the preamble instant
|
||||||
{
|
//flag preamble is true after the all page (even and odd) is recevived. I/NAV page period is 2 SECONDS
|
||||||
//std::cout<< "Using TOW_5 for timestamping" << std::endl;
|
{
|
||||||
d_TOW_at_Preamble = d_nav.TOW_5+GALILEO_INAV_PAGE_PART_SECONDS; //TOW_5 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later
|
Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
||||||
/* 1 sec (GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD) is added because
|
if(d_nav.flag_TOW_5 == true) //page 5 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec)
|
||||||
* if we have a TOW value it means that we are at the begining of the last page part
|
{
|
||||||
* (GNU Radio history keeps in a buffer the rest of the incomming frame part)*/
|
//std::cout<< "Using TOW_5 for timestamping" << std::endl;
|
||||||
d_TOW_at_current_symbol = d_TOW_at_Preamble;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD;
|
d_TOW_at_Preamble = d_nav.TOW_5+GALILEO_INAV_PAGE_PART_SECONDS; //TOW_5 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later
|
||||||
d_nav.flag_TOW_5 = false;
|
/* 1 sec (GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD) is added because
|
||||||
}
|
* if we have a TOW value it means that we are at the begining of the last page part
|
||||||
|
* (GNU Radio history keeps in a buffer the rest of the incomming frame part)*/
|
||||||
|
d_TOW_at_current_symbol = d_TOW_at_Preamble;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD;
|
||||||
|
d_nav.flag_TOW_5 = false;
|
||||||
|
}
|
||||||
|
|
||||||
else if(d_nav.flag_TOW_6 == true) //page 6 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec)
|
else if(d_nav.flag_TOW_6 == true) //page 6 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec)
|
||||||
{
|
{
|
||||||
//std::cout<< "Using TOW_6 for timestamping" << std::endl;
|
//std::cout<< "Using TOW_6 for timestamping" << std::endl;
|
||||||
d_TOW_at_Preamble = d_nav.TOW_6+GALILEO_INAV_PAGE_PART_SECONDS;
|
d_TOW_at_Preamble = d_nav.TOW_6+GALILEO_INAV_PAGE_PART_SECONDS;
|
||||||
//TOW_6 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later
|
//TOW_6 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later
|
||||||
/* 1 sec (GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD) is added because
|
/* 1 sec (GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD) is added because
|
||||||
* if we have a TOW value it means that we are at the begining of the last page part
|
* if we have a TOW value it means that we are at the begining of the last page part
|
||||||
* (GNU Radio history keeps in a buffer the rest of the incomming frame part)*/
|
* (GNU Radio history keeps in a buffer the rest of the incomming frame part)*/
|
||||||
d_TOW_at_current_symbol = d_TOW_at_Preamble;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD;
|
d_TOW_at_current_symbol = d_TOW_at_Preamble;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD;
|
||||||
d_nav.flag_TOW_6 = false;
|
d_nav.flag_TOW_6 = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//this page has no timming information
|
//this page has no timming information
|
||||||
d_TOW_at_Preamble = d_TOW_at_Preamble + GALILEO_INAV_PAGE_SECONDS;
|
d_TOW_at_Preamble = d_TOW_at_Preamble + GALILEO_INAV_PAGE_SECONDS;
|
||||||
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALIELO_E1_CODE_PERIOD;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD;
|
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALIELO_E1_CODE_PERIOD;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALIELO_E1_CODE_PERIOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else //if there is not a new preamble, we define the TOW of the current symbol
|
else //if there is not a new preamble, we define the TOW of the current symbol
|
||||||
{
|
{
|
||||||
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALIELO_E1_CODE_PERIOD;
|
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALIELO_E1_CODE_PERIOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true)
|
//if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true)
|
||||||
if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true)
|
if (d_flag_frame_sync == true and d_nav.flag_TOW_set == true)
|
||||||
{
|
{
|
||||||
current_synchro_data.Flag_valid_word = true;
|
current_synchro_data.Flag_valid_word = true;
|
||||||
}else{
|
}
|
||||||
current_synchro_data.Flag_valid_word = false;
|
else
|
||||||
}
|
{
|
||||||
|
current_synchro_data.Flag_valid_word = false;
|
||||||
|
}
|
||||||
|
|
||||||
current_synchro_data.d_TOW = d_TOW_at_Preamble;
|
current_synchro_data.d_TOW = d_TOW_at_Preamble;
|
||||||
current_synchro_data.d_TOW_at_current_symbol = d_TOW_at_current_symbol;
|
current_synchro_data.d_TOW_at_current_symbol = d_TOW_at_current_symbol;
|
||||||
current_synchro_data.Flag_preamble = d_flag_preamble;
|
current_synchro_data.Flag_preamble = d_flag_preamble;
|
||||||
current_synchro_data.Prn_timestamp_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
current_synchro_data.Prn_timestamp_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
||||||
current_synchro_data.Prn_timestamp_at_preamble_ms = Prn_timestamp_at_preamble_ms;
|
current_synchro_data.Prn_timestamp_at_preamble_ms = Prn_timestamp_at_preamble_ms;
|
||||||
|
|
||||||
if(d_dump == true)
|
if(d_dump == true)
|
||||||
{
|
{
|
||||||
// MULTIPLEXED FILE RECORDING - Record results to file
|
// MULTIPLEXED FILE RECORDING - Record results to file
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
double tmp_double;
|
double tmp_double;
|
||||||
tmp_double = d_TOW_at_current_symbol;
|
tmp_double = d_TOW_at_current_symbol;
|
||||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||||
tmp_double = current_synchro_data.Prn_timestamp_ms;
|
tmp_double = current_synchro_data.Prn_timestamp_ms;
|
||||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||||
tmp_double = d_TOW_at_Preamble;
|
tmp_double = d_TOW_at_Preamble;
|
||||||
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
d_dump_file.write((char*)&tmp_double, sizeof(double));
|
||||||
}
|
}
|
||||||
catch (const std::ifstream::failure& e)
|
catch (const std::ifstream::failure& e)
|
||||||
{
|
{
|
||||||
std::cout << "Exception writing observables dump file " << e.what() << std::endl;
|
std::cout << "Exception writing observables dump file " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//3. Make the output (copy the object contents to the GNURadio reserved memory)
|
//3. Make the output (copy the object contents to the GNURadio reserved memory)
|
||||||
*out[0] = current_synchro_data;
|
*out[0] = current_synchro_data;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1b_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite)
|
void galileo_e1b_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite)
|
||||||
{
|
{
|
||||||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||||
DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite;
|
DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite;
|
||||||
DLOG(INFO) << "Navigation Satellite set to " << d_satellite;
|
DLOG(INFO) << "Navigation Satellite set to " << d_satellite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1b_telemetry_decoder_cc::set_channel(int channel)
|
void galileo_e1b_telemetry_decoder_cc::set_channel(int channel)
|
||||||
{
|
{
|
||||||
d_channel = channel;
|
d_channel = channel;
|
||||||
DLOG(INFO) << "Navigation channel set to " << channel;
|
DLOG(INFO) << "Navigation channel set to " << channel;
|
||||||
// ############# ENABLE DATA FILE LOG #################
|
// ############# ENABLE DATA FILE LOG #################
|
||||||
if (d_dump == true)
|
if (d_dump == true)
|
||||||
{
|
{
|
||||||
if (d_dump_file.is_open() == false)
|
if (d_dump_file.is_open() == false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
d_dump_filename = "telemetry";
|
d_dump_filename = "telemetry";
|
||||||
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
|
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
|
||||||
d_dump_filename.append(".dat");
|
d_dump_filename.append(".dat");
|
||||||
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
|
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);
|
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||||
std::cout << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str() << std::endl;
|
std::cout << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: "
|
||||||
}
|
<< d_dump_filename.c_str() << std::endl;
|
||||||
catch (const std::ifstream::failure& e)
|
}
|
||||||
{
|
catch (const std::ifstream::failure& e)
|
||||||
std::cout << "channel " << d_channel << " Exception opening trk dump file " << e.what() << std::endl;
|
{
|
||||||
}
|
std::cout << "channel " << d_channel
|
||||||
}
|
<< " Exception opening trk dump file " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1b_telemetry_decoder_cc::set_ephemeris_queue(concurrent_queue<Galileo_Ephemeris> *ephemeris_queue)
|
void galileo_e1b_telemetry_decoder_cc::set_ephemeris_queue(concurrent_queue<Galileo_Ephemeris> *ephemeris_queue)
|
||||||
{
|
{
|
||||||
d_ephemeris_queue = ephemeris_queue;
|
d_ephemeris_queue = ephemeris_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1b_telemetry_decoder_cc::set_iono_queue(concurrent_queue<Galileo_Iono> *iono_queue)
|
void galileo_e1b_telemetry_decoder_cc::set_iono_queue(concurrent_queue<Galileo_Iono> *iono_queue)
|
||||||
{
|
{
|
||||||
d_iono_queue = iono_queue;
|
d_iono_queue = iono_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1b_telemetry_decoder_cc::set_almanac_queue(concurrent_queue<Galileo_Almanac> *almanac_queue)
|
void galileo_e1b_telemetry_decoder_cc::set_almanac_queue(concurrent_queue<Galileo_Almanac> *almanac_queue)
|
||||||
{
|
{
|
||||||
d_almanac_queue = almanac_queue;
|
d_almanac_queue = almanac_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void galileo_e1b_telemetry_decoder_cc::set_utc_model_queue(concurrent_queue<Galileo_Utc_Model> *utc_model_queue)
|
void galileo_e1b_telemetry_decoder_cc::set_utc_model_queue(concurrent_queue<Galileo_Utc_Model> *utc_model_queue)
|
||||||
{
|
{
|
||||||
d_utc_model_queue = utc_model_queue;
|
d_utc_model_queue = utc_model_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file galileo_e1b_telemetry_decoder_cc.h
|
* \file galileo_e1b_telemetry_decoder_cc.h
|
||||||
* \brief Interface of a Galileo NAV message demodulator block
|
* \brief Interface of a Galileo NAV message demodulator block
|
||||||
* \author Javier Arribas 2013. jarribas(at)cttc.es
|
* \author Javier Arribas 2013 jarribas(at)cttc.es,
|
||||||
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
|
* Mara Branzanti 2013 mara.branzanti(at)gmail.com
|
||||||
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
|
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
|
||||||
@ -28,8 +29,8 @@
|
|||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef GNSS_SDR_galileo_e1b_TELEMETRY_DECODER_CC_H
|
#ifndef GNSS_SDR_GALILEO_E1B_TELEMETRY_DECODER_CC_H
|
||||||
#define GNSS_SDR_galileo_e1b_TELEMETRY_DECODER_CC_H
|
#define GNSS_SDR_GALILEO_E1B_TELEMETRY_DECODER_CC_H
|
||||||
|
|
||||||
|
|
||||||
#include "Galileo_E1.h"
|
#include "Galileo_E1.h"
|
||||||
@ -38,7 +39,6 @@
|
|||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
#include <gnuradio/msg_queue.h>
|
#include <gnuradio/msg_queue.h>
|
||||||
|
|
||||||
#include "gnuradio/trellis/interleaver.h"
|
#include "gnuradio/trellis/interleaver.h"
|
||||||
#include "gnuradio/trellis/permutation.h"
|
#include "gnuradio/trellis/permutation.h"
|
||||||
#include "gnuradio/fec/viterbi.h"
|
#include "gnuradio/fec/viterbi.h"
|
||||||
@ -76,16 +76,20 @@ public:
|
|||||||
void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN
|
void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN
|
||||||
void set_channel(int channel); //!< Set receiver's channel
|
void set_channel(int channel); //!< Set receiver's channel
|
||||||
int flag_even_word_arrived;
|
int flag_even_word_arrived;
|
||||||
|
void set_ephemeris_queue(concurrent_queue<Galileo_Ephemeris> *ephemeris_queue); //!< Set the satellite data queue
|
||||||
|
void set_iono_queue(concurrent_queue<Galileo_Iono> *iono_queue); //!< Set the iono data queue
|
||||||
|
void set_almanac_queue(concurrent_queue<Galileo_Almanac> *almanac_queue); //!< Set the almanac data queue
|
||||||
|
void set_utc_model_queue(concurrent_queue<Galileo_Utc_Model> *utc_model_queue); //!< Set the UTC model queue
|
||||||
/*!
|
/*!
|
||||||
* \brief Set the satellite data queue
|
* \brief This is where all signal processing takes place
|
||||||
*/
|
*/
|
||||||
void set_ephemeris_queue(concurrent_queue<Galileo_Ephemeris> *ephemeris_queue);
|
|
||||||
void set_iono_queue(concurrent_queue<Galileo_Iono> *iono_queue);
|
|
||||||
void set_almanac_queue(concurrent_queue<Galileo_Almanac> *almanac_queue);
|
|
||||||
void set_utc_model_queue(concurrent_queue<Galileo_Utc_Model> *utc_model_queue);
|
|
||||||
|
|
||||||
int general_work (int noutput_items, gr_vector_int &ninput_items,
|
int general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Function which tells the scheduler how many input items
|
||||||
|
* are required to produce noutput_items output items.
|
||||||
|
*/
|
||||||
void forecast (int noutput_items, gr_vector_int &ninput_items_required);
|
void forecast (int noutput_items, gr_vector_int &ninput_items_required);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -121,7 +125,6 @@ private:
|
|||||||
// navigation message vars
|
// navigation message vars
|
||||||
Galileo_Navigation_Message d_nav;
|
Galileo_Navigation_Message d_nav;
|
||||||
|
|
||||||
|
|
||||||
// Galileo ephemeris queue
|
// Galileo ephemeris queue
|
||||||
concurrent_queue<Galileo_Ephemeris> *d_ephemeris_queue;
|
concurrent_queue<Galileo_Ephemeris> *d_ephemeris_queue;
|
||||||
// ionospheric parameters queue
|
// ionospheric parameters queue
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
|
* Copyright (C) 2010-2013 (see AUTHORS file for a list of contributors)
|
||||||
*
|
*
|
||||||
* GNSS-SDR is a software defined Global Navigation
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
* Satellite Systems receiver
|
* Satellite Systems receiver
|
||||||
@ -103,9 +103,9 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
|
|||||||
// preamble bits to sampled symbols
|
// preamble bits to sampled symbols
|
||||||
d_preambles_symbols = (signed int*)malloc(sizeof(signed int) * GPS_CA_PREAMBLE_LENGTH_BITS * d_samples_per_bit);
|
d_preambles_symbols = (signed int*)malloc(sizeof(signed int) * GPS_CA_PREAMBLE_LENGTH_BITS * d_samples_per_bit);
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (int i=0; i<GPS_CA_PREAMBLE_LENGTH_BITS; i++)
|
for (int i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++)
|
||||||
{
|
{
|
||||||
for (unsigned int j=0; j<d_samples_per_bit; j++)
|
for (unsigned int j = 0; j < d_samples_per_bit; j++)
|
||||||
{
|
{
|
||||||
if (d_preambles_bits[i] == 1)
|
if (d_preambles_bits[i] == 1)
|
||||||
{
|
{
|
||||||
@ -164,7 +164,7 @@ bool gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(unsigned int gpsword)
|
|||||||
// Now XOR the 5 6-bit fields together to produce the 6-bit final result.
|
// Now XOR the 5 6-bit fields together to produce the 6-bit final result.
|
||||||
parity = t ^ _lrotl(t,6) ^ _lrotl(t,12) ^ _lrotl(t,18) ^ _lrotl(t,24);
|
parity = t ^ _lrotl(t,6) ^ _lrotl(t,12) ^ _lrotl(t,18) ^ _lrotl(t,24);
|
||||||
parity = parity & 0x3F;
|
parity = parity & 0x3F;
|
||||||
if (parity == (gpsword&0x3F)) return(true);
|
if (parity == (gpsword & 0x3F)) return(true);
|
||||||
else return(false);
|
else return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
|||||||
|
|
||||||
// TODO Optimize me!
|
// TODO Optimize me!
|
||||||
//******* preamble correlation ********
|
//******* preamble correlation ********
|
||||||
for (unsigned int i=0; i<d_samples_per_bit*8; i++)
|
for (unsigned int i = 0; i < d_samples_per_bit*8; i++)
|
||||||
{
|
{
|
||||||
if (in[0][i].Prompt_I < 0) // symbols clipping
|
if (in[0][i].Prompt_I < 0) // symbols clipping
|
||||||
{
|
{
|
||||||
@ -297,7 +297,7 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_GPS_frame_4bytes<<=1; //shift 1 bit left the telemetry word
|
d_GPS_frame_4bytes <<= 1; //shift 1 bit left the telemetry word
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// output the frame
|
// output the frame
|
||||||
@ -306,12 +306,12 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
|||||||
//1. Copy the current tracking output
|
//1. Copy the current tracking output
|
||||||
current_synchro_data = in[0][0];
|
current_synchro_data = in[0][0];
|
||||||
//2. Add the telemetry decoder information
|
//2. Add the telemetry decoder information
|
||||||
if (this->d_flag_preamble==true and d_GPS_FSM.d_nav.d_TOW>0) //update TOW at the preamble instant (todo: check for valid d_TOW)
|
if (this->d_flag_preamble == true and d_GPS_FSM.d_nav.d_TOW > 0) //update TOW at the preamble instant (todo: check for valid d_TOW)
|
||||||
{
|
{
|
||||||
d_TOW_at_Preamble = d_GPS_FSM.d_nav.d_TOW + GPS_SUBFRAME_SECONDS; //we decoded the current TOW when the last word of the subframe arrive, so, we have a lag of ONE SUBFRAME
|
d_TOW_at_Preamble = d_GPS_FSM.d_nav.d_TOW + GPS_SUBFRAME_SECONDS; //we decoded the current TOW when the last word of the subframe arrive, so, we have a lag of ONE SUBFRAME
|
||||||
d_TOW_at_current_symbol = d_TOW_at_Preamble + GPS_CA_PREAMBLE_LENGTH_BITS/GPS_CA_TELEMETRY_RATE_BITS_SECOND;
|
d_TOW_at_current_symbol = d_TOW_at_Preamble + GPS_CA_PREAMBLE_LENGTH_BITS/GPS_CA_TELEMETRY_RATE_BITS_SECOND;
|
||||||
Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
|
||||||
if (flag_TOW_set==false)
|
if (flag_TOW_set == false)
|
||||||
{
|
{
|
||||||
flag_TOW_set = true;
|
flag_TOW_set = true;
|
||||||
}
|
}
|
||||||
@ -321,7 +321,6 @@ int gps_l1_ca_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_i
|
|||||||
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GPS_L1_CA_CODE_PERIOD;
|
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GPS_L1_CA_CODE_PERIOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
current_synchro_data.d_TOW = d_TOW_at_Preamble;
|
current_synchro_data.d_TOW = d_TOW_at_Preamble;
|
||||||
current_synchro_data.d_TOW_at_current_symbol = d_TOW_at_current_symbol;
|
current_synchro_data.d_TOW_at_current_symbol = d_TOW_at_current_symbol;
|
||||||
current_synchro_data.Flag_valid_word = (d_flag_frame_sync == true and d_flag_parity == true and flag_TOW_set==true);
|
current_synchro_data.Flag_valid_word = (d_flag_frame_sync == true and d_flag_parity == true and flag_TOW_set==true);
|
||||||
@ -379,11 +378,13 @@ void gps_l1_ca_telemetry_decoder_cc::set_channel(int channel)
|
|||||||
d_dump_filename.append(".dat");
|
d_dump_filename.append(".dat");
|
||||||
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
|
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);
|
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||||
std::cout << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str() << std::endl;
|
std::cout << "Telemetry decoder dump enabled on channel " << d_channel
|
||||||
|
<< " Log file: " << d_dump_filename.c_str() << std::endl;
|
||||||
}
|
}
|
||||||
catch (std::ifstream::failure e)
|
catch (std::ifstream::failure e)
|
||||||
{
|
{
|
||||||
std::cout << "channel " << d_channel << " Exception opening trk dump file " << e.what() << std::endl;
|
std::cout << "channel " << d_channel
|
||||||
|
<< " Exception opening trk dump file " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* \author Javier Arribas, 2011. jarribas(at)cttc.es
|
* \author Javier Arribas, 2011. jarribas(at)cttc.es
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
|
* Copyright (C) 2010-2013 (see AUTHORS file for a list of contributors)
|
||||||
*
|
*
|
||||||
* GNSS-SDR is a software defined Global Navigation
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
* Satellite Systems receiver
|
* Satellite Systems receiver
|
||||||
@ -39,7 +39,6 @@
|
|||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
#include <gnuradio/msg_queue.h>
|
#include <gnuradio/msg_queue.h>
|
||||||
//#include <gnuradio/gr_sync_block.h>
|
|
||||||
#include "gnss_satellite.h"
|
#include "gnss_satellite.h"
|
||||||
|
|
||||||
|
|
||||||
@ -62,24 +61,35 @@ public:
|
|||||||
~gps_l1_ca_telemetry_decoder_cc();
|
~gps_l1_ca_telemetry_decoder_cc();
|
||||||
void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN
|
void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN
|
||||||
void set_channel(int channel); //!< Set receiver's channel
|
void set_channel(int channel); //!< Set receiver's channel
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Set the satellite data queue
|
* \brief Set the satellite data queue
|
||||||
*/
|
*/
|
||||||
void set_ephemeris_queue(concurrent_queue<Gps_Ephemeris> *ephemeris_queue){d_GPS_FSM.d_ephemeris_queue = ephemeris_queue;}
|
void set_ephemeris_queue(concurrent_queue<Gps_Ephemeris> *ephemeris_queue){d_GPS_FSM.d_ephemeris_queue = ephemeris_queue;} //!< Set the ephemeris data queue
|
||||||
void set_iono_queue(concurrent_queue<Gps_Iono> *iono_queue){d_GPS_FSM.d_iono_queue = iono_queue;}
|
void set_iono_queue(concurrent_queue<Gps_Iono> *iono_queue){d_GPS_FSM.d_iono_queue = iono_queue;} //!< Set the iono data queue
|
||||||
void set_almanac_queue(concurrent_queue<Gps_Almanac> *almanac_queue){d_GPS_FSM.d_almanac_queue = almanac_queue;}
|
void set_almanac_queue(concurrent_queue<Gps_Almanac> *almanac_queue){d_GPS_FSM.d_almanac_queue = almanac_queue;} //!< Set the almanac data queue
|
||||||
void set_utc_model_queue(concurrent_queue<Gps_Utc_Model> *utc_model_queue){d_GPS_FSM.d_utc_model_queue = utc_model_queue;}
|
void set_utc_model_queue(concurrent_queue<Gps_Utc_Model> *utc_model_queue){d_GPS_FSM.d_utc_model_queue = utc_model_queue;} //!< Set the UTC model data queue
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief This is where all signal processing takes place
|
||||||
|
*/
|
||||||
int general_work (int noutput_items, gr_vector_int &ninput_items,
|
int general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Function which tells the scheduler how many input items
|
||||||
|
* are required to produce noutput_items output items.
|
||||||
|
*/
|
||||||
void forecast (int noutput_items, gr_vector_int &ninput_items_required);
|
void forecast (int noutput_items, gr_vector_int &ninput_items_required);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend gps_l1_ca_telemetry_decoder_cc_sptr
|
friend gps_l1_ca_telemetry_decoder_cc_sptr
|
||||||
gps_l1_ca_make_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, long fs_in,unsigned
|
gps_l1_ca_make_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, long fs_in,unsigned
|
||||||
int vector_length, boost::shared_ptr<gr::msg_queue> queue, bool dump);
|
int vector_length, boost::shared_ptr<gr::msg_queue> queue, bool dump);
|
||||||
|
|
||||||
gps_l1_ca_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, long fs_in, unsigned
|
gps_l1_ca_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, long fs_in, unsigned
|
||||||
int vector_length, boost::shared_ptr<gr::msg_queue> queue, bool dump);
|
int vector_length, boost::shared_ptr<gr::msg_queue> queue, bool dump);
|
||||||
|
|
||||||
bool gps_word_parityCheck(unsigned int gpsword);
|
bool gps_word_parityCheck(unsigned int gpsword);
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
|
@ -56,6 +56,8 @@ sbas_l1_make_telemetry_decoder_cc(Gnss_Satellite satellite, long if_freq, long f
|
|||||||
fs_in, vector_length, queue, dump));
|
fs_in, vector_length, queue, dump));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sbas_l1_telemetry_decoder_cc::sbas_l1_telemetry_decoder_cc(
|
sbas_l1_telemetry_decoder_cc::sbas_l1_telemetry_decoder_cc(
|
||||||
Gnss_Satellite satellite,
|
Gnss_Satellite satellite,
|
||||||
long if_freq,
|
long if_freq,
|
||||||
@ -64,41 +66,42 @@ sbas_l1_telemetry_decoder_cc::sbas_l1_telemetry_decoder_cc(
|
|||||||
int vector_length,
|
int vector_length,
|
||||||
boost::shared_ptr<gr::msg_queue> queue,
|
boost::shared_ptr<gr::msg_queue> queue,
|
||||||
bool dump) :
|
bool dump) :
|
||||||
gr::block("sbas_l1_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
|
gr::block("sbas_l1_telemetry_decoder_cc",
|
||||||
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
|
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
|
||||||
|
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
|
||||||
{
|
{
|
||||||
// initialize internal vars
|
// initialize internal vars
|
||||||
d_dump = dump;
|
d_dump = dump;
|
||||||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||||
DLOG(INFO) << "SBAS L1 TELEMETRY PROCESSING: satellite " << d_satellite;
|
DLOG(INFO) << "SBAS L1 TELEMETRY PROCESSING: satellite " << d_satellite;
|
||||||
d_fs_in = fs_in;
|
d_fs_in = fs_in;
|
||||||
|
|
||||||
d_block_size = d_samples_per_symbol * d_symbols_per_bit * d_block_size_in_bits;
|
d_block_size = d_samples_per_symbol * d_symbols_per_bit * d_block_size_in_bits;
|
||||||
|
|
||||||
set_output_multiple (1);
|
set_output_multiple (1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sbas_l1_telemetry_decoder_cc::~sbas_l1_telemetry_decoder_cc()
|
sbas_l1_telemetry_decoder_cc::~sbas_l1_telemetry_decoder_cc()
|
||||||
{
|
{
|
||||||
d_dump_file.close();
|
d_dump_file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
|
void sbas_l1_telemetry_decoder_cc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
|
||||||
{
|
{
|
||||||
unsigned ninputs = ninput_items_required.size ();
|
unsigned ninputs = ninput_items_required.size ();
|
||||||
for (unsigned i = 0; i < ninputs; i++)
|
for (unsigned i = 0; i < ninputs; i++)
|
||||||
ninput_items_required[i] = noutput_items;
|
ninput_items_required[i] = noutput_items;
|
||||||
|
|
||||||
VLOG(LMORE) << "forecast(): " << "noutput_items=" << noutput_items << "\tninput_items_required ninput_items_required.size()=" << ninput_items_required.size();
|
VLOG(LMORE) << "forecast(): " << "noutput_items=" << noutput_items << "\tninput_items_required ninput_items_required.size()=" << ninput_items_required.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int sbas_l1_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
|
int sbas_l1_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
|
||||||
{
|
{
|
||||||
|
|
||||||
VLOG(FLOW) << "general_work(): " << "noutput_items=" << noutput_items << "\toutput_items real size=" << output_items.size() << "\tninput_items size=" << ninput_items.size() << "\tinput_items real size=" << input_items.size() << "\tninput_items[0]=" << ninput_items[0];
|
VLOG(FLOW) << "general_work(): " << "noutput_items=" << noutput_items << "\toutput_items real size=" << output_items.size() << "\tninput_items size=" << ninput_items.size() << "\tinput_items real size=" << input_items.size() << "\tninput_items[0]=" << ninput_items[0];
|
||||||
|
|
||||||
// get pointers on in- and output gnss-synchro objects
|
// get pointers on in- and output gnss-synchro objects
|
||||||
const Gnss_Synchro *in = (const Gnss_Synchro *) input_items[0]; // input
|
const Gnss_Synchro *in = (const Gnss_Synchro *) input_items[0]; // input
|
||||||
Gnss_Synchro *out = (Gnss_Synchro *) output_items[0]; // output
|
Gnss_Synchro *out = (Gnss_Synchro *) output_items[0]; // output
|
||||||
@ -147,7 +150,7 @@ int sbas_l1_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_int
|
|||||||
{
|
{
|
||||||
int message_sample_offset =
|
int message_sample_offset =
|
||||||
(sample_alignment?0:-1)
|
(sample_alignment?0:-1)
|
||||||
+ d_samples_per_symbol*(symbol_alignment?-1:0)
|
+ d_samples_per_symbol*(symbol_alignment ? -1 : 0)
|
||||||
+ d_samples_per_symbol * d_symbols_per_bit * it->first;
|
+ d_samples_per_symbol * d_symbols_per_bit * it->first;
|
||||||
double message_sample_stamp = sample_stamp + ((double)message_sample_offset)/1000;
|
double message_sample_stamp = sample_stamp + ((double)message_sample_offset)/1000;
|
||||||
VLOG(EVENT) << "message_sample_stamp=" << message_sample_stamp
|
VLOG(EVENT) << "message_sample_stamp=" << message_sample_stamp
|
||||||
@ -188,6 +191,7 @@ int sbas_l1_telemetry_decoder_cc::general_work (int noutput_items, gr_vector_int
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite)
|
void sbas_l1_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite)
|
||||||
{
|
{
|
||||||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||||
@ -195,6 +199,7 @@ void sbas_l1_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::set_channel(int channel)
|
void sbas_l1_telemetry_decoder_cc::set_channel(int channel)
|
||||||
{
|
{
|
||||||
d_channel = channel;
|
d_channel = channel;
|
||||||
@ -241,7 +246,6 @@ bool sbas_l1_telemetry_decoder_cc::sample_aligner::get_symbols(const std::vector
|
|||||||
|
|
||||||
for (unsigned int i_sym = 0; i_sym < samples.size()/sbas_l1_telemetry_decoder_cc::d_samples_per_symbol; i_sym++)
|
for (unsigned int i_sym = 0; i_sym < samples.size()/sbas_l1_telemetry_decoder_cc::d_samples_per_symbol; i_sym++)
|
||||||
{
|
{
|
||||||
|
|
||||||
// get the next samples
|
// get the next samples
|
||||||
for (int i = 0; i < d_n_smpls_in_history; i++)
|
for (int i = 0; i < d_n_smpls_in_history; i++)
|
||||||
{
|
{
|
||||||
@ -266,7 +270,8 @@ bool sbas_l1_telemetry_decoder_cc::sample_aligner::get_symbols(const std::vector
|
|||||||
|
|
||||||
// sample alignment debug output
|
// sample alignment debug output
|
||||||
VLOG(SAMP_SYNC) << std::setprecision(5)
|
VLOG(SAMP_SYNC) << std::setprecision(5)
|
||||||
<< "smplp: " << std::setw(6) << smpls[0] << " " << "smpl0: " << std::setw(6) << smpls[1] << " " << "smpl1: " << std::setw(6) << smpls[2] << "\t"
|
<< "smplp: " << std::setw(6) << smpls[0] << " " << "smpl0: " << std::setw(6)
|
||||||
|
<< smpls[1] << " " << "smpl1: " << std::setw(6) << smpls[2] << "\t"
|
||||||
//<< "Flag_valid_tracking: " << std::setw(1) << in[0][0].Flag_valid_tracking << " " << std::setw(1) << in[0][0].Flag_valid_tracking << "\t"
|
//<< "Flag_valid_tracking: " << std::setw(1) << in[0][0].Flag_valid_tracking << " " << std::setw(1) << in[0][0].Flag_valid_tracking << "\t"
|
||||||
<< "d_corr_paired: " << std::setw(10) << d_corr_paired << "\t"
|
<< "d_corr_paired: " << std::setw(10) << d_corr_paired << "\t"
|
||||||
<< "d_corr_shifted: " << std::setw(10) << d_corr_shifted << "\t"
|
<< "d_corr_shifted: " << std::setw(10) << d_corr_shifted << "\t"
|
||||||
@ -306,6 +311,7 @@ sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::~symbol_aligner_and_de
|
|||||||
delete d_vd2;
|
delete d_vd2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::reset()
|
void sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::reset()
|
||||||
{
|
{
|
||||||
d_past_symbol = 0;
|
d_past_symbol = 0;
|
||||||
@ -313,6 +319,7 @@ void sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::reset()
|
|||||||
d_vd2->reset();
|
d_vd2->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::get_bits(const std::vector<double> symbols, std::vector<int> &bits)
|
bool sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::get_bits(const std::vector<double> symbols, std::vector<int> &bits)
|
||||||
{
|
{
|
||||||
const int traceback_depth = 5*d_KK;
|
const int traceback_depth = 5*d_KK;
|
||||||
@ -322,7 +329,7 @@ bool sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::get_bits(const st
|
|||||||
std::vector<double> symbols_vd1(symbols); // aligned symbol vector -> copy input symbol vector
|
std::vector<double> symbols_vd1(symbols); // aligned symbol vector -> copy input symbol vector
|
||||||
std::vector<double> symbols_vd2; // shifted symbol vector -> add past sample in front of input vector
|
std::vector<double> symbols_vd2; // shifted symbol vector -> add past sample in front of input vector
|
||||||
symbols_vd1.push_back(d_past_symbol);
|
symbols_vd1.push_back(d_past_symbol);
|
||||||
for (std::vector<double>::const_iterator symbol_it = symbols.begin(); symbol_it != symbols.end()-1; ++symbol_it)
|
for (std::vector<double>::const_iterator symbol_it = symbols.begin(); symbol_it != symbols.end() - 1; ++symbol_it)
|
||||||
{
|
{
|
||||||
symbols_vd2.push_back(*symbol_it);
|
symbols_vd2.push_back(*symbol_it);
|
||||||
}
|
}
|
||||||
@ -333,7 +340,7 @@ bool sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::get_bits(const st
|
|||||||
float metric_vd1 = d_vd1->decode_continuous(symbols_vd1.data(), traceback_depth, bits_vd1, nbits_requested, nbits_decoded);
|
float metric_vd1 = d_vd1->decode_continuous(symbols_vd1.data(), traceback_depth, bits_vd1, nbits_requested, nbits_decoded);
|
||||||
float metric_vd2 = d_vd2->decode_continuous(symbols_vd2.data(), traceback_depth, bits_vd2, nbits_requested, nbits_decoded);
|
float metric_vd2 = d_vd2->decode_continuous(symbols_vd2.data(), traceback_depth, bits_vd2, nbits_requested, nbits_decoded);
|
||||||
// choose the bits with the better metric
|
// choose the bits with the better metric
|
||||||
for (int i = 0; i<nbits_decoded; i++)
|
for (int i = 0; i < nbits_decoded; i++)
|
||||||
{
|
{
|
||||||
if (metric_vd1 > metric_vd2)
|
if (metric_vd1 > metric_vd2)
|
||||||
{// symbols aligned
|
{// symbols aligned
|
||||||
@ -363,8 +370,8 @@ void sbas_l1_telemetry_decoder_cc::frame_detector::get_frame_candidates(const st
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
unsigned int sbas_msg_length = 250;
|
unsigned int sbas_msg_length = 250;
|
||||||
std::vector<std::vector<int>> preambles = {{0, 1, 0, 1, 0, 0, 1 ,1},
|
std::vector<std::vector<int>> preambles = {{0, 1, 0, 1, 0, 0, 1 ,1},
|
||||||
{1, 0, 0, 1, 1, 0, 1, 0},
|
{1, 0, 0, 1, 1, 0, 1, 0},
|
||||||
{1, 1, 0, 0, 0, 1, 1, 0}};
|
{1, 1, 0, 0, 0, 1, 1, 0}};
|
||||||
VLOG(FLOW) << "get_frame_candidates(): " << "d_buffer.size()=" << d_buffer.size() << "\tbits.size()=" << bits.size();
|
VLOG(FLOW) << "get_frame_candidates(): " << "d_buffer.size()=" << d_buffer.size() << "\tbits.size()=" << bits.size();
|
||||||
ss << "copy bits ";
|
ss << "copy bits ";
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -399,7 +406,7 @@ void sbas_l1_telemetry_decoder_cc::frame_detector::get_frame_candidates(const st
|
|||||||
{
|
{
|
||||||
// invert bits
|
// invert bits
|
||||||
for (std::vector<int>::iterator candidate_bit_it = candidate.begin(); candidate_bit_it != candidate.end(); candidate_bit_it++)
|
for (std::vector<int>::iterator candidate_bit_it = candidate.begin(); candidate_bit_it != candidate.end(); candidate_bit_it++)
|
||||||
*candidate_bit_it = *candidate_bit_it == 0 ? 1:0;
|
*candidate_bit_it = *candidate_bit_it == 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
msg_candidates.push_back(std::pair<int,std::vector<int>>(relative_preamble_start, candidate));
|
msg_candidates.push_back(std::pair<int,std::vector<int>>(relative_preamble_start, candidate));
|
||||||
ss.str("");
|
ss.str("");
|
||||||
@ -438,12 +445,13 @@ void sbas_l1_telemetry_decoder_cc::crc_verifier::get_valid_frames(const std::vec
|
|||||||
d_checksum_agent.reset(0);
|
d_checksum_agent.reset(0);
|
||||||
d_checksum_agent.process_bytes(candidate_bytes.data(), candidate_bytes.size());
|
d_checksum_agent.process_bytes(candidate_bytes.data(), candidate_bytes.size());
|
||||||
unsigned int crc = d_checksum_agent.checksum();
|
unsigned int crc = d_checksum_agent.checksum();
|
||||||
VLOG(SAMP_SYNC) << "candidate " << candidate_it - msg_candidates.begin() << ": final crc remainder= " << std::hex << crc
|
VLOG(SAMP_SYNC) << "candidate " << candidate_it - msg_candidates.begin()
|
||||||
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
<< ": final crc remainder= " << std::hex << crc
|
||||||
|
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
||||||
// the final remainder must be zero for a valid message, because the CRC is done over the received CRC value
|
// the final remainder must be zero for a valid message, because the CRC is done over the received CRC value
|
||||||
if (crc == 0)
|
if (crc == 0)
|
||||||
{
|
{
|
||||||
valid_msgs.push_back(msg_candiate_char_t(candidate_it->first,candidate_bytes));
|
valid_msgs.push_back(msg_candiate_char_t(candidate_it->first, candidate_bytes));
|
||||||
ss << "Valid message found!";
|
ss << "Valid message found!";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -483,8 +491,9 @@ void sbas_l1_telemetry_decoder_cc::crc_verifier::zerropad_back_and_convert_to_by
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bytes.push_back(byte); // implies: insert 6 zeros at the end to fit the 250bits into a multiple of bytes
|
bytes.push_back(byte); // implies: insert 6 zeros at the end to fit the 250bits into a multiple of bytes
|
||||||
VLOG(LMORE) << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)byte
|
VLOG(LMORE) << " -> byte=" << std::setw(2)
|
||||||
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
<< std::setfill('0') << std::hex << (unsigned int)byte
|
||||||
|
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -504,13 +513,15 @@ void sbas_l1_telemetry_decoder_cc::crc_verifier::zerropad_front_and_convert_to_b
|
|||||||
if (idx_bit % bits_per_byte == bits_per_byte - 1)
|
if (idx_bit % bits_per_byte == bits_per_byte - 1)
|
||||||
{
|
{
|
||||||
bytes.push_back(byte);
|
bytes.push_back(byte);
|
||||||
VLOG(LMORE) << ss.str() << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)byte; ss.str("");
|
VLOG(LMORE) << ss.str() << " -> byte=" << std::setw(2)
|
||||||
|
<< std::setfill('0') << std::hex << (unsigned int)byte; ss.str("");
|
||||||
byte = 0;
|
byte = 0;
|
||||||
}
|
}
|
||||||
idx_bit++;
|
idx_bit++;
|
||||||
}
|
}
|
||||||
VLOG(LMORE) << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)byte
|
VLOG(LMORE) << " -> byte=" << std::setw(2)
|
||||||
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
<< std::setfill('0') << std::hex << (unsigned int)byte
|
||||||
|
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,13 +59,21 @@ public:
|
|||||||
void set_channel(int channel); //!< Set receiver's channel
|
void set_channel(int channel); //!< Set receiver's channel
|
||||||
|
|
||||||
// queues to communicate broadcasted SBAS data to other blocks of GNSS-SDR
|
// queues to communicate broadcasted SBAS data to other blocks of GNSS-SDR
|
||||||
void set_raw_msg_queue(concurrent_queue<Sbas_Raw_Msg> *raw_msg_queue);
|
void set_raw_msg_queue(concurrent_queue<Sbas_Raw_Msg> *raw_msg_queue); //!< Set raw msg queue
|
||||||
void set_iono_queue(concurrent_queue<Sbas_Ionosphere_Correction> *iono_queue);
|
void set_iono_queue(concurrent_queue<Sbas_Ionosphere_Correction> *iono_queue); //!< Set iono queue
|
||||||
void set_sat_corr_queue(concurrent_queue<Sbas_Satellite_Correction> *sat_corr_queue);
|
void set_sat_corr_queue(concurrent_queue<Sbas_Satellite_Correction> *sat_corr_queue); //!< Set sat correction queue
|
||||||
void set_ephemeris_queue(concurrent_queue<Sbas_Ephemeris> *ephemeris_queue);
|
void set_ephemeris_queue(concurrent_queue<Sbas_Ephemeris> *ephemeris_queue); //!< Set SBAS ephemeis queue
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief This is where all signal processing takes place
|
||||||
|
*/
|
||||||
int general_work (int noutput_items, gr_vector_int &ninput_items,
|
int general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Function which tells the scheduler how many input items
|
||||||
|
* are required to produce noutput_items output items.
|
||||||
|
*/
|
||||||
void forecast (int noutput_items, gr_vector_int &ninput_items_required);
|
void forecast (int noutput_items, gr_vector_int &ninput_items_required);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
|
* Copyright (C) 2010-2013 (see AUTHORS file for a list of contributors)
|
||||||
*
|
*
|
||||||
* GNSS-SDR is a software defined Global Navigation
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
* Satellite Systems receiver
|
* Satellite Systems receiver
|
||||||
@ -228,22 +228,28 @@ public:
|
|||||||
|
|
||||||
GpsL1CaSubframeFsm::GpsL1CaSubframeFsm()
|
GpsL1CaSubframeFsm::GpsL1CaSubframeFsm()
|
||||||
{
|
{
|
||||||
d_nav.reset();
|
d_nav.reset();
|
||||||
initiate(); //start the FSM
|
initiate(); //start the FSM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaSubframeFsm::gps_word_to_subframe(int position)
|
void GpsL1CaSubframeFsm::gps_word_to_subframe(int position)
|
||||||
{
|
{
|
||||||
// insert the word in the correct position of the subframe
|
// insert the word in the correct position of the subframe
|
||||||
std::memcpy(&d_subframe[position*GPS_WORD_LENGTH], &d_GPS_frame_4bytes, sizeof(char)*GPS_WORD_LENGTH);
|
std::memcpy(&d_subframe[position*GPS_WORD_LENGTH], &d_GPS_frame_4bytes, sizeof(char)*GPS_WORD_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaSubframeFsm::gps_subframe_to_nav_msg()
|
void GpsL1CaSubframeFsm::gps_subframe_to_nav_msg()
|
||||||
{
|
{
|
||||||
int subframe_ID;
|
int subframe_ID;
|
||||||
// NEW GPS SUBFRAME HAS ARRIVED!
|
// NEW GPS SUBFRAME HAS ARRIVED!
|
||||||
subframe_ID = d_nav.subframe_decoder(this->d_subframe); //decode the subframe
|
subframe_ID = d_nav.subframe_decoder(this->d_subframe); //decode the subframe
|
||||||
std::cout << "NAVIGATION FSM: received subframe " << subframe_ID << " for satellite " << Gnss_Satellite(std::string("GPS"), i_satellite_PRN) << std::endl;
|
std::cout << "NAVIGATION FSM: received subframe "
|
||||||
|
<< subframe_ID << " for satellite "
|
||||||
|
<< Gnss_Satellite(std::string("GPS"), i_satellite_PRN) << std::endl;
|
||||||
d_nav.i_satellite_PRN = i_satellite_PRN;
|
d_nav.i_satellite_PRN = i_satellite_PRN;
|
||||||
d_nav.i_channel_ID = i_channel_ID;
|
d_nav.i_channel_ID = i_channel_ID;
|
||||||
d_nav.d_subframe_timestamp_ms = this->d_preamble_time_ms;
|
d_nav.d_subframe_timestamp_ms = this->d_preamble_time_ms;
|
||||||
@ -251,48 +257,52 @@ void GpsL1CaSubframeFsm::gps_subframe_to_nav_msg()
|
|||||||
switch (subframe_ID)
|
switch (subframe_ID)
|
||||||
{
|
{
|
||||||
case 3: //we have a new set of ephemeris data for the current SV
|
case 3: //we have a new set of ephemeris data for the current SV
|
||||||
if (d_nav.satellite_validation()==true)
|
if (d_nav.satellite_validation() == true)
|
||||||
{
|
{
|
||||||
// get ephemeris object for this SV (mandatory)
|
// get ephemeris object for this SV (mandatory)
|
||||||
Gps_Ephemeris ephemeris=d_nav.get_ephemeris();
|
Gps_Ephemeris ephemeris = d_nav.get_ephemeris();
|
||||||
d_ephemeris_queue->push(ephemeris);
|
d_ephemeris_queue->push(ephemeris);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4: // Possible IONOSPHERE and UTC model update (page 18)
|
case 4: // Possible IONOSPHERE and UTC model update (page 18)
|
||||||
if (d_nav.flag_iono_valid==true)
|
if (d_nav.flag_iono_valid == true)
|
||||||
{
|
{
|
||||||
Gps_Iono iono=d_nav.get_iono(); //notice that the read operation will clear the valid flag
|
Gps_Iono iono = d_nav.get_iono(); //notice that the read operation will clear the valid flag
|
||||||
d_iono_queue->push(iono);
|
d_iono_queue->push(iono);
|
||||||
}
|
}
|
||||||
if (d_nav.flag_utc_model_valid==true)
|
if (d_nav.flag_utc_model_valid == true)
|
||||||
{
|
{
|
||||||
Gps_Utc_Model utc_model=d_nav.get_utc_model(); //notice that the read operation will clear the valid flag
|
Gps_Utc_Model utc_model = d_nav.get_utc_model(); //notice that the read operation will clear the valid flag
|
||||||
d_utc_model_queue->push(utc_model);
|
d_utc_model_queue->push(utc_model);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
// get almanac (if available)
|
// get almanac (if available)
|
||||||
//TODO: implement almanac reader in navigation_message
|
//TODO: implement almanac reader in navigation_message
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaSubframeFsm::Event_gps_word_valid()
|
void GpsL1CaSubframeFsm::Event_gps_word_valid()
|
||||||
{
|
{
|
||||||
this->process_event(Ev_gps_word_valid());
|
this->process_event(Ev_gps_word_valid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaSubframeFsm::Event_gps_word_invalid()
|
void GpsL1CaSubframeFsm::Event_gps_word_invalid()
|
||||||
{
|
{
|
||||||
this->process_event(Ev_gps_word_invalid());
|
this->process_event(Ev_gps_word_invalid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GpsL1CaSubframeFsm::Event_gps_word_preamble()
|
void GpsL1CaSubframeFsm::Event_gps_word_preamble()
|
||||||
{
|
{
|
||||||
this->process_event(Ev_gps_word_preamble());
|
this->process_event(Ev_gps_word_preamble());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,46 +67,48 @@ struct gps_subframe_fsm_S9;
|
|||||||
struct gps_subframe_fsm_S10;
|
struct gps_subframe_fsm_S10;
|
||||||
struct gps_subframe_fsm_S11;
|
struct gps_subframe_fsm_S11;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief This class implements a Finite State Machine that handles the decoding
|
||||||
|
* of the GPS L1 C/A NAV message
|
||||||
|
*/
|
||||||
class GpsL1CaSubframeFsm : public sc::state_machine< GpsL1CaSubframeFsm, gps_subframe_fsm_S0 >
|
class GpsL1CaSubframeFsm : public sc::state_machine< GpsL1CaSubframeFsm, gps_subframe_fsm_S0 >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// channel and satellite info
|
GpsL1CaSubframeFsm(); //!< The constructor starts the Finite State Machine
|
||||||
int i_channel_ID;
|
|
||||||
unsigned int i_satellite_PRN;
|
|
||||||
|
|
||||||
// ephemeris queue
|
// channel and satellite info
|
||||||
concurrent_queue<Gps_Ephemeris> *d_ephemeris_queue;
|
int i_channel_ID; //!< Channel id
|
||||||
// ionospheric parameters queue
|
unsigned int i_satellite_PRN; //!< Satellite PRN number
|
||||||
concurrent_queue<Gps_Iono> *d_iono_queue;
|
|
||||||
// UTC model parameters queue
|
|
||||||
concurrent_queue<Gps_Utc_Model> *d_utc_model_queue;
|
|
||||||
// Almanac queue
|
|
||||||
concurrent_queue<Gps_Almanac> *d_almanac_queue;
|
|
||||||
|
|
||||||
// navigation message class
|
concurrent_queue<Gps_Ephemeris> *d_ephemeris_queue; //!< Ephemeris queue
|
||||||
Gps_Navigation_Message d_nav;
|
concurrent_queue<Gps_Iono> *d_iono_queue; //!< Ionospheric parameters queue
|
||||||
|
concurrent_queue<Gps_Utc_Model> *d_utc_model_queue; //!< UTC model parameters queue
|
||||||
|
concurrent_queue<Gps_Almanac> *d_almanac_queue; //!< Almanac queue
|
||||||
|
|
||||||
// GPS SV and System parameters
|
Gps_Navigation_Message d_nav; //!< GPS L1 C/A navigation message object
|
||||||
Gps_Ephemeris ephemeris;
|
|
||||||
Gps_Almanac almanac;
|
|
||||||
Gps_Utc_Model utc_model;
|
|
||||||
Gps_Iono iono;
|
|
||||||
|
|
||||||
|
// GPS SV and System parameters
|
||||||
|
Gps_Ephemeris ephemeris; //!< Object that handles GPS ephemeris parameters
|
||||||
|
Gps_Almanac almanac; //!< Object that handles GPS almanac data
|
||||||
|
Gps_Utc_Model utc_model; //!< Object that handles UTM model parameters
|
||||||
|
Gps_Iono iono; //!< Object that handles ionospheric parameters
|
||||||
|
|
||||||
char d_subframe[GPS_SUBFRAME_LENGTH];
|
char d_subframe[GPS_SUBFRAME_LENGTH];
|
||||||
char d_GPS_frame_4bytes[GPS_WORD_LENGTH];
|
char d_GPS_frame_4bytes[GPS_WORD_LENGTH];
|
||||||
|
double d_preamble_time_ms;
|
||||||
|
|
||||||
double d_preamble_time_ms;
|
void gps_word_to_subframe(int position); //!< inserts the word in the correct position of the subframe
|
||||||
|
|
||||||
void gps_word_to_subframe(int position);
|
/*!
|
||||||
void gps_subframe_to_nav_msg();
|
* \brief This function decodes a NAv message subframe and pushes the information to the right queues
|
||||||
|
*/
|
||||||
|
void gps_subframe_to_nav_msg();
|
||||||
|
|
||||||
//FSM EVENTS
|
//FSM EVENTS
|
||||||
void Event_gps_word_valid();
|
void Event_gps_word_valid(); //!< FSM event: the received word is valid
|
||||||
void Event_gps_word_invalid();
|
void Event_gps_word_invalid(); //!< FSM event: the received word is not valid
|
||||||
void Event_gps_word_preamble();
|
void Event_gps_word_preamble(); //!< FSM event: word preamble detected
|
||||||
|
|
||||||
GpsL1CaSubframeFsm();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,7 +47,6 @@
|
|||||||
|
|
||||||
Viterbi_Decoder::Viterbi_Decoder(const int g_encoder[], const int KK, const int nn)
|
Viterbi_Decoder::Viterbi_Decoder(const int g_encoder[], const int KK, const int nn)
|
||||||
{
|
{
|
||||||
|
|
||||||
d_nn = nn; //Coding rate 1/n
|
d_nn = nn; //Coding rate 1/n
|
||||||
d_KK = KK; //Constraint Length
|
d_KK = KK; //Constraint Length
|
||||||
|
|
||||||
@ -84,27 +83,25 @@ Viterbi_Decoder::~Viterbi_Decoder()
|
|||||||
delete[] d_metric_c;
|
delete[] d_metric_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Viterbi_Decoder::reset()
|
|
||||||
|
void Viterbi_Decoder::reset()
|
||||||
{
|
{
|
||||||
init_trellis_state();
|
init_trellis_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Function decode_block()
|
/* Function decode_block()
|
||||||
|
|
||||||
Description: Uses the Viterbi algorithm to perform hard-decision decoding of a convolutional code.
|
Description: Uses the Viterbi algorithm to perform hard-decision decoding of a convolutional code.
|
||||||
|
|
||||||
Input parameters:
|
Input parameters:
|
||||||
r[] The received signal in LLR-form. For BPSK, must be in form r = 2*a*y/(sigma^2).
|
r[] The received signal in LLR-form. For BPSK, must be in form r = 2*a*y/(sigma^2).
|
||||||
LL The number of data bits to be decoded (doen't inlcude the mm zero-tail-bits)
|
LL The number of data bits to be decoded (doen't inlcude the mm zero-tail-bits)
|
||||||
|
|
||||||
Output parameters:
|
Output parameters:
|
||||||
output_u_int[] Hard decisions on the data bits (without the mm zero-tail-bits)
|
output_u_int[] Hard decisions on the data bits (without the mm zero-tail-bits)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
float Viterbi_Decoder::decode_block(const double input_c[], int output_u_int[], const int LL)
|
||||||
float
|
|
||||||
Viterbi_Decoder::decode_block(const double input_c[], int output_u_int[], const int LL)
|
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
int decoding_length_mismatch;
|
int decoding_length_mismatch;
|
||||||
@ -125,9 +122,13 @@ Viterbi_Decoder::decode_block(const double input_c[], int output_u_int[], const
|
|||||||
return d_indicator_metric;
|
return d_indicator_metric;
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
|
||||||
Viterbi_Decoder::decode_continuous(const double sym[], const int traceback_depth, int bits[],
|
|
||||||
const int nbits_requested, int &nbits_decoded)
|
float Viterbi_Decoder::decode_continuous(const double sym[],
|
||||||
|
const int traceback_depth,
|
||||||
|
int bits[],
|
||||||
|
const int nbits_requested,
|
||||||
|
int &nbits_decoded)
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
int decoding_length_mismatch;
|
int decoding_length_mismatch;
|
||||||
@ -150,11 +151,11 @@ Viterbi_Decoder::decode_continuous(const double sym[], const int traceback_depth
|
|||||||
return d_indicator_metric;
|
return d_indicator_metric;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Viterbi_Decoder::init_trellis_state()
|
|
||||||
|
void Viterbi_Decoder::init_trellis_state()
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
// if trellis state has been initialised, free old state memory
|
// if trellis state has been initialised, free old state memory
|
||||||
if(d_trellis_state_is_initialised)
|
if(d_trellis_state_is_initialised)
|
||||||
{
|
{
|
||||||
@ -182,8 +183,10 @@ Viterbi_Decoder::init_trellis_state()
|
|||||||
d_indicator_metric = 0;
|
d_indicator_metric = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
Viterbi_Decoder::do_acs(const double sym[], int nbits)
|
|
||||||
|
|
||||||
|
int Viterbi_Decoder::do_acs(const double sym[], int nbits)
|
||||||
{
|
{
|
||||||
int t, i, state_at_t;
|
int t, i, state_at_t;
|
||||||
float metric;
|
float metric;
|
||||||
@ -202,11 +205,9 @@ Viterbi_Decoder::do_acs(const double sym[], int nbits)
|
|||||||
pm_t_next[state_at_t] = -MAXLOG;
|
pm_t_next[state_at_t] = -MAXLOG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* go through trellis */
|
/* go through trellis */
|
||||||
for (t = 0; t < nbits; t++)
|
for (t = 0; t < nbits; t++)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Temporarily store the received symbols current decoding step */
|
/* Temporarily store the received symbols current decoding step */
|
||||||
for (i = 0; i < d_nn; i++)
|
for (i = 0; i < d_nn; i++)
|
||||||
d_rec_array[i] = (float) sym[d_nn * t + i];
|
d_rec_array[i] = (float) sym[d_nn * t + i];
|
||||||
@ -223,7 +224,6 @@ Viterbi_Decoder::do_acs(const double sym[], int nbits)
|
|||||||
/* step through all states */
|
/* step through all states */
|
||||||
for (state_at_t = 0; state_at_t < d_states; state_at_t++)
|
for (state_at_t = 0; state_at_t < d_states; state_at_t++)
|
||||||
{
|
{
|
||||||
|
|
||||||
int next_state_if_0 = d_state0[state_at_t];
|
int next_state_if_0 = d_state0[state_at_t];
|
||||||
int next_state_if_1 = d_state1[state_at_t];
|
int next_state_if_1 = d_state1[state_at_t];
|
||||||
|
|
||||||
@ -256,7 +256,6 @@ Viterbi_Decoder::do_acs(const double sym[], int nbits)
|
|||||||
|
|
||||||
d_trellis_paths.push_front(next_trellis_states);
|
d_trellis_paths.push_front(next_trellis_states);
|
||||||
|
|
||||||
|
|
||||||
/* normalize -> afterwards, the largest metric value is always 0 */
|
/* normalize -> afterwards, the largest metric value is always 0 */
|
||||||
//max_val = 0;
|
//max_val = 0;
|
||||||
max_val = -MAXLOG;
|
max_val = -MAXLOG;
|
||||||
@ -275,14 +274,14 @@ Viterbi_Decoder::do_acs(const double sym[], int nbits)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
delete[] pm_t_next;
|
delete[] pm_t_next;
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
Viterbi_Decoder::do_traceback(size_t traceback_length)
|
|
||||||
|
int Viterbi_Decoder::do_traceback(size_t traceback_length)
|
||||||
{
|
{
|
||||||
// traceback_length is in bits
|
// traceback_length is in bits
|
||||||
int state;
|
int state;
|
||||||
@ -303,17 +302,17 @@ Viterbi_Decoder::do_traceback(size_t traceback_length)
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
Viterbi_Decoder::do_tb_and_decode(int traceback_length, int requested_decoding_length, int state, int output_u_int[], float& indicator_metric)
|
|
||||||
|
|
||||||
|
int Viterbi_Decoder::do_tb_and_decode(int traceback_length, int requested_decoding_length, int state, int output_u_int[], float& indicator_metric)
|
||||||
{
|
{
|
||||||
int n_of_branches_for_indicator_metric = 500;
|
int n_of_branches_for_indicator_metric = 500;
|
||||||
|
|
||||||
int t_out;
|
int t_out;
|
||||||
std::deque<Prev>::iterator it;
|
std::deque<Prev>::iterator it;
|
||||||
int decoding_length_mismatch;
|
int decoding_length_mismatch;
|
||||||
int overstep_length;
|
int overstep_length;
|
||||||
|
int n_im = 0;
|
||||||
int n_im=0;
|
|
||||||
|
|
||||||
VLOG(FLOW) << "do_tb_and_decode(): requested_decoding_length=" << requested_decoding_length;
|
VLOG(FLOW) << "do_tb_and_decode(): requested_decoding_length=" << requested_decoding_length;
|
||||||
|
|
||||||
@ -323,12 +322,13 @@ Viterbi_Decoder::do_tb_and_decode(int traceback_length, int requested_decoding_l
|
|||||||
overstep_length = decoding_length_mismatch >= 0 ? decoding_length_mismatch : 0;
|
overstep_length = decoding_length_mismatch >= 0 ? decoding_length_mismatch : 0;
|
||||||
VLOG(BLOCK) << "overstep_length=" << overstep_length;
|
VLOG(BLOCK) << "overstep_length=" << overstep_length;
|
||||||
|
|
||||||
for (it = d_trellis_paths.begin() + traceback_length; it < d_trellis_paths.begin()+traceback_length + overstep_length; ++it)
|
for (it = d_trellis_paths.begin() + traceback_length;
|
||||||
|
it < d_trellis_paths.begin() + traceback_length + overstep_length; ++it)
|
||||||
{
|
{
|
||||||
state = it->get_anchestor_state_of_current_state(state);
|
state = it->get_anchestor_state_of_current_state(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
t_out = d_trellis_paths.end()-(d_trellis_paths.begin() + traceback_length + overstep_length)-1;//requested_decoding_length-1;
|
t_out = d_trellis_paths.end() - (d_trellis_paths.begin() + traceback_length + overstep_length) - 1;//requested_decoding_length-1;
|
||||||
indicator_metric = 0;
|
indicator_metric = 0;
|
||||||
for (it = d_trellis_paths.begin() + traceback_length + overstep_length; it < d_trellis_paths.end(); ++it)
|
for (it = d_trellis_paths.begin() + traceback_length + overstep_length; it < d_trellis_paths.end(); ++it)
|
||||||
{
|
{
|
||||||
@ -342,19 +342,20 @@ Viterbi_Decoder::do_tb_and_decode(int traceback_length, int requested_decoding_l
|
|||||||
}
|
}
|
||||||
output_u_int[t_out] = it->get_bit_of_current_state(state);
|
output_u_int[t_out] = it->get_bit_of_current_state(state);
|
||||||
state = it->get_anchestor_state_of_current_state(state);
|
state = it->get_anchestor_state_of_current_state(state);
|
||||||
|
|
||||||
t_out--;
|
t_out--;
|
||||||
}
|
}
|
||||||
indicator_metric/=n_im;
|
indicator_metric /= n_im;
|
||||||
VLOG(BLOCK) << "indicator metric: " << indicator_metric;
|
VLOG(BLOCK) << "indicator metric: " << indicator_metric;
|
||||||
// remove old states
|
// remove old states
|
||||||
if (d_trellis_paths.begin() + traceback_length+overstep_length <= d_trellis_paths.end())
|
if (d_trellis_paths.begin() + traceback_length + overstep_length <= d_trellis_paths.end())
|
||||||
{
|
{
|
||||||
d_trellis_paths.erase(d_trellis_paths.begin()+traceback_length+overstep_length, d_trellis_paths.end());
|
d_trellis_paths.erase(d_trellis_paths.begin() + traceback_length+overstep_length, d_trellis_paths.end());
|
||||||
}
|
}
|
||||||
return decoding_length_mismatch;
|
return decoding_length_mismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* function Gamma()
|
/* function Gamma()
|
||||||
|
|
||||||
Description: Computes the branch metric used for decoding.
|
Description: Computes the branch metric used for decoding.
|
||||||
@ -426,8 +427,7 @@ Viterbi_Decoder::nsc_transit(int output_p[], int trans_p[], int input, const int
|
|||||||
|
|
||||||
This function is used by rsc_encode(), nsc_transit(), rsc_transit(), and nsc_transit() */
|
This function is used by rsc_encode(), nsc_transit(), rsc_transit(), and nsc_transit() */
|
||||||
|
|
||||||
int
|
int Viterbi_Decoder::nsc_enc_bit(int state_out_p[], int input, int state_in,
|
||||||
Viterbi_Decoder::nsc_enc_bit(int state_out_p[], int input, int state_in,
|
|
||||||
const int g[], int KK, int nn)
|
const int g[], int KK, int nn)
|
||||||
{
|
{
|
||||||
/* declare variables */
|
/* declare variables */
|
||||||
@ -462,18 +462,15 @@ Viterbi_Decoder::nsc_enc_bit(int state_out_p[], int input, int state_in,
|
|||||||
|
|
||||||
This function is used by nsc_enc_bit(), rsc_enc_bit(), and rsc_tail() */
|
This function is used by nsc_enc_bit(), rsc_enc_bit(), and rsc_tail() */
|
||||||
|
|
||||||
int
|
int Viterbi_Decoder::parity_counter(int symbol, int length)
|
||||||
Viterbi_Decoder::parity_counter(int symbol, int length)
|
|
||||||
{
|
{
|
||||||
int counter;
|
int counter;
|
||||||
int temp_parity = 0;
|
int temp_parity = 0;
|
||||||
|
|
||||||
for (counter = 0; counter < length; counter++)
|
for (counter = 0; counter < length; counter++)
|
||||||
{
|
{
|
||||||
temp_parity = temp_parity ^ (symbol & 1);
|
temp_parity = temp_parity ^ (symbol & 1);
|
||||||
symbol = symbol >> 1;
|
symbol = symbol >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (temp_parity);
|
return (temp_parity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,27 +483,26 @@ Viterbi_Decoder::Prev::Prev(int states, int t)
|
|||||||
state = new int[states];
|
state = new int[states];
|
||||||
bit = new int[states];
|
bit = new int[states];
|
||||||
metric = new float[states];
|
metric = new float[states];
|
||||||
|
|
||||||
refcount = new int;
|
refcount = new int;
|
||||||
*refcount = 1;
|
*refcount = 1;
|
||||||
|
|
||||||
//std::cout << "Prev(" << states << ", " << t << ")" << " constructor" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// copy constructor
|
// copy constructor
|
||||||
Viterbi_Decoder::Prev::Prev(const Prev& prev)
|
Viterbi_Decoder::Prev::Prev(const Prev& prev)
|
||||||
{
|
{
|
||||||
refcount = prev.refcount;
|
refcount = prev.refcount;
|
||||||
(*refcount)++;
|
(*refcount)++;
|
||||||
|
|
||||||
t = prev.t;
|
t = prev.t;
|
||||||
state = prev.state;
|
state = prev.state;
|
||||||
bit = prev.bit;
|
bit = prev.bit;
|
||||||
metric = prev.metric;
|
metric = prev.metric;
|
||||||
|
|
||||||
VLOG(LMORE) << "Prev(" << "?" << ", " << t << ")" << " copy, new refcount = " << *refcount;
|
VLOG(LMORE) << "Prev(" << "?" << ", " << t << ")" << " copy, new refcount = " << *refcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// assignment constructor
|
// assignment constructor
|
||||||
Viterbi_Decoder::Prev& Viterbi_Decoder::Prev::operator=(const Prev& other)
|
Viterbi_Decoder::Prev& Viterbi_Decoder::Prev::operator=(const Prev& other)
|
||||||
{
|
{
|
||||||
@ -517,7 +513,7 @@ Viterbi_Decoder::Prev& Viterbi_Decoder::Prev::operator=(const Prev& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle old resources
|
// handle old resources
|
||||||
if(*refcount==1)
|
if(*refcount == 1)
|
||||||
{ // if they are not used anymore -> unallocate them
|
{ // if they are not used anymore -> unallocate them
|
||||||
delete[] state;
|
delete[] state;
|
||||||
delete[] bit;
|
delete[] bit;
|
||||||
@ -543,6 +539,9 @@ Viterbi_Decoder::Prev& Viterbi_Decoder::Prev::operator=(const Prev& other)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Viterbi_Decoder::Prev::~Prev()
|
Viterbi_Decoder::Prev::~Prev()
|
||||||
{
|
{
|
||||||
if (*refcount == 1)
|
if (*refcount == 1)
|
||||||
@ -560,12 +559,16 @@ Viterbi_Decoder::Prev::~Prev()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int Viterbi_Decoder::Prev::get_anchestor_state_of_current_state(int current_state)
|
int Viterbi_Decoder::Prev::get_anchestor_state_of_current_state(int current_state)
|
||||||
{
|
{
|
||||||
//std::cout << "get prev state: for state " << current_state << " at time " << t << ", the prev state at time " << t-1 << " is " << state[current_state] << std::endl;
|
//std::cout << "get prev state: for state " << current_state << " at time " << t << ", the prev state at time " << t-1 << " is " << state[current_state] << std::endl;
|
||||||
return state[current_state];
|
return state[current_state];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int Viterbi_Decoder::Prev::get_bit_of_current_state(int current_state)
|
int Viterbi_Decoder::Prev::get_bit_of_current_state(int current_state)
|
||||||
{
|
{
|
||||||
//std::cout << "get prev bit : for state " << current_state << " at time " << t << ", the send bit is " << bit[current_state] << std::endl;
|
//std::cout << "get prev bit : for state " << current_state << " at time " << t << ", the send bit is " << bit[current_state] << std::endl;
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef GNSS_SDR_VITERBIDECODER_H_
|
#ifndef GNSS_SDR_VITERBI_DECODER_H_
|
||||||
#define GNSS_SDR_VITERBIDECODER_H_
|
#define GNSS_SDR_VITERBI_DECODER_H_
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -41,12 +41,22 @@ public:
|
|||||||
Viterbi_Decoder(const int g_encoder[], const int KK, const int nn);
|
Viterbi_Decoder(const int g_encoder[], const int KK, const int nn);
|
||||||
~Viterbi_Decoder();
|
~Viterbi_Decoder();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Uses the Viterbi algorithm to perform hard-decision decoding of a convolutional code.
|
||||||
|
*
|
||||||
|
* \param input_c[] The received signal in LLR-form. For BPSK, must be in form r = 2*a*y/(sigma^2).
|
||||||
|
* \param LL The number of data bits to be decoded (does not include the mm zero-tail-bits)
|
||||||
|
*
|
||||||
|
* \return output_u_int[] Hard decisions on the data bits (without the mm zero-tail-bits)
|
||||||
|
*/
|
||||||
float decode_block(const double input_c[], int* output_u_int, const int LL);
|
float decode_block(const double input_c[], int* output_u_int, const int LL);
|
||||||
|
|
||||||
|
|
||||||
float decode_continuous(const double sym[], const int traceback_depth, int output_u_int[],
|
float decode_continuous(const double sym[], const int traceback_depth, int output_u_int[],
|
||||||
const int nbits_requested, int &nbits_decoded);
|
const int nbits_requested, int &nbits_decoded);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
class Prev
|
class Prev
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -111,4 +121,4 @@ private:
|
|||||||
int parity_counter(int symbol, int length);
|
int parity_counter(int symbol, int length);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* GNSS_SDR_VITERBIDECODER_H_ */
|
#endif /* GNSS_SDR_VITERBI_DECODER_H_ */
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
|
* Copyright (C) 2010-2013 (see AUTHORS file for a list of contributors)
|
||||||
*
|
*
|
||||||
* GNSS-SDR is a software defined Global Navigation
|
* GNSS-SDR is a software defined Global Navigation
|
||||||
* Satellite Systems receiver
|
* Satellite Systems receiver
|
||||||
@ -38,12 +38,10 @@
|
|||||||
#include "gps_iono.h"
|
#include "gps_iono.h"
|
||||||
#include "gps_utc_model.h"
|
#include "gps_utc_model.h"
|
||||||
#include "gps_almanac.h"
|
#include "gps_almanac.h"
|
||||||
|
|
||||||
#include "galileo_ephemeris.h"
|
#include "galileo_ephemeris.h"
|
||||||
#include "galileo_iono.h"
|
#include "galileo_iono.h"
|
||||||
#include "galileo_utc_model.h"
|
#include "galileo_utc_model.h"
|
||||||
#include "galileo_almanac.h"
|
#include "galileo_almanac.h"
|
||||||
|
|
||||||
#include "concurrent_queue.h"
|
#include "concurrent_queue.h"
|
||||||
#include "concurrent_map.h"
|
#include "concurrent_map.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -106,10 +104,10 @@ ControlThread::ControlThread(ConfigurationInterface *configuration)
|
|||||||
|
|
||||||
ControlThread::~ControlThread()
|
ControlThread::~ControlThread()
|
||||||
{
|
{
|
||||||
// save navigation data to files
|
// save navigation data to files
|
||||||
gps_ephemeris_data_write_to_XML();
|
gps_ephemeris_data_write_to_XML();
|
||||||
gps_iono_data_write_to_XML();
|
gps_iono_data_write_to_XML();
|
||||||
gps_utc_model_data_write_to_XML();
|
gps_utc_model_data_write_to_XML();
|
||||||
|
|
||||||
delete flowgraph_;
|
delete flowgraph_;
|
||||||
if (delete_configuration_) delete configuration_;
|
if (delete_configuration_) delete configuration_;
|
||||||
@ -155,14 +153,14 @@ void ControlThread::run()
|
|||||||
keyboard_thread_ = boost::thread(&ControlThread::keyboard_listener, this);
|
keyboard_thread_ = boost::thread(&ControlThread::keyboard_listener, this);
|
||||||
|
|
||||||
//start the GNSS SV data collector thread
|
//start the GNSS SV data collector thread
|
||||||
gps_ephemeris_data_collector_thread_ =boost::thread(&ControlThread::gps_ephemeris_data_collector, this);
|
gps_ephemeris_data_collector_thread_ = boost::thread(&ControlThread::gps_ephemeris_data_collector, this);
|
||||||
gps_iono_data_collector_thread_ =boost::thread(&ControlThread::gps_iono_data_collector, this);
|
gps_iono_data_collector_thread_ = boost::thread(&ControlThread::gps_iono_data_collector, this);
|
||||||
gps_utc_model_data_collector_thread_ =boost::thread(&ControlThread::gps_utc_model_data_collector, this);
|
gps_utc_model_data_collector_thread_ = boost::thread(&ControlThread::gps_utc_model_data_collector, this);
|
||||||
gps_acq_assist_data_collector_thread_=boost::thread(&ControlThread::gps_acq_assist_data_collector,this);
|
gps_acq_assist_data_collector_thread_= boost::thread(&ControlThread::gps_acq_assist_data_collector, this);
|
||||||
|
|
||||||
galileo_ephemeris_data_collector_thread_ =boost::thread(&ControlThread::galileo_ephemeris_data_collector, this);
|
galileo_ephemeris_data_collector_thread_ = boost::thread(&ControlThread::galileo_ephemeris_data_collector, this);
|
||||||
galileo_iono_data_collector_thread_ =boost::thread(&ControlThread::galileo_iono_data_collector, this);
|
galileo_iono_data_collector_thread_ = boost::thread(&ControlThread::galileo_iono_data_collector, this);
|
||||||
galileo_utc_model_data_collector_thread_ =boost::thread(&ControlThread::galileo_utc_model_data_collector, this);
|
galileo_utc_model_data_collector_thread_ = boost::thread(&ControlThread::galileo_utc_model_data_collector, this);
|
||||||
// Main loop to read and process the control messages
|
// Main loop to read and process the control messages
|
||||||
while (flowgraph_->running() && !stop_)
|
while (flowgraph_->running() && !stop_)
|
||||||
{
|
{
|
||||||
@ -170,7 +168,7 @@ void ControlThread::run()
|
|||||||
read_control_messages();
|
read_control_messages();
|
||||||
if (control_messages_ != 0) process_control_messages();
|
if (control_messages_ != 0) process_control_messages();
|
||||||
}
|
}
|
||||||
std::cout<<"Stopping GNSS-SDR, please wait!"<<std::endl;
|
std::cout << "Stopping GNSS-SDR, please wait!" << std::endl;
|
||||||
flowgraph_->stop();
|
flowgraph_->stop();
|
||||||
|
|
||||||
// Join GPS threads
|
// Join GPS threads
|
||||||
@ -205,163 +203,184 @@ void ControlThread::set_control_queue(boost::shared_ptr<gr::msg_queue> control_q
|
|||||||
|
|
||||||
bool ControlThread::read_assistance_from_XML()
|
bool ControlThread::read_assistance_from_XML()
|
||||||
{
|
{
|
||||||
std::string eph_xml_filename="gps_ephemeris.xml";
|
std::string eph_xml_filename = "gps_ephemeris.xml";
|
||||||
std::cout<< "SUPL: Try read GPS ephemeris from XML file "<<eph_xml_filename<<std::endl;
|
std::cout << "SUPL: Try read GPS ephemeris from XML file " << eph_xml_filename << std::endl;
|
||||||
if (supl_client_ephemeris_.load_ephemeris_xml(eph_xml_filename)==true)
|
if (supl_client_ephemeris_.load_ephemeris_xml(eph_xml_filename) == true)
|
||||||
{
|
{
|
||||||
std::map<int,Gps_Ephemeris>::iterator gps_eph_iter;
|
std::map<int,Gps_Ephemeris>::iterator gps_eph_iter;
|
||||||
for(gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.begin();
|
for(gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.begin();
|
||||||
gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end();
|
gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end();
|
||||||
gps_eph_iter++)
|
gps_eph_iter++)
|
||||||
{
|
{
|
||||||
std::cout<<"SUPL: Read XML Ephemeris for GPS SV "<<gps_eph_iter->first<<std::endl;
|
std::cout << "SUPL: Read XML Ephemeris for GPS SV " << gps_eph_iter->first << std::endl;
|
||||||
global_gps_ephemeris_queue.push(gps_eph_iter->second);
|
global_gps_ephemeris_queue.push(gps_eph_iter->second);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}else{
|
}
|
||||||
std::cout<< "ERROR: SUPL client error reading XML"<<std::endl;
|
else
|
||||||
std::cout<< "Disabling SUPL assistance.."<<std::endl;
|
{
|
||||||
return false;
|
std::cout << "ERROR: SUPL client error reading XML" << std::endl;
|
||||||
}
|
std::cout << "Disabling SUPL assistance.." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::init()
|
void ControlThread::init()
|
||||||
{
|
{
|
||||||
// Instantiates a control queue, a GNSS flowgraph, and a control message factory
|
// Instantiates a control queue, a GNSS flowgraph, and a control message factory
|
||||||
control_queue_ = gr::msg_queue::make(0);
|
control_queue_ = gr::msg_queue::make(0);
|
||||||
flowgraph_ = new GNSSFlowgraph(configuration_, control_queue_);
|
flowgraph_ = new GNSSFlowgraph(configuration_, control_queue_);
|
||||||
control_message_factory_ = new ControlMessageFactory();
|
control_message_factory_ = new ControlMessageFactory();
|
||||||
stop_ = false;
|
stop_ = false;
|
||||||
processed_control_messages_ = 0;
|
processed_control_messages_ = 0;
|
||||||
applied_actions_ = 0;
|
applied_actions_ = 0;
|
||||||
|
|
||||||
//#########GNSS Asistence #################################
|
//######### GNSS Assistance #################################
|
||||||
// GNSS Assistance configuration
|
// GNSS Assistance configuration
|
||||||
bool enable_gps_supl_assistance=configuration_->property("GNSS-SDR.SUPL_gps_enabled",false);
|
bool enable_gps_supl_assistance = configuration_->property("GNSS-SDR.SUPL_gps_enabled", false);
|
||||||
if (enable_gps_supl_assistance==true)
|
if (enable_gps_supl_assistance == true)
|
||||||
//SUPL SERVER TEST. Not operational yet!
|
//SUPL SERVER TEST. Not operational yet!
|
||||||
{
|
{
|
||||||
std::cout<< "SUPL RRLP GPS assistance enabled!"<<std::endl;
|
std::cout << "SUPL RRLP GPS assistance enabled!" << std::endl;
|
||||||
std::string default_acq_server="supl.nokia.com";
|
std::string default_acq_server = "supl.nokia.com";
|
||||||
std::string default_eph_server="supl.google.com";
|
std::string default_eph_server = "supl.google.com";
|
||||||
supl_client_ephemeris_.server_name=configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_server",default_acq_server);
|
supl_client_ephemeris_.server_name = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_server", default_acq_server);
|
||||||
supl_client_acquisition_.server_name=configuration_->property("GNSS-SDR.SUPL_gps_acquisition_server",default_eph_server);
|
supl_client_acquisition_.server_name = configuration_->property("GNSS-SDR.SUPL_gps_acquisition_server", default_eph_server);
|
||||||
supl_client_ephemeris_.server_port=configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_port",7275);
|
supl_client_ephemeris_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_ephemeris_port", 7275);
|
||||||
supl_client_acquisition_.server_port=configuration_->property("GNSS-SDR.SUPL_gps_acquisition_port",7275);
|
supl_client_acquisition_.server_port = configuration_->property("GNSS-SDR.SUPL_gps_acquisition_port", 7275);
|
||||||
supl_mcc=configuration_->property("GNSS-SDR.SUPL_MCC",244);
|
supl_mcc = configuration_->property("GNSS-SDR.SUPL_MCC", 244);
|
||||||
supl_mns=configuration_->property("GNSS-SDR.SUPL_MNS",5);
|
supl_mns = configuration_->property("GNSS-SDR.SUPL_MNS", 5);
|
||||||
|
|
||||||
std::string default_lac="0x59e2";
|
std::string default_lac = "0x59e2";
|
||||||
std::string default_ci="0x31b0";
|
std::string default_ci = "0x31b0";
|
||||||
try {
|
try
|
||||||
supl_lac = boost::lexical_cast<int>(configuration_->property("GNSS-SDR.SUPL_LAC",default_lac));
|
{
|
||||||
} catch(boost::bad_lexical_cast &) {
|
supl_lac = boost::lexical_cast<int>(configuration_->property("GNSS-SDR.SUPL_LAC", default_lac));
|
||||||
supl_lac=0x59e2;
|
}
|
||||||
}
|
catch(boost::bad_lexical_cast &)
|
||||||
try {
|
{
|
||||||
supl_ci = boost::lexical_cast<int>(configuration_->property("GNSS-SDR.SUPL_CI",default_ci));
|
supl_lac = 0x59e2;
|
||||||
} catch(boost::bad_lexical_cast &) {
|
}
|
||||||
supl_ci=0x31b0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SUPL_read_gps_assistance_xml=configuration_->property("GNSS-SDR.SUPL_read_gps_assistance_xml",false);
|
try
|
||||||
if (SUPL_read_gps_assistance_xml==true)
|
{
|
||||||
{
|
supl_ci = boost::lexical_cast<int>(configuration_->property("GNSS-SDR.SUPL_CI", default_ci));
|
||||||
// read assistance from file
|
}
|
||||||
read_assistance_from_XML();
|
catch(boost::bad_lexical_cast &)
|
||||||
}else{
|
{
|
||||||
|
supl_ci = 0x31b0;
|
||||||
|
}
|
||||||
|
|
||||||
// Request ephemeris from SUPL server
|
bool SUPL_read_gps_assistance_xml = configuration_->property("GNSS-SDR.SUPL_read_gps_assistance_xml", false);
|
||||||
int error;
|
if (SUPL_read_gps_assistance_xml == true)
|
||||||
supl_client_ephemeris_.request=1;
|
{
|
||||||
std::cout<< "SUPL: Try read GPS ephemeris from SUPL server.."<<std::endl;
|
// read assistance from file
|
||||||
error=supl_client_ephemeris_.get_assistance(supl_mcc,supl_mns,supl_lac,supl_ci);
|
read_assistance_from_XML();
|
||||||
if (error==0)
|
}
|
||||||
{
|
else
|
||||||
std::map<int,Gps_Ephemeris>::iterator gps_eph_iter;
|
{
|
||||||
for(gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.begin();
|
// Request ephemeris from SUPL server
|
||||||
gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end();
|
int error;
|
||||||
gps_eph_iter++)
|
supl_client_ephemeris_.request = 1;
|
||||||
{
|
std::cout << "SUPL: Try to read GPS ephemeris from SUPL server.." << std::endl;
|
||||||
std::cout<<"SUPL: Received Ephemeris for GPS SV "<<gps_eph_iter->first<<std::endl;
|
error = supl_client_ephemeris_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci);
|
||||||
global_gps_ephemeris_queue.push(gps_eph_iter->second);
|
if (error == 0)
|
||||||
}
|
{
|
||||||
//Save ephemeris to XML file
|
std::map<int,Gps_Ephemeris>::iterator gps_eph_iter;
|
||||||
std::string eph_xml_filename="gps_ephemeris.xml";
|
for(gps_eph_iter = supl_client_ephemeris_.gps_ephemeris_map.begin();
|
||||||
if (supl_client_ephemeris_.save_ephemeris_xml(eph_xml_filename)==true)
|
gps_eph_iter != supl_client_ephemeris_.gps_ephemeris_map.end();
|
||||||
{
|
gps_eph_iter++)
|
||||||
std::cout<<"SUPL: XML Ephemeris file created"<<std::endl;
|
{
|
||||||
}
|
std::cout << "SUPL: Received Ephemeris for GPS SV " << gps_eph_iter->first << std::endl;
|
||||||
}else{
|
global_gps_ephemeris_queue.push(gps_eph_iter->second);
|
||||||
std::cout<< "ERROR: SUPL client for Ephemeris returned "<<error<<std::endl;
|
}
|
||||||
std::cout<< "Please check internet connection and SUPL server configuration"<<error<<std::endl;
|
//Save ephemeris to XML file
|
||||||
std::cout<< "Trying to read ephemeris from XML file"<<std::endl;
|
std::string eph_xml_filename = "gps_ephemeris.xml";
|
||||||
if (read_assistance_from_XML()==false)
|
if (supl_client_ephemeris_.save_ephemeris_xml(eph_xml_filename) == true)
|
||||||
{
|
{
|
||||||
std::cout<< "ERROR: Could not read Ephemeris file: Disabling SUPL assistance.."<<std::endl;
|
std::cout << "SUPL: XML Ephemeris file created" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "ERROR: SUPL client for Ephemeris returned " << error << std::endl;
|
||||||
|
std::cout << "Please check internet connection and SUPL server configuration" << error << std::endl;
|
||||||
|
std::cout << "Trying to read ephemeris from XML file" << std::endl;
|
||||||
|
if (read_assistance_from_XML() == false)
|
||||||
|
{
|
||||||
|
std::cout << "ERROR: Could not read Ephemeris file: Disabling SUPL assistance.." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Request almanac , IONO and UTC Model
|
// Request almanac , IONO and UTC Model
|
||||||
supl_client_ephemeris_.request=0;
|
supl_client_ephemeris_.request = 0;
|
||||||
std::cout<< "SUPL: Try read Almanac, Iono, Utc Model, Ref Time and Ref Location from SUPL server.."<<std::endl;
|
std::cout << "SUPL: Try read Almanac, Iono, Utc Model, Ref Time and Ref Location from SUPL server..." << std::endl;
|
||||||
error=supl_client_ephemeris_.get_assistance(supl_mcc,supl_mns,supl_lac,supl_ci);
|
error = supl_client_ephemeris_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci);
|
||||||
if (error==0)
|
if (error == 0)
|
||||||
{
|
{
|
||||||
std::map<int,Gps_Almanac>::iterator gps_alm_iter;
|
std::map<int,Gps_Almanac>::iterator gps_alm_iter;
|
||||||
for(gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.begin();
|
for(gps_alm_iter = supl_client_ephemeris_.gps_almanac_map.begin();
|
||||||
gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.end();
|
gps_alm_iter != supl_client_ephemeris_.gps_almanac_map.end();
|
||||||
gps_alm_iter++)
|
gps_alm_iter++)
|
||||||
{
|
{
|
||||||
std::cout<<"SUPL: Received Almanac for GPS SV "<<gps_alm_iter->first<<std::endl;
|
std::cout << "SUPL: Received Almanac for GPS SV " << gps_alm_iter->first << std::endl;
|
||||||
global_gps_almanac_queue.push(gps_alm_iter->second);
|
global_gps_almanac_queue.push(gps_alm_iter->second);
|
||||||
}
|
}
|
||||||
if (supl_client_ephemeris_.gps_iono.valid==true)
|
if (supl_client_ephemeris_.gps_iono.valid == true)
|
||||||
{
|
{
|
||||||
std::cout<<"SUPL: Received GPS Iono"<<std::endl;
|
std::cout << "SUPL: Received GPS Iono" << std::endl;
|
||||||
global_gps_iono_queue.push(supl_client_ephemeris_.gps_iono);
|
global_gps_iono_queue.push(supl_client_ephemeris_.gps_iono);
|
||||||
}
|
}
|
||||||
if (supl_client_ephemeris_.gps_utc.valid==true)
|
if (supl_client_ephemeris_.gps_utc.valid == true)
|
||||||
{
|
{
|
||||||
std::cout<<"SUPL: Received GPS UTC Model"<<std::endl;
|
std::cout << "SUPL: Received GPS UTC Model" << std::endl;
|
||||||
global_gps_utc_model_queue.push(supl_client_ephemeris_.gps_utc);
|
global_gps_utc_model_queue.push(supl_client_ephemeris_.gps_utc);
|
||||||
}
|
}
|
||||||
}else{
|
}
|
||||||
std::cout<< "ERROR: SUPL client for Almanac returned "<<error<<std::endl;
|
else
|
||||||
std::cout<< "Please check internet connection and SUPL server configuration"<<error<<std::endl;
|
{
|
||||||
std::cout<< "Disabling SUPL assistance.."<<std::endl;
|
std::cout << "ERROR: SUPL client for Almanac returned " << error << std::endl;
|
||||||
}
|
std::cout << "Please check internet connection and SUPL server configuration" << error << std::endl;
|
||||||
|
std::cout << "Disabling SUPL assistance.." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
// Request acquisition assistance
|
// Request acquisition assistance
|
||||||
supl_client_acquisition_.request=2;
|
supl_client_acquisition_.request = 2;
|
||||||
std::cout<< "SUPL: Try read Acquisition assistance from SUPL server.."<<std::endl;
|
std::cout << "SUPL: Try read Acquisition assistance from SUPL server.." << std::endl;
|
||||||
error=supl_client_acquisition_.get_assistance(supl_mcc,supl_mns,supl_lac,supl_ci);
|
error = supl_client_acquisition_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci);
|
||||||
if (error==0)
|
if (error == 0)
|
||||||
{
|
{
|
||||||
std::map<int,Gps_Acq_Assist>::iterator gps_acq_iter;
|
std::map<int, Gps_Acq_Assist>::iterator gps_acq_iter;
|
||||||
for(gps_acq_iter = supl_client_acquisition_.gps_acq_map.begin();
|
for(gps_acq_iter = supl_client_acquisition_.gps_acq_map.begin();
|
||||||
gps_acq_iter != supl_client_acquisition_.gps_acq_map.end();
|
gps_acq_iter != supl_client_acquisition_.gps_acq_map.end();
|
||||||
gps_acq_iter++)
|
gps_acq_iter++)
|
||||||
{
|
{
|
||||||
std::cout<<"SUPL: Received Acquisition assistance for GPS SV "<<gps_acq_iter->first<<std::endl;
|
std::cout << "SUPL: Received Acquisition assistance for GPS SV " << gps_acq_iter->first << std::endl;
|
||||||
global_gps_acq_assist_queue.push(gps_acq_iter->second);
|
global_gps_acq_assist_queue.push(gps_acq_iter->second);
|
||||||
}
|
}
|
||||||
}else{
|
}
|
||||||
std::cout<< "ERROR: SUPL client for Acquisition assistance returned "<<error<<std::endl;
|
else
|
||||||
std::cout<< "Please check internet connection and SUPL server configuration"<<error<<std::endl;
|
{
|
||||||
std::cout<< "Disabling SUPL assistance.."<<std::endl;
|
std::cout << "ERROR: SUPL client for Acquisition assistance returned " << error << std::endl;
|
||||||
}
|
std::cout << "Please check internet connection and SUPL server configuration" << error << std::endl;
|
||||||
}
|
std::cout << "Disabling SUPL assistance.." << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::read_control_messages()
|
void ControlThread::read_control_messages()
|
||||||
{
|
{
|
||||||
DLOG(INFO) << "Reading control messages from queue";
|
DLOG(INFO) << "Reading control messages from queue";
|
||||||
boost::shared_ptr<gr::message> queue_message = control_queue_->delete_head();
|
boost::shared_ptr<gr::message> queue_message = control_queue_->delete_head();
|
||||||
if (queue_message != 0)
|
if (queue_message != 0)
|
||||||
{
|
{
|
||||||
control_messages_ = control_message_factory_->GetControlMessages(
|
control_messages_ = control_message_factory_->GetControlMessages(queue_message);
|
||||||
queue_message);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -383,8 +402,7 @@ void ControlThread::process_control_messages()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
flowgraph_->apply_action(control_messages_->at(i)->who,
|
flowgraph_->apply_action(control_messages_->at(i)->who, control_messages_->at(i)->what);
|
||||||
control_messages_->at(i)->what);
|
|
||||||
}
|
}
|
||||||
delete control_messages_->at(i);
|
delete control_messages_->at(i);
|
||||||
processed_control_messages_++;
|
processed_control_messages_++;
|
||||||
@ -411,260 +429,286 @@ void ControlThread::apply_action(unsigned int what)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::gps_acq_assist_data_collector()
|
void ControlThread::gps_acq_assist_data_collector()
|
||||||
{
|
{
|
||||||
|
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
|
||||||
|
Gps_Acq_Assist gps_acq;
|
||||||
|
Gps_Acq_Assist gps_acq_old;
|
||||||
|
while(stop_ == false)
|
||||||
|
{
|
||||||
|
global_gps_acq_assist_queue.wait_and_pop(gps_acq);
|
||||||
|
|
||||||
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
|
// DEBUG MESSAGE
|
||||||
Gps_Acq_Assist gps_acq;
|
std::cout << "Acquisition assistance record has arrived from SAT ID "
|
||||||
Gps_Acq_Assist gps_acq_old;
|
<< gps_acq.i_satellite_PRN
|
||||||
while(stop_==false)
|
<< " with Doppler "
|
||||||
{
|
<< gps_acq.d_Doppler0
|
||||||
global_gps_acq_assist_queue.wait_and_pop(gps_acq);
|
<< " [Hz] "<< std::endl;
|
||||||
|
// insert new acq record to the global ephemeris map
|
||||||
|
if (global_gps_acq_assist_map.read(gps_acq.i_satellite_PRN,gps_acq_old))
|
||||||
|
{
|
||||||
|
std::cout << "Acquisition assistance record updated" << std::endl;
|
||||||
|
global_gps_acq_assist_map.write(gps_acq.i_satellite_PRN, gps_acq);
|
||||||
|
|
||||||
// DEBUG MESSAGE
|
}
|
||||||
std::cout << "Acquisition assistance record has arrived from SAT ID "
|
else
|
||||||
<< gps_acq.i_satellite_PRN << " with Doppler " << gps_acq.d_Doppler0<<" [Hz] "<<std::endl;
|
{
|
||||||
// insert new acq record to the global ephemeris map
|
// insert new acq record
|
||||||
if (global_gps_acq_assist_map.read(gps_acq.i_satellite_PRN,gps_acq_old))
|
std::cout << "New acq assist record inserted" << std::endl;
|
||||||
{
|
global_gps_acq_assist_map.write(gps_acq.i_satellite_PRN, gps_acq);
|
||||||
|
}
|
||||||
std::cout << "Acquisition assistance record updated"<<std::endl;
|
}
|
||||||
global_gps_acq_assist_map.write(gps_acq.i_satellite_PRN,gps_acq);
|
|
||||||
|
|
||||||
}else{
|
|
||||||
// insert new acq record
|
|
||||||
std::cout << "New acq assist record inserted"<<std::endl;
|
|
||||||
global_gps_acq_assist_map.write(gps_acq.i_satellite_PRN,gps_acq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::gps_ephemeris_data_collector()
|
void ControlThread::gps_ephemeris_data_collector()
|
||||||
{
|
{
|
||||||
|
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
|
||||||
|
Gps_Ephemeris gps_eph;
|
||||||
|
Gps_Ephemeris gps_eph_old;
|
||||||
|
while(stop_ == false)
|
||||||
|
{
|
||||||
|
global_gps_ephemeris_queue.wait_and_pop(gps_eph);
|
||||||
|
|
||||||
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
|
// DEBUG MESSAGE
|
||||||
Gps_Ephemeris gps_eph;
|
std::cout << "Ephemeris record has arrived from SAT ID "
|
||||||
Gps_Ephemeris gps_eph_old;
|
<< gps_eph.i_satellite_PRN << " (Block "
|
||||||
while(stop_==false)
|
<< gps_eph.satelliteBlock[gps_eph.i_satellite_PRN]
|
||||||
{
|
<< ")" << std::endl;
|
||||||
global_gps_ephemeris_queue.wait_and_pop(gps_eph);
|
// insert new ephemeris record to the global ephemeris map
|
||||||
|
if (global_gps_ephemeris_map.read(gps_eph.i_satellite_PRN, gps_eph_old))
|
||||||
// DEBUG MESSAGE
|
{
|
||||||
std::cout << "Ephemeris record has arrived from SAT ID "
|
// Check the EPHEMERIS timestamp. If it is newer, then update the ephemeris
|
||||||
<< gps_eph.i_satellite_PRN << " (Block "
|
if (gps_eph.i_GPS_week > gps_eph_old.i_GPS_week)
|
||||||
<< gps_eph.satelliteBlock[gps_eph.i_satellite_PRN]
|
{
|
||||||
<< ")" << std::endl;
|
std::cout << "Ephemeris record updated (GPS week=" << gps_eph.i_GPS_week << std::endl;
|
||||||
// insert new ephemeris record to the global ephemeris map
|
global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN, gps_eph);
|
||||||
if (global_gps_ephemeris_map.read(gps_eph.i_satellite_PRN,gps_eph_old))
|
}
|
||||||
{
|
else
|
||||||
// Check the EPHEMERIS timestamp. If it is newer, then update the ephemeris
|
{
|
||||||
if (gps_eph.i_GPS_week > gps_eph_old.i_GPS_week)
|
if (gps_eph.d_Toe > gps_eph_old.d_Toe)
|
||||||
{
|
{
|
||||||
std::cout << "Ephemeris record updated (GPS week="<<gps_eph.i_GPS_week<<std::endl;
|
std::cout << "Ephemeris record updated (Toe=" << gps_eph.d_Toe << std::endl;
|
||||||
global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN,gps_eph);
|
global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN, gps_eph);
|
||||||
}else{
|
}
|
||||||
if (gps_eph.d_Toe>gps_eph_old.d_Toe)
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Ephemeris record updated (Toe="<<gps_eph.d_Toe<<std::endl;
|
std::cout << "Not updating the existing ephemeris" << std::endl;
|
||||||
global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN,gps_eph);
|
}
|
||||||
}else{
|
}
|
||||||
std::cout<<"Not updating the existing ephemeris"<<std::endl;
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
|
// insert new ephemeris record
|
||||||
}else{
|
std::cout << "New Ephemeris record inserted with Toe="
|
||||||
// insert new ephemeris record
|
<< gps_eph.d_Toe<<" and GPS Week="
|
||||||
std::cout << "New Ephemeris record inserted with Toe="<<gps_eph.d_Toe<<" and GPS Week="<<gps_eph.i_GPS_week<<std::endl;
|
<< gps_eph.i_GPS_week << std::endl;
|
||||||
global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN,gps_eph);
|
global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN, gps_eph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::galileo_ephemeris_data_collector()
|
void ControlThread::galileo_ephemeris_data_collector()
|
||||||
{
|
{
|
||||||
|
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
|
||||||
|
Galileo_Ephemeris galileo_eph;
|
||||||
|
Galileo_Ephemeris galileo_eph_old;
|
||||||
|
while(stop_ == false)
|
||||||
|
{
|
||||||
|
global_galileo_ephemeris_queue.wait_and_pop(galileo_eph);
|
||||||
|
|
||||||
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
|
// DEBUG MESSAGE
|
||||||
Galileo_Ephemeris galileo_eph;
|
std::cout << "Galileo Ephemeris record has arrived from SAT ID "
|
||||||
Galileo_Ephemeris galileo_eph_old;
|
<< galileo_eph.SV_ID_PRN_4 << std::endl;
|
||||||
while(stop_==false)
|
|
||||||
{
|
|
||||||
global_galileo_ephemeris_queue.wait_and_pop(galileo_eph);
|
|
||||||
|
|
||||||
// DEBUG MESSAGE
|
// insert new ephemeris record to the global ephemeris map
|
||||||
std::cout << "Galileo Ephemeris record has arrived from SAT ID "
|
if (global_galileo_ephemeris_map.read(galileo_eph.SV_ID_PRN_4, galileo_eph_old))
|
||||||
<< galileo_eph.SV_ID_PRN_4 << std::endl;
|
{
|
||||||
|
// Check the EPHEMERIS timestamp. If it is newer, then update the ephemeris
|
||||||
// insert new ephemeris record to the global ephemeris map
|
if (galileo_eph.WN_5 > galileo_eph_old.WN_5) //further check because it is not clear when IOD is reset
|
||||||
if (global_galileo_ephemeris_map.read(galileo_eph.SV_ID_PRN_4,galileo_eph_old))
|
{
|
||||||
{
|
std::cout << "Galileo Ephemeris record in global map updated -- GALILEO Week Number ="
|
||||||
// Check the EPHEMERIS timestamp. If it is newer, then update the ephemeris
|
<< galileo_eph.WN_5 << std::endl;
|
||||||
if (galileo_eph.WN_5 > galileo_eph_old.WN_5) //further check because it is not clear when IOD is reset
|
global_galileo_ephemeris_map.write(galileo_eph.SV_ID_PRN_4,galileo_eph);
|
||||||
{
|
}
|
||||||
std::cout << "Galileo Ephemeris record in global map updated -- GALILEO Week Number ="<<galileo_eph.WN_5<<std::endl;
|
else
|
||||||
global_galileo_ephemeris_map.write(galileo_eph.SV_ID_PRN_4,galileo_eph);
|
{
|
||||||
}else{
|
if (galileo_eph.IOD_ephemeris > galileo_eph_old.IOD_ephemeris)
|
||||||
if (galileo_eph.IOD_ephemeris > galileo_eph_old.IOD_ephemeris)
|
{
|
||||||
{
|
std::cout << "Galileo Ephemeris record updated in global map-- IOD_ephemeris ="
|
||||||
std::cout << "Galileo Ephemeris record updated in global map-- IOD_ephemeris ="<<galileo_eph.IOD_ephemeris<<std::endl;
|
<< galileo_eph.IOD_ephemeris << std::endl;
|
||||||
global_galileo_ephemeris_map.write(galileo_eph.SV_ID_PRN_4,galileo_eph);
|
global_galileo_ephemeris_map.write(galileo_eph.SV_ID_PRN_4, galileo_eph);
|
||||||
|
std::cout << "IOD_ephemeris OLD: " << galileo_eph_old.IOD_ephemeris << std::endl;
|
||||||
std::cout << "IOD_ephemeris OLD: " << galileo_eph_old.IOD_ephemeris<<std::endl;
|
std::cout << "satellite: " << galileo_eph.SV_ID_PRN_4 << std::endl;
|
||||||
std::cout << "satellite: " << galileo_eph.SV_ID_PRN_4<<std::endl;
|
}
|
||||||
}
|
else
|
||||||
else{
|
{
|
||||||
std::cout<<"Not updating the existing Galileo ephemeris, IOD is not changing"<<std::endl;
|
std::cout << "Not updating the existing Galileo ephemeris, IOD is not changing" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//
|
else
|
||||||
}else{
|
{
|
||||||
// insert new ephemeris record
|
// insert new ephemeris record
|
||||||
std::cout << "Galileo New Ephemeris record inserted in global map with TOW ="<<galileo_eph.TOW_5
|
std::cout << "Galileo New Ephemeris record inserted in global map with TOW =" << galileo_eph.TOW_5
|
||||||
<<", GALILEO Week Number ="<< galileo_eph.WN_5
|
<< ", GALILEO Week Number =" << galileo_eph.WN_5
|
||||||
<< " and Ephemeris IOD = " << galileo_eph.IOD_ephemeris << std::endl;
|
<< " and Ephemeris IOD = " << galileo_eph.IOD_ephemeris << std::endl;
|
||||||
global_galileo_ephemeris_map.write(galileo_eph.SV_ID_PRN_4, galileo_eph);
|
global_galileo_ephemeris_map.write(galileo_eph.SV_ID_PRN_4, galileo_eph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::gps_iono_data_collector()
|
void ControlThread::gps_iono_data_collector()
|
||||||
{
|
{
|
||||||
|
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
|
||||||
|
Gps_Iono gps_iono;
|
||||||
|
Gps_Iono gps_iono_old;
|
||||||
|
while(stop_ == false)
|
||||||
|
{
|
||||||
|
global_gps_iono_queue.wait_and_pop(gps_iono);
|
||||||
|
|
||||||
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
|
std::cout << "New IONO record has arrived " << std::endl;
|
||||||
Gps_Iono gps_iono;
|
// insert new ephemeris record to the global ephemeris map
|
||||||
Gps_Iono gps_iono_old;
|
if (global_gps_iono_map.read(0, gps_iono_old))
|
||||||
while(stop_==false)
|
{
|
||||||
{
|
// TODO: Check the IONO timestamp. If it is newer, then update the iono
|
||||||
global_gps_iono_queue.wait_and_pop(gps_iono);
|
global_gps_iono_map.write(0, gps_iono);
|
||||||
|
}
|
||||||
|
else
|
||||||
std::cout << "New IONO record has arrived "<< std::endl;
|
{
|
||||||
// insert new ephemeris record to the global ephemeris map
|
// insert new ephemeris record
|
||||||
if (global_gps_iono_map.read(0,gps_iono_old))
|
global_gps_iono_map.write(0 ,gps_iono);
|
||||||
{
|
}
|
||||||
// TODO: Check the IONO timestamp. If it is newer, then update the iono
|
}
|
||||||
global_gps_iono_map.write(0,gps_iono);
|
|
||||||
}else{
|
|
||||||
// insert new ephemeris record
|
|
||||||
global_gps_iono_map.write(0,gps_iono);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::galileo_iono_data_collector()
|
void ControlThread::galileo_iono_data_collector()
|
||||||
{
|
{
|
||||||
|
Galileo_Iono galileo_iono;
|
||||||
|
Galileo_Iono galileo_iono_old;
|
||||||
|
while(stop_ == false)
|
||||||
|
{
|
||||||
|
global_galileo_iono_queue.wait_and_pop(galileo_iono);
|
||||||
|
|
||||||
Galileo_Iono galileo_iono;
|
// DEBUG MESSAGE
|
||||||
Galileo_Iono galileo_iono_old;
|
std::cout << "Iono record has arrived" << std::endl;
|
||||||
while(stop_==false)
|
|
||||||
{
|
|
||||||
global_galileo_iono_queue.wait_and_pop(galileo_iono);
|
|
||||||
|
|
||||||
// DEBUG MESSAGE
|
// insert new Iono record to the global Iono map
|
||||||
std::cout << "Iono record has arrived"<<std::endl;
|
if (global_galileo_iono_map.read(0, galileo_iono_old))
|
||||||
|
{
|
||||||
// insert new Iono record to the global Iono map
|
// Check the Iono timestamp from UTC page (page 6). If it is newer, then update the Iono parameters
|
||||||
if (global_galileo_iono_map.read(0,galileo_iono_old))
|
if (galileo_iono.WN_5 > galileo_iono_old.WN_5)
|
||||||
{
|
{
|
||||||
// Check the Iono timestamp from UTC page (page 6). If it is newer, then update the Iono parameters
|
std::cout << "IONO record updated in global map--new GALILEO UTC-IONO Week Number" << std::endl;
|
||||||
if (galileo_iono.WN_5 > galileo_iono_old.WN_5)
|
global_galileo_iono_map.write(0, galileo_iono);
|
||||||
{
|
}
|
||||||
std::cout << "IONO record updated in global map--new GALILEO UTC-IONO Week Number"<< std::endl;
|
else
|
||||||
global_galileo_iono_map.write(0,galileo_iono);
|
{
|
||||||
}else{
|
if (galileo_iono.TOW_5 > galileo_iono_old.TOW_5)
|
||||||
if (galileo_iono.TOW_5 > galileo_iono_old.TOW_5)
|
{
|
||||||
{
|
std::cout << "IONO record updated in global map--new GALILEO UTC-IONO time of Week" << std::endl;
|
||||||
std::cout << "IONO record updated in global map--new GALILEO UTC-IONO time of Week" << std::endl;
|
global_galileo_iono_map.write(0, galileo_iono);
|
||||||
global_galileo_iono_map.write(0,galileo_iono);
|
//std::cout << "GALILEO IONO time of Week old: " << galileo_iono_old.t0t_6<<std::endl;
|
||||||
//std::cout << "GALILEO IONO time of Week old: " << galileo_iono_old.t0t_6<<std::endl;
|
}
|
||||||
|
else
|
||||||
}
|
{
|
||||||
else{
|
std::cout << "Not updating the existing Iono parameters in global map, Iono timestamp is not changing" << std::endl;
|
||||||
std::cout<<"Not updating the existing Iono parameters in global map, Iono timestamp is not changing"<<std::endl;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
}else{
|
// insert new ephemeris record
|
||||||
// insert new ephemeris record
|
std::cout << "New IONO record inserted in global map" << std::endl;
|
||||||
std::cout << "New IONO record inserted in global map" << std::endl;
|
global_galileo_iono_map.write(0, galileo_iono);
|
||||||
global_galileo_iono_map.write(0, galileo_iono);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::gps_utc_model_data_collector()
|
void ControlThread::gps_utc_model_data_collector()
|
||||||
{
|
{
|
||||||
|
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
|
||||||
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
|
Gps_Utc_Model gps_utc;
|
||||||
Gps_Utc_Model gps_utc;
|
Gps_Utc_Model gps_utc_old;
|
||||||
Gps_Utc_Model gps_utc_old;
|
while(stop_ == false)
|
||||||
while(stop_==false)
|
{
|
||||||
{
|
global_gps_utc_model_queue.wait_and_pop(gps_utc);
|
||||||
global_gps_utc_model_queue.wait_and_pop(gps_utc);
|
std::cout << "New UTC MODEL record has arrived with A0=" << gps_utc.d_A0 << std::endl;
|
||||||
std::cout << "New UTC MODEL record has arrived with A0="<< gps_utc.d_A0<< std::endl;
|
// insert new ephemeris record to the global ephemeris map
|
||||||
// insert new ephemeris record to the global ephemeris map
|
if (global_gps_utc_model_map.read(0, gps_utc_old))
|
||||||
if (global_gps_utc_model_map.read(0,gps_utc_old))
|
{
|
||||||
{
|
// TODO: Check the UTC MODEL timestamp. If it is newer, then update the UTC MODEL
|
||||||
// TODO: Check the UTC MODEL timestamp. If it is newer, then update the UTC MODEL
|
global_gps_utc_model_map.write(0, gps_utc);
|
||||||
global_gps_utc_model_map.write(0,gps_utc);
|
}
|
||||||
}else{
|
else
|
||||||
// insert new ephemeris record
|
{
|
||||||
global_gps_utc_model_map.write(0,gps_utc);
|
// insert new ephemeris record
|
||||||
}
|
global_gps_utc_model_map.write(0, gps_utc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::galileo_utc_model_data_collector()
|
void ControlThread::galileo_utc_model_data_collector()
|
||||||
{
|
{
|
||||||
Galileo_Utc_Model galileo_utc;
|
Galileo_Utc_Model galileo_utc;
|
||||||
Galileo_Utc_Model galileo_utc_old;
|
Galileo_Utc_Model galileo_utc_old;
|
||||||
while(stop_==false)
|
while(stop_ == false)
|
||||||
{
|
{
|
||||||
global_galileo_utc_model_queue.wait_and_pop(galileo_utc);
|
global_galileo_utc_model_queue.wait_and_pop(galileo_utc);
|
||||||
|
|
||||||
// DEBUG MESSAGE
|
// DEBUG MESSAGE
|
||||||
std::cout << "UTC record has arrived"<<std::endl;
|
std::cout << "UTC record has arrived" << std::endl;
|
||||||
|
|
||||||
// insert new UTC record to the global UTC map
|
// insert new UTC record to the global UTC map
|
||||||
if (global_galileo_utc_model_map.read(0,galileo_utc_old))
|
if (global_galileo_utc_model_map.read(0, galileo_utc_old))
|
||||||
{
|
{
|
||||||
// Check the UTC timestamp. If it is newer, then update the ephemeris
|
// Check the UTC timestamp. If it is newer, then update the ephemeris
|
||||||
if (galileo_utc.WNot_6 > galileo_utc_old.WNot_6) //further check because it is not clear when IOD is reset
|
if (galileo_utc.WNot_6 > galileo_utc_old.WNot_6) //further check because it is not clear when IOD is reset
|
||||||
{
|
{
|
||||||
//std::cout << "UTC record updated --new GALILEO UTC Week Number ="<<galileo_utc.WNot_6<<std::endl;
|
//std::cout << "UTC record updated --new GALILEO UTC Week Number ="<<galileo_utc.WNot_6<<std::endl;
|
||||||
global_galileo_utc_model_map.write(0,galileo_utc);
|
global_galileo_utc_model_map.write(0, galileo_utc);
|
||||||
}else{
|
}
|
||||||
if (galileo_utc.t0t_6 > galileo_utc_old.t0t_6)
|
else
|
||||||
{
|
{
|
||||||
//std::cout << "UTC record updated --new GALILEO UTC time of Week ="<<galileo_utc.t0t_6<<std::endl;
|
if (galileo_utc.t0t_6 > galileo_utc_old.t0t_6)
|
||||||
global_galileo_utc_model_map.write(0,galileo_utc);
|
{
|
||||||
|
//std::cout << "UTC record updated --new GALILEO UTC time of Week ="<<galileo_utc.t0t_6<<std::endl;
|
||||||
//std::cout << "GALILEO UTC time of Week old: " << galileo_utc_old.t0t_6<<std::endl;
|
global_galileo_utc_model_map.write(0, galileo_utc);
|
||||||
|
//std::cout << "GALILEO UTC time of Week old: " << galileo_utc_old.t0t_6<<std::endl;
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
std::cout<<"Not updating the existing UTC in global map, timestamp is not changing"<<std::endl;
|
{
|
||||||
}
|
std::cout << "Not updating the existing UTC in global map, timestamp is not changing" << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}else{
|
}
|
||||||
// insert new ephemeris record
|
else
|
||||||
std::cout << "New UTC record inserted in global map" << std::endl;
|
{
|
||||||
global_galileo_utc_model_map.write(0, galileo_utc);
|
// insert new ephemeris record
|
||||||
}
|
std::cout << "New UTC record inserted in global map" << std::endl;
|
||||||
}
|
global_galileo_utc_model_map.write(0, galileo_utc);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::gps_ephemeris_data_write_to_XML()
|
void ControlThread::gps_ephemeris_data_write_to_XML()
|
||||||
{
|
{
|
||||||
//Save ephemeris to XML file
|
//Save ephemeris to XML file
|
||||||
std::string eph_xml_filename ="gps_ephemeris_rx.xml";
|
std::string eph_xml_filename = "gps_ephemeris_rx.xml";
|
||||||
std::map<int,Gps_Ephemeris> eph_copy;
|
std::map<int,Gps_Ephemeris> eph_copy;
|
||||||
|
|
||||||
eph_copy = global_gps_ephemeris_map.get_map_copy();
|
eph_copy = global_gps_ephemeris_map.get_map_copy();
|
||||||
@ -685,53 +729,58 @@ void ControlThread::gps_ephemeris_data_write_to_XML()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::gps_utc_model_data_write_to_XML()
|
void ControlThread::gps_utc_model_data_write_to_XML()
|
||||||
{
|
{
|
||||||
//Save ephemeris to XML file
|
//Save ephemeris to XML file
|
||||||
std::string xml_filename="gps_utc_model_rx.xml";
|
std::string xml_filename = "gps_utc_model_rx.xml";
|
||||||
std::map<int,Gps_Utc_Model> map_copy;
|
std::map<int,Gps_Utc_Model> map_copy;
|
||||||
|
|
||||||
map_copy=global_gps_utc_model_map.get_map_copy();
|
map_copy = global_gps_utc_model_map.get_map_copy();
|
||||||
if (map_copy.size()>0)
|
if (map_copy.size() > 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::ofstream ofs(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out);
|
std::ofstream ofs(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out);
|
||||||
boost::archive::xml_oarchive xml(ofs);
|
boost::archive::xml_oarchive xml(ofs);
|
||||||
xml << boost::serialization::make_nvp("GNSS-SDR_utc_map", map_copy);
|
xml << boost::serialization::make_nvp("GNSS-SDR_utc_map", map_copy);
|
||||||
ofs.close();
|
ofs.close();
|
||||||
std::cout<<"Saved UTC Model data"<<std::endl;
|
std::cout << "Saved UTC Model data" << std::endl;
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
LOG_AT_LEVEL(ERROR) << e.what();
|
LOG_AT_LEVEL(ERROR) << e.what();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ControlThread::gps_iono_data_write_to_XML()
|
void ControlThread::gps_iono_data_write_to_XML()
|
||||||
{
|
{
|
||||||
//Save ephemeris to XML file
|
//Save ephemeris to XML file
|
||||||
std::string xml_filename="gps_iono_rx.xml";
|
std::string xml_filename = "gps_iono_rx.xml";
|
||||||
std::map<int,Gps_Iono> map_copy;
|
std::map<int,Gps_Iono> map_copy;
|
||||||
std::map<int,Gps_Iono>::iterator gps_iono_iter;
|
std::map<int,Gps_Iono>::iterator gps_iono_iter;
|
||||||
|
|
||||||
map_copy=global_gps_iono_map.get_map_copy();
|
map_copy = global_gps_iono_map.get_map_copy();
|
||||||
if (map_copy.size()>0)
|
if (map_copy.size() > 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::ofstream ofs(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out);
|
std::ofstream ofs(xml_filename.c_str(), std::ofstream::trunc | std::ofstream::out);
|
||||||
boost::archive::xml_oarchive xml(ofs);
|
boost::archive::xml_oarchive xml(ofs);
|
||||||
xml << boost::serialization::make_nvp("GNSS-SDR_iono_map", map_copy);
|
xml << boost::serialization::make_nvp("GNSS-SDR_iono_map", map_copy);
|
||||||
ofs.close();
|
ofs.close();
|
||||||
std::cout<<"Saved IONO Model data"<<std::endl;
|
std::cout << "Saved IONO Model data" << std::endl;
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
LOG_AT_LEVEL(ERROR) << e.what();
|
LOG_AT_LEVEL(ERROR) << e.what();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file control_thread.h
|
* \file control_thread.h
|
||||||
* \brief Interface of the receiver control plane
|
* \brief Interface of the receiver control plane
|
||||||
* \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
|
* \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
|
||||||
*
|
*
|
||||||
@ -68,9 +68,13 @@ public:
|
|||||||
/*! \brief Runs the control thread
|
/*! \brief Runs the control thread
|
||||||
*
|
*
|
||||||
* This is the main loop that reads and process the control messages:
|
* This is the main loop that reads and process the control messages:
|
||||||
|
*
|
||||||
* - Connect the GNSS receiver flowgraph;
|
* - Connect the GNSS receiver flowgraph;
|
||||||
|
*
|
||||||
* - Start the GNSS receiver flowgraph;
|
* - Start the GNSS receiver flowgraph;
|
||||||
* while (flowgraph_->running() && !stop)_{
|
*
|
||||||
|
* while (flowgraph_->running() && !stop_){
|
||||||
|
*
|
||||||
* - Read control messages and process them; }
|
* - Read control messages and process them; }
|
||||||
*/
|
*/
|
||||||
void run();
|
void run();
|
||||||
@ -78,7 +82,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief Sets the control_queue
|
* \brief Sets the control_queue
|
||||||
*
|
*
|
||||||
* \param[in] gr_msg_queue_sptr control_queue
|
* \param[in] boost::shared_ptr<gr::msg_queue> control_queue
|
||||||
*/
|
*/
|
||||||
void set_control_queue(boost::shared_ptr<gr::msg_queue> control_queue);
|
void set_control_queue(boost::shared_ptr<gr::msg_queue> control_queue);
|
||||||
|
|
||||||
@ -105,10 +109,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
//SUPL assistance classes
|
||||||
/*!
|
|
||||||
* \brief SUPL assistance classes
|
|
||||||
*/
|
|
||||||
gnss_sdr_supl_client supl_client_acquisition_;
|
gnss_sdr_supl_client supl_client_acquisition_;
|
||||||
gnss_sdr_supl_client supl_client_ephemeris_;
|
gnss_sdr_supl_client supl_client_ephemeris_;
|
||||||
int supl_mcc; // Current network MCC (Mobile country code), 3 digits.
|
int supl_mcc; // Current network MCC (Mobile country code), 3 digits.
|
||||||
@ -117,9 +118,8 @@ private:
|
|||||||
int supl_ci; // Cell Identity (16 bits, 0-65535 are valid values).
|
int supl_ci; // Cell Identity (16 bits, 0-65535 are valid values).
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
/*
|
|
||||||
* \brief Read ephemeris assistance from a local XML file previously recorded
|
// Read ephemeris assistance from a local XML file previously recorded
|
||||||
*/
|
|
||||||
bool read_assistance_from_XML();
|
bool read_assistance_from_XML();
|
||||||
|
|
||||||
void read_control_messages();
|
void read_control_messages();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user