mirror of https://github.com/gnss-sdr/gnss-sdr
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
|
@ -52,17 +52,17 @@ FirFilter::FirFilter(ConfigurationInterface* configuration, std::string role,
|
|||
item_size = sizeof(gr_complex);
|
||||
fir_filter_ccf_ = gr::filter::fir_filter_ccf::make(1, taps_);
|
||||
DLOG(INFO) << "input_filter(" << fir_filter_ccf_->unique_id() << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_AT_LEVEL(ERROR) << taps_item_type_ << " unknown input filter item type";
|
||||
}
|
||||
if (dump_)
|
||||
{
|
||||
DLOG(INFO) << "Dumping output into file " << dump_filename_;
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ FreqXlatingFirFilter::FreqXlatingFirFilter(ConfigurationInterface* configuration
|
|||
else
|
||||
{
|
||||
LOG_AT_LEVEL(ERROR) << taps_item_type_ << " unknown input filter item type";
|
||||
item_size = sizeof(gr_complex); //avoids unitialization
|
||||
}
|
||||
|
||||
if (dump_)
|
||||
|
@ -94,7 +95,9 @@ void FreqXlatingFirFilter::connect(gr::top_block_sptr top_block)
|
|||
if (input_size_ == sizeof(float))
|
||||
{
|
||||
top_block->connect(freq_xlating_fir_filter_fcf_, 0, file_sink_, 0);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
top_block->connect(freq_xlating_fir_filter_ccf_, 0, file_sink_, 0);
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +116,9 @@ void FreqXlatingFirFilter::disconnect(gr::top_block_sptr top_block)
|
|||
if (input_size_ == sizeof(float))
|
||||
{
|
||||
top_block->disconnect(freq_xlating_fir_filter_fcf_, 0, file_sink_, 0);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
top_block->disconnect(freq_xlating_fir_filter_ccf_, 0, file_sink_, 0);
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +131,9 @@ gr::basic_block_sptr FreqXlatingFirFilter::get_left_block()
|
|||
if (input_size_ == sizeof(float))
|
||||
{
|
||||
return freq_xlating_fir_filter_fcf_;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
return freq_xlating_fir_filter_ccf_;
|
||||
}
|
||||
|
||||
|
@ -138,7 +145,9 @@ gr::basic_block_sptr FreqXlatingFirFilter::get_right_block()
|
|||
if (input_size_ == sizeof(float))
|
||||
{
|
||||
return freq_xlating_fir_filter_fcf_;
|
||||
}else{
|
||||
}
|
||||
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
|
||||
* to a TelemetryDecoderInterface
|
||||
* \author Javier Arribas 2013. jarribas(at)cttc.es
|
||||
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
|
||||
* \author Javier Arribas 2013. jarribas(at)cttc.es,
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* \author Javier Arribas 2013 jarribas(at)cttc.es,
|
||||
* Mara Branzanti 2013. mara.branzanti(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
|
@ -59,6 +59,9 @@ public:
|
|||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Galileo_E1B_Telemetry_Decoder"
|
||||
*/
|
||||
std::string implementation()
|
||||
{
|
||||
return "Galileo_E1B_Telemetry_Decoder";
|
||||
|
|
|
@ -41,9 +41,7 @@
|
|||
#include "control_message_factory.h"
|
||||
#include "galileo_navigation_message.h"
|
||||
#include "gnss_synchro.h"
|
||||
|
||||
#include "convolutional.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -70,7 +68,6 @@ void galileo_e1b_telemetry_decoder_cc::forecast (int noutput_items, gr_vector_in
|
|||
|
||||
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;
|
||||
|
@ -104,7 +101,6 @@ void galileo_e1b_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols
|
|||
free( out1 );
|
||||
free( state0 );
|
||||
free( state1 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -177,16 +173,20 @@ galileo_e1b_telemetry_decoder_cc::galileo_e1b_telemetry_decoder_cc(
|
|||
d_TOW_at_current_symbol = 0;
|
||||
|
||||
d_CRC_error_counter = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
galileo_e1b_telemetry_decoder_cc::~galileo_e1b_telemetry_decoder_cc()
|
||||
{
|
||||
delete d_preambles_symbols;
|
||||
d_dump_file.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols,int frame_length)
|
||||
{
|
||||
double page_part_symbols_deint[frame_length];
|
||||
|
@ -195,7 +195,7 @@ void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols,int
|
|||
|
||||
// 2. Viterbi decoder
|
||||
// 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder)
|
||||
// 2.2 Take into account the possible inversion of the polarity due to PLL lock at 180º
|
||||
// 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++)
|
||||
{
|
||||
if ((i + 1) % 2 == 0)
|
||||
|
@ -216,7 +216,9 @@ void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols,int
|
|||
if (page_part_bits[i] > 0)
|
||||
{
|
||||
page_String.push_back('1');
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
page_String.push_back('0');
|
||||
}
|
||||
|
||||
|
@ -230,7 +232,9 @@ void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols,int
|
|||
if(d_nav.flag_CRC_test == true)
|
||||
{
|
||||
std::cout << "Galileo CRC correct on channel " << d_channel << std::endl;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Galileo CRC error on channel " << d_channel << std::endl;
|
||||
}
|
||||
flag_even_word_arrived = 0;
|
||||
|
@ -264,6 +268,10 @@ void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols,int
|
|||
d_utc_model_queue->push(utc_model);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -300,7 +308,8 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
|||
std::cout << "Preamble detection for Galileo SAT " << this->d_satellite << std::endl;
|
||||
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)
|
||||
{
|
||||
|
@ -313,14 +322,16 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
|||
d_preamble_index = d_sample_counter; //record the preamble sample stamp
|
||||
d_stat = 2;
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
if (preamble_diff > GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS)
|
||||
{
|
||||
d_stat = 0; // start again
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if (d_stat==2)
|
||||
}
|
||||
else if (d_stat == 2)
|
||||
{
|
||||
if (d_sample_counter == d_preamble_index+GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS)
|
||||
{
|
||||
|
@ -335,7 +346,9 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
|||
{
|
||||
page_part_symbols[i] = in[0][i + d_symbols_per_preamble].Prompt_I; // because last symbol of the preamble is just received now!
|
||||
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
page_part_symbols[i] = -in[0][i + d_symbols_per_preamble].Prompt_I; // because last symbol of the preamble is just received now!
|
||||
}
|
||||
}
|
||||
|
@ -366,7 +379,9 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
|||
d_flag_frame_sync = true;
|
||||
std::cout <<" Frame sync SAT " << this->d_satellite << " with preamble start at " << d_preamble_time_seconds << " [s]" << std::endl;
|
||||
}
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
d_CRC_error_counter++;
|
||||
d_preamble_index = d_sample_counter; //record the preamble sample stamp
|
||||
if (d_CRC_error_counter > CRC_ERROR_LIMIT)
|
||||
|
@ -428,7 +443,9 @@ int galileo_e1b_telemetry_decoder_cc::general_work (int noutput_items, gr_vector
|
|||
if (d_flag_frame_sync == true and d_nav.flag_TOW_set == true)
|
||||
{
|
||||
current_synchro_data.Flag_valid_word = true;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
current_synchro_data.Flag_valid_word = false;
|
||||
}
|
||||
|
||||
|
@ -486,28 +503,37 @@ void galileo_e1b_telemetry_decoder_cc::set_channel(int channel)
|
|||
d_dump_filename.append(".dat");
|
||||
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
|
||||
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
d_ephemeris_queue = ephemeris_queue;
|
||||
}
|
||||
|
||||
|
||||
void galileo_e1b_telemetry_decoder_cc::set_iono_queue(concurrent_queue<Galileo_Iono> *iono_queue)
|
||||
{
|
||||
d_iono_queue = iono_queue;
|
||||
}
|
||||
|
||||
|
||||
void galileo_e1b_telemetry_decoder_cc::set_almanac_queue(concurrent_queue<Galileo_Almanac> *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)
|
||||
{
|
||||
d_utc_model_queue = utc_model_queue;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/*!
|
||||
* \file galileo_e1b_telemetry_decoder_cc.h
|
||||
* \brief Interface of a Galileo NAV message demodulator block
|
||||
* \author Javier Arribas 2013. jarribas(at)cttc.es
|
||||
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
|
||||
* \author Javier Arribas 2013 jarribas(at)cttc.es,
|
||||
* Mara Branzanti 2013 mara.branzanti(at)gmail.com
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
||||
#define 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
|
||||
|
||||
|
||||
#include "Galileo_E1.h"
|
||||
|
@ -38,7 +39,6 @@
|
|||
#include <bitset>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
|
||||
#include "gnuradio/trellis/interleaver.h"
|
||||
#include "gnuradio/trellis/permutation.h"
|
||||
#include "gnuradio/fec/viterbi.h"
|
||||
|
@ -76,16 +76,20 @@ public:
|
|||
void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN
|
||||
void set_channel(int channel); //!< Set receiver's channel
|
||||
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,
|
||||
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);
|
||||
|
||||
private:
|
||||
|
@ -121,7 +125,6 @@ private:
|
|||
// navigation message vars
|
||||
Galileo_Navigation_Message d_nav;
|
||||
|
||||
|
||||
// Galileo ephemeris queue
|
||||
concurrent_queue<Galileo_Ephemeris> *d_ephemeris_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
|
||||
* Satellite Systems receiver
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
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.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_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
|
||||
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)
|
||||
{
|
||||
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
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
||||
* Satellite Systems receiver
|
||||
|
@ -39,7 +39,6 @@
|
|||
#include <bitset>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
//#include <gnuradio/gr_sync_block.h>
|
||||
#include "gnss_satellite.h"
|
||||
|
||||
|
||||
|
@ -62,24 +61,35 @@ public:
|
|||
~gps_l1_ca_telemetry_decoder_cc();
|
||||
void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN
|
||||
void set_channel(int channel); //!< Set receiver's channel
|
||||
|
||||
/*!
|
||||
* \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_iono_queue(concurrent_queue<Gps_Iono> *iono_queue){d_GPS_FSM.d_iono_queue = iono_queue;}
|
||||
void set_almanac_queue(concurrent_queue<Gps_Almanac> *almanac_queue){d_GPS_FSM.d_almanac_queue = almanac_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_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;} //!< Set the iono data 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;} //!< 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,
|
||||
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);
|
||||
|
||||
private:
|
||||
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
|
||||
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
|
||||
int vector_length, boost::shared_ptr<gr::msg_queue> queue, bool dump);
|
||||
|
||||
bool gps_word_parityCheck(unsigned int gpsword);
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
sbas_l1_telemetry_decoder_cc::sbas_l1_telemetry_decoder_cc(
|
||||
Gnss_Satellite satellite,
|
||||
long if_freq,
|
||||
|
@ -64,7 +66,8 @@ sbas_l1_telemetry_decoder_cc::sbas_l1_telemetry_decoder_cc(
|
|||
int vector_length,
|
||||
boost::shared_ptr<gr::msg_queue> queue,
|
||||
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)))
|
||||
{
|
||||
// initialize internal vars
|
||||
|
@ -72,33 +75,33 @@ sbas_l1_telemetry_decoder_cc::sbas_l1_telemetry_decoder_cc(
|
|||
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
|
||||
DLOG(INFO) << "SBAS L1 TELEMETRY PROCESSING: satellite " << d_satellite;
|
||||
d_fs_in = fs_in;
|
||||
|
||||
d_block_size = d_samples_per_symbol * d_symbols_per_bit * d_block_size_in_bits;
|
||||
|
||||
set_output_multiple (1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
sbas_l1_telemetry_decoder_cc::~sbas_l1_telemetry_decoder_cc()
|
||||
{
|
||||
d_dump_file.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void sbas_l1_telemetry_decoder_cc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
|
||||
{
|
||||
unsigned ninputs = ninput_items_required.size ();
|
||||
for (unsigned i = 0; i < ninputs; i++)
|
||||
ninput_items_required[i] = noutput_items;
|
||||
|
||||
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,
|
||||
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];
|
||||
|
||||
// get pointers on in- and output gnss-synchro objects
|
||||
const Gnss_Synchro *in = (const Gnss_Synchro *) input_items[0]; // input
|
||||
Gnss_Synchro *out = (Gnss_Synchro *) output_items[0]; // output
|
||||
|
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
|
||||
// get the next samples
|
||||
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
|
||||
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"
|
||||
<< "d_corr_paired: " << std::setw(10) << d_corr_paired << "\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;
|
||||
}
|
||||
|
||||
|
||||
void sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::reset()
|
||||
{
|
||||
d_past_symbol = 0;
|
||||
|
@ -313,6 +319,7 @@ void sbas_l1_telemetry_decoder_cc::symbol_aligner_and_decoder::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)
|
||||
{
|
||||
const int traceback_depth = 5*d_KK;
|
||||
|
@ -438,7 +445,8 @@ void sbas_l1_telemetry_decoder_cc::crc_verifier::get_valid_frames(const std::vec
|
|||
d_checksum_agent.reset(0);
|
||||
d_checksum_agent.process_bytes(candidate_bytes.data(), candidate_bytes.size());
|
||||
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()
|
||||
<< ": 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
|
||||
if (crc == 0)
|
||||
|
@ -483,7 +491,8 @@ 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
|
||||
VLOG(LMORE) << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)byte
|
||||
VLOG(LMORE) << " -> byte=" << std::setw(2)
|
||||
<< std::setfill('0') << std::hex << (unsigned int)byte
|
||||
<< std::setfill(' ') << std::resetiosflags(std::ios::hex);
|
||||
}
|
||||
|
||||
|
@ -504,12 +513,14 @@ void sbas_l1_telemetry_decoder_cc::crc_verifier::zerropad_front_and_convert_to_b
|
|||
if (idx_bit % bits_per_byte == bits_per_byte - 1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
idx_bit++;
|
||||
}
|
||||
VLOG(LMORE) << " -> byte=" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)byte
|
||||
VLOG(LMORE) << " -> byte=" << std::setw(2)
|
||||
<< 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
|
||||
|
||||
// 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_iono_queue(concurrent_queue<Sbas_Ionosphere_Correction> *iono_queue);
|
||||
void set_sat_corr_queue(concurrent_queue<Sbas_Satellite_Correction> *sat_corr_queue);
|
||||
void set_ephemeris_queue(concurrent_queue<Sbas_Ephemeris> *ephemeris_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); //!< Set iono 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); //!< Set SBAS ephemeis queue
|
||||
|
||||
/*!
|
||||
* \brief This is where all signal processing takes place
|
||||
*/
|
||||
int general_work (int noutput_items, gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
||||
|
||||
/*!
|
||||
* \brief 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);
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,108 +1,110 @@
|
|||
/* File convolutional.h
|
||||
|
||||
Description: General functions used to implement convolutional encoding.
|
||||
|
||||
Copyright (C) 2006-2008, Matthew C. Valenti
|
||||
|
||||
Last updated on May 22, 2008
|
||||
|
||||
The functions in this file are part of the Iterative Solutions
|
||||
Coded Modulation Library. The Iterative Solutions Coded Modulation
|
||||
Library is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
/*!
|
||||
* \file convolutional.h
|
||||
* \brief General functions used to implement convolutional encoding.
|
||||
* \author Matthew C. Valenti
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2006-2008 Matthew C. Valenti
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
*
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* at your option) any later version.
|
||||
*
|
||||
* This file is a derived work of the original file, which had this note:
|
||||
*
|
||||
* Last updated on May 22, 2008
|
||||
*
|
||||
* The functions in this file are part of the Iterative Solutions
|
||||
* Coded Modulation Library. The Iterative Solutions Coded Modulation
|
||||
* Library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation; either version 2.1 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* define constants used throughout the library */
|
||||
#define MAXLOG 1e7 /* Define infinity */
|
||||
|
||||
/* function itob()
|
||||
|
||||
Description: Converts an integer symbol into a vector of bits
|
||||
|
||||
Output parameters:
|
||||
binvec_p: The binary vector
|
||||
|
||||
Input parameters:
|
||||
symbol: The integer-valued symbol
|
||||
length: The length of the binary vector
|
||||
|
||||
This function is used by conv_encode() */
|
||||
|
||||
void itob(
|
||||
int binvec_p[],
|
||||
int symbol,
|
||||
int length )
|
||||
/*!
|
||||
* \brief Converts an integer symbol into a vector of bits
|
||||
*
|
||||
* \param[out] binvec_p The binary vector
|
||||
* \param[in] symbol The integer-valued symbol
|
||||
* \param[in] length The length of the binary vector
|
||||
*
|
||||
* This function is used by conv_encode()
|
||||
*/
|
||||
void itob(int binvec_p[], int symbol, int length)
|
||||
{
|
||||
int counter;
|
||||
|
||||
/* Go through each bit in the vector */
|
||||
for (counter=0;counter<length;counter++) {
|
||||
for (counter = 0; counter < length; counter++)
|
||||
{
|
||||
binvec_p[length - counter - 1] = (symbol & 1);
|
||||
symbol = symbol >> 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* function parity_counter()
|
||||
|
||||
Description: Determines if a symbol has odd (1) or even (0) parity
|
||||
|
||||
Output parameters:
|
||||
(returned int): The symbol's parity = 1 for odd and 0 for even
|
||||
|
||||
Input parameters:
|
||||
symbol: The integer-valued symbol
|
||||
length: The highest bit position in the symbol
|
||||
|
||||
This function is used by nsc_enc_bit(), rsc_enc_bit(), and rsc_tail() */
|
||||
|
||||
/*!
|
||||
* \brief Determines if a symbol has odd (1) or even (0) parity
|
||||
* Output parameters:
|
||||
* \return (returned int): The symbol's parity = 1 for odd and 0 for even
|
||||
*
|
||||
* \param[in] symbol The integer-valued symbol
|
||||
* \param[in] length The highest bit position in the symbol
|
||||
*
|
||||
* This function is used by nsc_enc_bit(), rsc_enc_bit(), and rsc_tail()
|
||||
*/
|
||||
int parity_counter(int symbol, int length)
|
||||
{
|
||||
int counter;
|
||||
int temp_parity = 0;
|
||||
|
||||
for (counter=0;counter<length;counter++) {
|
||||
for (counter = 0; counter < length; counter++)
|
||||
{
|
||||
temp_parity = temp_parity^(symbol & 1);
|
||||
symbol = symbol >> 1;
|
||||
}
|
||||
|
||||
return(temp_parity);
|
||||
}
|
||||
|
||||
|
||||
/* Function nsc_enc_bit()
|
||||
|
||||
Description: Convolutionally encodes a single bit using a rate 1/n encoder.
|
||||
Takes in one input bit at a time, and produces a n-bit output.
|
||||
|
||||
Input parameters:
|
||||
input The input data bit (i.e. a 0 or 1).
|
||||
state_in The starting state of the encoder (an int from 0 to 2^m-1).
|
||||
g[] An n-element vector containing the code generators in binary form.
|
||||
KK The constraint length of the convolutional code.
|
||||
|
||||
Output parameters:
|
||||
output_p[] An n-element vector containing the encoded bits.
|
||||
state_out_p[] An integer containing the final state of the encoder
|
||||
(i.e. the state after encoding this bit)
|
||||
|
||||
This function is used by rsc_encode(), nsc_transit(), rsc_transit(), and nsc_transit() */
|
||||
|
||||
static int nsc_enc_bit(
|
||||
int state_out_p[],
|
||||
/*!
|
||||
* \brief Convolutionally encodes a single bit using a rate 1/n encoder.
|
||||
* Takes in one input bit at a time, and produces a n-bit output.
|
||||
*
|
||||
* \param[in] input The input data bit (i.e. a 0 or 1).
|
||||
* \param[in] state_in The starting state of the encoder (an int from 0 to 2^m-1).
|
||||
* \param[in] g[] An n-element vector containing the code generators in binary form.
|
||||
* \param[in] KK The constraint length of the convolutional code.
|
||||
* \param[out] output_p[] An n-element vector containing the encoded bits.
|
||||
* \param[out] state_out_p[] An integer containing the final state of the encoder
|
||||
* (i.e. the state after encoding this bit)
|
||||
*
|
||||
* This function is used by rsc_encode(), nsc_transit(), rsc_transit(), and nsc_transit()
|
||||
*/
|
||||
static int nsc_enc_bit(int state_out_p[],
|
||||
int input,
|
||||
int state_in,
|
||||
int g[],
|
||||
|
@ -111,7 +113,7 @@ static int nsc_enc_bit(
|
|||
{
|
||||
/* declare variables */
|
||||
int state, i;
|
||||
int out = 0;
|
||||
int out_ = 0;
|
||||
|
||||
/* create a word made up of state and new input */
|
||||
state = (input << (KK - 1))^state_in;
|
||||
|
@ -120,17 +122,20 @@ static int nsc_enc_bit(
|
|||
for (i = 0; i < nn; i++)
|
||||
{
|
||||
/* update output symbol */
|
||||
out = (out<<1) + parity_counter( state&g[i], KK );
|
||||
out_ = (out_ << 1) + parity_counter(state & g[i], KK);
|
||||
}
|
||||
|
||||
/* shift the state to make the new state */
|
||||
state_out_p[0] = state >> 1;
|
||||
return(out);
|
||||
return(out_);
|
||||
}
|
||||
|
||||
/* like nsc_enc_bit() but for a RSC code */
|
||||
static int rsc_enc_bit(
|
||||
int state_out_p[],
|
||||
|
||||
|
||||
/*!
|
||||
* \brief like nsc_enc_bit() but for a RSC code
|
||||
*/
|
||||
static int rsc_enc_bit(int state_out_p[],
|
||||
int input,
|
||||
int state_in,
|
||||
int g[],
|
||||
|
@ -138,10 +143,10 @@ static int rsc_enc_bit(
|
|||
int nn)
|
||||
{
|
||||
/* declare variables */
|
||||
int state, i, out, a_k;
|
||||
int state, i, out_, a_k;
|
||||
|
||||
/* systematic output */
|
||||
out = input;
|
||||
out_ = input;
|
||||
|
||||
/* determine feedback bit */
|
||||
a_k = input^parity_counter(g[0]&state_in, KK);
|
||||
|
@ -153,17 +158,20 @@ static int rsc_enc_bit(
|
|||
for (i = 1; i < nn; i++)
|
||||
{
|
||||
/* update output symbol */
|
||||
out = (out<<1) + parity_counter( state&g[i], KK );
|
||||
out_ = (out_ << 1) + parity_counter(state & g[i], KK);
|
||||
}
|
||||
|
||||
/* shift the state to make the new state */
|
||||
state_out_p[0] = state >> 1;
|
||||
return(out);
|
||||
return(out_);
|
||||
}
|
||||
|
||||
/* function that creates the transit and output vectors */
|
||||
static void nsc_transit(
|
||||
int output_p[],
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Function that creates the transit and output vectors
|
||||
*/
|
||||
static void nsc_transit(int output_p[],
|
||||
int trans_p[],
|
||||
int input,
|
||||
int g[],
|
||||
|
@ -175,34 +183,32 @@ static void nsc_transit(
|
|||
states = (1 << (KK - 1)); /* The number of states: 2^mm */
|
||||
|
||||
/* Determine the output and next state for each possible starting state */
|
||||
for(state=0;state<states;state++) {
|
||||
for(state = 0; state < states; state++)
|
||||
{
|
||||
output_p[state] = nsc_enc_bit(nextstate, input, state, g, KK, nn);
|
||||
trans_p[state] = nextstate[0];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Function rsc_transit()
|
||||
|
||||
Description: Calculates the "transition matrix" for the trellis.
|
||||
This information tells the decoder what the next state and output bits
|
||||
will be given the current state and input bit.
|
||||
|
||||
Input parameters:
|
||||
input Either 0 or 1 --- the input data bit.
|
||||
g[] A two element vector containing the code generators.
|
||||
KK The constraint length of the convolutional code.
|
||||
|
||||
Output parameters:
|
||||
output_p[] A vector of length max_states = 2^(KK-1) containing
|
||||
the output symbols.
|
||||
trans_p[] A vector of length max_states that tells the decoder
|
||||
what the next state will be given the input and current state.
|
||||
|
||||
This function is used by turbo_decode() */
|
||||
|
||||
static void rsc_transit(
|
||||
int output_p[],
|
||||
/*!
|
||||
* \brief Calculates the "transition matrix" for the trellis.
|
||||
* This information tells the decoder what the next state and output bits
|
||||
* will be given the current state and input bit.
|
||||
*
|
||||
* \param[in] input Either 0 or 1 --- the input data bit.
|
||||
* \param[in] g[] A two element vector containing the code generators.
|
||||
* \param[in] KK The constraint length of the convolutional code.
|
||||
* \param[out] output_p[] A vector of length max_states = 2^(KK-1) containing
|
||||
* the output symbols.
|
||||
* \param[out] trans_p[] A vector of length max_states that tells the decoder
|
||||
* what the next state will be given the input and current state.
|
||||
*
|
||||
* This function is used by turbo_decode()
|
||||
*/
|
||||
static void rsc_transit(int output_p[],
|
||||
int trans_p[],
|
||||
int input,
|
||||
int g[],
|
||||
|
@ -212,19 +218,23 @@ static void rsc_transit(
|
|||
int nextstate[1];
|
||||
int state, states;
|
||||
|
||||
states = 1 << (KK-1); /* The number of states: 2^mm */
|
||||
states = 1 << (KK - 1); // The number of states: 2^mm
|
||||
|
||||
/* Determine the output and next state for each possible starting state */
|
||||
for(state=0;state<states;state++) {
|
||||
// Determine the output and next state for each possible starting state
|
||||
for(state = 0; state < states; state++)
|
||||
{
|
||||
output_p[state] = rsc_enc_bit( nextstate, input, state, g, KK, nn );
|
||||
trans_p[state] = nextstate[0];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* determine the tail for a RSC code */
|
||||
static void rsc_tail(
|
||||
int tail_p[],
|
||||
|
||||
|
||||
/*!
|
||||
* \brief determines the tail for a RSC code
|
||||
*/
|
||||
static void rsc_tail(int tail_p[],
|
||||
int g[],
|
||||
int max_states,
|
||||
int mm )
|
||||
|
@ -232,16 +242,20 @@ static void rsc_tail(
|
|||
int state;
|
||||
|
||||
/* Determine the tail for each state */
|
||||
for(state=0;state<max_states;state++) {
|
||||
for(state = 0; state < max_states; state++)
|
||||
{
|
||||
/* determine feedback word */
|
||||
tail_p[state] = parity_counter(g[0]&state, mm);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* perform convolutional encoding */
|
||||
static void conv_encode(
|
||||
int output_p[],
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Perform convolutional encoding
|
||||
*/
|
||||
static void conv_encode(int output_p[],
|
||||
int input[],
|
||||
int out0[],
|
||||
int state0[],
|
||||
|
@ -259,12 +273,17 @@ static void conv_encode(
|
|||
/* Negative value in "tail" is a flag that this is
|
||||
a tail-biting NSC code. Determine initial state */
|
||||
|
||||
if ( tail[0] < 0 ) {
|
||||
for (i=LL-KK+1;i<LL;i++) {
|
||||
if (input[i]) {
|
||||
if ( tail[0] < 0 )
|
||||
{
|
||||
for (i = LL - KK + 1; i < LL; i++)
|
||||
{
|
||||
if (input[i])
|
||||
{
|
||||
/* Determine next state */
|
||||
state = state1[state];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Determine next state */
|
||||
state = state0[state];
|
||||
}
|
||||
|
@ -274,14 +293,18 @@ static void conv_encode(
|
|||
bin_vec = (int*)calloc( nn, sizeof(int) );
|
||||
|
||||
/* encode data bits one bit at a time */
|
||||
for (i=0;i<LL;i++) {
|
||||
if (input[i]) {
|
||||
for (i = 0; i < LL; i++)
|
||||
{
|
||||
if (input[i])
|
||||
{
|
||||
/* Input is a one */
|
||||
outsym = out1[state]; /* The output symbol */
|
||||
|
||||
/* Determine next state */
|
||||
state = state1[state];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Input is a zero */
|
||||
outsym = out0[state]; /* The output symbol */
|
||||
|
||||
|
@ -298,15 +321,20 @@ static void conv_encode(
|
|||
}
|
||||
|
||||
/* encode tail if needed */
|
||||
if (tail[0] >= 0) {
|
||||
for (i=LL;i<LL+KK-1;i++) {
|
||||
if (tail[state]) {
|
||||
if (tail[0] >= 0)
|
||||
{
|
||||
for (i = LL; i < LL + KK - 1; i++)
|
||||
{
|
||||
if (tail[state])
|
||||
{
|
||||
/* Input is a one */
|
||||
outsym = out1[state]; /* The output symbol */
|
||||
|
||||
/* Determine next state */
|
||||
state = state1[state];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Input is a zero */
|
||||
outsym = out0[state]; /* The output symbol */
|
||||
|
||||
|
@ -324,65 +352,50 @@ static void conv_encode(
|
|||
}
|
||||
|
||||
free(bin_vec);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* function Gamma()
|
||||
|
||||
Description: Computes the branch metric used for decoding.
|
||||
|
||||
Output parameters:
|
||||
(returned float) The metric between the hypothetical symbol and the recevieved vector
|
||||
|
||||
Input parameters:
|
||||
rec_array The received vector, of length nn
|
||||
symbol The hypothetical symbol
|
||||
nn The length of the received vector
|
||||
|
||||
This function is used by siso() */
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Computes the branch metric used for decoding.
|
||||
* \return (returned float) The metric between the hypothetical symbol and the received vector
|
||||
* \param[in] rec_array The received vector, of length nn
|
||||
* \param[in] symbol The hypothetical symbol
|
||||
* \param[in] nn The length of the received vector
|
||||
*
|
||||
* This function is used by siso()
|
||||
*/
|
||||
static float Gamma(float rec_array[],
|
||||
int symbol,
|
||||
int nn)
|
||||
{
|
||||
float rm = 0;
|
||||
int i;
|
||||
int mask;
|
||||
int mask = 1;
|
||||
|
||||
mask = 1;
|
||||
for (i=0;i<nn;i++) {
|
||||
for (i = 0; i < nn; i++)
|
||||
{
|
||||
if (symbol & mask)
|
||||
rm += rec_array[nn - i - 1];
|
||||
mask = mask << 1;
|
||||
}
|
||||
|
||||
return(rm);
|
||||
}
|
||||
|
||||
|
||||
/* Function Viterbi()
|
||||
|
||||
Description: Uses the Viterbi algorithm to perform hard-decision decoding of a convolutional code.
|
||||
|
||||
Input parameters:
|
||||
out0[] The output bits for each state if input is a 0 (generated by rsc_transit).
|
||||
state0[] The next state if input is a 0 (generated by rsc_transit).
|
||||
out1[] The output bits for each state if input is a 1 (generated by rsc_transit).
|
||||
state1[] The next state if input is a 1 (generated by rsc_transit).
|
||||
r[] The received signal in LLR-form. For BPSK, must be in form r = 2*a*y/(sigma^2).
|
||||
KK The constraint length of the convolutional code.
|
||||
LL The number of data bits.
|
||||
|
||||
Output parameters:
|
||||
output_u_int[] Hard decisions on the data bits
|
||||
|
||||
/*!
|
||||
* \brief Uses the Viterbi algorithm to perform hard-decision decoding of a convolutional code.
|
||||
* \param[in] out0[] The output bits for each state if input is a 0 (generated by rsc_transit).
|
||||
* \param[in] state0[] The next state if input is a 0 (generated by rsc_transit).
|
||||
* \param[in] out1[] The output bits for each state if input is a 1 (generated by rsc_transit).
|
||||
* \param[in] state1[] The next state if input is a 1 (generated by rsc_transit).
|
||||
* \param[in] r[] The received signal in LLR-form. For BPSK, must be in form r = 2*a*y/(sigma^2).
|
||||
* \param[in] KK The constraint length of the convolutional code.
|
||||
* \param[in] LL The number of data bits.
|
||||
* \param[out] output_u_int[] Hard decisions on the data bits
|
||||
*
|
||||
*/
|
||||
|
||||
static void Viterbi(
|
||||
int output_u_int[],
|
||||
static void Viterbi(int output_u_int[],
|
||||
int out0[],
|
||||
int state0[],
|
||||
int out1[],
|
||||
|
@ -390,8 +403,7 @@ static void Viterbi(
|
|||
double input_c[],
|
||||
int KK,
|
||||
int nn,
|
||||
int LL
|
||||
)
|
||||
int LL)
|
||||
{
|
||||
int i, t, state, mm, states;
|
||||
int number_symbols;
|
||||
|
@ -417,14 +429,16 @@ static void Viterbi(
|
|||
metric_c = (float*)calloc( number_symbols, sizeof(float) );
|
||||
|
||||
/* initialize trellis */
|
||||
for (state=0;state<states;state++) {
|
||||
for (state = 0; state < states; state++)
|
||||
{
|
||||
prev_section[state] = -MAXLOG;
|
||||
next_section[state] = -MAXLOG;
|
||||
}
|
||||
prev_section[0] = 0; /* start in all-zeros state */
|
||||
|
||||
/* go through trellis */
|
||||
for (t=0;t<LL+mm;t++) {
|
||||
for (t = 0; t < LL + mm; t++)
|
||||
{
|
||||
for (i = 0; i < nn; i++)
|
||||
rec_array[i] = (float)input_c[nn*t + i];
|
||||
|
||||
|
@ -433,13 +447,14 @@ static void Viterbi(
|
|||
metric_c[i] = Gamma( rec_array, i, nn );
|
||||
|
||||
/* step through all states */
|
||||
for (state=0;state<states;state++) {
|
||||
|
||||
for (state = 0; state < states; state++)
|
||||
{
|
||||
/* hypothesis: info bit is a zero */
|
||||
metric = prev_section[state] + metric_c[ out0[ state ] ];
|
||||
|
||||
/* store new metric if more than metric in storage */
|
||||
if ( metric > next_section[state0[state]] ) {
|
||||
if ( metric > next_section[state0[state]] )
|
||||
{
|
||||
next_section[state0[state]] = metric;
|
||||
prev_state[t*states + state0[state]] = state;
|
||||
prev_bit[t*states + state0[state]] = 0;
|
||||
|
@ -449,7 +464,8 @@ static void Viterbi(
|
|||
metric = prev_section[state] + metric_c[ out1[ state ] ];
|
||||
|
||||
/* store new metric if more than metric in storage */
|
||||
if ( metric > next_section[state1[state]] ) {
|
||||
if ( metric > next_section[state1[state]] )
|
||||
{
|
||||
next_section[state1[state]] = metric;
|
||||
prev_state[t*states + state1[state]] = state;
|
||||
prev_bit[t*states + state1[state]] = 1;
|
||||
|
@ -458,12 +474,15 @@ static void Viterbi(
|
|||
|
||||
/* normalize */
|
||||
max_val = 0;
|
||||
for (state=0;state<states;state++) {
|
||||
if (next_section[state]>max_val){
|
||||
for (state = 0; state < states; state++)
|
||||
{
|
||||
if (next_section[state] > max_val)
|
||||
{
|
||||
max_val = next_section[state];
|
||||
}
|
||||
}
|
||||
for (state=0;state<states;state++) {
|
||||
for (state = 0; state < states; state++)
|
||||
{
|
||||
prev_section[state] = next_section[state] - max_val;
|
||||
next_section[state] = -MAXLOG;
|
||||
}
|
||||
|
@ -473,11 +492,13 @@ static void Viterbi(
|
|||
state = 0;
|
||||
|
||||
/* tail, no need to output */
|
||||
for (t=LL+mm-1; t>=LL; t--) {
|
||||
for (t = LL + mm - 1; t >= LL; t--)
|
||||
{
|
||||
state = prev_state[t*states + state];
|
||||
}
|
||||
|
||||
for (t=LL-1; t>=0; t--) {
|
||||
for (t = LL - 1; t >= 0; t--)
|
||||
{
|
||||
output_u_int[t] = prev_bit[t*states + state];
|
||||
state = prev_state[t*states + state];
|
||||
}
|
||||
|
@ -489,31 +510,24 @@ static void Viterbi(
|
|||
free(prev_state);
|
||||
free(rec_array);
|
||||
free(metric_c);
|
||||
|
||||
}
|
||||
|
||||
/* Function ViterbiTb()
|
||||
|
||||
Description: Uses the Viterbi algorithm to perform hard-decision decoding of a tail-biting convolutional code.
|
||||
|
||||
Input parameters:
|
||||
out0[] The output bits for each state if input is a 0 (generated by rsc_transit).
|
||||
state0[] The next state if input is a 0 (generated by rsc_transit).
|
||||
out1[] The output bits for each state if input is a 1 (generated by rsc_transit).
|
||||
state1[] The next state if input is a 1 (generated by rsc_transit).
|
||||
r[] The received signal in LLR-form. For BPSK, must be in form r = 2*a*y/(sigma^2).
|
||||
KK The constraint length of the convolutional code.
|
||||
LL The number of data bits.
|
||||
depth head and tail decoding length [Ref. W. Sung, Electronics Letters, vol. 36, no. 7]
|
||||
|
||||
Output parameters:
|
||||
output_u_int[] Hard decisions on the data bits
|
||||
|
||||
/*!
|
||||
* \brief Uses the Viterbi algorithm to perform hard-decision decoding of a tail-biting convolutional code.
|
||||
* Input parameters:
|
||||
* out0[] The output bits for each state if input is a 0 (generated by rsc_transit).
|
||||
* state0[] The next state if input is a 0 (generated by rsc_transit).
|
||||
* out1[] The output bits for each state if input is a 1 (generated by rsc_transit).
|
||||
* state1[] The next state if input is a 1 (generated by rsc_transit).
|
||||
* r[] The received signal in LLR-form. For BPSK, must be in form r = 2*a*y/(sigma^2).
|
||||
* KK The constraint length of the convolutional code.
|
||||
* LL The number of data bits.
|
||||
* depth head and tail decoding length [Ref. W. Sung, Electronics Letters, vol. 36, no. 7]
|
||||
* Output parameters:
|
||||
* output_u_int[] Hard decisions on the data bits
|
||||
*/
|
||||
|
||||
|
||||
static void ViterbiTb(
|
||||
int output_u_int[],
|
||||
static void ViterbiTb(int output_u_int[],
|
||||
int out0[],
|
||||
int state0[],
|
||||
int out1[],
|
||||
|
@ -522,8 +536,7 @@ static void ViterbiTb(
|
|||
int KK,
|
||||
int nn,
|
||||
int LL,
|
||||
int depth
|
||||
)
|
||||
int depth)
|
||||
{
|
||||
int i, t, state, mm, states, max_state;
|
||||
int number_symbols, starting_bit;
|
||||
|
@ -549,22 +562,23 @@ static void ViterbiTb(
|
|||
metric_c = (float*)calloc( number_symbols, sizeof(float) );
|
||||
|
||||
/* initialize trellis */
|
||||
for (state=0;state<states;state++) {
|
||||
for (state = 0; state < states; state++)
|
||||
{
|
||||
prev_section[state] = 0; /* equally likely starting state */
|
||||
next_section[state] = -MAXLOG;
|
||||
}
|
||||
|
||||
/* go through trellis */
|
||||
for (t=-depth;t<LL+depth;t++) {
|
||||
for (t = -depth; t < LL + depth; t++)
|
||||
{
|
||||
/* determine the corresponding data bits */
|
||||
starting_bit = nn*(t % LL);
|
||||
if (starting_bit < 0 )
|
||||
starting_bit = nn*LL + starting_bit;
|
||||
|
||||
/* printf( "start at %d\n", starting_bit ); */
|
||||
for (i=0;i<nn;i++) {
|
||||
for (i = 0; i < nn; i++)
|
||||
{
|
||||
rec_array[i] = (float)input_c[starting_bit+i];
|
||||
/* printf( "%1f\n", rec_array[i] ); */
|
||||
}
|
||||
|
||||
/* precompute all possible branch metrics */
|
||||
|
@ -572,15 +586,17 @@ static void ViterbiTb(
|
|||
metric_c[i] = Gamma( rec_array, i, nn );
|
||||
|
||||
/* step through all states */
|
||||
for (state=0;state<states;state++) {
|
||||
|
||||
for (state = 0; state < states; state++)
|
||||
{
|
||||
/* hypothesis: info bit is a zero */
|
||||
metric = prev_section[state] + metric_c[ out0[ state ] ];
|
||||
|
||||
/* store new metric if more than metric in storage */
|
||||
if ( metric > next_section[state0[state]] ) {
|
||||
if ( metric > next_section[state0[state]] )
|
||||
{
|
||||
next_section[state0[state]] = metric;
|
||||
if (t>=0) {
|
||||
if (t >= 0)
|
||||
{
|
||||
prev_state[t*states+state0[state]] = state;
|
||||
prev_bit[t*states+state0[state]] = 0;
|
||||
}
|
||||
|
@ -590,9 +606,11 @@ static void ViterbiTb(
|
|||
metric = prev_section[state] + metric_c[ out1[ state ] ];
|
||||
|
||||
/* store new metric if more than metric in storage */
|
||||
if ( metric > next_section[state1[state]] ) {
|
||||
if ( metric > next_section[state1[state]] )
|
||||
{
|
||||
next_section[state1[state]] = metric;
|
||||
if (t>=0) {
|
||||
if (t >= 0)
|
||||
{
|
||||
prev_state[t*states+state1[state]] = state;
|
||||
prev_bit[t*states+state1[state]] = 1;
|
||||
}
|
||||
|
@ -601,13 +619,16 @@ static void ViterbiTb(
|
|||
|
||||
/* normalize */
|
||||
max_val = 0;
|
||||
for (state=0;state<states;state++) {
|
||||
if (next_section[state]>max_val){
|
||||
for (state = 0; state < states; state++)
|
||||
{
|
||||
if (next_section[state] > max_val)
|
||||
{
|
||||
max_val = next_section[state];
|
||||
max_state = state;
|
||||
}
|
||||
}
|
||||
for (state=0;state<states;state++) {
|
||||
for (state = 0; state < states; state++)
|
||||
{
|
||||
prev_section[state] = next_section[state] - max_val;
|
||||
next_section[state] = -MAXLOG;
|
||||
}
|
||||
|
@ -617,11 +638,13 @@ static void ViterbiTb(
|
|||
state = max_state;
|
||||
|
||||
/* tail, no need to output */
|
||||
for (t=LL+depth-1; t>=LL; t--) {
|
||||
for (t = LL + depth - 1; t >= LL; t--)
|
||||
{
|
||||
state = prev_state[t*states + state];
|
||||
}
|
||||
|
||||
for (t=LL-1; t>=0; t--) {
|
||||
for (t = LL - 1; t >= 0; t--)
|
||||
{
|
||||
output_u_int[t] = prev_bit[t*states + state];
|
||||
state = prev_state[t*states + state];
|
||||
}
|
||||
|
@ -633,5 +656,4 @@ static void ViterbiTb(
|
|||
free(prev_state);
|
||||
free(rec_array);
|
||||
free(metric_c);
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* Satellite Systems receiver
|
||||
|
@ -232,18 +232,24 @@ GpsL1CaSubframeFsm::GpsL1CaSubframeFsm()
|
|||
initiate(); //start the FSM
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GpsL1CaSubframeFsm::gps_word_to_subframe(int position)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GpsL1CaSubframeFsm::gps_subframe_to_nav_msg()
|
||||
{
|
||||
int subframe_ID;
|
||||
// NEW GPS SUBFRAME HAS ARRIVED!
|
||||
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_channel_ID = i_channel_ID;
|
||||
d_nav.d_subframe_timestamp_ms = this->d_preamble_time_ms;
|
||||
|
@ -279,11 +285,15 @@ void GpsL1CaSubframeFsm::gps_subframe_to_nav_msg()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GpsL1CaSubframeFsm::Event_gps_word_valid()
|
||||
{
|
||||
this->process_event(Ev_gps_word_valid());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GpsL1CaSubframeFsm::Event_gps_word_invalid()
|
||||
{
|
||||
this->process_event(Ev_gps_word_invalid());
|
||||
|
|
|
@ -67,46 +67,48 @@ struct gps_subframe_fsm_S9;
|
|||
struct gps_subframe_fsm_S10;
|
||||
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 >
|
||||
{
|
||||
public:
|
||||
GpsL1CaSubframeFsm(); //!< The constructor starts the Finite State Machine
|
||||
|
||||
// channel and satellite info
|
||||
int i_channel_ID;
|
||||
unsigned int i_satellite_PRN;
|
||||
int i_channel_ID; //!< Channel id
|
||||
unsigned int i_satellite_PRN; //!< Satellite PRN number
|
||||
|
||||
// ephemeris queue
|
||||
concurrent_queue<Gps_Ephemeris> *d_ephemeris_queue;
|
||||
// ionospheric parameters queue
|
||||
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;
|
||||
concurrent_queue<Gps_Ephemeris> *d_ephemeris_queue; //!< Ephemeris queue
|
||||
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
|
||||
|
||||
// navigation message class
|
||||
Gps_Navigation_Message d_nav;
|
||||
Gps_Navigation_Message d_nav; //!< GPS L1 C/A navigation message object
|
||||
|
||||
// GPS SV and System parameters
|
||||
Gps_Ephemeris ephemeris;
|
||||
Gps_Almanac almanac;
|
||||
Gps_Utc_Model utc_model;
|
||||
Gps_Iono iono;
|
||||
|
||||
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_GPS_frame_4bytes[GPS_WORD_LENGTH];
|
||||
|
||||
double d_preamble_time_ms;
|
||||
|
||||
void gps_word_to_subframe(int position);
|
||||
void gps_word_to_subframe(int position); //!< inserts the word in the correct position of the subframe
|
||||
|
||||
/*!
|
||||
* \brief This function decodes a NAv message subframe and pushes the information to the right queues
|
||||
*/
|
||||
void gps_subframe_to_nav_msg();
|
||||
|
||||
//FSM EVENTS
|
||||
void Event_gps_word_valid();
|
||||
void Event_gps_word_invalid();
|
||||
void Event_gps_word_preamble();
|
||||
|
||||
GpsL1CaSubframeFsm();
|
||||
void Event_gps_word_valid(); //!< FSM event: the received word is valid
|
||||
void Event_gps_word_invalid(); //!< FSM event: the received word is not valid
|
||||
void Event_gps_word_preamble(); //!< FSM event: word preamble detected
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
|
||||
Viterbi_Decoder::Viterbi_Decoder(const int g_encoder[], const int KK, const int nn)
|
||||
{
|
||||
|
||||
d_nn = nn; //Coding rate 1/n
|
||||
d_KK = KK; //Constraint Length
|
||||
|
||||
|
@ -84,27 +83,25 @@ Viterbi_Decoder::~Viterbi_Decoder()
|
|||
delete[] d_metric_c;
|
||||
}
|
||||
|
||||
void
|
||||
Viterbi_Decoder::reset()
|
||||
|
||||
|
||||
void Viterbi_Decoder::reset()
|
||||
{
|
||||
init_trellis_state();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Function decode_block()
|
||||
|
||||
Description: Uses the Viterbi algorithm to perform hard-decision decoding of a convolutional code.
|
||||
|
||||
Input parameters:
|
||||
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)
|
||||
|
||||
Output parameters:
|
||||
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 decoding_length_mismatch;
|
||||
|
@ -125,9 +122,13 @@ Viterbi_Decoder::decode_block(const double input_c[], int output_u_int[], const
|
|||
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 decoding_length_mismatch;
|
||||
|
@ -150,11 +151,11 @@ Viterbi_Decoder::decode_continuous(const double sym[], const int traceback_depth
|
|||
return d_indicator_metric;
|
||||
}
|
||||
|
||||
void
|
||||
Viterbi_Decoder::init_trellis_state()
|
||||
|
||||
|
||||
void Viterbi_Decoder::init_trellis_state()
|
||||
{
|
||||
int state;
|
||||
|
||||
// if trellis state has been initialised, free old state memory
|
||||
if(d_trellis_state_is_initialised)
|
||||
{
|
||||
|
@ -182,8 +183,10 @@ Viterbi_Decoder::init_trellis_state()
|
|||
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;
|
||||
float metric;
|
||||
|
@ -202,11 +205,9 @@ Viterbi_Decoder::do_acs(const double sym[], int nbits)
|
|||
pm_t_next[state_at_t] = -MAXLOG;
|
||||
}
|
||||
|
||||
|
||||
/* go through trellis */
|
||||
for (t = 0; t < nbits; t++)
|
||||
{
|
||||
|
||||
/* Temporarily store the received symbols current decoding step */
|
||||
for (i = 0; i < d_nn; 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 */
|
||||
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_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);
|
||||
|
||||
|
||||
/* normalize -> afterwards, the largest metric value is always 0 */
|
||||
//max_val = 0;
|
||||
max_val = -MAXLOG;
|
||||
|
@ -275,14 +274,14 @@ Viterbi_Decoder::do_acs(const double sym[], int nbits)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
delete[] pm_t_next;
|
||||
|
||||
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
|
||||
int state;
|
||||
|
@ -303,16 +302,16 @@ Viterbi_Decoder::do_traceback(size_t traceback_length)
|
|||
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 t_out;
|
||||
std::deque<Prev>::iterator it;
|
||||
int decoding_length_mismatch;
|
||||
int overstep_length;
|
||||
|
||||
int n_im = 0;
|
||||
|
||||
VLOG(FLOW) << "do_tb_and_decode(): requested_decoding_length=" << requested_decoding_length;
|
||||
|
@ -323,7 +322,8 @@ Viterbi_Decoder::do_tb_and_decode(int traceback_length, int requested_decoding_l
|
|||
overstep_length = decoding_length_mismatch >= 0 ? decoding_length_mismatch : 0;
|
||||
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);
|
||||
}
|
||||
|
@ -342,7 +342,6 @@ 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);
|
||||
state = it->get_anchestor_state_of_current_state(state);
|
||||
|
||||
t_out--;
|
||||
}
|
||||
indicator_metric /= n_im;
|
||||
|
@ -355,6 +354,8 @@ Viterbi_Decoder::do_tb_and_decode(int traceback_length, int requested_decoding_l
|
|||
return decoding_length_mismatch;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* function Gamma()
|
||||
|
||||
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() */
|
||||
|
||||
int
|
||||
Viterbi_Decoder::nsc_enc_bit(int state_out_p[], int input, int state_in,
|
||||
int Viterbi_Decoder::nsc_enc_bit(int state_out_p[], int input, int state_in,
|
||||
const int g[], int KK, int nn)
|
||||
{
|
||||
/* 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() */
|
||||
|
||||
int
|
||||
Viterbi_Decoder::parity_counter(int symbol, int length)
|
||||
int Viterbi_Decoder::parity_counter(int symbol, int length)
|
||||
{
|
||||
int counter;
|
||||
int temp_parity = 0;
|
||||
|
||||
for (counter = 0; counter < length; counter++)
|
||||
{
|
||||
temp_parity = temp_parity ^ (symbol & 1);
|
||||
symbol = symbol >> 1;
|
||||
}
|
||||
|
||||
return (temp_parity);
|
||||
}
|
||||
|
||||
|
@ -486,27 +483,26 @@ Viterbi_Decoder::Prev::Prev(int states, int t)
|
|||
state = new int[states];
|
||||
bit = new int[states];
|
||||
metric = new float[states];
|
||||
|
||||
refcount = new int;
|
||||
*refcount = 1;
|
||||
|
||||
//std::cout << "Prev(" << states << ", " << t << ")" << " constructor" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// copy constructor
|
||||
Viterbi_Decoder::Prev::Prev(const Prev& prev)
|
||||
{
|
||||
refcount = prev.refcount;
|
||||
(*refcount)++;
|
||||
|
||||
t = prev.t;
|
||||
state = prev.state;
|
||||
bit = prev.bit;
|
||||
metric = prev.metric;
|
||||
|
||||
VLOG(LMORE) << "Prev(" << "?" << ", " << t << ")" << " copy, new refcount = " << *refcount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// assignment constructor
|
||||
Viterbi_Decoder::Prev& Viterbi_Decoder::Prev::operator=(const Prev& other)
|
||||
{
|
||||
|
@ -543,6 +539,9 @@ Viterbi_Decoder::Prev& Viterbi_Decoder::Prev::operator=(const Prev& other)
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Viterbi_Decoder::Prev::~Prev()
|
||||
{
|
||||
if (*refcount == 1)
|
||||
|
@ -560,12 +559,16 @@ Viterbi_Decoder::Prev::~Prev()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
return state[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;
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_VITERBIDECODER_H_
|
||||
#define GNSS_SDR_VITERBIDECODER_H_
|
||||
#ifndef GNSS_SDR_VITERBI_DECODER_H_
|
||||
#define GNSS_SDR_VITERBI_DECODER_H_
|
||||
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
|
@ -41,12 +41,22 @@ public:
|
|||
Viterbi_Decoder(const int g_encoder[], const int KK, const int nn);
|
||||
~Viterbi_Decoder();
|
||||
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_continuous(const double sym[], const int traceback_depth, int output_u_int[],
|
||||
const int nbits_requested, int &nbits_decoded);
|
||||
|
||||
private:
|
||||
|
||||
class Prev
|
||||
{
|
||||
public:
|
||||
|
@ -111,4 +121,4 @@ private:
|
|||
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
|
||||
* Satellite Systems receiver
|
||||
|
@ -38,12 +38,10 @@
|
|||
#include "gps_iono.h"
|
||||
#include "gps_utc_model.h"
|
||||
#include "gps_almanac.h"
|
||||
|
||||
#include "galileo_ephemeris.h"
|
||||
#include "galileo_iono.h"
|
||||
#include "galileo_utc_model.h"
|
||||
#include "galileo_almanac.h"
|
||||
|
||||
#include "concurrent_queue.h"
|
||||
#include "concurrent_map.h"
|
||||
#include <unistd.h>
|
||||
|
@ -218,12 +216,17 @@ bool ControlThread::read_assistance_from_XML()
|
|||
global_gps_ephemeris_queue.push(gps_eph_iter->second);
|
||||
}
|
||||
return false;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ERROR: SUPL client error reading XML" << std::endl;
|
||||
std::cout << "Disabling SUPL assistance.." << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ControlThread::init()
|
||||
{
|
||||
// Instantiates a control queue, a GNSS flowgraph, and a control message factory
|
||||
|
@ -234,7 +237,7 @@ void ControlThread::init()
|
|||
processed_control_messages_ = 0;
|
||||
applied_actions_ = 0;
|
||||
|
||||
//#########GNSS Asistence #################################
|
||||
//######### GNSS Assistance #################################
|
||||
// GNSS Assistance configuration
|
||||
bool enable_gps_supl_assistance = configuration_->property("GNSS-SDR.SUPL_gps_enabled", false);
|
||||
if (enable_gps_supl_assistance == true)
|
||||
|
@ -252,14 +255,21 @@ void ControlThread::init()
|
|||
|
||||
std::string default_lac = "0x59e2";
|
||||
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 &) {
|
||||
}
|
||||
catch(boost::bad_lexical_cast &)
|
||||
{
|
||||
supl_lac = 0x59e2;
|
||||
}
|
||||
try {
|
||||
|
||||
try
|
||||
{
|
||||
supl_ci = boost::lexical_cast<int>(configuration_->property("GNSS-SDR.SUPL_CI", default_ci));
|
||||
} catch(boost::bad_lexical_cast &) {
|
||||
}
|
||||
catch(boost::bad_lexical_cast &)
|
||||
{
|
||||
supl_ci = 0x31b0;
|
||||
}
|
||||
|
||||
|
@ -268,12 +278,13 @@ void ControlThread::init()
|
|||
{
|
||||
// read assistance from file
|
||||
read_assistance_from_XML();
|
||||
}else{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Request ephemeris from SUPL server
|
||||
int error;
|
||||
supl_client_ephemeris_.request = 1;
|
||||
std::cout<< "SUPL: Try read GPS ephemeris from SUPL server.."<<std::endl;
|
||||
std::cout << "SUPL: Try to read GPS ephemeris from SUPL server.." << std::endl;
|
||||
error = supl_client_ephemeris_.get_assistance(supl_mcc, supl_mns, supl_lac, supl_ci);
|
||||
if (error == 0)
|
||||
{
|
||||
|
@ -291,7 +302,9 @@ void ControlThread::init()
|
|||
{
|
||||
std::cout << "SUPL: XML Ephemeris file created" << std::endl;
|
||||
}
|
||||
}else{
|
||||
}
|
||||
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;
|
||||
|
@ -303,7 +316,7 @@ void ControlThread::init()
|
|||
|
||||
// Request almanac , IONO and UTC Model
|
||||
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);
|
||||
if (error == 0)
|
||||
{
|
||||
|
@ -325,7 +338,9 @@ void ControlThread::init()
|
|||
std::cout << "SUPL: Received GPS UTC Model" << std::endl;
|
||||
global_gps_utc_model_queue.push(supl_client_ephemeris_.gps_utc);
|
||||
}
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
@ -345,7 +360,9 @@ void ControlThread::init()
|
|||
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);
|
||||
}
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
@ -354,14 +371,16 @@ void ControlThread::init()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ControlThread::read_control_messages()
|
||||
{
|
||||
DLOG(INFO) << "Reading control messages from queue";
|
||||
boost::shared_ptr<gr::message> queue_message = control_queue_->delete_head();
|
||||
if (queue_message != 0)
|
||||
{
|
||||
control_messages_ = control_message_factory_->GetControlMessages(
|
||||
queue_message);
|
||||
control_messages_ = control_message_factory_->GetControlMessages(queue_message);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -383,8 +402,7 @@ void ControlThread::process_control_messages()
|
|||
}
|
||||
else
|
||||
{
|
||||
flowgraph_->apply_action(control_messages_->at(i)->who,
|
||||
control_messages_->at(i)->what);
|
||||
flowgraph_->apply_action(control_messages_->at(i)->who, control_messages_->at(i)->what);
|
||||
}
|
||||
delete control_messages_->at(i);
|
||||
processed_control_messages_++;
|
||||
|
@ -411,9 +429,12 @@ void ControlThread::apply_action(unsigned int what)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
@ -423,15 +444,19 @@ void ControlThread::gps_acq_assist_data_collector()
|
|||
|
||||
// DEBUG MESSAGE
|
||||
std::cout << "Acquisition assistance record has arrived from SAT ID "
|
||||
<< gps_acq.i_satellite_PRN << " with Doppler " << gps_acq.d_Doppler0<<" [Hz] "<<std::endl;
|
||||
<< gps_acq.i_satellite_PRN
|
||||
<< " with Doppler "
|
||||
<< gps_acq.d_Doppler0
|
||||
<< " [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);
|
||||
|
||||
}else{
|
||||
}
|
||||
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);
|
||||
|
@ -442,7 +467,6 @@ void ControlThread::gps_acq_assist_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;
|
||||
|
@ -463,19 +487,26 @@ void ControlThread::gps_ephemeris_data_collector()
|
|||
{
|
||||
std::cout << "Ephemeris record updated (GPS week=" << gps_eph.i_GPS_week << std::endl;
|
||||
global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN, gps_eph);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gps_eph.d_Toe > gps_eph_old.d_Toe)
|
||||
{
|
||||
std::cout << "Ephemeris record updated (Toe=" << gps_eph.d_Toe << std::endl;
|
||||
global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN, gps_eph);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Not updating the existing ephemeris" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert new ephemeris record
|
||||
std::cout << "New Ephemeris record inserted with Toe="<<gps_eph.d_Toe<<" and GPS Week="<<gps_eph.i_GPS_week<<std::endl;
|
||||
std::cout << "New Ephemeris record inserted with Toe="
|
||||
<< gps_eph.d_Toe<<" and GPS Week="
|
||||
<< gps_eph.i_GPS_week << std::endl;
|
||||
global_gps_ephemeris_map.write(gps_eph.i_satellite_PRN, gps_eph);
|
||||
}
|
||||
}
|
||||
|
@ -484,7 +515,6 @@ void ControlThread::gps_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;
|
||||
|
@ -502,24 +532,28 @@ void ControlThread::galileo_ephemeris_data_collector()
|
|||
// Check the EPHEMERIS timestamp. If it is newer, then update the ephemeris
|
||||
if (galileo_eph.WN_5 > galileo_eph_old.WN_5) //further check because it is not clear when IOD is reset
|
||||
{
|
||||
std::cout << "Galileo Ephemeris record in global map updated -- GALILEO Week Number ="<<galileo_eph.WN_5<<std::endl;
|
||||
std::cout << "Galileo Ephemeris record in global map updated -- GALILEO Week Number ="
|
||||
<< galileo_eph.WN_5 << std::endl;
|
||||
global_galileo_ephemeris_map.write(galileo_eph.SV_ID_PRN_4,galileo_eph);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (galileo_eph.IOD_ephemeris > galileo_eph_old.IOD_ephemeris)
|
||||
{
|
||||
std::cout << "Galileo Ephemeris record updated in global map-- IOD_ephemeris ="<<galileo_eph.IOD_ephemeris<<std::endl;
|
||||
std::cout << "Galileo Ephemeris record updated in global map-- IOD_ephemeris ="
|
||||
<< galileo_eph.IOD_ephemeris << std::endl;
|
||||
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 << "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;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert new ephemeris record
|
||||
std::cout << "Galileo New Ephemeris record inserted in global map with TOW =" << galileo_eph.TOW_5
|
||||
<< ", GALILEO Week Number =" << galileo_eph.WN_5
|
||||
|
@ -533,7 +567,6 @@ void ControlThread::galileo_ephemeris_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;
|
||||
|
@ -541,23 +574,25 @@ void ControlThread::gps_iono_data_collector()
|
|||
{
|
||||
global_gps_iono_queue.wait_and_pop(gps_iono);
|
||||
|
||||
|
||||
std::cout << "New IONO record has arrived " << std::endl;
|
||||
// insert new ephemeris record to the global ephemeris map
|
||||
if (global_gps_iono_map.read(0, gps_iono_old))
|
||||
{
|
||||
// TODO: Check the IONO timestamp. If it is newer, then update the iono
|
||||
global_gps_iono_map.write(0, gps_iono);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert new ephemeris record
|
||||
global_gps_iono_map.write(0 ,gps_iono);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ControlThread::galileo_iono_data_collector()
|
||||
{
|
||||
|
||||
Galileo_Iono galileo_iono;
|
||||
Galileo_Iono galileo_iono_old;
|
||||
while(stop_ == false)
|
||||
|
@ -575,21 +610,23 @@ void ControlThread::galileo_iono_data_collector()
|
|||
{
|
||||
std::cout << "IONO record updated in global map--new GALILEO UTC-IONO Week Number" << std::endl;
|
||||
global_galileo_iono_map.write(0, galileo_iono);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
global_galileo_iono_map.write(0, galileo_iono);
|
||||
//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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert new ephemeris record
|
||||
std::cout << "New IONO record inserted in global map" << std::endl;
|
||||
global_galileo_iono_map.write(0, galileo_iono);
|
||||
|
@ -600,7 +637,6 @@ void ControlThread::galileo_iono_data_collector()
|
|||
|
||||
void ControlThread::gps_utc_model_data_collector()
|
||||
{
|
||||
|
||||
// ############ 1.bis READ EPHEMERIS/UTC_MODE/IONO QUEUE ####################
|
||||
Gps_Utc_Model gps_utc;
|
||||
Gps_Utc_Model gps_utc_old;
|
||||
|
@ -613,13 +649,17 @@ void ControlThread::gps_utc_model_data_collector()
|
|||
{
|
||||
// TODO: Check the UTC MODEL timestamp. If it is newer, then update the UTC MODEL
|
||||
global_gps_utc_model_map.write(0, gps_utc);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert new ephemeris record
|
||||
global_gps_utc_model_map.write(0, gps_utc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ControlThread::galileo_utc_model_data_collector()
|
||||
{
|
||||
Galileo_Utc_Model galileo_utc;
|
||||
|
@ -639,21 +679,23 @@ void ControlThread::galileo_utc_model_data_collector()
|
|||
{
|
||||
//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);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (galileo_utc.t0t_6 > galileo_utc_old.t0t_6)
|
||||
{
|
||||
//std::cout << "UTC record updated --new GALILEO UTC time of Week ="<<galileo_utc.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;
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert new ephemeris record
|
||||
std::cout << "New UTC record inserted in global map" << std::endl;
|
||||
global_galileo_utc_model_map.write(0, galileo_utc);
|
||||
|
@ -661,6 +703,8 @@ void ControlThread::galileo_utc_model_data_collector()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ControlThread::gps_ephemeris_data_write_to_XML()
|
||||
{
|
||||
//Save ephemeris to XML file
|
||||
|
@ -685,6 +729,8 @@ void ControlThread::gps_ephemeris_data_write_to_XML()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ControlThread::gps_utc_model_data_write_to_XML()
|
||||
{
|
||||
//Save ephemeris to XML file
|
||||
|
@ -709,6 +755,9 @@ void ControlThread::gps_utc_model_data_write_to_XML()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ControlThread::gps_iono_data_write_to_XML()
|
||||
{
|
||||
//Save ephemeris to XML file
|
||||
|
|
|
@ -68,9 +68,13 @@ public:
|
|||
/*! \brief Runs the control thread
|
||||
*
|
||||
* This is the main loop that reads and process the control messages:
|
||||
*
|
||||
* - Connect the GNSS receiver flowgraph;
|
||||
*
|
||||
* - Start the GNSS receiver flowgraph;
|
||||
* while (flowgraph_->running() && !stop)_{
|
||||
*
|
||||
* while (flowgraph_->running() && !stop_){
|
||||
*
|
||||
* - Read control messages and process them; }
|
||||
*/
|
||||
void run();
|
||||
|
@ -78,7 +82,7 @@ public:
|
|||
/*!
|
||||
* \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);
|
||||
|
||||
|
@ -105,10 +109,7 @@ public:
|
|||
|
||||
|
||||
private:
|
||||
|
||||
/*!
|
||||
* \brief SUPL assistance classes
|
||||
*/
|
||||
//SUPL assistance classes
|
||||
gnss_sdr_supl_client supl_client_acquisition_;
|
||||
gnss_sdr_supl_client supl_client_ephemeris_;
|
||||
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).
|
||||
|
||||
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();
|
||||
|
||||
void read_control_messages();
|
||||
|
|
Loading…
Reference in New Issue