1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-10-31 15:23:04 +00:00

Towards a Galileo INAV Navigation decoder: First version of the Galileo_E1_Telemetry_Decoder block. In this version only the preamble detection and page part synchro is functional.

git-svn-id: https://svn.code.sf.net/p/gnss-sdr/code/trunk@389 64b25241-fba3-4117-9849-534c7e92360d
This commit is contained in:
Javier Arribas
2013-07-15 17:07:10 +00:00
parent 27b20b0a6d
commit b0a323095d
28 changed files with 2710 additions and 66 deletions

View File

@@ -16,7 +16,10 @@
# along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
#
set(TELEMETRY_DECODER_ADAPTER_SOURCES gps_l1_ca_telemetry_decoder.cc )
set(TELEMETRY_DECODER_ADAPTER_SOURCES
gps_l1_ca_telemetry_decoder.cc
galileo_e1b_telemetry_decoder.cc
)
include_directories(
$(CMAKE_CURRENT_SOURCE_DIR)

View File

@@ -0,0 +1,119 @@
/*!
* \file galileo_l1_ca_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
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "galileo_e1b_telemetry_decoder.h"
#include "configuration_interface.h"
#include "galileo_e1b_telemetry_decoder_cc.h"
#include <gnuradio/io_signature.h>
#include <glog/log_severity.h>
#include <glog/logging.h>
#include "galileo_ephemeris.h"
#include "galileo_almanac.h"
#include "galileo_iono.h"
#include "galileo_utc_model.h"
extern concurrent_queue<Galileo_Ephemeris> global_galileo_ephemeris_queue;
extern concurrent_queue<Galileo_Iono> global_galileo_iono_queue;
extern concurrent_queue<Galileo_Utc_Model> global_galileo_utc_model_queue;
extern concurrent_queue<Galileo_Almanac> global_galileo_almanac_queue;
using google::LogMessage;
GalileoE1BTelemetryDecoder::GalileoE1BTelemetryDecoder(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams,
boost::shared_ptr<gr::msg_queue> queue) :
role_(role),
in_streams_(in_streams),
out_streams_(out_streams),
queue_(queue)
{
std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./navigation.dat";
DLOG(INFO) << "role " << role;
DLOG(INFO) << "vector length " << vector_length_;
vector_length_ = configuration->property(role + ".vector_length", 2048);
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
int fs_in;
fs_in = configuration->property("GNSS-SDR.internal_fs_hz", 2048000);
// make telemetry decoder object
telemetry_decoder_ = galileo_e1b_make_telemetry_decoder_cc(satellite_, 0, (long)fs_in, vector_length_, queue_, dump_); // TODO fix me
DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")";
// set the navigation msg queue;
telemetry_decoder_->set_ephemeris_queue(&global_galileo_ephemeris_queue);
telemetry_decoder_->set_iono_queue(&global_galileo_iono_queue);
telemetry_decoder_->set_almanac_queue(&global_galileo_almanac_queue);
telemetry_decoder_->set_utc_model_queue(&global_galileo_utc_model_queue);
}
GalileoE1BTelemetryDecoder::~GalileoE1BTelemetryDecoder()
{}
void GalileoE1BTelemetryDecoder::set_satellite(Gnss_Satellite satellite)
{
satellite_ = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
telemetry_decoder_->set_satellite(satellite_);
DLOG(INFO) << "GALILEO TELEMETRY DECODER: satellite set to " << satellite_;
}
void GalileoE1BTelemetryDecoder::connect(gr::top_block_sptr top_block)
{
// Nothing to connect internally
DLOG(INFO) << "nothing to connect internally";
}
void GalileoE1BTelemetryDecoder::disconnect(gr::top_block_sptr top_block)
{
// Nothing to disconnect
}
gr::basic_block_sptr GalileoE1BTelemetryDecoder::get_left_block()
{
return telemetry_decoder_;
}
gr::basic_block_sptr GalileoE1BTelemetryDecoder::get_right_block()
{
return telemetry_decoder_;
}

View File

@@ -0,0 +1,95 @@
/*!
* \file galileo_l1_ca_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
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GALILEO_E1B_TELEMETRY_DECODER_H_
#define GNSS_SDR_GALILEO_E1B_TELEMETRY_DECODER_H_
#include "telemetry_decoder_interface.h"
#include "galileo_e1b_telemetry_decoder_cc.h"
#include <gnuradio/msg_queue.h>
class ConfigurationInterface;
/*!
* \brief This class implements a NAV data decoder for Galileo INAV frames in E1B radio link
*/
class GalileoE1BTelemetryDecoder : public TelemetryDecoderInterface
{
public:
GalileoE1BTelemetryDecoder(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams,
boost::shared_ptr<gr::msg_queue> queue);
virtual ~GalileoE1BTelemetryDecoder();
std::string role()
{
return role_;
}
std::string implementation()
{
return "Galileo_E1B_Telemetry_Decoder";
}
void connect(gr::top_block_sptr top_block);
void disconnect(gr::top_block_sptr top_block);
gr::basic_block_sptr get_left_block();
gr::basic_block_sptr get_right_block();
void set_satellite(Gnss_Satellite satellite);
void set_channel(int channel){telemetry_decoder_->set_channel(channel);}
void reset()
{
return;
}
size_t item_size()
{
return 0;
}
private:
galileo_e1b_telemetry_decoder_cc_sptr telemetry_decoder_;
Gnss_Satellite satellite_;
int channel_;
unsigned int vector_length_;
std::string item_type_;
bool dump_;
std::string dump_filename_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
boost::shared_ptr<gr::msg_queue> queue_;
};
#endif

View File

@@ -18,7 +18,7 @@
set(TELEMETRY_DECODER_GR_BLOCKS_SOURCES
gps_l1_ca_telemetry_decoder_cc.cc
# direct_resampler_conditioner_ss.cc
galileo_e1b_telemetry_decoder_cc.cc
)
include_directories(

View File

@@ -0,0 +1,333 @@
/*!
* \file galileo_e1b_telemetry_decoder_cc.cc
* \brief Implementation of a NAV message demodulator block
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
* \author Javier Arribas 2013. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "gnss_synchro.h"
#include "galileo_e1b_telemetry_decoder_cc.h"
#include <iostream>
#include <sstream>
#include <bitset>
#include <gnuradio/io_signature.h>
#include <glog/log_severity.h>
#include <glog/logging.h>
#include <boost/lexical_cast.hpp>
#include "control_message_factory.h"
#include "gnss_synchro.h"
using google::LogMessage;
galileo_e1b_telemetry_decoder_cc_sptr
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)
{
return galileo_e1b_telemetry_decoder_cc_sptr(new galileo_e1b_telemetry_decoder_cc(satellite, if_freq,
fs_in, vector_length, queue, dump));
}
void galileo_e1b_telemetry_decoder_cc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
{
for (unsigned i = 0; i < 3; i++)
{
ninput_items_required[i] = GALILEO_INAV_PAGE_SYMBOLS; //set the required sample history
}
}
galileo_e1b_telemetry_decoder_cc::galileo_e1b_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) :
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)))
{
// initialize internal vars
d_queue = queue;
d_dump = dump;
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
DLOG(INFO) << "GALILEO E1B TELEMETRY PROCESSING: satellite " << d_satellite;
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_fs_in = fs_in;
// set the 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;
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
d_preambles_symbols = (signed int*)malloc(sizeof(signed int) * d_symbols_per_preamble);
int n = 0;
for (int i=0; i<GALILEO_INAV_PREAMBLE_LENGTH_BITS; i++)
{
for (unsigned int j=0; j<d_samples_per_symbol; j++)
{
if (d_preambles_bits[i] == 1)
{
d_preambles_symbols[n] = 1;
}
else
{
d_preambles_symbols[n] = -1;
}
n++;
}
}
d_sample_counter = 0;
d_stat = 0;
d_preamble_index = 0;
d_preamble_time_seconds = 0;
d_flag_frame_sync = false;
d_flag_parity = false;
d_TOW_at_Preamble = 0;
d_TOW_at_current_symbol = 0;
flag_TOW_set = false;
// set up de-interleaver table
// std::vector<int> positions;
// for (int rows=0;rows<GALILEO_INAV_INTERLEAVER_ROWS;rows++)
// {
// for (int cols=0;cols<GALILEO_INAV_INTERLEAVER_COLS;cols++)
// {
// positions.push_back(rows*GALILEO_INAV_INTERLEAVER_ROWS+cols);
// }
// }
// d_interleaver= new gr::trellis::interleaver();
// set up trellis decoder
}
galileo_e1b_telemetry_decoder_cc::~galileo_e1b_telemetry_decoder_cc()
{
delete d_preambles_symbols;
d_dump_file.close();
}
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)
{
int corr_value = 0;
int preamble_diff = 0;
Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0];
d_sample_counter++; //count for the processed samples
// ########### Output the tracking data to navigation and PVT ##########
const Gnss_Synchro **in = (const Gnss_Synchro **) &input_items[0]; //Get the input samples pointer
// TODO Optimize me!
//******* preamble correlation ********
for (int i=0; i<d_symbols_per_preamble; i++)
{
if (in[0][i].Prompt_I < 0) // symbols clipping
{
corr_value -= d_preambles_symbols[i];
}
else
{
corr_value += d_preambles_symbols[i];
}
}
d_flag_preamble = false;
//******* frame sync ******************
if (abs(corr_value) >= d_symbols_per_preamble)
{
//std::cout << "Positive preamble correlation for Galileo SAT " << this->d_satellite << std::endl;
//TODO: Rewrite with state machine
if (d_stat == 0)
{
//d_GPS_FSM.Event_gps_word_preamble();
d_preamble_index = d_sample_counter;//record the preamble sample stamp
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) //check preamble separation
{
preamble_diff = abs(d_sample_counter - d_preamble_index);
//std::cout << "preamble_diff="<< preamble_diff <<" for Galileo SAT " << this->d_satellite << std::endl;
if (abs(preamble_diff - GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS) < 1)
{
// NEW Galileo page part is received
// 1. De-interleave
// 2. Viterbi decoder
// 3. Call the Galileo page decoder
//d_GPS_FSM.Event_gps_word_preamble();
d_flag_preamble = true;
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
if (!d_flag_frame_sync)
{
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
{
if (d_stat == 1)
{
preamble_diff = d_sample_counter - d_preamble_index;
if (preamble_diff > GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS)
{
std::cout << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff << std::endl;
d_stat = 0; //lost of frame sync
d_flag_frame_sync = false;
//flag_TOW_set=false;
}
}
}
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];
//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) //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_current_symbol = d_TOW_at_Preamble + GALILEO_INAV_PREAMBLE_LENGTH_BITS/Galileo_E1_B_SYMBOL_RATE_BPS;
Prn_timestamp_at_preamble_ms = in[0][0].Tracking_timestamp_secs * 1000.0;
///if (flag_TOW_set==false)
//{
// flag_TOW_set = true;
//}
}
else
{
//d_TOW_at_current_symbol = d_TOW_at_current_symbol + Galileo_E1_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);
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_at_preamble_ms = Prn_timestamp_at_preamble_ms;
if(d_dump == true)
{
// MULTIPLEXED FILE RECORDING - Record results to file
try
{
double tmp_double;
tmp_double = d_TOW_at_current_symbol;
d_dump_file.write((char*)&tmp_double, sizeof(double));
tmp_double = current_synchro_data.Prn_timestamp_ms;
d_dump_file.write((char*)&tmp_double, sizeof(double));
tmp_double = d_TOW_at_Preamble;
d_dump_file.write((char*)&tmp_double, sizeof(double));
}
catch (std::ifstream::failure e)
{
std::cout << "Exception writing observables dump file " << e.what() << std::endl;
}
}
//3. Make the output (copy the object contents to the GNURadio reserved memory)
*out[0] = current_synchro_data;
return 1;
}
void galileo_e1b_telemetry_decoder_cc::set_satellite(Gnss_Satellite satellite)
{
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite;
//d_GPS_FSM.i_satellite_PRN = d_satellite.get_PRN();
DLOG(INFO) << "Navigation Satellite set to " << d_satellite;
}
void galileo_e1b_telemetry_decoder_cc::set_channel(int channel)
{
d_channel = channel;
//d_GPS_FSM.i_channel_ID = channel;
DLOG(INFO) << "Navigation channel set to " << channel;
// ############# ENABLE DATA FILE LOG #################
if (d_dump == true)
{
if (d_dump_file.is_open() == false)
{
try
{
d_dump_filename = "telemetry";
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
d_dump_filename.append(".dat");
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
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;
}
}
}
}
void galileo_e1b_telemetry_decoder_cc::set_ephemeris_queue(concurrent_queue<Galileo_Ephemeris> *ephemeris_queue)
{
//d_Galileo_INAV_FSM.d_ephemeris_queue = ephemeris_queue;
}
void galileo_e1b_telemetry_decoder_cc::set_iono_queue(concurrent_queue<Galileo_Iono> *iono_queue)
{
//d_Galileo_INAV_FSM.d_iono_queue = iono_queue;
}
void galileo_e1b_telemetry_decoder_cc::set_almanac_queue(concurrent_queue<Galileo_Almanac> *almanac_queue)
{
//d_Galileo_INAV_FSM.d_almanac_queue = almanac_queue;
}
void galileo_e1b_telemetry_decoder_cc::set_utc_model_queue(concurrent_queue<Galileo_Utc_Model> *utc_model_queue)
{
//d_Galileo_INAV_FSM.d_utc_model_queue = utc_model_queue;
}

View File

@@ -0,0 +1,132 @@
/*!
* \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
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2011 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_galileo_e1b_TELEMETRY_DECODER_CC_H
#define GNSS_SDR_galileo_e1b_TELEMETRY_DECODER_CC_H
#include "Galileo_E1.h"
#include "concurrent_queue.h"
#include <fstream>
#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"
//#include <gnuradio/gr_sync_block.h>
#include "gnss_satellite.h"
//#include "galileo_inav_fsm.h"
#include "galileo_navigation_message.h"
#include "galileo_ephemeris.h"
#include "galileo_almanac.h"
#include "galileo_iono.h"
#include "galileo_utc_model.h"
class galileo_e1b_telemetry_decoder_cc;
typedef boost::shared_ptr<galileo_e1b_telemetry_decoder_cc> galileo_e1b_telemetry_decoder_cc_sptr;
galileo_e1b_telemetry_decoder_cc_sptr
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);
/*!
* \brief This class implements a block that decodes the INAV data defined in Galileo ICD
*
*/
class galileo_e1b_telemetry_decoder_cc : public gr::block
{
public:
~galileo_e1b_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<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);
void forecast (int noutput_items, gr_vector_int &ninput_items_required);
private:
friend galileo_e1b_telemetry_decoder_cc_sptr
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);
galileo_e1b_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);
unsigned short int d_preambles_bits[GALILEO_INAV_PREAMBLE_LENGTH_BITS];
signed int *d_preambles_symbols;
unsigned int d_samples_per_symbol;
int d_symbols_per_preamble;
long unsigned int d_sample_counter;
long unsigned int d_preamble_index;
unsigned int d_stat;
bool d_flag_frame_sync;
bool d_flag_parity;
bool d_flag_preamble;
long d_fs_in;
//gr::trellis::interleaver d_interleaver;
// navigation message vars
Galileo_Navigation_Message d_nav;
//GalileoINAVFsm d_Galileo_INAV_FSM;
boost::shared_ptr<gr::msg_queue> d_queue;
unsigned int d_vector_length;
bool d_dump;
Gnss_Satellite d_satellite;
int d_channel;
double d_preamble_time_seconds;
double d_TOW_at_Preamble;
double d_TOW_at_current_symbol;
double Prn_timestamp_at_preamble_ms;
bool flag_TOW_set;
std::string d_dump_filename;
std::ofstream d_dump_file;
};
#endif

View File

@@ -0,0 +1,298 @@
/*!
* \file gps_l1_ca_subframe_fsm.cc
* \brief Implementation of a GPS NAV message word-to-subframe decoder state machine
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "gps_l1_ca_subframe_fsm.h"
//************ GPS WORD TO SUBFRAME DECODER STATE MACHINE **********
struct Ev_gps_word_valid : sc::event<Ev_gps_word_valid> {};
struct Ev_gps_word_invalid : sc::event<Ev_gps_word_invalid>{};
struct Ev_gps_word_preamble : sc::event<Ev_gps_word_preamble>{};
struct gps_subframe_fsm_S0: public sc::state<gps_subframe_fsm_S0, GpsL1CaSubframeFsm>
{
public:
// sc::transition(event,next_status)
typedef sc::transition< Ev_gps_word_preamble, gps_subframe_fsm_S1 > reactions;
gps_subframe_fsm_S0(my_context ctx): my_base( ctx )
{
//std::cout<<"Enter S0 "<<std::endl;
}
};
struct gps_subframe_fsm_S1: public sc::state<gps_subframe_fsm_S1, GpsL1CaSubframeFsm>
{
public:
typedef mpl::list<sc::transition< Ev_gps_word_invalid, gps_subframe_fsm_S0 >,
sc::transition< Ev_gps_word_valid, gps_subframe_fsm_S2 > > reactions;
gps_subframe_fsm_S1(my_context ctx): my_base( ctx )
{
//std::cout<<"Enter S1 "<<std::endl;
}
};
struct gps_subframe_fsm_S2: public sc::state<gps_subframe_fsm_S2, GpsL1CaSubframeFsm>
{
public:
typedef mpl::list<sc::transition< Ev_gps_word_invalid, gps_subframe_fsm_S0 >,
sc::transition< Ev_gps_word_valid, gps_subframe_fsm_S3 > > reactions;
gps_subframe_fsm_S2(my_context ctx): my_base( ctx )
{
//std::cout<<"Enter S2 "<<std::endl;
context< GpsL1CaSubframeFsm >().gps_word_to_subframe(0);
}
};
struct gps_subframe_fsm_S3: public sc::state<gps_subframe_fsm_S3, GpsL1CaSubframeFsm>
{
public:
typedef mpl::list<sc::transition< Ev_gps_word_invalid, gps_subframe_fsm_S0 >,
sc::transition< Ev_gps_word_valid, gps_subframe_fsm_S4 > > reactions;
gps_subframe_fsm_S3(my_context ctx): my_base( ctx )
{
//std::cout<<"Enter S3 "<<std::endl;
context< GpsL1CaSubframeFsm >().gps_word_to_subframe(1);
}
};
struct gps_subframe_fsm_S4: public sc::state<gps_subframe_fsm_S4, GpsL1CaSubframeFsm>
{
public:
typedef mpl::list<sc::transition< Ev_gps_word_invalid, gps_subframe_fsm_S0 >,
sc::transition< Ev_gps_word_valid, gps_subframe_fsm_S5 > > reactions;
gps_subframe_fsm_S4(my_context ctx): my_base( ctx )
{
//std::cout<<"Enter S4 "<<std::endl;
context< GpsL1CaSubframeFsm >().gps_word_to_subframe(2);
}
};
struct gps_subframe_fsm_S5: public sc::state<gps_subframe_fsm_S5, GpsL1CaSubframeFsm>
{
public:
typedef mpl::list<sc::transition< Ev_gps_word_invalid, gps_subframe_fsm_S0 >,
sc::transition< Ev_gps_word_valid, gps_subframe_fsm_S6 > > reactions;
gps_subframe_fsm_S5(my_context ctx): my_base( ctx )
{
//std::cout<<"Enter S5 "<<std::endl;
context< GpsL1CaSubframeFsm >().gps_word_to_subframe(3);
}
};
struct gps_subframe_fsm_S6: public sc::state<gps_subframe_fsm_S6, GpsL1CaSubframeFsm>
{
public:
typedef mpl::list<sc::transition< Ev_gps_word_invalid, gps_subframe_fsm_S0 >,
sc::transition< Ev_gps_word_valid, gps_subframe_fsm_S7 > > reactions;
gps_subframe_fsm_S6(my_context ctx): my_base( ctx )
{
//std::cout<<"Enter S6 "<<std::endl;
context< GpsL1CaSubframeFsm >().gps_word_to_subframe(4);
}
};
struct gps_subframe_fsm_S7: public sc::state<gps_subframe_fsm_S7, GpsL1CaSubframeFsm>
{
public:
typedef mpl::list<sc::transition< Ev_gps_word_invalid, gps_subframe_fsm_S0 >,
sc::transition< Ev_gps_word_valid, gps_subframe_fsm_S8 > > reactions;
gps_subframe_fsm_S7(my_context ctx): my_base( ctx )
{
//std::cout<<"Enter S7 "<<std::endl;
context< GpsL1CaSubframeFsm >().gps_word_to_subframe(5);
}
};
struct gps_subframe_fsm_S8: public sc::state<gps_subframe_fsm_S8, GpsL1CaSubframeFsm>
{
public:
typedef mpl::list<sc::transition< Ev_gps_word_invalid, gps_subframe_fsm_S0 >,
sc::transition< Ev_gps_word_valid, gps_subframe_fsm_S9 > > reactions;
gps_subframe_fsm_S8(my_context ctx): my_base( ctx )
{
//std::cout<<"Enter S8 "<<std::endl;
context< GpsL1CaSubframeFsm >().gps_word_to_subframe(6);
}
};
struct gps_subframe_fsm_S9: public sc::state<gps_subframe_fsm_S9, GpsL1CaSubframeFsm>
{
public:
typedef mpl::list<sc::transition< Ev_gps_word_invalid, gps_subframe_fsm_S0 >,
sc::transition< Ev_gps_word_valid, gps_subframe_fsm_S10 > > reactions;
gps_subframe_fsm_S9(my_context ctx): my_base( ctx )
{
//std::cout<<"Enter S9 "<<std::endl;
context< GpsL1CaSubframeFsm >().gps_word_to_subframe(7);
}
};
struct gps_subframe_fsm_S10: public sc::state<gps_subframe_fsm_S10, GpsL1CaSubframeFsm>
{
public:
typedef mpl::list<sc::transition< Ev_gps_word_invalid, gps_subframe_fsm_S0 >,
sc::transition< Ev_gps_word_valid, gps_subframe_fsm_S11 > > reactions;
gps_subframe_fsm_S10(my_context ctx): my_base( ctx )
{
//std::cout<<"Enter S10 "<<std::endl;
context< GpsL1CaSubframeFsm >().gps_word_to_subframe(8);
}
};
struct gps_subframe_fsm_S11: public sc::state<gps_subframe_fsm_S11, GpsL1CaSubframeFsm>
{
public:
typedef sc::transition< Ev_gps_word_preamble, gps_subframe_fsm_S1 > reactions;
gps_subframe_fsm_S11(my_context ctx): my_base( ctx )
{
//std::cout<<"Completed GPS Subframe!"<<std::endl;
context< GpsL1CaSubframeFsm >().gps_word_to_subframe(9);
context< GpsL1CaSubframeFsm >().gps_subframe_to_nav_msg(); //decode the subframe
// DECODE SUBFRAME
//std::cout<<"Enter S11"<<std::endl;
}
};
GpsL1CaSubframeFsm::GpsL1CaSubframeFsm()
{
d_nav.reset();
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;
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;
switch (subframe_ID)
{
case 3: //we have a new set of ephemeris data for the current SV
if (d_nav.satellite_validation()==true)
{
// get ephemeris object for this SV (mandatory)
Gps_Ephemeris ephemeris=d_nav.get_ephemeris();
d_ephemeris_queue->push(ephemeris);
}
break;
case 4: // Possible IONOSPHERE and UTC model update (page 18)
if (d_nav.flag_iono_valid==true)
{
Gps_Iono iono=d_nav.get_iono(); //notice that the read operation will clear the valid flag
d_iono_queue->push(iono);
}
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
d_utc_model_queue->push(utc_model);
}
break;
case 5:
// get almanac (if available)
//TODO: implement almanac reader in navigation_message
break;
default:
break;
}
}
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());
}
void GpsL1CaSubframeFsm::Event_gps_word_preamble()
{
this->process_event(Ev_gps_word_preamble());
}

View File

@@ -0,0 +1,112 @@
/*!
* \file gps_l1_ca_subframe_fsm.h
* \brief Interface of a Galileo NAV message word-to-subframe decoder state machine
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2012 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GALILEO_INAV_FSM_H_
#define GNSS_SDR_GALILEO_INAV_FSM_H_
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/state.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/custom_reaction.hpp>
#include <boost/mpl/list.hpp>
#include <queue>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include "concurrent_queue.h"
#include <iostream>
#include <cstring>
#include "galileo_navigation_message.h"
#include "galileo_ephemeris.h"
#include "galileo_almanac.h"
#include "galileo_iono.h"
#include "galileo_utc_model.h"
namespace sc = boost::statechart;
namespace mpl = boost::mpl;
struct gps_subframe_fsm_S0;
struct gps_subframe_fsm_S1;
struct gps_subframe_fsm_S2;
struct gps_subframe_fsm_S3;
struct gps_subframe_fsm_S4;
struct gps_subframe_fsm_S5;
struct gps_subframe_fsm_S6;
struct gps_subframe_fsm_S7;
struct gps_subframe_fsm_S8;
struct gps_subframe_fsm_S9;
struct gps_subframe_fsm_S10;
struct gps_subframe_fsm_S11;
class GalileoINAVFsm : public sc::state_machine< GalileoINAVFsm, gps_subframe_fsm_S0 >
{
public:
// channel and satellite info
int i_channel_ID;
unsigned int i_satellite_PRN;
// ephemeris queue
concurrent_queue<Galileo_Ephemeris> *d_ephemeris_queue;
// ionospheric parameters queue
concurrent_queue<Galileo_Iono> *d_iono_queue;
// UTC model parameters queue
concurrent_queue<Galileo_Utc_Model> *d_utc_model_queue;
// Almanac queue
concurrent_queue<Galileo_Almanac> *d_almanac_queue;
// navigation message class
Gps_Navigation_Message d_nav;
// GPS SV and System parameters
Galileo_Ephemeris ephemeris;
Galileo_Almanac almanac;
Galileo_Utc_Model utc_model;
Galileo_Iono iono;
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_subframe_to_nav_msg();
//FSM EVENTS
void Event_gps_word_valid();
void Event_gps_word_invalid();
void Event_gps_word_preamble();
GalileoINAVFsm();
};
#endif