1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-09-27 14:48:24 +00:00

Adding code for telemetry decoder algorithms

This commit is contained in:
Damian Miralles 2017-07-09 23:00:49 -07:00 committed by Damian Miralles
parent 6c8a29d3d4
commit b34a82a949
7 changed files with 952 additions and 234 deletions

View File

@ -0,0 +1,102 @@
/*!
* \file glonass_l1_ca_telemetry_decoder.cc
* \brief Implementation of an adapter of a GLONASS L1 C/A NAV data decoder block
* to a TelemetryDecoderInterface
* \author Damian Miralles, 2017. dmiralles2009(at)gmail.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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 "glonass_l1_ca_telemetry_decoder.h"
#include <gnuradio/io_signature.h>
#include <glog/logging.h>
#include "concurrent_queue.h"
#include "glonass_gnav_ephemeris.h"
#include "glonass_gnav_almanac.h"
#include "glonass_gnav_iono.h"
#include "glonass_gnav_utc_model.h"
#include "configuration_interface.h"
using google::LogMessage;
GlonassL1CaTelemetryDecoder::GlonassL1CaTelemetryDecoder(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams) :
role_(role),
in_streams_(in_streams),
out_streams_(out_streams)
{
std::string default_dump_filename = "./navigation.dat";
DLOG(INFO) << "role " << role;
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
// make telemetry decoder object
telemetry_decoder_ = glonass_l1_ca_make_telemetry_decoder_cc(satellite_, dump_); // TODO fix me
DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")";
DLOG(INFO) << "global navigation message queue assigned to telemetry_decoder ("<< telemetry_decoder_->unique_id() << ")";
channel_ = 0;
}
GlonassL1CaTelemetryDecoder::~GlonassL1CaTelemetryDecoder()
{}
void GlonassL1CaTelemetryDecoder::set_satellite(Gnss_Satellite satellite)
{
satellite_ = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
telemetry_decoder_->set_satellite(satellite_);
DLOG(INFO) << "TELEMETRY DECODER: satellite set to " << satellite_;
}
void GlonassL1CaTelemetryDecoder::connect(gr::top_block_sptr top_block)
{
if(top_block) { /* top_block is not null */};
// Nothing to connect internally
DLOG(INFO) << "nothing to connect internally";
}
void GlonassL1CaTelemetryDecoder::disconnect(gr::top_block_sptr top_block)
{
if(top_block) { /* top_block is not null */};
// Nothing to disconnect
}
gr::basic_block_sptr GlonassL1CaTelemetryDecoder::get_left_block()
{
return telemetry_decoder_;
}
gr::basic_block_sptr GlonassL1CaTelemetryDecoder::get_right_block()
{
return telemetry_decoder_;
}

View File

@ -0,0 +1,91 @@
/*!
* \file glonass_l1_ca_telemetry_decoder.h
* \brief Interface of an adapter of a GLONASS L1 C/A NAV data decoder block
* to a TelemetryDecoderInterface
* \author Damian Miralles, 2017. dmiralles2009(at)gmail.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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_GLONASS_L1_CA_TELEMETRY_DECODER_H_
#define GNSS_SDR_GLONASS_L1_CA_TELEMETRY_DECODER_H_
#include <string>
#include "telemetry_decoder_interface.h"
#include "glonass_l1_ca_telemetry_decoder_cc.h"
class ConfigurationInterface;
/*!
* \brief This class implements a NAV data decoder for GLONASS L1 C/A
*/
class GlonassL1CaTelemetryDecoder : public TelemetryDecoderInterface
{
public:
GlonassL1CaTelemetryDecoder(ConfigurationInterface* configuration,
std::string role,
unsigned int in_streams,
unsigned int out_streams);
virtual ~GlonassL1CaTelemetryDecoder();
std::string role()
{
return role_;
}
//! Returns "GLONASS_L1_CA_Telemetry_Decoder"
std::string implementation()
{
return "GLONASS_L1_CA_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:
glonass_l1_ca_telemetry_decoder_cc_sptr telemetry_decoder_;
Gnss_Satellite satellite_;
int channel_;
bool dump_;
std::string dump_filename_;
std::string role_;
unsigned int in_streams_;
unsigned int out_streams_;
};
#endif

View File

@ -0,0 +1,441 @@
/*!
* \file galileo_e1b_telemetry_decoder_cc.cc
* \brief Implementation of a Galileo INAV message demodulator block
* \author Mara Branzanti 2013. mara.branzanti(at)gmail.com
* \author Javier Arribas 2013. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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_cc.h"
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <gnuradio/io_signature.h>
#include <glog/logging.h>
#include "control_message_factory.h"
#include "gnss_synchro.h"
#include "convolutional.h"
#define CRC_ERROR_LIMIT 6
using google::LogMessage;
glonass_l1_ca_telemetry_decoder_cc_sptr
glonass_l1_ca_make_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump)
{
return glonass_l1_ca_telemetry_decoder_cc_sptr(new glonass_l1_ca_telemetry_decoder_cc(satellite, dump));
}
glonass_l1_ca_telemetry_decoder_cc::glonass_l1_ca_telemetry_decoder_cc(
Gnss_Satellite satellite,
bool dump) :
gr::block("glonass_l1_ca_telemetry_decoder_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{
// Telemetry Bit transition synchronization port out
this->message_port_register_out(pmt::mp("preamble_timestamp_s"));
// Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry"));
// initialize internal vars
d_dump = dump;
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
LOG(INFO) << "Initializing GLONASS L1CA TELEMETRY PROCESSING";
// TODO. WHAT IS THIS?
d_samples_per_symbol = ( GLONASS_L1_CODE_CHIP_RATE_HZ / GLONASS_L1_CA_CODE_LENGTH_CHIPS ) / GLONASS_L1_CA_SYMBOL_RATE_BPS;
// set the preamble
unsigned short int preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS] = GLONASS_GNAV_PREAMBLE;
d_symbols_per_preamble = GLONASS_GNAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol;
memcpy((unsigned short int*)this->d_preambles_bits, (unsigned short int*)preambles_bits, GLONASS_GNAV_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 < GLONASS_GNAV_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_flag_frame_sync = false;
d_flag_parity = false;
d_TOW_at_current_symbol = 0;
delta_t = 0;
d_CRC_error_counter = 0;
flag_even_word_arrived = 0;
d_flag_preamble = false;
d_channel = 0;
flag_TOW_set = false;
}
glonass_l1_ca_telemetry_decoder_cc::~glonass_l1_ca_telemetry_decoder_cc()
{
delete d_preambles_symbols;
d_dump_file.close();
}
void glonass_l1_ca_telemetry_decoder_cc::decode_string(double *page_part_symbols,int frame_length)
{
double page_part_symbols_deint[frame_length];
// 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<38>
for (int i = 0; i < frame_length; i++)
{
if ((i + 1) % 2 == 0)
{
page_part_symbols_deint[i] = -page_part_symbols_deint[i];
}
}
int page_part_bits[frame_length/2];
viterbi_decoder(page_part_symbols_deint, page_part_bits);
// 3. Call the Galileo page decoder
std::string page_String;
for(int i = 0; i < (frame_length/2); i++)
{
if (page_part_bits[i] > 0)
{
page_String.push_back('1');
}
else
{
page_String.push_back('0');
}
}
d_nav.decode_string(page_String);
if(d_nav.flag_CRC_test == true)
{
LOG(INFO) << "GLONASS GNAV CRC correct on channel " << d_channel << " from satellite " << d_satellite;
std::cout << "GLONASS GNAV CRC correct on channel " << d_channel << " from satellite " << d_satellite << std::endl;
}
else
{
std::cout << "GLONASS GNAV CRC error on channel " << d_channel << " from satellite " << d_satellite << std::endl;
LOG(INFO) << "GLONASS GNAV CRC error on channel " << d_channel << " from satellite " << d_satellite;
}
// 4. Push the new navigation data to the queues
if (d_nav.have_new_ephemeris() == true)
{
// get object for this SV (mandatory)
std::shared_ptr<Glonass_Gnav_Ephemeris> tmp_obj = std::make_shared<Glonass_Gnav_Ephemeris>(d_nav.get_ephemeris());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
}
if (d_nav.have_new_utc_model() == true)
{
// get object for this SV (mandatory)
std::shared_ptr<Glonass_Gnav_Utc_Model> tmp_obj = std::make_shared<Glonass_Gnav_Utc_Model>(d_nav.get_utc_model());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
}
if (d_nav.have_new_almanac() == true)
{
std::shared_ptr<Glonass_Gnav_Almanac> tmp_obj= std::make_shared<Glonass_Gnav_Almanac>(d_nav.get_almanac());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
//debug
std::cout << "GLONASS GNAV almanac received!" << std::endl;
DLOG(INFO) << "Current parameters:";
DLOG(INFO) << "d_TOW_at_current_symbol=" << d_TOW_at_current_symbol;
DLOG(INFO) << "d_nav.WN_0=" << d_nav.WN_0;
delta_t = tmp_obj->A_0G_10 + tmp_obj->A_1G_10 * (d_TOW_at_current_symbol - tmp_obj->t_0G_10 + 604800 * (fmod((d_nav.WN_0 - tmp_obj->WN_0G_10), 64)));
DLOG(INFO) << "delta_t=" << delta_t << "[s]";
}
}
int glonass_l1_ca_telemetry_decoder_cc::general_work (int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{
int corr_value = 0;
int preamble_diff = 0;
Gnss_Synchro **out = (Gnss_Synchro **) &output_items[0];
const Gnss_Synchro **in = (const Gnss_Synchro **) &input_items[0]; //Get the input samples pointer
Gnss_Synchro current_symbol; //structure to save the synchronization information and send the output object to the next block
//1. Copy the current tracking output
current_symbol = in[0][0];
d_symbol_history.push_back(current_symbol); //add new symbol to the symbol queue
d_sample_counter++; //count for the processed samples
consume_each(1);
d_flag_preamble = false;
unsigned int required_symbols=GLONASS_GNAV_PAGE_SYMBOLS+d_symbols_per_preamble;
if (d_symbol_history.size()>required_symbols)
{
//******* preamble correlation ********
for (int i = 0; i < d_symbols_per_preamble; i++)
{
if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping
{
corr_value -= d_preambles_symbols[i];
}
else
{
corr_value += d_preambles_symbols[i];
}
}
}
//******* frame sync ******************
if (d_stat == 0) //no preamble information
{
if (abs(corr_value) >= d_symbols_per_preamble)
{
d_preamble_index = d_sample_counter;//record the preamble sample stamp
LOG(INFO) << "Preamble detection for GLONASS L1 C/A SAT " << this->d_satellite;
d_stat = 1; // enter into frame pre-detection status
}
}
else if (d_stat == 1) // posible preamble lock
{
if (abs(corr_value) >= d_symbols_per_preamble)
{
//check preamble separation
preamble_diff = d_sample_counter - d_preamble_index;
if (abs(preamble_diff - GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS) == 0)
{
//try to decode frame
LOG(INFO) << "Starting page decoder for GLONASS L1 C/A SAT " << this->d_satellite;
d_preamble_index = d_sample_counter; //record the preamble sample stamp
d_stat = 2;
}
else
{
if (preamble_diff > GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS)
{
d_stat = 0; // start again
}
}
}
}
else if (d_stat == 2)
{
if (d_sample_counter == d_preamble_index + GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS)
{
// NEW GLONASS string received
// 0. fetch the symbols into an array
int frame_length = GLONASS_GNAV_STRING_SYMBOLS - d_symbols_per_preamble;
double page_part_symbols[frame_length];
//******* SYMBOL TO BIT *******
if (d_symbol_history.at(0).Flag_valid_symbol_output == true)
{
// extended correlation to bit period is enabled in tracking!
d_symbol_accumulator += d_symbol_history.at(0).Prompt_I; // accumulate the input value in d_symbol_accumulator
d_symbol_accumulator_counter += d_symbol_history.at(0).correlation_length_ms;
}
if (d_symbol_accumulator_counter >= 20)
{
}
for (int i = 0; i < frame_length; i++)
{
if (corr_value > 0)
{
page_part_symbols[i] = d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now!
}
else
{
page_part_symbols[i] = -d_symbol_history.at(i + d_symbols_per_preamble).Prompt_I; // because last symbol of the preamble is just received now!
}
}
//call the decoder
decode_string(page_part_symbols);
if (d_nav.flag_CRC_test == true)
{
d_CRC_error_counter = 0;
d_flag_preamble = true; //valid preamble indicator (initialized to false every work())
d_preamble_index = d_sample_counter; //record the preamble sample stamp (t_P)
if (!d_flag_frame_sync)
{
d_flag_frame_sync = true;
DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at "
<< d_symbol_history.at(0).Tracking_sample_counter << " [samples]";
}
}
else
{
d_CRC_error_counter++;
d_preamble_index = d_sample_counter; //record the preamble sample stamp
if (d_CRC_error_counter > CRC_ERROR_LIMIT)
{
LOG(INFO) << "Lost of frame sync SAT " << this->d_satellite;
d_flag_frame_sync = false;
d_stat = 0;
}
}
}
}
// UPDATE GNSS SYNCHRO DATA
//2. Add the telemetry decoder information
if (this->d_flag_preamble == true and d_nav.flag_TOW_set == true)
//update TOW at the preamble instant
{
if(d_nav.flag_TOW_5 == true) //page 5 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec)
{
//TOW_5 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay
d_TOW_at_current_symbol = d_nav.TOW_5 + GALILEO_INAV_PAGE_PART_SECONDS+((double)required_symbols)*GALILEO_E1_CODE_PERIOD; //-GALILEO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND;
d_nav.flag_TOW_5 = false;
}
else if(d_nav.flag_TOW_6 == true) //page 6 arrived and decoded, so we are in the odd page (since Tow refers to the even page, we have to add 1 sec)
{
//TOW_6 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay
d_TOW_at_current_symbol = d_nav.TOW_6 + GALILEO_INAV_PAGE_PART_SECONDS+((double)required_symbols)*GALILEO_E1_CODE_PERIOD;//-GALILEO_E1_CODE_PERIOD;//+ (double)GALILEO_INAV_PREAMBLE_LENGTH_BITS/(double)GALILEO_TELEMETRY_RATE_BITS_SECOND;
d_nav.flag_TOW_6 = false;
}
else
{
//this page has no timing information
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E1_CODE_PERIOD;// + GALILEO_INAV_PAGE_PART_SYMBOLS*GALILEO_E1_CODE_PERIOD;
}
}
else //if there is not a new preamble, we define the TOW of the current symbol
{
d_TOW_at_current_symbol = d_TOW_at_current_symbol + GALILEO_E1_CODE_PERIOD;
}
//if (d_flag_frame_sync == true and d_nav.flag_TOW_set==true and d_nav.flag_CRC_test == true)
if(d_nav.flag_GGTO_1 == true and d_nav.flag_GGTO_2 == true and d_nav.flag_GGTO_3 == true and d_nav.flag_GGTO_4 == true) //all GGTO parameters arrived
{
delta_t = d_nav.A_0G_10 + d_nav.A_1G_10 * (d_TOW_at_current_symbol - d_nav.t_0G_10 + 604800.0 * (fmod((d_nav.WN_0 - d_nav.WN_0G_10), 64)));
}
if (d_flag_frame_sync == true and d_nav.flag_TOW_set == true)
{
current_symbol.Flag_valid_word = true;
}
else
{
current_symbol.Flag_valid_word = false;
}
current_symbol.TOW_at_current_symbol_s = floor(d_TOW_at_current_symbol*1000.0)/1000.0;
current_symbol.TOW_at_current_symbol_s -=delta_t; //Galileo to GPS TOW
if(d_dump == true)
{
// MULTIPLEXED FILE RECORDING - Record results to file
try
{
double tmp_double;
unsigned long int tmp_ulong_int;
tmp_double = d_TOW_at_current_symbol;
d_dump_file.write((char*)&tmp_double, sizeof(double));
tmp_ulong_int = current_symbol.Tracking_sample_counter;
d_dump_file.write((char*)&tmp_ulong_int, sizeof(unsigned long int));
tmp_double = 0;
d_dump_file.write((char*)&tmp_double, sizeof(double));
}
catch (const std::ifstream::failure & e)
{
LOG(WARNING) << "Exception writing observables dump file " << e.what();
}
}
// remove used symbols from history
if (d_symbol_history.size()>required_symbols)
{
d_symbol_history.pop_front();
}
//3. Make the output (copy the object contents to the GNURadio reserved memory)
*out[0] = current_symbol;
return 1;
}
void glonass_l1_ca_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;
DLOG(INFO) << "Navigation Satellite set to " << d_satellite;
}
void glonass_l1_ca_telemetry_decoder_cc::set_channel(int channel)
{
d_channel = channel;
LOG(INFO) << "Navigation channel set to " << channel;
// ############# ENABLE DATA FILE LOG #################
if (d_dump == true)
{
if (d_dump_file.is_open() == false)
{
try
{
d_dump_filename = "telemetry";
d_dump_filename.append(boost::lexical_cast<std::string>(d_channel));
d_dump_filename.append(".dat");
d_dump_file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
d_dump_file.open(d_dump_filename.c_str(), std::ios::out | std::ios::binary);
LOG(INFO) << "Telemetry decoder dump enabled on channel " << d_channel << " Log file: " << d_dump_filename.c_str();
}
catch (const std::ifstream::failure& e)
{
LOG(WARNING) << "channel " << d_channel << " Exception opening trk dump file " << e.what();
}
}
}
}

View File

@ -0,0 +1,114 @@
/*!
* \file glonass_l1_ca_telemetry_decoder_cc.h
* \brief Interface of a GLONASS GNAV message demodulator block
* \author Damian Miralles, 2017. dmiralles2009(at)gmail.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2015 (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_GLONASS_L1_CA_TELEMETRY_DECODER_CC_H
#define GNSS_SDR_GLONASS_L1_CA_TELEMETRY_DECODER_CC_H
#include <fstream>
#include <string>
#include <gnuradio/block.h>
#include "GLONASS_L1_CA.h"
#include "concurrent_queue.h"
#include "gnss_satellite.h"
#include "glonass_gnav_navigation_message.h"
#include "glonass_gnav_ephemeris.h"
#include "glonass_gnav_almanac.h"
#include "glonass_gnav_iono.h"
#include "glonass_gnav_utc_model.h"
#include "gnss_synchro.h"
class glonass_l1_ca_telemetry_decoder_cc;
typedef boost::shared_ptr<glonass_l1_ca_telemetry_decoder_cc> glonass_l1_ca_telemetry_decoder_cc_sptr;
glonass_l1_ca_telemetry_decoder_cc_sptr glonass_l1_ca_make_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump);
/*!
* \brief This class implements a block that decodes the GNAV data defined in GLONASS ICD
*
*/
class glonass_l1_ca_telemetry_decoder_cc : public gr::block
{
public:
~glonass_l1_ca_telemetry_decoder_cc();
void set_satellite(Gnss_Satellite satellite); //!< Set satellite PRN
void set_channel(int channel); //!< Set receiver's channel
/*!
* \brief This is where all signal processing takes place
*/
int general_work (int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
private:
friend glonass_l1_ca_telemetry_decoder_cc_sptr
glonass_l1_ca_make_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump);
glonass_l1_ca_telemetry_decoder_cc(Gnss_Satellite satellite, bool dump);
void decode_word(double *symbols,int frame_length);
//!< Preamble decoding
unsigned short int d_preambles_bits[GLONASS_GNAV_PREAMBLE_LENGTH_BITS];
int *d_preambles_symbols;
unsigned int d_samples_per_symbol;
int d_symbols_per_preamble;
//!< Storage for incoming data
std::deque<Gnss_Synchro> d_symbol_history;
//!< Variables for internal functionality
long unsigned int d_sample_counter; //!< Sample counter as an index (1,2,3,..etc) indicating number of samples processed
long unsigned int d_preamble_index; //!< Index of sample number where preamble was found
unsigned int d_stat; //!< Status of decoder
bool d_flag_frame_sync; //!< Indicate when a frame sync is achieved
bool d_flag_parity; //!< Flag indicating when parity check was achieved (crc check)
bool d_flag_preamble;
int d_CRC_error_counter;
bool flag_TOW_set; //!<
double delta_t; //!< GPS-GLONASS time offset
//!< Navigation Message variable
Glonass_Gnav_Navigation_Message d_nav;
//!< Values to populate gnss synchronization structure
double d_TOW_at_current_symbol;
bool Flag_valid_word;
//!< Satellite Information and logging capacity
Gnss_Satellite d_satellite;
int d_channel;
bool d_dump;
std::string d_dump_filename;
std::ofstream d_dump_file;
};
#endif

View File

@ -84,6 +84,7 @@ const double GLONASS_L1_CA_CODE_RATE_HZ = 0.511e6; //!< GLONASS L1 C/
const double GLONASS_L1_CA_CODE_LENGTH_CHIPS = 511.0; //!< GLONASS L1 C/A code length [chips]
const double GLONASS_L1_CA_CODE_PERIOD = 0.001; //!< GLONASS L1 C/A code period [seconds]
const double GLONASS_L1_CA_CHIP_PERIOD = 1.9569e-06; //!< GLONASS L1 C/A chip period [seconds]
const double GLONASS_L1_CA_SYMBOL_RATE_BPS = 1000;
const double GLONASS_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (this cannot go here)
@ -91,7 +92,6 @@ const double GLONASS_STARTOFFSET_ms = 68.802; //[ms] Initial sign. travel time (
const int GLONASS_L1_CA_HISTORY_DEEP = 100;
// NAVIGATION MESSAGE DEMODULATION AND DECODING
#define GLONASS_CA_PREAMBLE {1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0}
const int GLONASS_CA_PREAMBLE_LENGTH_BITS = 30;
const int GLONASS_CA_PREAMBLE_LENGTH_SYMBOLS = 300;
@ -99,9 +99,7 @@ const double GLONASS_CA_PREAMBLE_DURATION_S = 0.3;
const int GLONASS_CA_TELEMETRY_RATE_BITS_SECOND = 50; //!< NAV message bit rate [bits/s]
const int GLONASS_CA_TELEMETRY_SYMBOLS_PER_BIT = 10;
const int GLONASS_CA_TELEMETRY_RATE_SYMBOLS_SECOND = GLONASS_CA_TELEMETRY_RATE_BITS_SECOND*GLONASS_CA_TELEMETRY_SYMBOLS_PER_BIT; //!< NAV message bit rate [symbols/s]
const int GLONASS_GNAV_WORD_LENGTH = 4; //!< \TODO cHECK this, size is not integer bte size
const int GLONASS_GNAV_FRAME_LENGTH = 40; //!< \TODO GPS_WORD_LENGTH x 10 = 40 bytes
const int GLONASS_GNAV_PREAMBLE_PERIOD_SYMBOLS = 1700;
const int GLONASS_GNAV_FRAME_BITS = 1725; //!< Number of chips per frame in the GNAV message 15 strings*(85 data bits + 30 time mark bits)[bits]
const int GLONASS_GNAV_FRAME_SECONDS = 30; //!< Subframe duration [seconds]
const int GLONASS_GNAV_FRAME_MS = 30000; //!< Subframe duration [seconds]

View File

@ -37,98 +37,55 @@ m * \file glonass_gnav_navigation_message.cc
void Glonass_Gnav_Navigation_Message::reset()
{
b_valid_ephemeris_set_flag = false;
double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s]
d_TOW_SF1 = 0; //!< Time of GPS Week from HOW word of Subframe 1 [s]
d_TOW_SF2 = 0; //!< Time of GPS Week from HOW word of Subframe 2 [s]
d_TOW_SF3 = 0; //!< Time of GPS Week from HOW word of Subframe 3 [s]
d_TOW_SF4 = 0; //!< Time of GPS Week from HOW word of Subframe 4 [s]
d_TOW_SF5 = 0; //!< Time of GPS Week from HOW word of Subframe 5 [s]
//!< Satellite Identification
i_channel_ID = 0; //!< Channel ID assigned by the receiver
i_satellite_freq_channel = 0; //!< SV Frequency Slot Number
i_satellite_slot_number = 0; //!< SV Orbit Slot Number
d_m = 0.0; //!< String number within frame [dimensionless]
d_t_k = 0.0; //!< Time referenced to the beginning of the frame within the current day [hours, minutes, seconds]
d_t_b = 0.0; //!< Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. [minutes]
d_M = 0.0; //!< Type of satellite transmitting navigation signal [dimensionless]
d_gamma_n = 0.0; //!< Relative deviation of predicted carrier frequency value of n- satellite from nominal value at the instant tb [dimensionless]
d_tau_n = 0.0; //!< Correction to the nth satellite time (tn) relative to GLONASS time (te),
d_B_n = 0.0; //!< Health flag [dimensionless]
d_P = 0.0; //!< Technological parameter of control segment, indication the satellite operation mode in respect of time parameters [dimensionless]
d_N_T = 0.0; //!< Current date, calendar number of day within four-year interval starting from the 1-st of January in a leap year [days]
d_F_T = 0.0; //!< Parameter that provides the predicted satellite user range accuracy at time tb [dimensionless]
d_n = 0.0; //!< Index of the satellite transmitting given navigation signal. It corresponds to a slot number within GLONASS constellation
d_Delta_tau_n = 0.0; //!< Time difference between navigation RF signal transmitted in L2 sub- band and aviation RF signal transmitted in L1 sub-band by nth satellite. [dimensionless]
d_E_n = 0.0; //!< Characterises "age" of a current information [days]
d_P_1 = 0.0; //!< Flag of the immediate data updating.
d_P_2 = 0.0; //!< Flag of oddness ("1") or evenness ("0") of the value of (tb) [dimensionless]
d_P_3 = 0.0; //!< Flag indicating a number of satellites for which almanac is transmitted within given frame: "1" corresponds to 5 satellites and "0" corresponds to 4 satellites [dimensionless]
d_P_4 = 0.0; //!< Flag to show that ephemeris parameters are present. "1" indicates that updated ephemeris or frequency/time parameters have been uploaded by the control segment [dimensionless]
d_l_n = 0.0; //!< Health flag for nth satellite; ln = 0 indicates the n-th satellite is helthy, ln = 1 indicates malfunction of this nth satellite [dimensionless]
//!< Ephmeris Flags
flag_all_ephemeris = false;
flag_ephemeris_str_1 = false;
flag_ephemeris_str_2 = false;
flag_ephemeris_str_3 = false;
flag_ephemeris_str_4 = false;
// Almanac and Not Inmediate Information
d_tau_c = 0.0; //!< GLONASS time scale correction to UTC(SU) time. [s]
d_tau_gps = 0.0; //!< Correction to GPS time to GLONASS time [day]
d_N_4 = 0.0; //!< Four year interval number starting from 1996 [4 year interval]
d_N_A = 0.0; //!< Calendar day number within the four-year period beginning since the leap year [days]
d_n_A = 0.0; //!< Conventional number of satellite within GLONASS space segment [dimensionless]
d_H_n_A = 0.0; //!< Carrier frequency number of navigation RF signal transmitted by d_nA satellite [dimensionless]
d_lambda_n_A = 0.0; //!< Longitude of the first (within the d_NA day) ascending node of d_nA [semi-circles]
d_t_lambda_n_A = 0.0; //!< Time of first ascending node passage [s]
d_Delta_i_n_A = 0.0; //!< Correction of the mean value of inclination of d_n_A satellite at instant t_lambda_n_A [semi-circles]
d_Delta_T_n_A = 0.0; //!< Correction to the mean value of Draconian period of d_n_A satellite at instant t_lambda_n_A[s / orbital period]
d_Delta_T_n_A_dot = 0.0; //!< Rate of change of Draconian period of d_n_A satellite at instant t_lambda_n_A [s / orbital period^2]
d_epsilon_n_A = 0.0; //!< Eccentricity of d_n_A satellite at instant t_lambda_n_A [dimensionless]
d_omega_n_A = 0.0; //!< Argument of preigree of d_n_A satellite at instant t_lambdan_A [semi-circles]
d_M_n_A = 0.0; //!< Type of satellite n_A [dimensionless]
d_B1 = 0.0; //!< Coefficient to determine DeltaUT1 [s]
d_B2 = 0.0; //!< Coefficient to determine DeltaUT1 [s/msd]
d_KP = 0.0; //!< Notification on forthcoming leap second correction of UTC [dimensionless]
d_tau_n_A = 0.0; //!< Coarse value of d_n_A satellite time correction to GLONASS time at instant t_lambdan_A[s]
d_C_n_A = 0.0; //!< Generalized “unhealthy flag” of n_A satellite at instant of almanac upload [dimensionless]
//!< Almanac Flags
flag_all_almanac = false;
flag_almanac_str_6 = false;
flag_almanac_str_7 = false;
flag_almanac_str_8 = false;
flag_almanac_str_9 = false;
flag_almanac_str_10 = false;
flag_almanac_str_11 = false;
flag_almanac_str_12 = false;
flag_almanac_str_13 = false;
flag_almanac_str_14 = false;
flag_almanac_str_15 = false;
std::map<int,std::string> satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus
//!< UTC and System Clocks Flags
flag_utc_model_valid; //!< If set, it indicates that the UTC model parameters are filled
flag_utc_model_str_5; //!< Clock info send in string 5 of navigation data
flag_utc_model_str_15; //!< Clock info send in string 15 of frame 5 of navigation data
flag_TOW_5;
flag_TOW_6;
flag_TOW_set; //!< it is true when page 5 or page 6 arrives
/*! \brief If true, enhanced level of integrity assurance.
*
* If false, indicates that the conveying signal is provided with the legacy level of integrity assurance.
* That is, the probability that the instantaneous URE of the conveying signal exceeds 4.42 times the upper bound
* value of the current broadcast URA index, for more than 5.2 seconds, without an accompanying alert, is less
* than 1E-5 per hour. If true, indicates that the conveying signal is provided with an enhanced level of
* integrity assurance. That is, the probability that the instantaneous URE of the conveying signal exceeds 5.73
* times the upper bound value of the current broadcast URA index, for more than 5.2 seconds, without an
* accompanying alert, is less than 1E-8 per hour.
*/
b_integrity_status_flag = false;
b_alert_flag = false; //!< If true, indicates that the SV URA may be worse than indicated in d_SV_accuracy, use that SV at our own risk.
b_antispoofing_flag = false; //!< If true, the AntiSpoofing mode is ON in that SV
//broadcast orbit 1
//TODO Need to send the information regarding the frame number
double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s]
double d_TOW_F1; //!< Time of GPS Week from HOW word of Subframe 1 [s]
double d_TOW_F2; //!< Time of GPS Week from HOW word of Subframe 2 [s]
double d_TOW_F3; //!< Time of GPS Week from HOW word of Subframe 3 [s]
double d_TOW_F4; //!< Time of GPS Week from HOW word of Subframe 4 [s]
double d_TOW_F5; //!< Time of GPS Week from HOW word of Subframe 5 [s]
// Clock terms
d_satClkCorr = 0.0; // Satellite clock error
d_dtr = 0.0; // Relativistic clock correction term
d_satClkDrift = 0.0; // Satellite clock drift
d_satClkCorr = 0.0;
d_dtr = 0.0;
d_satClkDrift = 0.0;
// satellite identification info
int i_channel_ID = 0;
int i_satellite_freq_channel = 0; //!< SV PRN NUMBER
// time synchro
d_subframe_timestamp_ms = 0; //[ms]
// UTC parameters
bool flag_utc_model_valid = false; //!< If set, it indicates that the UTC model parameters are filled
// satellite positions
d_satpos_X = 0.0; //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km].
d_satpos_Y = 0.0; //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km]
d_satpos_Z = 0.0; //!< Earth-fixed coordinate z of the satellite in PZ-90.02 coordinate system [km]
// Satellite velocity
d_satvel_X = 0.0; //!< Earth-fixed velocity coordinate x of the satellite in PZ-90.02 coordinate system [km/s]
d_satvel_Y = 0.0; //!< Earth-fixed velocity coordinate y of the satellite in PZ-90.02 coordinate system [km/s]
d_satvel_Z = 0.0; //!< Earth-fixed velocity coordinate z of the satellite in PZ-90.02 coordinate system [km/s]
// Satellite acceleration
d_satacc_X = 0.0; //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2]
d_satacc_Y = 0.0; //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2]
d_satacc_Z = 0.0; //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2]
std::map<int,std::string> satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus
auto gnss_sat = Gnss_Satellite();
std::string _system ("GLONASS");
@ -145,79 +102,97 @@ Glonass_Gnav_Navigation_Message::Glonass_Gnav_Navigation_Message()
reset();
}
bool Glonass_Gnav_Navigation_Message::_CRC_test(std::bitset<GLONASS_GNAV_STRING_BITS> data_bits, std::bitset<GLONASS_GNAV_STRING_BITS> hamming_code_bits )
{
int sum;
int sum_bits;
int sum_hamming;
//!< Compute C1 term
sum = 0;
sum_bits = 0;
for(int i = 0; i < GLONASS_GNAV_CRC_I_INDEX.size; i++)
{
sum += data_bits[GLONASS_GNAV_CRC_I_INDEX[i]]
sum_bits += data_bits[GLONASS_GNAV_CRC_I_INDEX[i]];
}
C1 = hamming_code_bits[0]^fmod(sum,2);
C1 = hamming_code_bits[0]^fmod(sum_bits,2);
//!< Compute C2 term
sum = 0;
sum_bits = 0;
for(int j = 0; j < GLONASS_GNAV_CRC_J_INDEX.size; j++)
{
sum += data_bits[GLONASS_GNAV_CRC_J_INDEX[j]]
sum_bits += data_bits[GLONASS_GNAV_CRC_J_INDEX[j]];
}
C2 = hamming_code_bits[1]^fmod(sum,2);
C2 = hamming_code_bits[1]^fmod(sum_bits,2);
//!< Compute C3 term
sum = 0;
sum_bits = 0;
for(int k = 0; k < GLONASS_GNAV_CRC_K_INDEX.size; k++)
{
sum += data_bits[GLONASS_GNAV_CRC_K_INDEX[k]]
sum_bits += data_bits[GLONASS_GNAV_CRC_K_INDEX[k]];
}
C3 = hamming_code_bits[2]^fmod(sum,2);
C3 = hamming_code_bits[2]^fmod(sum_bits,2);
//!< Compute C4 term
sum = 0;
sum_bits = 0;
for(int l = 0; l < GLONASS_GNAV_CRC_L_INDEX.size; l++)
{
sum += data_bits[GLONASS_GNAV_CRC_L_INDEX[l]]
sum_bits += data_bits[GLONASS_GNAV_CRC_L_INDEX[l]];
}
C4 = hamming_code_bits[3]^fmod(sum,2);
C4 = hamming_code_bits[3]^fmod(sum_bits,2);
//!< Compute C5 term
sum = 0;
sum_bits = 0;
for(int m = 0; m < GLONASS_GNAV_CRC_M_INDEX.size; m++)
{
sum += data_bits[GLONASS_GNAV_CRC_M_INDEX[m]]
sum_bits += data_bits[GLONASS_GNAV_CRC_M_INDEX[m]];
}
C5 = hamming_code_bits[4]^fmod(sum,2);
C5 = hamming_code_bits[4]^fmod(sum_bits,2);
//!< Compute C6 term
sum = 0;
sum_bits = 0;
for(int n = 0; n < GLONASS_GNAV_CRC_N_INDEX.size; n++)
{
sum += data_bits[GLONASS_GNAV_CRC_N_INDEX[n]]
sum_bits += data_bits[GLONASS_GNAV_CRC_N_INDEX[n]];
}
C6 = hamming_code_bits[5]^fmod(sum,2);
C6 = hamming_code_bits[5]^fmod(sum_bits,2);
//!< Compute C7 term
sum = 0;
sum_bits = 0;
for(int p = 0; p < GLONASS_GNAV_CRC_P_INDEX.size; p++)
{
sum += data_bits[GLONASS_GNAV_CRC_P_INDEX[p]]
sum_bits += data_bits[GLONASS_GNAV_CRC_P_INDEX[p]];
}
C7 = hamming_code_bits[6]^fmod(sum,2);
C7 = hamming_code_bits[6]^fmod(sum_bits,2);
//!< Compute C8 term
sum = 0;
//!< Compute C_Sigma term
sum_bits = 0;
sum_hamming = 0;
for(int q = 0; q < GLONASS_GNAV_CRC_Q_INDEX.size; q++)
{
sum += data_bits[GLONASS_GNAV_CRC_Q_INDEX[q]]
sum_bits += data_bits[GLONASS_GNAV_CRC_Q_INDEX[q]];
}
C8 = hamming_code_bits[7]^fmod(sum,2);
for(int q = 0; q < 8; q++)
{
sum_hamming += hamming_code_bits[q];
}
C_Sigma = fmod(sum_bits, 2)^fmod(sum_bits,2);
if isempty(find(C,1)) || (length(find(C(1,1:7))) == 1 && C(1,8) == 1)
status = 1;
else
status = 0;
end
//!< Verification of the data
// All of the checksums are equal to zero
if((C1 & C2 & C3 & C4 & C5 & C6 & C7 & C_Sigma) == 0 )
{
return true;
}
// only one of the checksums (C1,...,C7) is equal to zero but C_Sigma = 1
else if(C_Sigma == 1 && C1+C2+C3+C4+C5+C6+C7 == 6)
{
return true;
}
else
{
return false;
}
}
@ -315,6 +290,7 @@ signed long int Glonass_Gnav_Navigation_Message::read_navigation_signed(std::bit
return value;
}
unsigned int Glonass_Gnav_Navigation_Message::get_frame_number(unsigned int satellite_slot_number)
{
unsigned int frame_ID = 0;
@ -346,6 +322,7 @@ unsigned int Glonass_Gnav_Navigation_Message::get_frame_number(unsigned int sate
}
}
int Glonass_Gnav_Navigation_Message::string_decoder(char * frame_string)
{
int string_ID = 0;
@ -591,8 +568,6 @@ int Glonass_Gnav_Navigation_Message::string_decoder(char * frame_string)
}
double Glonass_Gnav_Navigation_Message::utc_time(const double glonass_time_corrected) const
{
double t_utc;
@ -602,71 +577,25 @@ double Glonass_Gnav_Navigation_Message::utc_time(const double glonass_time_corre
}
Glonass_Gnav_Ephemeris Glonass_Gnav_Navigation_Message::get_ephemeris()
{
Glonass_Gnav_Ephemeris ephemeris;
ephemeris.i_satellite_freq_channel = i_satellite_freq_channel;
ephemeris.d_m = d_m;
ephemeris.d_t_k = d_t_k;
ephemeris.d_t_b = d_t_b;
ephemeris.d_M = d_M;
ephemeris.d_gamma_n = d_gamma_n;
ephemeris.d_tau_n = d_tau_n;
// satellite positions
ephemeris.d_satpos_X = d_satpos_X;
ephemeris.d_satpos_Y = d_satpos_Y;
ephemeris.d_satpos_Z = d_satpos_Z;
// Satellite velocity
ephemeris.d_satvel_X = d_satvel_X;
ephemeris.d_satvel_Y = d_satvel_Y;
ephemeris.d_satvel_Z = d_satvel_Z;
// Satellite acceleration
ephemeris.d_satacc_X = d_satacc_X;
ephemeris.d_satacc_Y = d_satacc_Y;
ephemeris.d_satacc_Z = d_satacc_Z;
ephemeris.d_B_n = d_B_n;
ephemeris.d_P = d_P;
ephemeris.d_N_T = d_N_T;
ephemeris.d_F_T = d_F_T;
ephemeris.d_n = d_n;
ephemeris.d_Delta_tau_n = d_Delta_tau_n;
ephemeris.d_E_n = d_E_n;
ephemeris.d_P_1 = d_P_1;
ephemeris.d_P_2 = d_P_2;
ephemeris.d_P_3 = d_P_3;
ephemeris.d_P_4 = d_P_4;
ephemeris.d_l_n = d_l_n;
// clock terms derived from ephemeris data
ephemeris.d_satClkDrift = d_satClkDrift;
ephemeris.d_dtr = d_dtr;
return ephemeris;
return gnav_ephemeris;
}
Glonass_Gnav_Utc_Model Glonass_Gnav_Navigation_Message::get_utc_model()
{
Gps_Utc_Model utc_model;
utc_model.valid = flag_utc_model_valid;
// UTC parameters
utc_model.d_A1 = d_A1;
utc_model.d_A0 = d_A0;
utc_model.d_t_OT = d_t_OT;
utc_model.i_WN_T = i_WN_T;
utc_model.d_DeltaT_LS = d_DeltaT_LS;
utc_model.i_WN_LSF = i_WN_LSF;
utc_model.i_DN = i_DN;
utc_model.d_DeltaT_LSF = d_DeltaT_LSF;
// warning: We clear flag_utc_model_valid in order to not re-send the same information to the ionospheric parameters queue
flag_utc_model_valid = false;
return utc_model;
return gnav_utc_model;
}
bool Glonass_Gnav_Navigation_Message::satellite_validation()
Glonass_Gnav_Almanac get_almanac()
{
return gnav_almanac;
}
bool Glonass_Gnav_Navigation_Message::have_new_ephemeris() //Check if we have a new ephemeris stored in the galileo navigation class
{
bool flag_data_valid = false;
b_valid_ephemeris_set_flag = false;
@ -674,7 +603,7 @@ bool Glonass_Gnav_Navigation_Message::satellite_validation()
// First Step:
// check Issue Of Ephemeris Data (IODE IODC..) to find a possible interrupted reception
// and check if the data have been filled (!=0)
if (d_TOW_SF1 != 0 and d_TOW_SF2 != 0 and d_TOW_SF3 != 0)
if (d_TOW_F1 != 0 and d_TOW_F2 != 0 and d_TOW_F3 != 0)
{
if (d_IODE_SF2 == d_IODE_SF3 and d_IODC == d_IODE_SF2 and d_IODC!= -1)
{
@ -682,5 +611,67 @@ bool Glonass_Gnav_Navigation_Message::satellite_validation()
b_valid_ephemeris_set_flag = true;
}
}
return flag_data_valid;
if ((flag_ephemeris_str_1 == true) and (flag_ephemeris_str_2 == true) and (flag_ephemeris_str_3 == true) and (flag_ephemeris_str_4 == true) and (flag_iono_and_GST == true))
{
//if all ephemeris pages have the same IOD, then they belong to the same block
if ((gnav_ephemeris.d_t_b== IOD_nav_2) and (IOD_nav_3 == IOD_nav_4) and (IOD_nav_1 == IOD_nav_3))
{
std::cout << "Ephemeris (1, 2, 3, 4) have been received and belong to the same batch" << std::endl;
flag_ephemeris_1 = false;// clear the flag
flag_ephemeris_2 = false;// clear the flag
flag_ephemeris_3 = false;// clear the flag
flag_ephemeris_4 = false;// clear the flag
flag_all_ephemeris = true;
IOD_ephemeris = IOD_nav_1;
std::cout << "Batch number: "<< IOD_ephemeris << std::endl;
return true;
}
else
{
return false;
}
}
else
return false;
}
bool Glonass_Gnav_Navigation_Message::have_new_utc_model() // Check if we have a new utc data set stored in the galileo navigation class
{
if (flag_utc_model == true)
{
flag_utc_model = false; // clear the flag
return true;
}
else
return false;
}
bool Glonass_Gnav_Navigation_Message::have_new_almanac() //Check if we have a new almanac data set stored in the galileo navigation class
{
if ((flag_almanac_str_6 == true) and (flag_almanac_str_7 == true) and
(flag_almanac_str_8 == true) and (flag_almanac_str_9 == true) and
(flag_almanac_str_10 == true) and (flag_almanac_str_11 == true) and
(flag_almanac_str_12 == true) and (flag_almanac_str_13 == true) and
(flag_almanac_str_14 == true) and (flag_almanac_str_15 == true))
{
//All almanac have been received
flag_almanac_str_6 = false;
flag_almanac_str_7 = false;
flag_almanac_str_8 = false;
flag_almanac_str_9 = false;
flag_almanac_str_10 = false;
flag_almanac_str_11 = false;
flag_almanac_str_12 = false;
flag_almanac_str_13 = false;
flag_almanac_str_14 = false;
flag_almanac_str_15 = false;
flag_all_almanac = true;
return true;
}
else
return false;
}

View File

@ -64,78 +64,61 @@ private:
unsigned int get_frame_number(unsigned int satellite_slot_number);
public:
bool b_valid_ephemeris_set_flag; // flag indicating that this ephemeris set have passed the validation check
int Page_type_time_stamp;
int flag_even_word;
std::string page_Even;
bool flag_CRC_test;
unsigned int u_frame_number;
Glonass_Gnav_Ephemeris gnav_ephemeris; //!< Ephemeris information decoded
Glonass_Gnav_Iono gnav_iono; //!< Iono corrections information
//Glonass_Gnav_Iono gnav_iono; //!< Iono corrections information
Glonass_Gnav_Utc_Model gnav_utc_model; //!< UTC model information
Glonass_Gnav_Almanac gnav_almanac[24]; //!< Almanac information for all 24 satellites
//!< Satellite Identification
int i_channel_ID; //!< Channel ID assigned by the receiver
int i_satellite_freq_channel; //!< SV Frequency Slot Number
int i_satellite_slot_number; //!< SV Orbit Slot Number
//!< Ephmeris Flags
bool flag_all_ephemeris; //!< Flag indicating that all strings containing ephemeris have been received
bool flag_ephemeris_str_1; //!< Flag indicating that ephemeris 1/4 (word 1) have been received
bool flag_ephemeris_str_2; //!< Flag indicating that ephemeris 2/4 (word 2) have been received
bool flag_ephemeris_str_3; //!< Flag indicating that ephemeris 3/4 (word 3) have been received
bool flag_ephemeris_str_4; //!< Flag indicating that ephemeris 4/4 (word 4) have been received
bool flag_ephemeris_str_1; //!< Flag indicating that ephemeris 1/4 (string 1) have been received
bool flag_ephemeris_str_2; //!< Flag indicating that ephemeris 2/4 (string 2) have been received
bool flag_ephemeris_str_3; //!< Flag indicating that ephemeris 3/4 (string 3) have been received
bool flag_ephemeris_str_4; //!< Flag indicating that ephemeris 4/4 (string 4) have been received
bool flag_iono_and_GST; //!< Flag indicating that ionospheric and GST parameters (word 5) have been received
//!< Almanac Flags
bool flag_all_almanac; //!< Flag indicating that all almanac have been received
bool flag_almanac_str_6; //!< Flag indicating that almanac of string 6 have been received
bool flag_almanac_str_7; //!< Flag indicating that almanac of string 7 have been received
bool flag_almanac_str_8; //!< Flag indicating that almanac of string 8 have been received
bool flag_almanac_str_9; //!< Flag indicating that almanac of string 9 have been received
bool flag_almanac_str_10; //!< Flag indicating that almanac of string 10 have been received
bool flag_almanac_str_11; //!< Flag indicating that almanac of string 11 have been received
bool flag_almanac_str_12; //!< Flag indicating that almanac of string 12 have been received
bool flag_almanac_str_13; //!< Flag indicating that almanac of string 13 have been received
bool flag_almanac_str_14; //!< Flag indicating that almanac of string 14 have been received
bool flag_almanac_str_15; //!< Flag indicating that almanac of string 15 have been received
//!< UTC and System Clocks Flags
bool flag_utc_model_valid; //!< If set, it indicates that the UTC model parameters are filled
bool flag_utc_model_str_5; //!< Clock info send in string 5 of navigation data
bool flag_utc_model_str_15; //!< Clock info send in string 15 of frame 5 of navigation data
bool flag_TOW_5;
bool flag_TOW_6;
bool flag_TOW_set; //!< it is true when page 5 or page 6 arrives
bool flag_utc_model; //!< Flag indicating that utc model parameters (word 6) have been received
bool flag_all_almanac; //!< Flag indicating that all almanac have been received
bool flag_almanac_str_6; //!< Flag indicating that almanac 1/4 (word 7) have been received
bool flag_almanac_str_7; //!< Flag indicating that almanac 2/4 (word 8) have been received
bool flag_almanac_str_8; //!< Flag indicating that almanac 3/4 (word 9) have been received
bool flag_almanac_str_9; //!< Flag indicating that almanac 4/4 (word 10) have been received
bool flag_almanac_str_10; //!< Flag indicating that almanac 4/4 (word 10) have been received
bool flag_almanac_str_11; //!< Flag indicating that almanac 4/4 (word 10) have been received
bool flag_almanac_str_12; //!< Flag indicating that almanac 4/4 (word 10) have been received
bool flag_almanac_str_13; //!< Flag indicating that almanac 4/4 (word 10) have been received
bool flag_almanac_str_14; //!< Flag indicating that almanac 4/4 (word 10) have been received
bool flag_almanac_str_15; //!< Flag indicating that almanac 4/4 (word 10) have been received
bool flag_TOW_set; //!< it is true when page 5 or page 6 arrives
//broadcast orbit 1
//TODO Need to send the information regarding the frame number
double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s]
double d_TOW_F1; //!< Time of GPS Week from HOW word of Subframe 1 [s]
double d_TOW_F2; //!< Time of GPS Week from HOW word of Subframe 2 [s]
double d_TOW_F3; //!< Time of GPS Week from HOW word of Subframe 3 [s]
double d_TOW_F4; //!< Time of GPS Week from HOW word of Subframe 4 [s]
double d_TOW_F5; //!< Time of GPS Week from HOW word of Subframe 5 [s]
double d_TOW; //!< Time of GPS Week of the ephemeris set (taken from subframes TOW) [s]
double d_TOW_F1; //!< Time of GPS Week from HOW word of Subframe 1 [s]
double d_TOW_F2; //!< Time of GPS Week from HOW word of Subframe 2 [s]
double d_TOW_F3; //!< Time of GPS Week from HOW word of Subframe 3 [s]
double d_TOW_F4; //!< Time of GPS Week from HOW word of Subframe 4 [s]
double d_TOW_F5; //!< Time of GPS Week from HOW word of Subframe 5 [s]
// Clock terms
double d_satClkCorr; // Satellite clock error
double d_dtr; // Relativistic clock correction term
double d_satClkDrift; // Satellite clock drift
// satellite identification info
int i_channel_ID;
unsigned int i_satellite_PRN; //!< SV PRN Number
int i_satellite_freq_channel; //!< SV Frequency Slot Number
int i_satellite_slot_number; //!< SV Orbit Slot Number
// UTC parameters
bool flag_utc_model_valid; //!< If set, it indicates that the UTC model parameters are filled
// satellite positions
double d_satpos_X; //!< Earth-fixed coordinate x of the satellite in PZ-90.02 coordinate system [km].
double d_satpos_Y; //!< Earth-fixed coordinate y of the satellite in PZ-90.02 coordinate system [km]
double d_satpos_Z; //!< Earth-fixed coordinate z of the satellite in PZ-90.02 coordinate system [km]
// Satellite velocity
double d_satvel_X; //!< Earth-fixed velocity coordinate x of the satellite in PZ-90.02 coordinate system [km/s]
double d_satvel_Y; //!< Earth-fixed velocity coordinate y of the satellite in PZ-90.02 coordinate system [km/s]
double d_satvel_Z; //!< Earth-fixed velocity coordinate z of the satellite in PZ-90.02 coordinate system [km/s]
// Satellite acceleration
double d_satacc_X; //!< Earth-fixed acceleration coordinate x of the satellite in PZ-90.02 coordinate system [km/s^2]
double d_satacc_Y; //!< Earth-fixed acceleration coordinate y of the satellite in PZ-90.02 coordinate system [km/s^2]
double d_satacc_Z; //!< Earth-fixed acceleration coordinate z of the satellite in PZ-90.02 coordinate system [km/s^2]
/*!
* \brief Reset GLONASS GNAV Navigation Information
*/
@ -182,12 +165,10 @@ public:
*/
bool have_new_almanac();
/*!
* \brief Decodes the GLONASS GNAV frame
* \brief Decodes the GLONASS GNAV string
*/
int string_decoder(char *string, int frame_ID);
int string_decoder(char *string);
/*!
* \brief Computes the Coordinated Universal Time (UTC) and returns it in [s]