1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-06-03 07:04:09 +00:00

tracking working

This commit is contained in:
Sergi Segura 2018-08-06 13:52:08 +02:00
parent 51aa80aa46
commit e4a86173fa
28 changed files with 1743 additions and 436 deletions

View File

@ -38,7 +38,7 @@ Resampler.sample_freq_out=25000000
Resampler.item_type=gr_complex Resampler.item_type=gr_complex
;######### CHANNELS GLOBAL CONFIG ############ ;######### CHANNELS GLOBAL CONFIG ############
Channels_B1.count=8 Channels_B1.count=1
Channels.in_acquisition=1 Channels.in_acquisition=1
Channel.signal=B1 Channel.signal=B1
@ -47,10 +47,10 @@ Channel.signal=B1
Acquisition_B1.implementation=BEIDOU_B1I_PCPS_Acquisition Acquisition_B1.implementation=BEIDOU_B1I_PCPS_Acquisition
Acquisition_B1.item_type=gr_complex Acquisition_B1.item_type=gr_complex
Acquisition_B1.coherent_integration_time_ms=1 Acquisition_B1.coherent_integration_time_ms=1
Acquisition_B1.threshold=18 Acquisition_B1.threshold=20
;Acquisition_B1.pfa=0.000001 ;Acquisition_B1.pfa=0.000001
Acquisition_B1.doppler_max=10000 Acquisition_B1.doppler_max=10000
Acquisition_B1.doppler_step=250 Acquisition_B1.doppler_step=2500
Acquisition_B1.dump=true Acquisition_B1.dump=true
Acquisition_B1.dump_filename=./acq_dump.dat Acquisition_B1.dump_filename=./acq_dump.dat
Acquisition_B1.blocking=false; Acquisition_B1.blocking=false;
@ -60,7 +60,7 @@ Acquisition_B1.use_CFAR_algorithm=false
Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking
Tracking_B1.item_type=gr_complex Tracking_B1.item_type=gr_complex
Tracking_B1.pll_bw_hz=40.0; Tracking_B1.pll_bw_hz=40.0;
Tracking_B1.dll_bw_hz=4.0; Tracking_B1.dll_bw_hz=8.0;
Tracking_B1.order=3; Tracking_B1.order=3;
Tracking_B1.dump=true; Tracking_B1.dump=true;
Tracking_B1.dump_filename=./epl_tracking_ch_ Tracking_B1.dump_filename=./epl_tracking_ch_
@ -68,7 +68,7 @@ Tracking_B1.dump_filename=./epl_tracking_ch_
;######### TELEMETRY DECODER GPS CONFIG ############ ;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_B1.implementation=BEIDOU_B1I_Telemetry_Decoder TelemetryDecoder_B1.implementation=BEIDOU_B1I_Telemetry_Decoder
TelemetryDecoder_B1.dump=false TelemetryDecoder_B1.dump=true
;######### OBSERVABLES CONFIG ############ ;######### OBSERVABLES CONFIG ############

View File

@ -29,13 +29,14 @@ SignalSource.enable_throttle_control=false
;######### SIGNAL_CONDITIONER CONFIG ############ ;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Signal_Conditioner SignalConditioner.implementation=Signal_Conditioner
DataTypeAdapter.implementation=Ishort_To_Cshort DataTypeAdapter.implementation=Ishort_To_Complex
InputFilter.implementation=Pass_Through InputFilter.implementation=Pass_Through
InputFilter.item_type=cshort InputFilter.item_type=gr_complex
Resampler.implementation=Direct_Resampler Resampler.implementation=Direct_Resampler
Resampler.sample_freq_in=4000000 Resampler.sample_freq_in=4000000
Resampler.sample_freq_out=2000000 Resampler.sample_freq_out=2000000
Resampler.item_type=cshort Resampler.item_type=gr_complex
;######### CHANNELS GLOBAL CONFIG ############ ;######### CHANNELS GLOBAL CONFIG ############
Channels_1C.count=8 Channels_1C.count=8
@ -45,7 +46,7 @@ Channel.signal=1C
;######### ACQUISITION GLOBAL CONFIG ############ ;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
Acquisition_1C.item_type=cshort Acquisition_1C.item_type=gr_complex
Acquisition_1C.coherent_integration_time_ms=1 Acquisition_1C.coherent_integration_time_ms=1
Acquisition_1C.threshold=0.008 Acquisition_1C.threshold=0.008
;Acquisition_1C.pfa=0.000001 ;Acquisition_1C.pfa=0.000001
@ -56,8 +57,8 @@ Acquisition_1C.dump_filename=./acq_dump.dat
Acquisition_1C.blocking=false; Acquisition_1C.blocking=false;
;######### TRACKING GLOBAL CONFIG ############ ;######### TRACKING GLOBAL CONFIG ############
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
Tracking_1C.item_type=cshort Tracking_1C.item_type=gr_complex
Tracking_1C.pll_bw_hz=40.0; Tracking_1C.pll_bw_hz=40.0;
Tracking_1C.dll_bw_hz=4.0; Tracking_1C.dll_bw_hz=4.0;
Tracking_1C.order=3; Tracking_1C.order=3;

56
conf/prova.conf Normal file
View File

@ -0,0 +1,56 @@
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
GNSS-SDR.internal_fs_hz=2000000
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=File_Signal_Source
SignalSource.filename=/home/sergi/gnss/gnss-sdr/data/2013_04_04_GNSS_SIGNAL_at_CTTC_SPAIN.dat
SignalSource.item_type=ishort
SignalSource.sampling_frequency=4000000
SignalSource.freq=1575420000
SignalSource.samples=0
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Signal_Conditioner
DataTypeAdapter.implementation=Ishort_To_Complex
InputFilter.implementation=Pass_Through
InputFilter.item_type=gr_complex
Resampler.implementation=Direct_Resampler
Resampler.sample_freq_in=4000000
Resampler.sample_freq_out=2000000
Resampler.item_type=gr_complex
;######### CHANNELS GLOBAL CONFIG ############
Channels_1C.count=8
Channels.in_acquisition=1
Channel.signal=1C
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
Acquisition_1C.item_type=gr_complex
Acquisition_1C.threshold=0.008
Acquisition_1C.doppler_max=10000
Acquisition_1C.doppler_step=250
;######### TRACKING GLOBAL CONFIG ############
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
Tracking_1C.item_type=gr_complex
Tracking_1C.pll_bw_hz=40.0;
Tracking_1C.dll_bw_hz=4.0;
;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
;######### OBSERVABLES CONFIG ############
Observables.implementation=GPS_L1_CA_Observables
;######### PVT CONFIG ############
PVT.implementation=GPS_L1_CA_PVT
PVT.averaging_depth=100
PVT.flag_averaging=true
PVT.output_rate_ms=10
PVT.display_rate_ms=500

View File

@ -0,0 +1,179 @@
void decodeBCHBeidou(std::list<bool> *firstBranch_encoded, std::list<int> *output)
{
bool input[15];
std::copy(firstBranch_encoded.begin(),firstBranch_encoded.end(),input);
std::array<bool, 4> D_register = {0,0,0,0};
std::array<bool, 15> stage_buffer;
std::array<bool, 15> ROM_list_circuit;
for (i = 0; i < 15; i++)
{
D_register = {inputBit[i] ^ D_register[3], D_register[0] ^ D_register[3], D_register[1], D_register[2]};
stage_buffer[i] = inputBit[i];
}
if(D_register == {0,0,0,0}) {
ROM_list_circuit = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
} else if(D_register == {0,0,0,1}) {
ROM_list_circuit = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
} else if(D_register == {0,0,1,0}) {
ROM_list_circuit = {0,0,0,0,0,0,0,0,0,0,0,0,0,1,0};
} else if(D_register == {0,0,1,1}) {
ROM_list_circuit = {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0};
} else if(D_register == {0,1,0,0}) {
ROM_list_circuit = {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0};
} else if(D_register == {0,1,0,1}) {
ROM_list_circuit = {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0};
} else if(D_register == {0,1,1,0}) {
ROM_list_circuit = {0,0,0,0,0,0,0,0,0,1,0,0,0,0,0};
} else if(D_register == {0,1,1,1}) {
ROM_list_circuit = {0,0,0,0,1,0,0,0,0,0,0,0,0,0,0};
} else if(D_register == {1,0,0,0}) {
ROM_list_circuit = {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0};
} else if(D_register == {1,0,0,1}) {
ROM_list_circuit = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
} else if(D_register == {1,0,1,0}) {
ROM_list_circuit = {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0};
} else if(D_register == {1,0,1,1}) {
ROM_list_circuit = {0,0,0,0,0,0,0,1,0,0,0,0,0,0,0};
} else if(D_register == {1,1,0,0}) {
ROM_list_circuit = {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0};
} else if(D_register == {1,1,0,1}) {
ROM_list_circuit = {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0};
} else if(D_register == {1,1,1,0}) {
ROM_list_circuit = {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0};
} else if(D_register == {1,1,1,1}) {
ROM_list_circuit = {0,0,1,0,0,0,0,0,0,0,0,0,0,0,0};
}
for (i = 0; i < 15; i++)
{
if(stage_buffer[i] ^ ROM_list_circuit[i])
{
output.push_back(1);
}
else
{
output.push_back(-1);
}
}
}
void remove_NH_Beidou(bool *input, bool *output)
{
int *code_NH_Beidou = {-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1};
int corr_NH = 0;
int correlation = 0;
for (int i = 0; i < 20; i++)
{
if ((code_NH_Beidou[i] * input[i]) > 0.0)
{
corr_NH += 1;
}
else
{
corr_NH -= 1;
}
}
if (abs(corr_NH) == 20)
{
correlation = 1;
if (corr_NH > 0)
{
output = 1;
}
else
{
output = 0;
}
}
}
void process_TRK_output_Beidou(bool *input, int n_input_bits, int *output)
{
bool buffer_NH[15];
bool new_bit;
std::list<bool> firstBranch_encoded;
std::list<int> firstBranch_decoded;
std::list<bool> secondBranch_encoded;
std::list<int> secondBranch_decoded;
std::list<int> output_list;
for (int i = 0; i < n_input_bits/15; i++)
{
for (int j = 0; j < 15; i++)
{
buffer_NH[j] = input[i + j];
}
remove_NH_Beidou(buffer_NH, &new_bit)
if ( i % 2 == 0 )
{
firstBranch_encoded.push_back(new_bit);
}
else
{
secondBranch_encoded.push_back(new_bit);
}
if (firstBranch_encoded.size() == 15)
{
decodeBCHBeidou(&firstBranch_encoded, &firstBranch_decoded);
firstBranch_encoded.clear();
}
if (secondBranch_encoded.size() == 15)
{
decodeBCHBeidou(&secondBranch_encoded, &secondBranch_decoded);
secondBranch_encoded.clear();
}
if (firstBranch_decoded.size() > 10)
{
for (i = 0; i < 11; i++)
{
output_list.push_back(firstBranch_decoded.front());
firstBranch_decoded.pop_front();
}
}
if (secondBranch_decoded.size() > 10)
{
for (i = 0; i < 11; i++)
{
output_list.push_back(secondBranch_decoded.front());
secondBranch_decoded.pop_front();
}
}
}
std::copy(output_list.begin(),output_list.end(),output);
}

View File

@ -30,19 +30,19 @@
*/ */
#include "gps_l1_ca_telemetry_decoder.h" #include "beidou_b1i_telemetry_decoder.h"
#include "configuration_interface.h" #include "configuration_interface.h"
#include "gps_ephemeris.h" #include "beidou_ephemeris.h"
#include "gps_almanac.h" #include "beidou_almanac.h"
#include "gps_iono.h" #include "beidou_iono.h"
#include "gps_utc_model.h" #include "beidou_utc_model.h"
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <glog/logging.h> #include <glog/logging.h>
using google::LogMessage; using google::LogMessage;
GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder(ConfigurationInterface* configuration, BeidouB1iTelemetryDecoder::BeidouB1iTelemetryDecoder(ConfigurationInterface* configuration,
std::string role, std::string role,
unsigned int in_streams, unsigned int in_streams,
unsigned int out_streams) : role_(role), unsigned int out_streams) : role_(role),
@ -54,7 +54,7 @@ GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder(ConfigurationInterface* configu
dump_ = configuration->property(role + ".dump", false); dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
// make telemetry decoder object // make telemetry decoder object
telemetry_decoder_ = gps_l1_ca_make_telemetry_decoder_cc(satellite_, dump_); // TODO fix me telemetry_decoder_ = beidou_b1i_make_telemetry_decoder_cc(satellite_, dump_); // TODO fix me
DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")";
channel_ = 0; channel_ = 0;
if (in_streams_ > 1) if (in_streams_ > 1)
@ -68,12 +68,12 @@ GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder(ConfigurationInterface* configu
} }
GpsL1CaTelemetryDecoder::~GpsL1CaTelemetryDecoder() BeidouB1iTelemetryDecoder::~BeidouB1iTelemetryDecoder()
{ {
} }
void GpsL1CaTelemetryDecoder::set_satellite(const Gnss_Satellite& satellite) void BeidouB1iTelemetryDecoder::set_satellite(const Gnss_Satellite& satellite)
{ {
satellite_ = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); satellite_ = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
telemetry_decoder_->set_satellite(satellite_); telemetry_decoder_->set_satellite(satellite_);
@ -81,7 +81,7 @@ void GpsL1CaTelemetryDecoder::set_satellite(const Gnss_Satellite& satellite)
} }
void GpsL1CaTelemetryDecoder::connect(gr::top_block_sptr top_block) void BeidouB1iTelemetryDecoder::connect(gr::top_block_sptr top_block)
{ {
if (top_block) if (top_block)
{ /* top_block is not null */ { /* top_block is not null */
@ -91,7 +91,7 @@ void GpsL1CaTelemetryDecoder::connect(gr::top_block_sptr top_block)
} }
void GpsL1CaTelemetryDecoder::disconnect(gr::top_block_sptr top_block) void BeidouB1iTelemetryDecoder::disconnect(gr::top_block_sptr top_block)
{ {
if (top_block) if (top_block)
{ /* top_block is not null */ { /* top_block is not null */
@ -100,13 +100,13 @@ void GpsL1CaTelemetryDecoder::disconnect(gr::top_block_sptr top_block)
} }
gr::basic_block_sptr GpsL1CaTelemetryDecoder::get_left_block() gr::basic_block_sptr BeidouB1iTelemetryDecoder::get_left_block()
{ {
return telemetry_decoder_; return telemetry_decoder_;
} }
gr::basic_block_sptr GpsL1CaTelemetryDecoder::get_right_block() gr::basic_block_sptr BeidouB1iTelemetryDecoder::get_right_block()
{ {
return telemetry_decoder_; return telemetry_decoder_;
} }

View File

@ -30,10 +30,10 @@
*/ */
#ifndef GNSS_SDR_GPS_L1_CA_TELEMETRY_DECODER_H_ #ifndef GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_H_
#define GNSS_SDR_GPS_L1_CA_TELEMETRY_DECODER_H_ #define GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_H_
#include "gps_l1_ca_telemetry_decoder_cc.h" #include "beidou_b1i_telemetry_decoder_cc.h"
#include "telemetry_decoder_interface.h" #include "telemetry_decoder_interface.h"
#include <string> #include <string>
@ -42,15 +42,15 @@ class ConfigurationInterface;
/*! /*!
* \brief This class implements a NAV data decoder for GPS L1 C/A * \brief This class implements a NAV data decoder for GPS L1 C/A
*/ */
class GpsL1CaTelemetryDecoder : public TelemetryDecoderInterface class BeidouB1iTelemetryDecoder : public TelemetryDecoderInterface
{ {
public: public:
GpsL1CaTelemetryDecoder(ConfigurationInterface* configuration, BeidouB1iTelemetryDecoder(ConfigurationInterface* configuration,
std::string role, std::string role,
unsigned int in_streams, unsigned int in_streams,
unsigned int out_streams); unsigned int out_streams);
virtual ~GpsL1CaTelemetryDecoder(); virtual ~BeidouB1iTelemetryDecoder();
inline std::string role() override inline std::string role() override
{ {
@ -82,7 +82,7 @@ public:
} }
private: private:
gps_l1_ca_telemetry_decoder_cc_sptr telemetry_decoder_; beidou_b1i_telemetry_decoder_cc_sptr telemetry_decoder_;
Gnss_Satellite satellite_; Gnss_Satellite satellite_;
int channel_; int channel_;
bool dump_; bool dump_;

View File

@ -1,8 +1,8 @@
/*! /*!
* \file gps_l1_ca_telemetry_decoder_cc.cc * \file beidou_b1i_telemetry_decoder_cc.cc
* \brief Implementation of a NAV message demodulator block based on * \brief Implementation of a NAV message demodulator block based on
* Kay Borre book MATLAB-based GPS receiver * Kay Borre book MATLAB-based GPS receiver
* \author Javier Arribas, 2011. jarribas(at)cttc.es * \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.es
* *
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
@ -29,7 +29,7 @@
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
#include "gps_l1_ca_telemetry_decoder_cc.h" #include "beidou_b1i_telemetry_decoder_cc.h"
#include "control_message_factory.h" #include "control_message_factory.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <glog/logging.h> #include <glog/logging.h>
@ -43,18 +43,19 @@
using google::LogMessage; using google::LogMessage;
gps_l1_ca_telemetry_decoder_cc_sptr beidou_b1i_telemetry_decoder_cc_sptr
gps_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump) beidou_b1i_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump)
{ {
return gps_l1_ca_telemetry_decoder_cc_sptr(new gps_l1_ca_telemetry_decoder_cc(satellite, dump)); return beidou_b1i_telemetry_decoder_cc_sptr(new beidou_b1i_telemetry_decoder_cc(satellite, dump));
} }
gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc( beidou_b1i_telemetry_decoder_cc::beidou_b1i_telemetry_decoder_cc(
const Gnss_Satellite &satellite, const Gnss_Satellite &satellite,
bool dump) : gr::block("gps_navigation_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), bool dump) : gr::block("beidou_navigation_cc", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
// Ephemeris data port out // Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry")); this->message_port_register_out(pmt::mp("telemetry"));
// initialize internal vars // initialize internal vars
@ -62,15 +63,14 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
// set the preamble // set the preamble
unsigned short int preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE; unsigned short int preambles_bits[BEIDOU_B1I_PREAMBLE_LENGTH_BITS] = BEIDOU_PREAMBLE;
// preamble bits to sampled symbols // preamble bits to sampled symbols
d_preambles_symbols = static_cast<int *>(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int), volk_gnsssdr_get_alignment())); d_preambles_symbols = static_cast<int *>(volk_gnsssdr_malloc(BEIDOU_B1I_PREAMBLE_LENGTH_SYMBOLS * sizeof(int), volk_gnsssdr_get_alignment()));
int n = 0; int n = 0;
for (int i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++) for (int i = 0; i < BEIDOU_B1I_PREAMBLE_LENGTH_BITS; i++)
{ {
for (unsigned int j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++)
{
if (preambles_bits[i] == 1) if (preambles_bits[i] == 1)
{ {
d_preambles_symbols[n] = 1; d_preambles_symbols[n] = 1;
@ -80,33 +80,50 @@ gps_l1_ca_telemetry_decoder_cc::gps_l1_ca_telemetry_decoder_cc(
d_preambles_symbols[n] = -1; d_preambles_symbols[n] = -1;
} }
n++; n++;
}
} }
d_stat = 0; d_stat = 0;
d_symbol_accumulator = 0; d_symbol_accumulator = 0;
d_symbol_accumulator_counter = 0; d_symbol_accumulator_counter = 0;
d_frame_bit_index = 0; d_frame_bit_index = 0;
d_flag_frame_sync = false; d_flag_frame_sync = false;
d_GPS_frame_4bytes = 0; d_BEIDOU_frame_4bytes = 0;
d_prev_GPS_frame_4bytes = 0; d_prev_BEIDOU_frame_4bytes = 0;
d_flag_parity = false; d_flag_parity = false;
d_TOW_at_Preamble_ms = 0; d_TOW_at_Preamble_ms = 0;
flag_TOW_set = false; flag_TOW_set = false;
d_flag_preamble = false; d_flag_preamble = false;
d_flag_new_tow_available = false; d_flag_new_tow_available = false;
d_word_number = 0; word_number = 0;
d_channel = 0; d_channel = 0;
flag_PLL_180_deg_phase_locked = false; flag_PLL_180_deg_phase_locked = false;
d_preamble_time_samples = 0; d_preamble_time_samples = 0;
d_TOW_at_current_symbol_ms = 0; d_TOW_at_current_symbol_ms = 0;
d_symbol_history.resize(GPS_CA_PREAMBLE_LENGTH_SYMBOLS + 1); // Change fixed buffer size d_symbol_history.resize(BEIDOU_B1I_PREAMBLE_LENGTH_BITS); // Change fixed buffer size
d_symbol_nh_history.resize(BEIDOU_B1I_NH_CODE_LENGTH + 1); // Change fixed buffer size
d_bit_buffer.resize(30); // Change fixed buffer size
d_symbol_history.clear(); // Clear all the elements in the buffer d_symbol_history.clear(); // Clear all the elements in the buffer
d_symbol_nh_history.clear();
d_bit_buffer.clear();
d_make_correlation = true; d_make_correlation = true;
d_symbol_counter_corr = 0; d_symbol_counter_corr = 0;
for (int aux = 0; aux < BEIDOU_B1I_NH_CODE_LENGTH; aux++)
{
if (BEIDOU_B1I_NH_CODE[aux] == 0)
{
bits_NH[aux] = -1.0;
}
else
{
bits_NH[aux] = 1.0;
}
}
sync_NH = false;
new_sym = false;
} }
gps_l1_ca_telemetry_decoder_cc::~gps_l1_ca_telemetry_decoder_cc() beidou_b1i_telemetry_decoder_cc::~beidou_b1i_telemetry_decoder_cc()
{ {
volk_gnsssdr_free(d_preambles_symbols); volk_gnsssdr_free(d_preambles_symbols);
if (d_dump_file.is_open() == true) if (d_dump_file.is_open() == true)
@ -123,44 +140,45 @@ gps_l1_ca_telemetry_decoder_cc::~gps_l1_ca_telemetry_decoder_cc()
} }
bool gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(unsigned int gpsword) bool beidou_b1i_telemetry_decoder_cc::beidou_word_parityCheck(unsigned int beidouword)
{ {
unsigned int d1, d2, d3, d4, d5, d6, d7, t, parity; unsigned int d1, d2, d3, d4, d5, d6, d7, t, parity;
/* XOR as many bits in parallel as possible. The magic constants pick /* XOR as many bits in parallel as possible. The magic constants pick
up bits which are to be XOR'ed together to implement the GPS parity up bits which are to be XOR'ed together to implement the GPS parity
check algorithm described in IS-GPS-200E. This avoids lengthy shift- check algorithm described in IS-GPS-200E. This avoids lengthy shift-
and-xor loops. */ and-xor loops. */
d1 = gpsword & 0xFBFFBF00; d1 = beidouword & 0xFBFFBF00;
d2 = _rotl(gpsword, 1) & 0x07FFBF01; d2 = _rotl(beidouword, 1) & 0x07FFBF01;
d3 = _rotl(gpsword, 2) & 0xFC0F8100; d3 = _rotl(beidouword, 2) & 0xFC0F8100;
d4 = _rotl(gpsword, 3) & 0xF81FFE02; d4 = _rotl(beidouword, 3) & 0xF81FFE02;
d5 = _rotl(gpsword, 4) & 0xFC00000E; d5 = _rotl(beidouword, 4) & 0xFC00000E;
d6 = _rotl(gpsword, 5) & 0x07F00001; d6 = _rotl(beidouword, 5) & 0x07F00001;
d7 = _rotl(gpsword, 6) & 0x00003000; d7 = _rotl(beidouword, 6) & 0x00003000;
t = d1 ^ d2 ^ d3 ^ d4 ^ d5 ^ d6 ^ d7; t = d1 ^ d2 ^ d3 ^ d4 ^ d5 ^ d6 ^ d7;
// Now XOR the 5 6-bit fields together to produce the 6-bit final result. // Now XOR the 5 6-bit fields together to produce the 6-bit final result.
parity = t ^ _rotl(t, 6) ^ _rotl(t, 12) ^ _rotl(t, 18) ^ _rotl(t, 24); parity = t ^ _rotl(t, 6) ^ _rotl(t, 12) ^ _rotl(t, 18) ^ _rotl(t, 24);
parity = parity & 0x3F; parity = parity & 0x3F;
if (parity == (gpsword & 0x3F)) if (parity == (beidouword & 0x3F))
return (true); return (true);
else else
return (false); return (false);
} }
void gps_l1_ca_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite) void beidou_b1i_telemetry_decoder_cc::set_satellite(const Gnss_Satellite &satellite)
{ {
d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN()); d_satellite = Gnss_Satellite(satellite.get_system(), satellite.get_PRN());
DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite; DLOG(INFO) << "Setting decoder Finite State Machine to satellite " << d_satellite;
d_GPS_FSM.i_satellite_PRN = d_satellite.get_PRN(); d_BEIDOU_FSM.i_satellite_PRN = d_satellite.get_PRN();
DLOG(INFO) << "Navigation Satellite set to " << d_satellite; DLOG(INFO) << "Navigation Satellite set to " << d_satellite;
} }
void gps_l1_ca_telemetry_decoder_cc::set_channel(int channel) void beidou_b1i_telemetry_decoder_cc::set_channel(int channel)
{ {
d_channel = channel; d_channel = channel;
d_GPS_FSM.i_channel_ID = channel; d_BEIDOU_FSM.i_channel_ID = channel;
DLOG(INFO) << "Navigation channel set to " << channel; DLOG(INFO) << "Navigation channel set to " << channel;
// ############# ENABLE DATA FILE LOG ################# // ############# ENABLE DATA FILE LOG #################
if (d_dump == true) if (d_dump == true)
@ -186,32 +204,156 @@ void gps_l1_ca_telemetry_decoder_cc::set_channel(int channel)
} }
int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)), void beidou_b1i_telemetry_decoder_cc::decode_word(int word_counter, boost::circular_buffer<signed int> *d_bit_buffer, unsigned int& d_BEIDOU_frame_4bytes)
{
//std::cout << word_counter << std::endl;
signed int firstBranch[15];
signed int secondBranch[15];
d_BEIDOU_frame_4bytes = 0;
if (word_counter == 1)
{
for (unsigned int i = 0; i < 15 ; i++)
{
if (d_bit_buffer->at(i) == 1)
{
d_BEIDOU_frame_4bytes++;
}
d_BEIDOU_frame_4bytes <<= 1;
}
for (unsigned int i = 15; i < 30 ; i++)
{
if (d_bit_buffer->at(i) == 1)
{
d_BEIDOU_frame_4bytes++;
}
d_BEIDOU_frame_4bytes <<= 1;
}
d_BEIDOU_frame_4bytes >>= 1;
}
else
{
for (unsigned int i = 0; i < 30 ; i = i + 2)
{
firstBranch[i/2] = d_bit_buffer->at(i);
secondBranch[i/2] = d_bit_buffer->at(i + 1);
}
for (unsigned int i = 0; i < 11 ; i++)
{
if (firstBranch[i] == 1)
{
d_BEIDOU_frame_4bytes++;
}
d_BEIDOU_frame_4bytes <<= 1;;
}
for (unsigned int i = 0; i < 11 ; i++)
{
if (secondBranch[i] == 1)
{
d_BEIDOU_frame_4bytes++;
}
d_BEIDOU_frame_4bytes <<= 1;;
}
for (unsigned int i = 11; i < 15 ; i++)
{
if (firstBranch[i] == 1)
{
d_BEIDOU_frame_4bytes++;
}
d_BEIDOU_frame_4bytes <<= 1;;
}
for (unsigned int i = 11; i < 15 ; i++)
{
if (secondBranch[i] == 1)
{
d_BEIDOU_frame_4bytes++;
}
d_BEIDOU_frame_4bytes <<= 1;;
}
d_BEIDOU_frame_4bytes >>= 1;
}
for (unsigned int i = 0; i < d_bit_buffer->size() ; i++)
{
std::cout << d_bit_buffer->at(i);
}
std::cout << std::endl;
// std::cout << d_BEIDOU_frame_4bytes << std::endl;
}
int beidou_b1i_telemetry_decoder_cc::general_work(int noutput_items __attribute__((unused)), gr_vector_int &ninput_items __attribute__((unused)),
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
{ {
int corr_value = 0; int corr_value = 0;
int preamble_diff_ms = 0; int preamble_diff_ms = 0;
int corr_NH = 0;
Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer Gnss_Synchro **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); // Get the output buffer pointer
const Gnss_Synchro **in = reinterpret_cast<const Gnss_Synchro **>(&input_items[0]); // Get the input buffer pointer const Gnss_Synchro **in = reinterpret_cast<const Gnss_Synchro **>(&input_items[0]); // Get the input buffer pointer
new_sym = false;
Gnss_Synchro current_symbol; //structure to save the synchronization information and send the output object to the next block 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 //1. Copy the current tracking output
current_symbol = in[0][0]; current_symbol = in[0][0];
d_symbol_history.push_back(current_symbol); //add new symbol to the symbol queue double current_time_samples = current_symbol.Tracking_sample_counter;
double current_samples_fs = current_symbol.fs;
int symbol_value = 0;
bool Flag_valid_symbol_output = false;
d_symbol_nh_history.push_back(current_symbol.Prompt_I); //add new symbol to the symbol queue
consume_each(1); consume_each(1);
unsigned int required_symbols = GPS_CA_PREAMBLE_LENGTH_SYMBOLS; if (d_symbol_nh_history.size() == BEIDOU_B1I_NH_CODE_LENGTH)
d_flag_preamble = false; {
for (int i = 0; i < BEIDOU_B1I_NH_CODE_LENGTH; i++)
{
if ((bits_NH[i] * d_symbol_nh_history.at(i)) > 0.0)
{
corr_NH += 1;
}
else
{
corr_NH -= 1;
}
}
if (abs(corr_NH) == BEIDOU_B1I_NH_CODE_LENGTH)
{
sync_NH = true;
if (corr_NH > 0)
{
symbol_value = 1;
}
else
{
symbol_value = -1;
}
// std::cout << "SUCCESSFUL NH CORRELATION" << std::endl;
if ((d_symbol_history.size() > required_symbols) and (d_make_correlation or !d_flag_frame_sync)) d_symbol_history.push_back(symbol_value);
new_sym = true;
d_symbol_nh_history.clear();
}
else
{
d_symbol_nh_history.pop_front();
sync_NH = false;
new_sym = false;
}
}
if ((d_symbol_history.size() >= BEIDOU_B1I_PREAMBLE_LENGTH_BITS) and (d_make_correlation or !d_flag_frame_sync))
{ {
//******* preamble correlation ******** //******* preamble correlation ********
for (unsigned int i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++) for (unsigned int i = 0; i < BEIDOU_B1I_PREAMBLE_LENGTH_BITS; i++)
{ {
if (d_symbol_history.at(i).Flag_valid_symbol_output == true) if (d_symbol_history.at(i) < 0) // symbols clipping
{
if (d_symbol_history.at(i).Prompt_I < 0) // symbols clipping
{ {
corr_value -= d_preambles_symbols[i]; corr_value -= d_preambles_symbols[i];
} }
@ -219,41 +361,69 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__
{ {
corr_value += d_preambles_symbols[i]; corr_value += d_preambles_symbols[i];
} }
}
} }
if (std::abs(corr_value) >= GPS_CA_PREAMBLE_LENGTH_SYMBOLS) //std::cout << corr_value << std::endl;
if (std::abs(corr_value) >= BEIDOU_B1I_PREAMBLE_LENGTH_BITS)
{ {
/* for (unsigned int i = 0; i < d_symbol_history.size() ; i++)
{
std::cout << d_symbol_history.at(i);
}
std::cout << std::endl;
*/
// std::cout << "SUCCESSFUL PREAMBLE CORRELATION" << std::endl;
d_symbol_history.clear();
d_symbol_counter_corr++; d_symbol_counter_corr++;
} }
} }
//******* frame sync ****************** /*if (new_sym and )
if (std::abs(corr_value) == GPS_CA_PREAMBLE_LENGTH_SYMBOLS)
{ {
flag_new_cnav_frame = beidou_nav_msg_decoder_add_symbol(&d_cnav_decoder, symbol_clip, &msg, &delay);
new_sym = false;
}*/
unsigned int required_symbols = BEIDOU_B1I_PREAMBLE_LENGTH_SYMBOLS;
d_flag_preamble = false;
//******* frame sync ******************
if (std::abs(corr_value) == BEIDOU_B1I_PREAMBLE_LENGTH_BITS)
{
// std::cout << "FRAME SYNC" << std::endl;
//TODO: Rewrite with state machine //TODO: Rewrite with state machine
if (d_stat == 0) if (d_stat == 0)
{ {
d_GPS_FSM.Event_gps_word_preamble(); // std::cout << "STATE MACHINE" << std::endl;
d_BEIDOU_FSM.Event_beidou_word_preamble();
//record the preamble sample stamp //record the preamble sample stamp
d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the preamble sample stamp d_preamble_time_samples = current_time_samples; // record the preamble sample stamp
DLOG(INFO) << "Preamble detection for SAT " << this->d_satellite << "d_symbol_history.at(0).Tracking_sample_counter=" << d_symbol_history.at(0).Tracking_sample_counter; DLOG(INFO) << "Preamble detection for SAT " << this->d_satellite << "current_time_samples=" << current_time_samples;
//sync the symbol to bits integrator //sync the symbol to bits integrator
d_symbol_accumulator = 0; d_symbol_accumulator = 0;
d_symbol_accumulator_counter = 0; d_symbol_accumulator_counter = 0;
d_frame_bit_index = 0;
d_stat = 1; // enter into frame pre-detection status d_stat = 1; // enter into frame pre-detection status
} }
else if (d_stat == 1) //check 6 seconds of preamble separation else if (d_stat == 1) //check 6 seconds of preamble separation
{ {
preamble_diff_ms = std::round(((static_cast<double>(d_symbol_history.at(0).Tracking_sample_counter) - d_preamble_time_samples) / static_cast<double>(d_symbol_history.at(0).fs)) * 1000.0); // std::cout << "6 SECONDS" << std::endl;
if (std::abs(preamble_diff_ms - GPS_SUBFRAME_MS) < 1)
preamble_diff_ms = std::round(((static_cast<double>(current_time_samples) - d_preamble_time_samples) / static_cast<double>(current_samples_fs)) * 1000.0);
if (std::abs(preamble_diff_ms - BEIDOU_SUBFRAME_MS) < 1)
{ {
std::cout << "Preamble confirmation for SAT" << std::endl;
DLOG(INFO) << "Preamble confirmation for SAT " << this->d_satellite; DLOG(INFO) << "Preamble confirmation for SAT " << this->d_satellite;
d_GPS_FSM.Event_gps_word_preamble(); d_BEIDOU_FSM.Event_beidou_word_preamble();
d_flag_preamble = true; d_flag_preamble = true;
d_make_correlation = false; d_make_correlation = false;
d_symbol_counter_corr = 0; d_symbol_counter_corr = 0;
d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // record the PRN start sample index associated to the preamble d_preamble_time_samples = current_time_samples; // record the PRN start sample index associated to the preamble
if (!d_flag_frame_sync) if (!d_flag_frame_sync)
{ {
d_flag_frame_sync = true; d_flag_frame_sync = true;
@ -267,22 +437,29 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__
flag_PLL_180_deg_phase_locked = false; flag_PLL_180_deg_phase_locked = false;
} }
DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at "
<< static_cast<double>(d_preamble_time_samples) / static_cast<double>(d_symbol_history.at(0).fs) << " [s]"; << static_cast<double>(d_preamble_time_samples) / static_cast<double>(current_samples_fs) << " [s]";
} }
} }
d_frame_bit_index = 11;
d_symbol_history.clear();
for (int i = 0; i < BEIDOU_B1I_PREAMBLE_LENGTH_BITS; i++)
{
d_bit_buffer.push_back(d_preambles_symbols[i]);
}
word_number = 0;
} }
} }
else else
{ {
d_symbol_counter_corr++; d_symbol_counter_corr++;
if (d_symbol_counter_corr > (GPS_SUBFRAME_MS - GPS_CA_TELEMETRY_SYMBOLS_PER_BIT)) if (d_symbol_counter_corr > (BEIDOU_SUBFRAME_MS - BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT))
{ {
d_make_correlation = true; d_make_correlation = true;
} }
if (d_stat == 1) if (d_stat == 1)
{ {
preamble_diff_ms = round(((static_cast<double>(d_symbol_history.at(0).Tracking_sample_counter) - static_cast<double>(d_preamble_time_samples)) / static_cast<double>(d_symbol_history.at(0).fs)) * 1000.0); preamble_diff_ms = round(((static_cast<double>(current_time_samples) - static_cast<double>(d_preamble_time_samples)) / static_cast<double>(current_samples_fs)) * 1000.0);
if (preamble_diff_ms > GPS_SUBFRAME_MS + 1) if (preamble_diff_ms > BEIDOU_SUBFRAME_MS + 1)
{ {
DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms; DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms;
d_stat = 0; //lost of frame sync d_stat = 0; //lost of frame sync
@ -293,73 +470,52 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__
} }
} }
} }
if (d_flag_frame_sync and new_sym)
//******* SYMBOL TO BIT ******* {
if (d_symbol_history.at(0).Flag_valid_symbol_output == true) // std::cout << symbol_value << std::endl;
{ if (flag_PLL_180_deg_phase_locked)
// 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_bit_buffer.push_back(-symbol_value);
d_symbol_accumulator_counter += d_symbol_history.at(0).correlation_length_ms; }
} else
if (d_symbol_accumulator_counter >= 20) {
{ d_bit_buffer.push_back(symbol_value);
if (d_symbol_accumulator > 0) }
{ //symbol to bit
d_GPS_frame_4bytes += 1; //insert the telemetry bit in LSB
}
d_symbol_accumulator = 0;
d_symbol_accumulator_counter = 0;
//******* bits to words ****** //******* bits to words ******
d_frame_bit_index++; d_frame_bit_index++;
if (d_frame_bit_index == 30) if (d_frame_bit_index == 30)
{ {
word_number++;
beidou_b1i_telemetry_decoder_cc::decode_word(word_number, &d_bit_buffer, d_BEIDOU_frame_4bytes);
// std::cout << d_BEIDOU_frame_4bytes << std::endl;
d_bit_buffer.clear();
d_frame_bit_index = 0; d_frame_bit_index = 0;
// parity check memcpy(&d_BEIDOU_FSM.d_BEIDOU_frame_4bytes, &d_BEIDOU_frame_4bytes, sizeof(char) * 4);
// Each word in wordbuff is composed of: //d_BEIDOU_FSM.d_preamble_time_ms = d_preamble_time_seconds * 1000.0;
// Bits 0 to 29 = the GPS data word d_BEIDOU_FSM.Event_beidou_word_valid();
// Bits 30 to 31 = 2 LSBs of the GPS word ahead.
// prepare the extended frame [-2 -1 0 ... 30]
if (d_prev_GPS_frame_4bytes & 0x00000001)
{
d_GPS_frame_4bytes = d_GPS_frame_4bytes | 0x40000000;
}
if (d_prev_GPS_frame_4bytes & 0x00000002)
{
d_GPS_frame_4bytes = d_GPS_frame_4bytes | 0x80000000;
}
/* Check that the 2 most recently logged words pass parity. Have to first
invert the data bits according to bit 30 of the previous word. */
if (d_GPS_frame_4bytes & 0x40000000)
{
d_GPS_frame_4bytes ^= 0x3FFFFFC0; // invert the data bits (using XOR)
}
if (gps_l1_ca_telemetry_decoder_cc::gps_word_parityCheck(d_GPS_frame_4bytes))
{
memcpy(&d_GPS_FSM.d_GPS_frame_4bytes, &d_GPS_frame_4bytes, sizeof(char) * 4);
//d_GPS_FSM.d_preamble_time_ms = d_preamble_time_seconds * 1000.0;
d_GPS_FSM.Event_gps_word_valid();
// send TLM data to PVT using asynchronous message queues // send TLM data to PVT using asynchronous message queues
if (d_GPS_FSM.d_flag_new_subframe == true) if (d_BEIDOU_FSM.d_flag_new_subframe == true)
{ {
switch (d_GPS_FSM.d_subframe_ID) switch (d_BEIDOU_FSM.d_subframe_ID)
{ {
case 3: //we have a new set of ephemeris data for the current SV case 3: //we have a new set of ephemeris data for the current SV
if (d_GPS_FSM.d_nav.satellite_validation() == true) if (d_BEIDOU_FSM.d_nav.satellite_validation() == true)
{ {
// get ephemeris object for this SV (mandatory) // get ephemeris object for this SV (mandatory)
std::shared_ptr<Gps_Ephemeris> tmp_obj = std::make_shared<Gps_Ephemeris>(d_GPS_FSM.d_nav.get_ephemeris()); std::shared_ptr<Beidou_Ephemeris> tmp_obj = std::make_shared<Beidou_Ephemeris>(d_BEIDOU_FSM.d_nav.get_ephemeris());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
} }
break; break;
case 4: // Possible IONOSPHERE and UTC model update (page 18) case 4: // Possible IONOSPHERE and UTC model update (page 18)
if (d_GPS_FSM.d_nav.flag_iono_valid == true) if (d_BEIDOU_FSM.d_nav.flag_iono_valid == true)
{ {
std::shared_ptr<Gps_Iono> tmp_obj = std::make_shared<Gps_Iono>(d_GPS_FSM.d_nav.get_iono()); std::shared_ptr<Beidou_Iono> tmp_obj = std::make_shared<Beidou_Iono>(d_BEIDOU_FSM.d_nav.get_iono());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
} }
if (d_GPS_FSM.d_nav.flag_utc_model_valid == true) if (d_BEIDOU_FSM.d_nav.flag_utc_model_valid == true)
{ {
std::shared_ptr<Gps_Utc_Model> tmp_obj = std::make_shared<Gps_Utc_Model>(d_GPS_FSM.d_nav.get_utc_model()); std::shared_ptr<Beidou_Utc_Model> tmp_obj = std::make_shared<Beidou_Utc_Model>(d_BEIDOU_FSM.d_nav.get_utc_model());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
} }
break; break;
@ -370,37 +526,22 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__
default: default:
break; break;
} }
d_GPS_FSM.clear_flag_new_subframe(); d_BEIDOU_FSM.clear_flag_new_subframe();
d_flag_new_tow_available = true; d_flag_new_tow_available = true;
} }
d_flag_parity = true;
}
else
{
d_GPS_FSM.Event_gps_word_invalid();
d_flag_parity = false;
}
d_prev_GPS_frame_4bytes = d_GPS_frame_4bytes; // save the actual frame
d_GPS_frame_4bytes = d_GPS_frame_4bytes & 0;
} }
else }
{
d_GPS_frame_4bytes <<= 1; //shift 1 bit left the telemetry word
}
}
//2. Add the telemetry decoder information //2. Add the telemetry decoder information
if (this->d_flag_preamble == true and d_flag_new_tow_available == true) if (this->d_flag_preamble == true and d_flag_new_tow_available == true)
{ {
d_TOW_at_current_symbol_ms = static_cast<unsigned int>(d_GPS_FSM.d_nav.d_TOW) * 1000 + GPS_L1_CA_CODE_PERIOD_MS + GPS_CA_PREAMBLE_DURATION_MS; d_TOW_at_current_symbol_ms = static_cast<unsigned int>(d_BEIDOU_FSM.d_nav.d_SOW) * 1000 + BEIDOU_B1I_CODE_PERIOD_MS + BEIDOU_B1I_PREAMBLE_DURATION_MS;
d_TOW_at_Preamble_ms = d_TOW_at_current_symbol_ms; d_TOW_at_Preamble_ms = d_TOW_at_current_symbol_ms;
flag_TOW_set = true; flag_TOW_set = true;
d_flag_new_tow_available = false; d_flag_new_tow_available = false;
} }
else else
{ {
d_TOW_at_current_symbol_ms += GPS_L1_CA_CODE_PERIOD_MS; d_TOW_at_current_symbol_ms += BEIDOU_B1I_CODE_PERIOD_MS;
} }
current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms;
@ -409,7 +550,7 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__
if (flag_PLL_180_deg_phase_locked == true) if (flag_PLL_180_deg_phase_locked == true)
{ {
//correct the accumulated phase for the Costas loop phase shift, if required //correct the accumulated phase for the Costas loop phase shift, if required
current_symbol.Carrier_phase_rads += GPS_PI; current_symbol.Carrier_phase_rads += BEIDOU_PI;
} }
if (d_dump == true) if (d_dump == true)

View File

@ -1,8 +1,8 @@
/*! /*!
* \file gps_l1_ca_telemetry_decoder_cc.h * \file beidou_b1i_telemetry_decoder_cc.h
* \brief Interface of a NAV message demodulator block based on * \brief Interface of a NAV message demodulator block based on
* Kay Borre book MATLAB-based GPS receiver * Kay Borre book MATLAB-based GPS receiver
* \author Javier Arribas, 2011. jarribas(at)cttc.es * \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
* *
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
@ -28,11 +28,11 @@
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
#ifndef GNSS_SDR_GPS_L1_CA_TELEMETRY_DECODER_CC_H #ifndef GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_CC_H
#define GNSS_SDR_GPS_L1_CA_TELEMETRY_DECODER_CC_H #define GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_CC_H
#include "GPS_L1_CA.h" #include "beidou_b1I.h"
#include "gps_l1_ca_subframe_fsm.h" #include "beidou_b1i_subframe_fsm.h"
#include "gnss_satellite.h" #include "gnss_satellite.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include <gnuradio/block.h> #include <gnuradio/block.h>
@ -40,23 +40,25 @@
#include <string> #include <string>
#include <boost/circular_buffer.hpp> #include <boost/circular_buffer.hpp>
class gps_l1_ca_telemetry_decoder_cc; class beidou_b1i_telemetry_decoder_cc;
typedef boost::shared_ptr<gps_l1_ca_telemetry_decoder_cc> gps_l1_ca_telemetry_decoder_cc_sptr; typedef boost::shared_ptr<beidou_b1i_telemetry_decoder_cc> beidou_b1i_telemetry_decoder_cc_sptr;
gps_l1_ca_telemetry_decoder_cc_sptr beidou_b1i_telemetry_decoder_cc_sptr
gps_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); beidou_b1i_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump);
/*! /*!
* \brief This class implements a block that decodes the NAV data defined in IS-GPS-200E * \brief This class implements a block that decodes the NAV data defined in IS-GPS-200E
* *
*/ */
class gps_l1_ca_telemetry_decoder_cc : public gr::block class beidou_b1i_telemetry_decoder_cc : public gr::block
{ {
public: public:
~gps_l1_ca_telemetry_decoder_cc(); ~beidou_b1i_telemetry_decoder_cc();
void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN void set_satellite(const Gnss_Satellite &satellite); //!< Set satellite PRN
void set_channel(int channel); //!< Set receiver's channel void set_channel(int channel);
void decode_word(int word_counter, boost::circular_buffer<signed int> *d_bit_buffer, unsigned int& d_BEIDOU_frame_4bytes);
/*! /*!
* \brief This is where all signal processing takes place * \brief This is where all signal processing takes place
@ -65,12 +67,12 @@ public:
gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
private: private:
friend gps_l1_ca_telemetry_decoder_cc_sptr friend beidou_b1i_telemetry_decoder_cc_sptr
gps_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); beidou_b1i_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump);
gps_l1_ca_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); beidou_b1i_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump);
bool gps_word_parityCheck(unsigned int gpsword); bool beidou_word_parityCheck(unsigned int beidouword);
// class private vars // class private vars
@ -79,7 +81,9 @@ private:
bool d_flag_frame_sync; bool d_flag_frame_sync;
// symbols // symbols
boost::circular_buffer<Gnss_Synchro> d_symbol_history; boost::circular_buffer<signed int> d_symbol_history;
boost::circular_buffer<signed int> d_symbol_nh_history;
boost::circular_buffer<signed int> d_bit_buffer;
double d_symbol_accumulator; double d_symbol_accumulator;
short int d_symbol_accumulator_counter; short int d_symbol_accumulator_counter;
@ -90,16 +94,17 @@ private:
//bits and frame //bits and frame
unsigned short int d_frame_bit_index; unsigned short int d_frame_bit_index;
unsigned int d_GPS_frame_4bytes; double bits_NH[BEIDOU_B1I_NH_CODE_LENGTH];
unsigned int d_prev_GPS_frame_4bytes; unsigned int d_BEIDOU_frame_4bytes;
unsigned int d_prev_BEIDOU_frame_4bytes;
bool d_flag_parity; bool d_flag_parity;
bool d_flag_preamble; bool d_flag_preamble;
bool d_flag_new_tow_available; bool d_flag_new_tow_available;
int d_word_number; int d_word_number;
// navigation message vars // navigation message vars
Gps_Navigation_Message d_nav; Beidou_Navigation_Message_D1 d_nav;
GpsL1CaSubframeFsm d_GPS_FSM; BeidouB1iSubframeFsm d_BEIDOU_FSM;
bool d_dump; bool d_dump;
Gnss_Satellite d_satellite; Gnss_Satellite d_satellite;
@ -109,12 +114,15 @@ private:
unsigned int d_TOW_at_Preamble_ms; unsigned int d_TOW_at_Preamble_ms;
unsigned int d_TOW_at_current_symbol_ms; unsigned int d_TOW_at_current_symbol_ms;
unsigned int word_number;
bool flag_TOW_set; bool flag_TOW_set;
bool flag_PLL_180_deg_phase_locked; bool flag_PLL_180_deg_phase_locked;
std::string d_dump_filename; std::string d_dump_filename;
std::ofstream d_dump_file; std::ofstream d_dump_file;
bool sync_NH;
bool new_sym;
}; };
#endif #endif

View File

@ -19,7 +19,8 @@
add_subdirectory(libswiftcnav) add_subdirectory(libswiftcnav)
set(TELEMETRY_DECODER_LIB_SOURCES set(TELEMETRY_DECODER_LIB_SOURCES
gps_l1_ca_subframe_fsm.cc gps_l1_ca_subframe_fsm.cc
beidou_b1i_subframe_fsm.cc
viterbi_decoder.cc viterbi_decoder.cc
) )

View File

@ -0,0 +1,289 @@
/*!
* \file beidou_b1i_subframe_fsm.cc
* \brief Implementation of a BEIDOU NAV message word-to-subframe decoder state machine
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "beidou_b1i_subframe_fsm.h"
#include "gnss_satellite.h"
#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 <cstring>
#include <iostream>
//************ GPS WORD TO SUBFRAME DECODER STATE MACHINE **********
struct Ev_beidou_word_valid : sc::event<Ev_beidou_word_valid>
{
};
struct Ev_beidou_word_invalid : sc::event<Ev_beidou_word_invalid>
{
};
struct Ev_beidou_word_preamble : sc::event<Ev_beidou_word_preamble>
{
};
struct beidou_subframe_fsm_S0 : public sc::state<beidou_subframe_fsm_S0, BeidouB1iSubframeFsm>
{
public:
// sc::transition(event,next_status)
typedef sc::transition<Ev_beidou_word_preamble, beidou_subframe_fsm_S1> reactions;
beidou_subframe_fsm_S0(my_context ctx) : my_base(ctx)
{
//std::cout<<"Enter S0 "<<std::endl;
}
};
struct beidou_subframe_fsm_S1 : public sc::state<beidou_subframe_fsm_S1, BeidouB1iSubframeFsm>
{
public:
typedef mpl::list<sc::transition<Ev_beidou_word_invalid, beidou_subframe_fsm_S0>,
sc::transition<Ev_beidou_word_valid, beidou_subframe_fsm_S2> >
reactions;
beidou_subframe_fsm_S1(my_context ctx) : my_base(ctx)
{
//std::cout<<"Enter S1 "<<std::endl;
}
};
struct beidou_subframe_fsm_S2 : public sc::state<beidou_subframe_fsm_S2, BeidouB1iSubframeFsm>
{
public:
typedef mpl::list<sc::transition<Ev_beidou_word_invalid, beidou_subframe_fsm_S0>,
sc::transition<Ev_beidou_word_valid, beidou_subframe_fsm_S3> >
reactions;
beidou_subframe_fsm_S2(my_context ctx) : my_base(ctx)
{
//std::cout<<"Enter S2 "<<std::endl;
context<BeidouB1iSubframeFsm>().beidou_word_to_subframe(0);
}
};
struct beidou_subframe_fsm_S3 : public sc::state<beidou_subframe_fsm_S3, BeidouB1iSubframeFsm>
{
public:
typedef mpl::list<sc::transition<Ev_beidou_word_invalid, beidou_subframe_fsm_S0>,
sc::transition<Ev_beidou_word_valid, beidou_subframe_fsm_S4> >
reactions;
beidou_subframe_fsm_S3(my_context ctx) : my_base(ctx)
{
//std::cout<<"Enter S3 "<<std::endl;
context<BeidouB1iSubframeFsm>().beidou_word_to_subframe(1);
}
};
struct beidou_subframe_fsm_S4 : public sc::state<beidou_subframe_fsm_S4, BeidouB1iSubframeFsm>
{
public:
typedef mpl::list<sc::transition<Ev_beidou_word_invalid, beidou_subframe_fsm_S0>,
sc::transition<Ev_beidou_word_valid, beidou_subframe_fsm_S5> >
reactions;
beidou_subframe_fsm_S4(my_context ctx) : my_base(ctx)
{
//std::cout<<"Enter S4 "<<std::endl;
context<BeidouB1iSubframeFsm>().beidou_word_to_subframe(2);
}
};
struct beidou_subframe_fsm_S5 : public sc::state<beidou_subframe_fsm_S5, BeidouB1iSubframeFsm>
{
public:
typedef mpl::list<sc::transition<Ev_beidou_word_invalid, beidou_subframe_fsm_S0>,
sc::transition<Ev_beidou_word_valid, beidou_subframe_fsm_S6> >
reactions;
beidou_subframe_fsm_S5(my_context ctx) : my_base(ctx)
{
//std::cout<<"Enter S5 "<<std::endl;
context<BeidouB1iSubframeFsm>().beidou_word_to_subframe(3);
}
};
struct beidou_subframe_fsm_S6 : public sc::state<beidou_subframe_fsm_S6, BeidouB1iSubframeFsm>
{
public:
typedef mpl::list<sc::transition<Ev_beidou_word_invalid, beidou_subframe_fsm_S0>,
sc::transition<Ev_beidou_word_valid, beidou_subframe_fsm_S7> >
reactions;
beidou_subframe_fsm_S6(my_context ctx) : my_base(ctx)
{
//std::cout<<"Enter S6 "<<std::endl;
context<BeidouB1iSubframeFsm>().beidou_word_to_subframe(4);
}
};
struct beidou_subframe_fsm_S7 : public sc::state<beidou_subframe_fsm_S7, BeidouB1iSubframeFsm>
{
public:
typedef mpl::list<sc::transition<Ev_beidou_word_invalid, beidou_subframe_fsm_S0>,
sc::transition<Ev_beidou_word_valid, beidou_subframe_fsm_S8> >
reactions;
beidou_subframe_fsm_S7(my_context ctx) : my_base(ctx)
{
//std::cout<<"Enter S7 "<<std::endl;
context<BeidouB1iSubframeFsm>().beidou_word_to_subframe(5);
}
};
struct beidou_subframe_fsm_S8 : public sc::state<beidou_subframe_fsm_S8, BeidouB1iSubframeFsm>
{
public:
typedef mpl::list<sc::transition<Ev_beidou_word_invalid, beidou_subframe_fsm_S0>,
sc::transition<Ev_beidou_word_valid, beidou_subframe_fsm_S9> >
reactions;
beidou_subframe_fsm_S8(my_context ctx) : my_base(ctx)
{
//std::cout<<"Enter S8 "<<std::endl;
context<BeidouB1iSubframeFsm>().beidou_word_to_subframe(6);
}
};
struct beidou_subframe_fsm_S9 : public sc::state<beidou_subframe_fsm_S9, BeidouB1iSubframeFsm>
{
public:
typedef mpl::list<sc::transition<Ev_beidou_word_invalid, beidou_subframe_fsm_S0>,
sc::transition<Ev_beidou_word_valid, beidou_subframe_fsm_S10> >
reactions;
beidou_subframe_fsm_S9(my_context ctx) : my_base(ctx)
{
//std::cout<<"Enter S9 "<<std::endl;
context<BeidouB1iSubframeFsm>().beidou_word_to_subframe(7);
}
};
struct beidou_subframe_fsm_S10 : public sc::state<beidou_subframe_fsm_S10, BeidouB1iSubframeFsm>
{
public:
typedef mpl::list<sc::transition<Ev_beidou_word_invalid, beidou_subframe_fsm_S0>,
sc::transition<Ev_beidou_word_valid, beidou_subframe_fsm_S11> >
reactions;
beidou_subframe_fsm_S10(my_context ctx) : my_base(ctx)
{
//std::cout<<"Enter S10 "<<std::endl;
context<BeidouB1iSubframeFsm>().beidou_word_to_subframe(8);
}
};
struct beidou_subframe_fsm_S11 : public sc::state<beidou_subframe_fsm_S11, BeidouB1iSubframeFsm>
{
public:
typedef sc::transition<Ev_beidou_word_preamble, beidou_subframe_fsm_S1> reactions;
beidou_subframe_fsm_S11(my_context ctx) : my_base(ctx)
{
//std::cout<<"Completed GPS Subframe!"<<std::endl;
context<BeidouB1iSubframeFsm>().beidou_word_to_subframe(9);
context<BeidouB1iSubframeFsm>().beidou_subframe_to_nav_msg(); //decode the subframe
// DECODE SUBFRAME
//std::cout<<"Enter S11"<<std::endl;
}
};
BeidouB1iSubframeFsm::BeidouB1iSubframeFsm()
{
d_nav.reset();
i_channel_ID = 0;
i_satellite_PRN = 0;
d_subframe_ID = 0;
d_flag_new_subframe = false;
initiate(); //start the FSM
}
void BeidouB1iSubframeFsm::beidou_word_to_subframe(int position)
{
// insert the word in the correct position of the subframe
std::memcpy(&d_subframe[position * BEIDOU_WORD_LENGTH], &d_BEIDOU_frame_4bytes, sizeof(char) * BEIDOU_WORD_LENGTH);
}
void BeidouB1iSubframeFsm::clear_flag_new_subframe()
{
d_flag_new_subframe = false;
}
void BeidouB1iSubframeFsm::beidou_subframe_to_nav_msg()
{
//int subframe_ID;
// NEW GPS SUBFRAME HAS ARRIVED!
d_subframe_ID = d_nav.subframe_decoder(this->d_subframe); //decode the subframe
std::cout << "New BEIDOU NAV message received in channel " << i_channel_ID << ": "
<< "subframe "
<< d_subframe_ID << " from satellite "
<< Gnss_Satellite(std::string("Beidou"), i_satellite_PRN) << std::endl;
d_nav.i_satellite_PRN = i_satellite_PRN;
d_nav.i_channel_ID = i_channel_ID;
d_flag_new_subframe = true;
}
void BeidouB1iSubframeFsm::Event_beidou_word_valid()
{
this->process_event(Ev_beidou_word_valid());
}
void BeidouB1iSubframeFsm::Event_beidou_word_invalid()
{
this->process_event(Ev_beidou_word_invalid());
}
void BeidouB1iSubframeFsm::Event_beidou_word_preamble()
{
this->process_event(Ev_beidou_word_preamble());
}

View File

@ -0,0 +1,100 @@
/*!
* \file gps_l1_ca_subframe_fsm.h
* \brief Interface of a BEIDOU NAV message word-to-subframe decoder state machine
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_BEIDOU_B1I_SUBFRAME_FSM_H_
#define GNSS_SDR_BEIDOU_B1I_SUBFRAME_FSM_H_
#include "beidou_b1I.h"
#include "beidou_navigation_message.h"
#include "beidou_ephemeris.h"
#include "beidou_iono.h"
#include "beidou_almanac.h"
#include "beidou_utc_model.h"
#include <boost/statechart/state_machine.hpp>
namespace sc = boost::statechart;
namespace mpl = boost::mpl;
struct beidou_subframe_fsm_S0;
struct beidou_subframe_fsm_S1;
struct beidou_subframe_fsm_S2;
struct beidou_subframe_fsm_S3;
struct beidou_subframe_fsm_S4;
struct beidou_subframe_fsm_S5;
struct beidou_subframe_fsm_S6;
struct beidou_subframe_fsm_S7;
struct beidou_subframe_fsm_S8;
struct beidou_subframe_fsm_S9;
struct beidou_subframe_fsm_S10;
struct beidou_subframe_fsm_S11;
/*!
* \brief This class implements a Finite State Machine that handles the decoding
* of the GPS L1 C/A NAV message
*/
class BeidouB1iSubframeFsm : public sc::state_machine<BeidouB1iSubframeFsm, beidou_subframe_fsm_S0>
{
public:
BeidouB1iSubframeFsm(); //!< The constructor starts the Finite State Machine
void clear_flag_new_subframe();
// channel and satellite info
int i_channel_ID; //!< Channel id
unsigned int i_satellite_PRN; //!< Satellite PRN number
Beidou_Navigation_Message_D1 d_nav; //!< GPS L1 C/A navigation message object
// GPS SV and System parameters
Beidou_Ephemeris ephemeris; //!< Object that handles GPS ephemeris parameters
Beidou_Almanac almanac; //!< Object that handles GPS almanac data
Beidou_Utc_Model utc_model; //!< Object that handles UTM model parameters
Beidou_Iono iono; //!< Object that handles ionospheric parameters
char d_subframe[BEIDOU_SUBFRAME_LENGTH];
int d_subframe_ID;
bool d_flag_new_subframe;
char d_BEIDOU_frame_4bytes[BEIDOU_WORD_LENGTH];
//double d_preamble_time_ms;
void beidou_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 beidou_subframe_to_nav_msg();
//FSM EVENTS
void Event_beidou_word_valid(); //!< FSM event: the received word is valid
void Event_beidou_word_invalid(); //!< FSM event: the received word is not valid
void Event_beidou_word_preamble(); //!< FSM event: word preamble detected
};
#endif

View File

@ -254,9 +254,12 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(dllpllconf_t conf_) : gr::block("dl
d_symbols_per_bit = BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT; d_symbols_per_bit = BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT;
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_code_samples_per_chip = 1; d_code_samples_per_chip = 1;
d_secondary = false; d_secondary = true;
trk_parameters.track_pilot = false; trk_parameters.track_pilot = false;
interchange_iq = false; interchange_iq = false;
d_secondary_code_length = static_cast<unsigned int>(BEIDOU_B1I_NH_CODE_LENGTH);
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_NH_CODE_STR);
} }
else else
{ {

View File

@ -1712,7 +1712,7 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
} }
else if (implementation.compare("BEIDOU_B1I_Telemetry_Decoder") == 0) else if (implementation.compare("BEIDOU_B1I_Telemetry_Decoder") == 0)
{ {
std::unique_ptr<GNSSBlockInterface> block_(new GpsL1CaTelemetryDecoder(configuration.get(), role, in_streams, std::unique_ptr<GNSSBlockInterface> block_(new BeidouB1iTelemetryDecoder(configuration.get(), role, in_streams,
out_streams)); out_streams));
block = std::move(block_); block = std::move(block_);
} }
@ -2061,7 +2061,7 @@ std::unique_ptr<TelemetryDecoderInterface> GNSSBlockFactory::GetTlmBlock(
} }
else if (implementation.compare("BEIDOU_B1I_Telemetry_Decoder") == 0) else if (implementation.compare("BEIDOU_B1I_Telemetry_Decoder") == 0)
{ {
std::unique_ptr<TelemetryDecoderInterface> block_(new GpsL1CaTelemetryDecoder(configuration.get(), role, in_streams, std::unique_ptr<TelemetryDecoderInterface> block_(new BeidouB1iTelemetryDecoder(configuration.get(), role, in_streams,
out_streams)); out_streams));
block = std::move(block_); block = std::move(block_);
} }

Binary file not shown.

View File

@ -32,6 +32,11 @@ set(SYSTEM_PARAMETERS_SOURCES
galileo_almanac.cc galileo_almanac.cc
galileo_iono.cc galileo_iono.cc
galileo_navigation_message.cc galileo_navigation_message.cc
beidou_navigation_message.cc
beidou_ephemeris.cc
beidou_iono.cc
beidou_almanac.cc
beidou_utc_model.cc
sbas_ephemeris.cc sbas_ephemeris.cc
galileo_fnav_message.cc galileo_fnav_message.cc
gps_cnav_ephemeris.cc gps_cnav_ephemeris.cc

View File

@ -0,0 +1,49 @@
/*!
* \file gps_almanac.cc
* \brief Interface of a BEIDOU ALMANAC storage
*
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
* \author Sergi Segura, 2018. sergi.segura.munoz(at)gmail.com
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "beidou_almanac.h"
Beidou_Almanac::Beidou_Almanac()
{
i_satellite_PRN = 0;
d_Delta_i = 0.0;
d_Toa = 0.0;
d_M_0 = 0.0;
d_e_eccentricity = 0.0;
d_sqrt_A = 0.0;
d_OMEGA0 = 0.0;
d_OMEGA = 0.0;
d_OMEGA_DOT = 0.0;
i_SV_health = 0;
d_A_f0 = 0.0;
d_A_f1 = 0.0;
}

View File

@ -0,0 +1,63 @@
/*!
* \file gps_almanac.h
* \brief Interface of a GPS ALMANAC storage
* \author Javier Arribas, 2013. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_BEIDOU_ALMANAC_H_
#define GNSS_SDR_BEIDOU_ALMANAC_H_
/*!
* \brief This class is a storage for the GPS SV ALMANAC data as described in IS-GPS-200E
*
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
*/
class Beidou_Almanac
{
public:
unsigned int i_satellite_PRN; //!< SV PRN NUMBER
double d_Delta_i;
double d_Toa; //!< Almanac data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
double d_M_0; //!< Mean Anomaly at Reference Time [semi-circles]
double d_e_eccentricity; //!< Eccentricity [dimensionless]
double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)]
double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
double d_OMEGA; //!< Argument of Perigee [semi-cicles]
double d_OMEGA_DOT; //!< Rate of Right Ascension [semi-circles/s]
int i_SV_health; // SV Health
double d_A_f0; //!< Coefficient 0 of code phase offset model [s]
double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s]
/*!
* Default constructor
*/
Beidou_Almanac();
};
#endif

View File

@ -51,6 +51,7 @@ const double BEIDOU_B1I_FREQ_HZ = 1.561098e9; //!< b1I [Hz]
const double BEIDOU_B1I_CODE_RATE_HZ = 2.046e6; //!< beidou b1I code rate [chips/s] const double BEIDOU_B1I_CODE_RATE_HZ = 2.046e6; //!< beidou b1I code rate [chips/s]
const double BEIDOU_B1I_CODE_LENGTH_CHIPS = 2046.0; //!< beidou b1I code length [chips] const double BEIDOU_B1I_CODE_LENGTH_CHIPS = 2046.0; //!< beidou b1I code length [chips]
const double BEIDOU_B1I_CODE_PERIOD = 0.001; //!< beidou b1I code period [seconds] const double BEIDOU_B1I_CODE_PERIOD = 0.001; //!< beidou b1I code period [seconds]
const unsigned int BEIDOU_B1I_CODE_PERIOD_MS = 1; //!< GPS L1 C/A code period [ms]
const double BEIDOU_B1I_CHIP_PERIOD = 4.8875e-07; //!< beidou b1I chip period [seconds] const double BEIDOU_B1I_CHIP_PERIOD = 4.8875e-07; //!< beidou b1I chip period [seconds]
/*! /*!
@ -74,7 +75,9 @@ const int BEIDOU_B1I_HISTORY_DEEP = 100; // ****************
#define BEIDOU_PREAMBLE {1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0} #define BEIDOU_PREAMBLE {1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0}
const int BEIDOU_B1I_PREAMBLE_LENGTH_BITS = 11; const int BEIDOU_B1I_PREAMBLE_LENGTH_BITS = 11;
const int BEIDOU_B1I_PREAMBLE_LENGTH_SYMBOLS = 160; // ************** const int BEIDOU_B1I_PREAMBLE_LENGTH_SYMBOLS = 220; // **************
const double BEIDOU_B1I_PREAMBLE_DURATION_S = 0.220;
const int BEIDOU_B1I_PREAMBLE_DURATION_MS = 220;
const int BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND = 50; //!< D1 NAV message bit rate [bits/s] const int BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND = 50; //!< D1 NAV message bit rate [bits/s]
const int BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT = 20; // ************* const int BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT = 20; // *************
const int BEIDOU_B1I_TELEMETRY_RATE_SYMBOLS_SECOND = BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND*BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT; //************!< NAV message bit rate [symbols/s] const int BEIDOU_B1I_TELEMETRY_RATE_SYMBOLS_SECOND = BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND*BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT; //************!< NAV message bit rate [symbols/s]
@ -84,6 +87,9 @@ const int BEIDOU_SUBFRAME_BITS = 300; //!< Number of bits per s
const int BEIDOU_SUBFRAME_SECONDS = 6; //!< Subframe duration [seconds] const int BEIDOU_SUBFRAME_SECONDS = 6; //!< Subframe duration [seconds]
const int BEIDOU_SUBFRAME_MS = 6000; //!< Subframe duration [miliseconds] const int BEIDOU_SUBFRAME_MS = 6000; //!< Subframe duration [miliseconds]
const int BEIDOU_WORD_BITS = 30; //!< Number of bits per word in the NAV message [bits] const int BEIDOU_WORD_BITS = 30; //!< Number of bits per word in the NAV message [bits]
const int BEIDOU_B1I_NH_CODE_LENGTH = 20;
const int BEIDOU_B1I_NH_CODE[20] = {0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0};
const std::string BEIDOU_B1I_NH_CODE_STR = "00000100110101001110";
// BEIDOU D1 NAVIGATION MESSAGE STRUCTURE // BEIDOU D1 NAVIGATION MESSAGE STRUCTURE
@ -91,6 +97,8 @@ const int BEIDOU_WORD_BITS = 30; //!< Number of bits per w
const std::vector<std::pair<int,int> > D1_PRE( { {1,11} } ); const std::vector<std::pair<int,int> > D1_PRE( { {1,11} } );
const std::vector<std::pair<int,int> > D1_FRAID( { {16,3} } ); const std::vector<std::pair<int,int> > D1_FRAID( { {16,3} } );
const std::vector<std::pair<int,int> > D1_SOW( { {19,8},{31,12} } ); const std::vector<std::pair<int,int> > D1_SOW( { {19,8},{31,12} } );
const std::vector<std::pair<int,int> > D1_PNUM( { {44,7} } );
// SUBFRAME 1 // SUBFRAME 1
const std::vector<std::pair<int,int> > D1_SAT_H1( { {43,1} } ); const std::vector<std::pair<int,int> > D1_SAT_H1( { {43,1} } );
const std::vector<std::pair<int,int> > D1_AODC( { {44,5} } ); const std::vector<std::pair<int,int> > D1_AODC( { {44,5} } );

View File

@ -60,10 +60,10 @@ Beidou_Ephemeris::Beidou_Ephemeris()
i_SV_health = 0; i_SV_health = 0;
d_AODE = 0; d_AODE = 0;
d_TGD1 = 0; d_TGD1 = 0;
d_TGD2 = 0: d_TGD2 = 0;
d_AODC = 0; // Issue of Data, Clock d_AODC = 0; // Issue of Data, Clock
i_AODO = 0; // Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] i_AODO = 0; // Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s]
d_AODC = 0;
b_fit_interval_flag = false; // indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours. b_fit_interval_flag = false; // indicates the curve-fit interval used by the CS (Block II/IIA/IIR/IIR-M/IIF) and SS (Block IIIA) in determining the ephemeris parameters, as follows: 0 = 4 hours, 1 = greater than 4 hours.
d_spare1 = 0; d_spare1 = 0;
d_spare2 = 0; d_spare2 = 0;

View File

@ -155,10 +155,10 @@ public:
archive & make_nvp("d_OMEGA", d_OMEGA); //!< Argument of Perigee [semi-cicles] archive & make_nvp("d_OMEGA", d_OMEGA); //!< Argument of Perigee [semi-cicles]
archive & make_nvp("d_OMEGA_DOT", d_OMEGA_DOT); //!< Rate of Right Ascension [semi-circles/s] archive & make_nvp("d_OMEGA_DOT", d_OMEGA_DOT); //!< Rate of Right Ascension [semi-circles/s]
archive & make_nvp("d_IDOT", d_IDOT); //!< Rate of Inclination Angle [semi-circles/s] archive & make_nvp("d_IDOT", d_IDOT); //!< Rate of Inclination Angle [semi-circles/s]
archive & make_nvp("i_BEIDOU_week", i_GPS_week); //!< GPS week number, aka WN [week] archive & make_nvp("i_BEIDOU_week", i_BEIDOU_week); //!< GPS week number, aka WN [week]
archive & make_nvp("i_SV_accuracy", i_SV_accuracy); //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200E) archive & make_nvp("i_SV_accuracy", i_SV_accuracy); //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200E)
archive & make_nvp("i_SV_health", i_SV_health); archive & make_nvp("i_SV_health", i_SV_health);
archive & make_nvp("d_IODC", d_IODC); //!< Issue of Data, Clock archive & make_nvp("d_AODC", d_AODC); //!< Issue of Data, Clock
archive & make_nvp("d_TGD1", d_TGD1); //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s] archive & make_nvp("d_TGD1", d_TGD1); //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s]
archive & make_nvp("d_TGD2", d_TGD2); //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s] archive & make_nvp("d_TGD2", d_TGD2); //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s]
archive & make_nvp("i_AODO", i_AODO); //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s] archive & make_nvp("i_AODO", i_AODO); //!< Age of Data Offset (AODO) term for the navigation message correction table (NMCT) contained in subframe 4 (reference paragraph 20.3.3.5.1.9) [s]
@ -199,7 +199,7 @@ public:
/*! /*!
* Default constructor * Default constructor
*/ */
Gps_Ephemeris(); Beidou_Ephemeris();
}; };
#endif #endif

View File

@ -35,15 +35,15 @@ m * \file beidou_navigation_message.cc
#include <gnss_satellite.h> #include <gnss_satellite.h>
void Beidou_Navigation_Message::reset() void Beidou_Navigation_Message_D1::reset()
{ {
b_valid_ephemeris_set_flag = false; b_valid_ephemeris_set_flag = false;
d_TOW = 0; d_SOW = 0;
d_TOW_SF1 = 0; d_SOW_SF1 = 0;
d_TOW_SF2 = 0; d_SOW_SF2 = 0;
d_TOW_SF3 = 0; d_SOW_SF3 = 0;
d_TOW_SF4 = 0; d_SOW_SF4 = 0;
d_TOW_SF5 = 0; d_SOW_SF5 = 0;
d_AODE = 0; d_AODE = 0;
d_Crs = 0; d_Crs = 0;
d_Delta_n = 0; d_Delta_n = 0;
@ -65,7 +65,8 @@ void Beidou_Navigation_Message::reset()
i_BEIDOU_week = 0; i_BEIDOU_week = 0;
i_SV_accuracy = 0; i_SV_accuracy = 0;
i_SV_health = 0; i_SV_health = 0;
d_TGD = 0; d_TGD1 = 0;
d_TGD2 = 0;
d_AODC = -1; d_AODC = -1;
// i_AODO = 0; // i_AODO = 0;
@ -111,8 +112,8 @@ void Beidou_Navigation_Message::reset()
d_beta1 = 0; d_beta1 = 0;
d_beta2 = 0; d_beta2 = 0;
d_beta3 = 0; d_beta3 = 0;
d_A1 = 0; d_A1UTC = 0;
d_A0 = 0; d_A0UTC = 0;
d_t_OT = 0; d_t_OT = 0;
i_WN_T = 0; i_WN_T = 0;
d_DeltaT_LS = 0; d_DeltaT_LS = 0;
@ -132,6 +133,28 @@ void Beidou_Navigation_Message::reset()
d_satvel_X = 0; d_satvel_X = 0;
d_satvel_Y = 0; d_satvel_Y = 0;
d_satvel_Z = 0; d_satvel_Z = 0;
d_A1GPS = 0;
d_A0GPS = 0;
d_A1GAL = 0;
d_A0GAL = 0;
d_A1GLO = 0;
d_A0GLO = 0;
d_AODE_SF1 = 0;
d_SQRT_A_ALMANAC = 0;
d_A1_ALMANAC = 0;
d_A0_ALMANAC = 0;
d_OMEGA0_ALMANAC = 0;
d_E_ALMANAC = 0;
d_DELTA_I = 0;
d_TOA = 0;
d_OMEGA_DOT_ALMANAC = 0;
d_OMEGA_ALMANAC = 0;
d_M0_ALMANAC = 0;
almanac_WN = 0;
d_toa2 = 0;
d_A0 = 0;
d_A1 = 0;
d_A2 = 0;
auto gnss_sat = Gnss_Satellite(); auto gnss_sat = Gnss_Satellite();
std::string _system ("Beidou"); std::string _system ("Beidou");
@ -143,14 +166,14 @@ void Beidou_Navigation_Message::reset()
Beidou_Navigation_Message::Gps_Navigation_Message() Beidou_Navigation_Message_D1::Beidou_Navigation_Message_D1()
{ {
reset(); reset();
} }
void Beidou_Navigation_Message::print_beidou_word_bytes(unsigned int BEIDOU_word) void Beidou_Navigation_Message_D1::print_beidou_word_bytes(unsigned int BEIDOU_word)
{ {
std::cout << " Word ="; std::cout << " Word =";
std::cout << std::bitset<32>(BEIDOU_word); std::cout << std::bitset<32>(BEIDOU_word);
@ -159,7 +182,7 @@ void Beidou_Navigation_Message::print_beidou_word_bytes(unsigned int BEIDOU_word
bool Beidou_Navigation_Message::read_navigation_bool(std::bitset<BEIDOU_SUBFRAME_BITS> bits, const std::vector<std::pair<int,int>> parameter) bool Beidou_Navigation_Message_D1::read_navigation_bool(std::bitset<BEIDOU_SUBFRAME_BITS> bits, const std::vector<std::pair<int,int>> parameter)
{ {
bool value; bool value;
@ -175,7 +198,7 @@ bool Beidou_Navigation_Message::read_navigation_bool(std::bitset<BEIDOU_SUBFRAME
} }
unsigned long int Beidou_Navigation_Message::read_navigation_unsigned(std::bitset<BEIDOU_SUBFRAME_BITS> bits, const std::vector<std::pair<int,int>> parameter) unsigned long int Beidou_Navigation_Message_D1::read_navigation_unsigned(std::bitset<BEIDOU_SUBFRAME_BITS> bits, const std::vector<std::pair<int,int>> parameter)
{ {
unsigned long int value = 0; unsigned long int value = 0;
int num_of_slices = parameter.size(); int num_of_slices = parameter.size();
@ -193,7 +216,7 @@ unsigned long int Beidou_Navigation_Message::read_navigation_unsigned(std::bitse
return value; return value;
} }
signed long int Beidou_Navigation_Message::read_navigation_signed(std::bitset<BEIDOU_SUBFRAME_BITS> bits, const std::vector<std::pair<int,int>> parameter) signed long int Beidou_Navigation_Message_D1::read_navigation_signed(std::bitset<BEIDOU_SUBFRAME_BITS> bits, const std::vector<std::pair<int,int>> parameter)
{ {
signed long int value = 0; signed long int value = 0;
int num_of_slices = parameter.size(); int num_of_slices = parameter.size();
@ -252,7 +275,7 @@ signed long int Beidou_Navigation_Message::read_navigation_signed(std::bitset<BE
return value; return value;
} }
double Beidou_Navigation_Message::check_t(double time) double Beidou_Navigation_Message_D1::check_t(double time)
{ {
double corrTime; double corrTime;
double half_week = 302400; // seconds double half_week = 302400; // seconds
@ -269,7 +292,7 @@ double Beidou_Navigation_Message::check_t(double time)
} }
// User Algorithm for SV Clock Correction. // User Algorithm for SV Clock Correction.
double Beidou_Navigation_Message::sv_clock_correction(double transmitTime) double Beidou_Navigation_Message_D1::sv_clock_correction(double transmitTime)
{ {
double dt; double dt;
dt = check_t(transmitTime - d_Toc); dt = check_t(transmitTime - d_Toc);
@ -278,7 +301,7 @@ double Beidou_Navigation_Message::sv_clock_correction(double transmitTime)
return correctedTime; return correctedTime;
} }
void Beidou_Navigation_Message::satellitePosition(double transmitTime) void Beidou_Navigation_Message_D1::satellitePosition(double transmitTime)
{ {
double tk; double tk;
double a; double a;
@ -376,11 +399,19 @@ void Beidou_Navigation_Message::satellitePosition(double transmitTime)
int Beidou_Navigation_Message::subframe_decoder(char *subframe) int Beidou_Navigation_Message_D1::subframe_decoder(char *subframe)
{ {
int subframe_ID = 0; int subframe_ID = 0;
std::cout << "Beidou_Navigation_Message_D1::subframe_decoder" << std::endl;
std::bitset<BEIDOU_SUBFRAME_BITS> mysubframe_bits;
mysubframe_bits = std::bitset<(BEIDOU_SUBFRAME_BITS) > (subframe);
for (int i = 0; i < BEIDOU_SUBFRAME_BITS; i++)
{
std::cout << mysubframe_bits[i] ;
}
std::cout << std::endl;
//double tmp_TOW; //double tmp_SOW;
unsigned int beidou_word; unsigned int beidou_word;
@ -394,10 +425,17 @@ int Beidou_Navigation_Message::subframe_decoder(char *subframe)
for (int j = 0; j < BEIDOU_WORD_BITS; j++) for (int j = 0; j < BEIDOU_WORD_BITS; j++)
{ {
subframe_bits[BEIDOU_WORD_BITS * (9 - i) + j] = word_bits[j]; subframe_bits[BEIDOU_WORD_BITS * (9 - i) + j] = word_bits[j];
std::cout << word_bits[j];
} }
std::cout << std::endl;
}
for (int i = 0; i < BEIDOU_SUBFRAME_BITS; i++)
{
std::cout << subframe_bits[i] ;
} }
subframe_ID = static_cast<int>(read_navigation_unsigned(subframe_bits, SUBFRAME_ID)); std::cout << std::endl;
subframe_ID = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_FRAID));
// Decode all 5 sub-frames // Decode all 5 sub-frames
switch (subframe_ID) switch (subframe_ID)
@ -405,100 +443,203 @@ int Beidou_Navigation_Message::subframe_decoder(char *subframe)
//--- Decode the sub-frame id ------------------------------------------ //--- Decode the sub-frame id ------------------------------------------
case 1: case 1:
//--- It is subframe 1 ------------------------------------- //--- It is subframe 1 -------------------------------------
// Compute the time of week (TOW) of the first sub-frames in the array ==== // Compute the time of week (SOW) of the first sub-frames in the array ====
// The transmitted TOW is actual TOW of the next subframe // The transmitted SOW is actual SOW of the next subframe
// (the variable subframe at this point contains bits of the last subframe). // (the variable subframe at this point contains bits of the last subframe).
//TOW = bin2dec(subframe(31:47)) * 6; //SOW = bin2dec(subframe(31:47)) * 6;
d_TOW_SF1 = static_cast<double>(read_navigation_unsigned(subframe_bits, TOW)); //we are in the first subframe (the transmitted SOW is the start time of the next subframe) !
//we are in the first subframe (the transmitted TOW is the start time of the next subframe) ! //d_SOW_SF1 = d_SOW_SF1 * 6;
d_TOW_SF1 = d_TOW_SF1 * 6; //b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
d_TOW = d_TOW_SF1; // Set transmission time //b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); //b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); //i_SV_accuracy = static_cast<int>(read_navigation_unsigned(subframe_bits, SV_ACCURACY)); // (20.3.3.3.1.3)
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); // b_L2_P_data_flag = read_navigation_bool(subframe_bits, L2_P_DATA_FLAG); //
i_GPS_week = static_cast<int>(read_navigation_unsigned(subframe_bits, GPS_WEEK)); //i_code_on_L2 = static_cast<int>(read_navigation_unsigned(subframe_bits, CA_OR_P_ON_L2));
i_SV_accuracy = static_cast<int>(read_navigation_unsigned(subframe_bits, SV_ACCURACY)); // (20.3.3.3.1.3)
i_SV_health = static_cast<int>(read_navigation_unsigned(subframe_bits, SV_HEALTH));
b_L2_P_data_flag = read_navigation_bool(subframe_bits, L2_P_DATA_FLAG); // d_SOW_SF1 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SOW));
i_code_on_L2 = static_cast<int>(read_navigation_unsigned(subframe_bits, CA_OR_P_ON_L2)); d_SOW = d_SOW_SF1; // Set transmission time
d_TGD = static_cast<double>(read_navigation_signed(subframe_bits, T_GD));
d_TGD = d_TGD * T_GD_LSB; std::cout << "I decoded subframe 1" << std::endl;
d_IODC = static_cast<double>(read_navigation_unsigned(subframe_bits, IODC)); std::cout << "TOW: " << d_SOW_SF1 << std::endl;
d_Toc = static_cast<double>(read_navigation_unsigned(subframe_bits, T_OC));
d_Toc = d_Toc * T_OC_LSB; i_SV_health = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_SAT_H1));
d_A_f0 = static_cast<double>(read_navigation_signed(subframe_bits, A_F0));
d_A_f0 = d_A_f0 * A_F0_LSB; d_AODC = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_AODC));
d_A_f1 = static_cast<double>(read_navigation_signed(subframe_bits, A_F1)); i_SV_accuracy = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_URAI)); // (20.3.3.3.1.3)
d_A_f1 = d_A_f1 * A_F1_LSB;
d_A_f2 = static_cast<double>(read_navigation_signed(subframe_bits, A_F2)); i_BEIDOU_week = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_WN));
d_A_f2 = d_A_f2 * A_F2_LSB;
d_Toc = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_TOC));
d_Toc = d_Toc * D1_TOC_LSB;
d_TGD1 = static_cast<double>(read_navigation_signed(subframe_bits, D1_TGD1));
d_TGD1 = d_TGD1 * D1_TGD1_LSB;
d_TGD2 = static_cast<double>(read_navigation_signed(subframe_bits, D1_TGD2));
d_TGD2 = d_TGD2 * D1_TGD2_LSB;
d_alpha0 = static_cast<double>(read_navigation_signed(subframe_bits, D1_ALPHA0));
d_alpha0 = d_alpha0 * D1_ALPHA0_LSB;
d_alpha1 = static_cast<double>(read_navigation_signed(subframe_bits, D1_ALPHA1));
d_alpha1 = d_alpha1 * D1_ALPHA1_LSB;
d_alpha2 = static_cast<double>(read_navigation_signed(subframe_bits, D1_ALPHA2));
d_alpha2 = d_alpha2 * D1_ALPHA2_LSB;
d_alpha3 = static_cast<double>(read_navigation_signed(subframe_bits, D1_ALPHA3));
d_alpha3 = d_alpha3 * D1_ALPHA3_LSB;
d_beta0 = static_cast<double>(read_navigation_signed(subframe_bits, D1_BETA0));
d_beta0 = d_beta0 * D1_BETA0_LSB;
d_beta1 = static_cast<double>(read_navigation_signed(subframe_bits, D1_BETA1));
d_beta1 = d_beta1 * D1_BETA1_LSB;
d_beta2 = static_cast<double>(read_navigation_signed(subframe_bits, D1_BETA2));
d_beta2 = d_beta2 * D1_BETA2_LSB;
d_beta3 = static_cast<double>(read_navigation_signed(subframe_bits, D1_BETA3));
d_beta3 = d_beta3 * D1_BETA3_LSB;
d_A2 = static_cast<double>(read_navigation_signed(subframe_bits, D1_A2));
d_A2 = d_A2 * D1_A2_LSB;
d_A0 = static_cast<double>(read_navigation_signed(subframe_bits, D1_A0));
d_A0 = d_A0 * D1_A0_LSB;
d_A1 = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1));
d_A1 = d_A1 * D1_A1_LSB;
d_AODE_SF1 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_AODE));
//d_A_f0 = static_cast<double>(read_navigation_signed(subframe_bits, A_F0));
//d_A_f0 = d_A_f0 * A_F0_LSB;
//d_A_f1 = static_cast<double>(read_navigation_signed(subframe_bits, A_F1));
//d_A_f1 = d_A_f1 * A_F1_LSB;
//d_A_f2 = static_cast<double>(read_navigation_signed(subframe_bits, A_F2));
//d_A_f2 = d_A_f2 * A_F2_LSB;
break; break;
case 2: //--- It is subframe 2 ------------------- case 2: //--- It is subframe 2 -------------------
d_TOW_SF2 = static_cast<double>(read_navigation_unsigned(subframe_bits, TOW));
d_TOW_SF2 = d_TOW_SF2 * 6;
d_TOW = d_TOW_SF2; // Set transmission time d_SOW_SF2 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SOW));
b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); d_SOW = d_SOW_SF2; // Set transmission time
b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); std::cout << "I decoded subframe 2" << std::endl;
d_IODE_SF2 = static_cast<double>(read_navigation_unsigned(subframe_bits, IODE_SF2)); std::cout << "TOW: " << d_SOW_SF2 << std::endl;
d_Crs = static_cast<double>(read_navigation_signed(subframe_bits, C_RS));
d_Crs = d_Crs * C_RS_LSB; d_Cuc = static_cast<double>(read_navigation_signed(subframe_bits, D1_CUC));
d_Delta_n = static_cast<double>(read_navigation_signed(subframe_bits, DELTA_N)); d_Cuc = d_Cuc * D1_CUC_LSB;
d_Delta_n = d_Delta_n * DELTA_N_LSB;
d_M_0 = static_cast<double>(read_navigation_signed(subframe_bits, M_0)); d_M_0 = static_cast<double>(read_navigation_signed(subframe_bits, D1_M0));
d_M_0 = d_M_0 * M_0_LSB; d_M_0 = d_M_0 * D1_M0_LSB;
d_Cuc = static_cast<double>(read_navigation_signed(subframe_bits, C_UC));
d_Cuc = d_Cuc * C_UC_LSB; d_e_eccentricity = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_E));
d_e_eccentricity = static_cast<double>(read_navigation_unsigned(subframe_bits, E)); d_e_eccentricity = d_e_eccentricity * D1_E_LSB;
d_e_eccentricity = d_e_eccentricity * E_LSB;
d_Cus = static_cast<double>(read_navigation_signed(subframe_bits, C_US)); d_Cus = static_cast<double>(read_navigation_signed(subframe_bits, D1_CUS));
d_Cus = d_Cus * C_US_LSB; d_Cus = d_Cus * D1_CUS_LSB;
d_sqrt_A = static_cast<double>(read_navigation_unsigned(subframe_bits, SQRT_A));
d_sqrt_A = d_sqrt_A * SQRT_A_LSB; d_Crc = static_cast<double>(read_navigation_signed(subframe_bits, D1_CRC));
d_Toe = static_cast<double>(read_navigation_unsigned(subframe_bits, T_OE)); d_Crc = d_Crc * D1_CRC_LSB;
d_Toe = d_Toe * T_OE_LSB;
b_fit_interval_flag = read_navigation_bool(subframe_bits, FIT_INTERVAL_FLAG); d_Crs = static_cast<double>(read_navigation_signed(subframe_bits, D1_CRS));
i_AODO = static_cast<int>(read_navigation_unsigned(subframe_bits, AODO)); d_Crs = d_Crs * D1_CRS_LSB;
i_AODO = i_AODO * AODO_LSB;
d_sqrt_A = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SQRT_A));
d_sqrt_A = d_sqrt_A * D1_SQRT_A_LSB;
d_Toe = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_TOE));
d_Toe = d_Toe * D1_TOE_LSB;
// d_SOW = d_SOW_SF2; // Set transmission time
// b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
// b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
// b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
// b_fit_interval_flag = read_navigation_bool(subframe_bits, FIT_INTERVAL_FLAG);
// i_AODO = static_cast<int>(read_navigation_unsigned(subframe_bits, AODO));
// i_AODO = i_AODO * AODO_LSB;
break; break;
case 3: // --- It is subframe 3 ------------------------------------- case 3: // --- It is subframe 3 -------------------------------------
d_TOW_SF3 = static_cast<double>(read_navigation_unsigned(subframe_bits, TOW));
d_TOW_SF3 = d_TOW_SF3 * 6; d_SOW_SF3 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SOW));
d_TOW = d_TOW_SF3; // Set transmission time d_SOW = d_SOW_SF3; // Set transmission time
b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); std::cout << "I decoded subframe 3" << std::endl;
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); std::cout << "TOW: " << d_SOW_SF3 << std::endl;
d_Cic = static_cast<double>(read_navigation_signed(subframe_bits, C_IC));
d_Cic = d_Cic * C_IC_LSB; d_Toe = d_Toe * D1_TOE_LSB;
d_OMEGA0 = static_cast<double>(read_navigation_signed(subframe_bits, OMEGA_0));
d_OMEGA0 = d_OMEGA0 * OMEGA_0_LSB; d_i_0 = static_cast<double>(read_navigation_signed(subframe_bits, D1_I0));
d_Cis = static_cast<double>(read_navigation_signed(subframe_bits, C_IS)); d_i_0 = d_i_0 * D1_I0_LSB;
d_Cis = d_Cis * C_IS_LSB;
d_i_0 = static_cast<double>(read_navigation_signed(subframe_bits, I_0)); d_Cic = static_cast<double>(read_navigation_signed(subframe_bits, D1_CIC));
d_i_0 = d_i_0 * I_0_LSB; d_Cic = d_Cic * D1_CIC_LSB;
d_Crc = static_cast<double>(read_navigation_signed(subframe_bits, C_RC));
d_Crc = d_Crc * C_RC_LSB; d_OMEGA_DOT = static_cast<double>(read_navigation_signed(subframe_bits, D1_OMEGA_DOT));
d_OMEGA = static_cast<double>(read_navigation_signed(subframe_bits, OMEGA)); d_OMEGA_DOT = d_OMEGA_DOT * D1_OMEGA_DOT_LSB;
d_OMEGA = d_OMEGA * OMEGA_LSB;
d_OMEGA_DOT = static_cast<double>(read_navigation_signed(subframe_bits, OMEGA_DOT)); d_Cis = static_cast<double>(read_navigation_signed(subframe_bits, D1_CIS));
d_OMEGA_DOT = d_OMEGA_DOT * OMEGA_DOT_LSB; d_Cis = d_Cis * D1_CIS_LSB;
d_IODE_SF3 = static_cast<double>(read_navigation_unsigned(subframe_bits, IODE_SF3));
d_IDOT = static_cast<double>(read_navigation_signed(subframe_bits, I_DOT)); d_IDOT = static_cast<double>(read_navigation_signed(subframe_bits, D1_IDOT));
d_IDOT = d_IDOT * I_DOT_LSB; d_IDOT = d_IDOT * D1_IDOT_LSB;
d_OMEGA0 = static_cast<double>(read_navigation_signed(subframe_bits, D1_OMEGA0));
d_OMEGA0 = d_OMEGA0 * D1_OMEGA0_LSB;
d_OMEGA = static_cast<double>(read_navigation_signed(subframe_bits, D1_OMEGA));
d_OMEGA = d_OMEGA * D1_OMEGA_LSB;
//d_SOW_SF3 = static_cast<double>(read_navigation_unsigned(subframe_bits, SOW));
//d_SOW_SF3 = d_SOW_SF3 * 6;
//d_SOW = d_SOW_SF3; // Set transmission time
//b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
//b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
//b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
//d_AODE_SF3 = static_cast<double>(read_navigation_unsigned(subframe_bits, AODE_SF3));
break; break;
case 4: // --- It is subframe 4 ---------- Almanac, ionospheric model, UTC parameters, SV health (PRN: 25-32) case 4: // --- It is subframe 4 ---------- Almanac, ionospheric model, UTC parameters, SV health (PRN: 25-32)
int SV_data_ID; d_SOW_SF4 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SOW));
int SV_page; d_SOW = d_SOW_SF4; // Set transmission time
d_TOW_SF4 = static_cast<double>(read_navigation_unsigned(subframe_bits, TOW));
d_TOW_SF4 = d_TOW_SF4 * 6; std::cout << "I decoded subframe 4" << std::endl;
d_TOW = d_TOW_SF4; // Set transmission time std::cout << "TOW: " << d_SOW_SF4 << std::endl;
b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
d_SQRT_A_ALMANAC = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SQRT_A_ALMANAC));
d_SQRT_A_ALMANAC = d_SQRT_A_ALMANAC * D1_SQRT_A_ALMANAC_LSB;
d_A1_ALMANAC = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1_ALMANAC));
d_A1_ALMANAC = d_A1_ALMANAC * D1_A1_ALMANAC_LSB;
d_A0_ALMANAC = static_cast<double>(read_navigation_signed(subframe_bits, D1_A0_ALMANAC));
d_A0_ALMANAC = d_A0_ALMANAC * D1_A0_ALMANAC_LSB;
d_OMEGA0_ALMANAC = static_cast<double>(read_navigation_signed(subframe_bits, D1_OMEGA0_ALMANAC));
d_OMEGA0_ALMANAC = d_OMEGA0_ALMANAC * D1_OMEGA0_ALMANAC_LSB;
d_E_ALMANAC = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_E));
d_E_ALMANAC = d_E_ALMANAC * D1_E_ALMANAC_LSB;
d_DELTA_I = static_cast<double>(read_navigation_signed(subframe_bits, D1_DELTA_I));
d_DELTA_I = D1_DELTA_I_LSB;
d_TOA = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_TOA));
d_TOA = d_TOA * D1_TOA_LSB;
d_OMEGA_DOT_ALMANAC = static_cast<double>(read_navigation_signed(subframe_bits, D1_OMEGA_DOT_ALMANAC));
d_OMEGA_DOT_ALMANAC = D1_OMEGA_DOT_ALMANAC_LSB;
d_OMEGA_ALMANAC = static_cast<double>(read_navigation_signed(subframe_bits, D1_OMEGA_ALMANAC));
d_OMEGA_ALMANAC = d_OMEGA_ALMANAC * D1_OMEGA_ALMANAC_LSB;
d_M0_ALMANAC = static_cast<double>(read_navigation_signed(subframe_bits, D1_M0));
d_M0_ALMANAC = d_M0_ALMANAC * D1_M0_ALMANAC_LSB;
/* b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG);
b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG);
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
SV_data_ID = static_cast<int>(read_navigation_unsigned(subframe_bits, SV_DATA_ID)); SV_data_ID = static_cast<int>(read_navigation_unsigned(subframe_bits, SV_DATA_ID));
@ -517,26 +658,6 @@ int Beidou_Navigation_Message::subframe_decoder(char *subframe)
if (SV_page == 56) // Page 18 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110) if (SV_page == 56) // Page 18 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110)
{ {
// Page 18 - Ionospheric and UTC data // Page 18 - Ionospheric and UTC data
d_alpha0 = static_cast<double>(read_navigation_signed(subframe_bits, ALPHA_0));
d_alpha0 = d_alpha0 * ALPHA_0_LSB;
d_alpha1 = static_cast<double>(read_navigation_signed(subframe_bits, ALPHA_1));
d_alpha1 = d_alpha1 * ALPHA_1_LSB;
d_alpha2 = static_cast<double>(read_navigation_signed(subframe_bits, ALPHA_2));
d_alpha2 = d_alpha2 * ALPHA_2_LSB;
d_alpha3 = static_cast<double>(read_navigation_signed(subframe_bits, ALPHA_3));
d_alpha3 = d_alpha3 * ALPHA_3_LSB;
d_beta0 = static_cast<double>(read_navigation_signed(subframe_bits, BETA_0));
d_beta0 = d_beta0 * BETA_0_LSB;
d_beta1 = static_cast<double>(read_navigation_signed(subframe_bits, BETA_1));
d_beta1 = d_beta1 * BETA_1_LSB;
d_beta2 = static_cast<double>(read_navigation_signed(subframe_bits, BETA_2));
d_beta2 = d_beta2 * BETA_2_LSB;
d_beta3 = static_cast<double>(read_navigation_signed(subframe_bits, BETA_3));
d_beta3 = d_beta3 * BETA_3_LSB;
d_A1 = static_cast<double>(read_navigation_signed(subframe_bits, A_1));
d_A1 = d_A1 * A_1_LSB;
d_A0 = static_cast<double>(read_navigation_signed(subframe_bits, A_0));
d_A0 = d_A0 * A_0_LSB;
d_t_OT = static_cast<double>(read_navigation_unsigned(subframe_bits, T_OT)); d_t_OT = static_cast<double>(read_navigation_unsigned(subframe_bits, T_OT));
d_t_OT = d_t_OT * T_OT_LSB; d_t_OT = d_t_OT * T_OT_LSB;
i_WN_T = static_cast<int>(read_navigation_unsigned(subframe_bits, WN_T)); i_WN_T = static_cast<int>(read_navigation_unsigned(subframe_bits, WN_T));
@ -556,64 +677,133 @@ int Beidou_Navigation_Message::subframe_decoder(char *subframe)
{ {
// Page 25 Anti-Spoofing, SV config and almanac health (PRN: 25-32) // Page 25 Anti-Spoofing, SV config and almanac health (PRN: 25-32)
//! \TODO Read Anti-Spoofing, SV config //! \TODO Read Anti-Spoofing, SV config
almanacHealth[25] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV25)); almanacHealth[25] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA25));
almanacHealth[26] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV26)); almanacHealth[26] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA26));
almanacHealth[27] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV27)); almanacHealth[27] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA27));
almanacHealth[28] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV28)); almanacHealth[28] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA28));
almanacHealth[29] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV29)); almanacHealth[29] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA29));
almanacHealth[30] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV30)); almanacHealth[30] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA30));
almanacHealth[31] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV31)); almanacHealth[31] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA31));
almanacHealth[32] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV32)); almanacHealth[32] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA32));
} }
break; break;
*/
case 5://--- It is subframe 5 -----------------almanac health (PRN: 1-24) and Almanac reference week number and time. case 5://--- It is subframe 5 -----------------almanac health (PRN: 1-24) and Almanac reference week number and time.
int SV_data_ID_5;
int SV_page_5; int SV_page_5;
d_TOW_SF5 = static_cast<double>(read_navigation_unsigned(subframe_bits, TOW)); d_SOW_SF5 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SOW));
d_TOW_SF5 = d_TOW_SF5 * 6; d_SOW = d_SOW_SF5; // Set transmission time
d_TOW = d_TOW_SF5; // Set transmission time
b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); std::cout << "I decoded subframe 5" << std::endl;
b_alert_flag = read_navigation_bool(subframe_bits, ALERT_FLAG); std::cout << "TOW: " << d_SOW_SF5 << std::endl;
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
SV_data_ID_5 = static_cast<int>(read_navigation_unsigned(subframe_bits, SV_DATA_ID));
SV_page_5 = static_cast<int>(read_navigation_unsigned(subframe_bits, SV_PAGE)); SV_page_5 = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_PNUM));
if (SV_page_5 < 25)
if (SV_page_5 < 7)
{
d_SOW_SF4 = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SOW));
d_SQRT_A_ALMANAC = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_SQRT_A_ALMANAC));
d_SQRT_A_ALMANAC = d_SQRT_A_ALMANAC * D1_SQRT_A_ALMANAC_LSB;
d_A1UTC = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1_ALMANAC));
d_A1UTC = d_A1UTC * D1_A1_ALMANAC_LSB;
d_A0_ALMANAC = static_cast<double>(read_navigation_signed(subframe_bits, D1_A0_ALMANAC));
d_A0_ALMANAC = d_A0_ALMANAC * D1_A0_ALMANAC_LSB;
d_OMEGA0_ALMANAC = static_cast<double>(read_navigation_signed(subframe_bits, D1_OMEGA0_ALMANAC));
d_OMEGA0_ALMANAC = d_OMEGA0_ALMANAC * D1_OMEGA0_ALMANAC_LSB;
d_E_ALMANAC = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_E));
d_E_ALMANAC = d_E_ALMANAC * D1_E_ALMANAC_LSB;
d_DELTA_I = static_cast<double>(read_navigation_signed(subframe_bits, D1_DELTA_I));
d_DELTA_I = D1_DELTA_I_LSB;
d_TOA = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_TOA));
d_TOA = d_TOA * D1_TOA_LSB;
d_OMEGA_DOT_ALMANAC = static_cast<double>(read_navigation_signed(subframe_bits, D1_OMEGA_DOT_ALMANAC));
d_OMEGA_DOT_ALMANAC = D1_OMEGA_DOT_ALMANAC_LSB;
d_OMEGA_ALMANAC = static_cast<double>(read_navigation_signed(subframe_bits, D1_OMEGA_ALMANAC));
d_OMEGA_ALMANAC = d_OMEGA_ALMANAC * D1_OMEGA_ALMANAC_LSB;
d_M0_ALMANAC = static_cast<double>(read_navigation_signed(subframe_bits, D1_M0));
d_M0_ALMANAC = d_M0_ALMANAC * D1_M0_ALMANAC_LSB;
}
if (SV_page_5 == 7)
{ {
//! \TODO read almanac //! \TODO read almanac
if(SV_data_ID_5){} almanacHealth[1] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA1));
almanacHealth[2] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA2));
almanacHealth[3] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA3));
almanacHealth[4] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA4));
almanacHealth[5] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA5));
almanacHealth[6] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA6));
almanacHealth[7] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA7));
almanacHealth[8] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA8));
almanacHealth[9] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA9));
almanacHealth[10] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA10));
almanacHealth[11] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA11));
almanacHealth[12] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA12));
almanacHealth[13] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA13));
almanacHealth[14] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA14));
almanacHealth[15] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA15));
almanacHealth[16] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA16));
almanacHealth[17] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA17));
almanacHealth[18] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA18));
almanacHealth[19] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA19));
} }
if (SV_page_5 == 51) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110) if (SV_page_5 == 8) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110)
{ {
d_Toa = static_cast<double>(read_navigation_unsigned(subframe_bits, T_OA)); almanacHealth[20] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA20));
d_Toa = d_Toa * T_OA_LSB; almanacHealth[21] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA21));
i_WN_A = static_cast<int>(read_navigation_unsigned(subframe_bits, WN_A)); almanacHealth[22] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA22));
almanacHealth[1] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV1)); almanacHealth[23] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA23));
almanacHealth[2] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV2)); almanacHealth[24] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA24));
almanacHealth[3] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV3)); almanacHealth[25] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA25));
almanacHealth[4] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV4)); almanacHealth[26] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA26));
almanacHealth[5] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV5)); almanacHealth[27] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA27));
almanacHealth[6] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV6)); almanacHealth[28] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA28));
almanacHealth[7] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV7)); almanacHealth[29] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA29));
almanacHealth[8] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV8)); almanacHealth[30] = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_HEA30));
almanacHealth[9] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV9)); almanac_WN = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_WNA));
almanacHealth[10] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV10)); d_toa2 = static_cast<int>(read_navigation_unsigned(subframe_bits, D1_TOA2));
almanacHealth[11] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV11));
almanacHealth[12] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV12));
almanacHealth[13] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV13));
almanacHealth[14] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV14));
almanacHealth[15] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV15));
almanacHealth[16] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV16));
almanacHealth[17] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV17));
almanacHealth[18] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV18));
almanacHealth[19] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV19));
almanacHealth[20] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV20));
almanacHealth[21] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV21));
almanacHealth[22] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV22));
almanacHealth[23] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV23));
almanacHealth[24] = static_cast<int>(read_navigation_unsigned(subframe_bits, HEALTH_SV24));
} }
if (SV_page_5 == 9) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200H, page 110)
{
d_A0GPS = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_A0GPS));
d_A0GPS = d_A0GPS * D1_A0GPS_LSB;
d_A1GPS = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_A1GPS));
d_A1GPS = d_A1GPS * D1_A1GPS_LSB;
d_A0GAL = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_A0GAL));
d_A0GAL = d_A0GAL * D1_A0GAL_LSB;
d_A1GAL = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_A1GAL));
d_A1GAL = d_A1GAL* D1_A1GAL_LSB;
d_A0GLO = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_A0GLO));
d_A0GLO = d_A0GLO * D1_A0GLO_LSB;
d_A1GLO = static_cast<double>(read_navigation_unsigned(subframe_bits, D1_A1GLO));
d_A1GLO = d_A1GLO* D1_A1GLO_LSB;
}
if (SV_page_5 == 10)
{
d_DeltaT_LS = static_cast<double>(read_navigation_signed(subframe_bits, D1_DELTA_T_LS));
}
break; break;
default: default:
@ -626,14 +816,14 @@ int Beidou_Navigation_Message::subframe_decoder(char *subframe)
double Beidou_Navigation_Message::utc_time(const double gpstime_corrected) const double Beidou_Navigation_Message_D1::utc_time(const double beidoutime_corrected) const
{ {
double t_utc; double t_utc;
double t_utc_daytime; double t_utc_daytime;
double Delta_t_UTC = d_DeltaT_LS + d_A0 + d_A1 * (gpstime_corrected - d_t_OT + 604800 * static_cast<double>((i_GPS_week - i_WN_T))); double Delta_t_UTC = d_DeltaT_LS + d_A0 + d_A1UTC * (beidoutime_corrected);
// Determine if the effectivity time of the leap second event is in the past // Determine if the effectivity time of the leap second event is in the past
int weeksToLeapSecondEvent = i_WN_LSF - i_GPS_week; int weeksToLeapSecondEvent = i_WN_LSF - i_BEIDOU_week;
if ((weeksToLeapSecondEvent) >= 0) // is not in the past if ((weeksToLeapSecondEvent) >= 0) // is not in the past
{ {
@ -641,63 +831,45 @@ double Beidou_Navigation_Message::utc_time(const double gpstime_corrected) const
int secondOfLeapSecondEvent = i_DN * 24 * 60 * 60; int secondOfLeapSecondEvent = i_DN * 24 * 60 * 60;
if (weeksToLeapSecondEvent > 0) if (weeksToLeapSecondEvent > 0)
{ {
t_utc_daytime = fmod(gpstime_corrected - Delta_t_UTC, 86400); t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
} }
else //we are in the same week than the leap second event else //we are in the same week than the leap second event
{ {
if (std::abs(gpstime_corrected - secondOfLeapSecondEvent) > 21600) if ((beidoutime_corrected - secondOfLeapSecondEvent) < (2/3) * 24 * 60 * 60)
{ {
/* 20.3.3.5.2.4a t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
* Whenever the effectivity time indicated by the WN_LSF and the DN values
* is not in the past (relative to the user's present time), and the user's
* present time does not fall in the time span which starts at six hours prior
* to the effectivity time and ends at six hours after the effectivity time,
* the UTC/GPS-time relationship is given by
*/
t_utc_daytime = fmod(gpstime_corrected - Delta_t_UTC, 86400);
} }
else else
{ {
/* 20.3.3.5.2.4b if ((beidoutime_corrected - secondOfLeapSecondEvent) < (5/4) * 24 * 60 * 60)
* Whenever the user's current time falls within the time span of six hours {
* prior to the effectivity time to six hours after the effectivity time, int W = fmod(beidoutime_corrected - Delta_t_UTC - 43200, 86400) + 43200;
* proper accommodation of the leap second event with a possible week number t_utc_daytime = fmod(W, 86400 + d_DeltaT_LSF - d_DeltaT_LS);
* transition is provided by the following expression for UTC: }
*/ else
int W = fmod(gpstime_corrected - Delta_t_UTC - 43200, 86400) + 43200; {
t_utc_daytime = fmod(W, 86400 + d_DeltaT_LSF - d_DeltaT_LS); t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
//implement something to handle a leap second event! }
}
if ( (gpstime_corrected - secondOfLeapSecondEvent) > 21600)
{
Delta_t_UTC = d_DeltaT_LSF + d_A0 + d_A1 * (gpstime_corrected - d_t_OT + 604800 * static_cast<double>((i_GPS_week - i_WN_T)));
t_utc_daytime = fmod(gpstime_corrected - Delta_t_UTC, 86400);
} }
} }
} }
else // the effectivity time is in the past else // the effectivity time is in the past
{ {
/* 20.3.3.5.2.4c t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
* Whenever the effectivity time of the leap second event, as indicated by the
* WNLSF and DN values, is in the "past" (relative to the user's current time),
* and the user<EFBFBD>s current time does not fall in the time span as given above
* in 20.3.3.5.2.4b,*/
Delta_t_UTC = d_DeltaT_LSF + d_A0 + d_A1 * (gpstime_corrected - d_t_OT + 604800 * static_cast<double>((i_GPS_week - i_WN_T)));
t_utc_daytime = fmod(gpstime_corrected - Delta_t_UTC, 86400);
} }
double secondsOfWeekBeforeToday = 43200 * floor(gpstime_corrected / 43200); double secondsOfWeekBeforeToday = 43200 * floor(beidoutime_corrected / 43200);
t_utc = secondsOfWeekBeforeToday + t_utc_daytime; t_utc = secondsOfWeekBeforeToday + t_utc_daytime;
return t_utc; return t_utc;
} }
Gps_Ephemeris Beidou_Navigation_Message::get_ephemeris() Beidou_Ephemeris Beidou_Navigation_Message_D1::get_ephemeris()
{ {
Gps_Ephemeris ephemeris; Beidou_Ephemeris ephemeris;
ephemeris.i_satellite_PRN = i_satellite_PRN; ephemeris.i_satellite_PRN = i_satellite_PRN;
ephemeris.d_TOW = d_TOW; ephemeris.d_TOW = d_SOW;
ephemeris.d_Crs = d_Crs; ephemeris.d_Crs = d_Crs;
ephemeris.d_Delta_n = d_Delta_n; ephemeris.d_Delta_n = d_Delta_n;
ephemeris.d_M_0 = d_M_0; ephemeris.d_M_0 = d_M_0;
@ -705,7 +877,7 @@ Gps_Ephemeris Beidou_Navigation_Message::get_ephemeris()
ephemeris.d_e_eccentricity = d_e_eccentricity; ephemeris.d_e_eccentricity = d_e_eccentricity;
ephemeris.d_Cus = d_Cus; ephemeris.d_Cus = d_Cus;
ephemeris.d_sqrt_A = d_sqrt_A; ephemeris.d_sqrt_A = d_sqrt_A;
ephemeris.d_Toe = d_Toe; ephemeris.d_Toe =static_cast<float>( (static_cast<int>(d_Toe) << 15) | static_cast<int>(d_Toe2)) ;
ephemeris.d_Toc = d_Toc; ephemeris.d_Toc = d_Toc;
ephemeris.d_Cic = d_Cic; ephemeris.d_Cic = d_Cic;
ephemeris.d_OMEGA0 = d_OMEGA0; ephemeris.d_OMEGA0 = d_OMEGA0;
@ -715,16 +887,14 @@ Gps_Ephemeris Beidou_Navigation_Message::get_ephemeris()
ephemeris.d_OMEGA = d_OMEGA; ephemeris.d_OMEGA = d_OMEGA;
ephemeris.d_OMEGA_DOT = d_OMEGA_DOT; ephemeris.d_OMEGA_DOT = d_OMEGA_DOT;
ephemeris.d_IDOT = d_IDOT; ephemeris.d_IDOT = d_IDOT;
ephemeris.i_code_on_L2 = i_code_on_L2; ephemeris.i_BEIDOU_week = i_BEIDOU_week;
ephemeris.i_GPS_week = i_GPS_week;
ephemeris.b_L2_P_data_flag = b_L2_P_data_flag;
ephemeris.i_SV_accuracy = i_SV_accuracy; ephemeris.i_SV_accuracy = i_SV_accuracy;
ephemeris.i_SV_health = i_SV_health; ephemeris.i_SV_health = i_SV_health;
ephemeris.d_TGD = d_TGD; ephemeris.d_TGD1 = d_TGD1;
ephemeris.d_IODC = d_IODC; ephemeris.d_AODC = d_AODC;
ephemeris.d_IODE_SF2 = d_IODE_SF2; //ephemeris.d_AODE_SF2 = d_AODE_SF2;
ephemeris.d_IODE_SF3 = d_IODE_SF3; //ephemeris.d_AODE_SF3 = d_AODE_SF3;
ephemeris.i_AODO = i_AODO; //ephemeris.i_AODO = i_AODO;
ephemeris.b_fit_interval_flag = b_fit_interval_flag; ephemeris.b_fit_interval_flag = b_fit_interval_flag;
ephemeris.d_spare1 = d_spare1; ephemeris.d_spare1 = d_spare1;
ephemeris.d_spare2 = d_spare2; ephemeris.d_spare2 = d_spare2;
@ -747,9 +917,9 @@ Gps_Ephemeris Beidou_Navigation_Message::get_ephemeris()
} }
Gps_Iono Beidou_Navigation_Message::get_iono() Beidou_Iono Beidou_Navigation_Message_D1::get_iono()
{ {
Gps_Iono iono; Beidou_Iono iono;
iono.d_alpha0 = d_alpha0; iono.d_alpha0 = d_alpha0;
iono.d_alpha1 = d_alpha1; iono.d_alpha1 = d_alpha1;
iono.d_alpha2 = d_alpha2; iono.d_alpha2 = d_alpha2;
@ -765,12 +935,12 @@ Gps_Iono Beidou_Navigation_Message::get_iono()
} }
Gps_Utc_Model Beidou_Navigation_Message::get_utc_model() Beidou_Utc_Model Beidou_Navigation_Message_D1::get_utc_model()
{ {
Gps_Utc_Model utc_model; Beidou_Utc_Model utc_model;
utc_model.valid = flag_utc_model_valid; utc_model.valid = flag_utc_model_valid;
// UTC parameters // UTC parameters
utc_model.d_A1 = d_A1; utc_model.d_A1 = d_A1UTC;
utc_model.d_A0 = d_A0; utc_model.d_A0 = d_A0;
utc_model.d_t_OT = d_t_OT; utc_model.d_t_OT = d_t_OT;
utc_model.i_WN_T = i_WN_T; utc_model.i_WN_T = i_WN_T;
@ -784,17 +954,17 @@ Gps_Utc_Model Beidou_Navigation_Message::get_utc_model()
} }
bool Beidou_Navigation_Message::satellite_validation() bool Beidou_Navigation_Message_D1::satellite_validation()
{ {
bool flag_data_valid = false; bool flag_data_valid = false;
b_valid_ephemeris_set_flag = false; b_valid_ephemeris_set_flag = false;
// First Step: // First Step:
// check Issue Of Ephemeris Data (IODE IODC..) to find a possible interrupted reception // check Issue Of Ephemeris Data (AODE AODC..) to find a possible interrupted reception
// and check if the data have been filled (!=0) // 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_SOW_SF1 != 0 and d_SOW_SF2 != 0 and d_SOW_SF3 != 0)
{ {
if (d_IODE_SF2 == d_IODE_SF3 and d_IODC == d_IODE_SF2 and d_IODC!= -1) if (d_AODC!= -1)
{ {
flag_data_valid = true; flag_data_valid = true;
b_valid_ephemeris_set_flag = true; b_valid_ephemeris_set_flag = true;

View File

@ -70,12 +70,12 @@ private:
public: public:
bool b_valid_ephemeris_set_flag; // flag indicating that this ephemeris set have passed the validation check bool b_valid_ephemeris_set_flag; // flag indicating that this ephemeris set have passed the validation check
//broadcast orbit 1 //broadcast orbit 1
double d_TOW; //!< Time of BeiDou Week of the ephemeris set (taken from subframes TOW) [s] double d_SOW; //!< Time of BeiDou Week of the ephemeris set (taken from subframes SOW) [s]
double d_TOW_SF1; //!< Time of BeiDou Week from HOW word of Subframe 1 [s] double d_SOW_SF1; //!< Time of BeiDou Week from HOW word of Subframe 1 [s]
double d_TOW_SF2; //!< Time of BeiDou Week from HOW word of Subframe 2 [s] double d_SOW_SF2; //!< Time of BeiDou Week from HOW word of Subframe 2 [s]
double d_TOW_SF3; //!< Time of BeiDou Week from HOW word of Subframe 3 [s] double d_SOW_SF3; //!< Time of BeiDou Week from HOW word of Subframe 3 [s]
double d_TOW_SF4; //!< Time of BeiDou Week from HOW word of Subframe 4 [s] double d_SOW_SF4; //!< Time of BeiDou Week from HOW word of Subframe 4 [s]
double d_TOW_SF5; //!< Time of BeiDou Week from HOW word of Subframe 5 [s] double d_SOW_SF5; //!< Time of BeiDou Week from HOW word of Subframe 5 [s]
double d_AODE; double d_AODE;
double d_Crs; //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m] double d_Crs; //!< Amplitude of the Sine Harmonic Correction Term to the Orbit Radius [m]
@ -88,6 +88,7 @@ public:
double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)] double d_sqrt_A; //!< Square Root of the Semi-Major Axis [sqrt(m)]
//broadcast orbit 3 //broadcast orbit 3
double d_Toe; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s] double d_Toe; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200E) [s]
double d_Toe2;
double d_Toc; //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s] double d_Toc; //!< clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200E) [s]
double d_Cic; //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad] double d_Cic; //!< Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad]
double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles] double d_OMEGA0; //!< Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
@ -117,6 +118,9 @@ public:
double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s] double d_A_f1; //!< Coefficient 1 of code phase offset model [s/s]
double d_A_f2; //!< Coefficient 2 of code phase offset model [s/s^2] double d_A_f2; //!< Coefficient 2 of code phase offset model [s/s^2]
double d_A0;
double d_A1;
double d_A2;
// Almanac // Almanac
double d_Toa; //!< Almanac reference time [s] double d_Toa; //!< Almanac reference time [s]
@ -172,37 +176,65 @@ public:
// UTC parameters // UTC parameters
bool flag_utc_model_valid; //!< If set, it indicates that the UTC model parameters are filled bool flag_utc_model_valid; //!< If set, it indicates that the UTC model parameters are filled
double d_A1; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s/s] double d_A2UTC;
double d_A0; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s] double d_A1UTC; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s/s]
double d_A0UTC; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s]
double d_t_OT; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200E) [s] double d_t_OT; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200E) [s]
int i_WN_T; //!< UTC reference week number [weeks] int i_WN_T; //!< UTC reference week number [weeks]
double d_DeltaT_LS; //!< delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac. double d_DeltaT_LS; //!< delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac.
int i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks] int i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks]
int i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days] int i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days]
double d_DeltaT_LSF; //!< Scheduled future or recent past (relative to NAV message upload) value of the delta time due to leap seconds [s] double d_DeltaT_LSF; //!< Scheduled future or recent past (relative to NAV message upload) value of the delta time due to leap seconds [s]
double d_A1GPS;
double d_A0GPS;
double d_A1GAL;
double d_A0GAL;
double d_A1GLO;
double d_A0GLO;
double d_AODE_SF1;
double d_SQRT_A_ALMANAC;
double d_A1_ALMANAC;
double d_A0_ALMANAC;
double d_OMEGA0_ALMANAC;
double d_E_ALMANAC;
double d_DELTA_I;
double d_TOA;
double d_OMEGA_DOT_ALMANAC;
double d_OMEGA_ALMANAC;
double d_M0_ALMANAC;
int almanac_WN;
double d_toa2;
// Satellite velocity // Satellite velocity
double d_satvel_X; //!< Earth-fixed velocity coordinate x of the satellite [m] double d_satvel_X; //!< Earth-fixed velocity coordinate x of the satellite [m]
double d_satvel_Y; //!< Earth-fixed velocity coordinate y of the satellite [m] double d_satvel_Y; //!< Earth-fixed velocity coordinate y of the satellite [m]
double d_satvel_Z; //!< Earth-fixed velocity coordinate z of the satellite [m] double d_satvel_Z; //!< Earth-fixed velocity coordinate z of the satellite [m]
// public functions // public functions
void reset(); void reset();
/*! /*!
* \brief Obtain a GPS SV Ephemeris class filled with current SV data * \brief Obtain a GPS SV Ephemeris class filled with current SV data
*/ */
Gps_Ephemeris get_ephemeris(); Beidou_Ephemeris get_ephemeris();
/*! /*!
* \brief Obtain a GPS ionospheric correction parameters class filled with current SV data * \brief Obtain a GPS ionospheric correction parameters class filled with current SV data
*/ */
Gps_Iono get_iono(); Beidou_Iono get_iono();
/*! /*!
* \brief Obtain a GPS UTC model parameters class filled with current SV data * \brief Obtain a GPS UTC model parameters class filled with current SV data
*/ */
Gps_Utc_Model get_utc_model(); Beidou_Utc_Model get_utc_model();
/*! /*!

View File

@ -0,0 +1,111 @@
/*
* \file gps_utc_model.h
* \brief Interface of a GPS UTC MODEL storage
* \author Javier Arribas, 2013. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#include "beidou_utc_model.h"
#include <cmath>
Beidou_Utc_Model::Beidou_Utc_Model()
{
valid = false;
d_A1 = 0;
d_A0 = 0;
d_t_OT = 0;
i_WN_T = 0;
d_DeltaT_LS = 0;
i_WN_LSF = 0;
i_DN = 0;
d_DeltaT_LSF = 0;
}
double Beidou_Utc_Model::utc_time(double beidoutime_corrected, int i_BEIDOU_week)
{
double t_utc;
double t_utc_daytime;
double Delta_t_UTC = d_DeltaT_LS + d_A0 + d_A1 * (beidoutime_corrected - d_t_OT + 604800 * static_cast<double>(i_BEIDOU_week - i_WN_T));
// Determine if the effectivity time of the leap second event is in the past
int weeksToLeapSecondEvent = i_WN_LSF - i_BEIDOU_week;
if (weeksToLeapSecondEvent >= 0) // is not in the past
{
//Detect if the effectivity time and user's time is within six hours = 6 * 60 *60 = 21600 s
int secondOfLeapSecondEvent = i_DN * 24 * 60 * 60;
if (weeksToLeapSecondEvent > 0)
{
t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
}
else //we are in the same week than the leap second event
{
if (std::abs(beidoutime_corrected - secondOfLeapSecondEvent) > 21600)
{
/* 20.3.3.5.2.4a
* Whenever the effectivity time indicated by the WN_LSF and the DN values
* is not in the past (relative to the user's present time), and the user's
* present time does not fall in the time span which starts at six hours prior
* to the effectivity time and ends at six hours after the effectivity time,
* the UTC/GPS-time relationship is given by
*/
t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
}
else
{
/* 20.3.3.5.2.4b
* Whenever the user's current time falls within the time span of six hours
* prior to the effectivity time to six hours after the effectivity time,
* proper accommodation of the leap second event with a possible week number
* transition is provided by the following expression for UTC:
*/
int W = fmod(beidoutime_corrected - Delta_t_UTC - 43200, 86400) + 43200;
t_utc_daytime = fmod(W, 86400 + d_DeltaT_LSF - d_DeltaT_LS);
//implement something to handle a leap second event!
}
if ((beidoutime_corrected - secondOfLeapSecondEvent) > 21600)
{
Delta_t_UTC = d_DeltaT_LSF + d_A0 + d_A1 * (beidoutime_corrected - d_t_OT + 604800 * static_cast<double>(i_BEIDOU_week - i_WN_T));
t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
}
}
}
else // the effectivity time is in the past
{
/* 20.3.3.5.2.4c
* Whenever the effectivity time of the leap second event, as indicated by the
* WNLSF and DN values, is in the "past" (relative to the user's current time),
* and the user's current time does not fall in the time span as given above
* in 20.3.3.5.2.4b,*/
Delta_t_UTC = d_DeltaT_LSF + d_A0 + d_A1 * (beidoutime_corrected - d_t_OT + 604800 * static_cast<double>(i_BEIDOU_week - i_WN_T));
t_utc_daytime = fmod(beidoutime_corrected - Delta_t_UTC, 86400);
}
double secondsOfWeekBeforeToday = 86400 * floor(beidoutime_corrected / 86400);
t_utc = secondsOfWeekBeforeToday + t_utc_daytime;
return t_utc;
}

View File

@ -0,0 +1,91 @@
/*!
* \file gps_utc_model.h
* \brief Interface of a GPS UTC MODEL storage
* \author Javier Arribas, 2013. jarribas(at)cttc.es
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors)
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS-SDR.
*
* GNSS-SDR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GNSS-SDR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
*
* -------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_BEIDOU_UTC_MODEL_H_
#define GNSS_SDR_BEIDOU_UTC_MODEL_H_
#include <boost/assign.hpp>
#include <boost/serialization/nvp.hpp>
/*!
* \brief This class is a storage for the GPS UTC MODEL data as described in IS-GPS-200E
*
* See http://www.gps.gov/technical/icwg/IS-GPS-200E.pdf Appendix II
*/
class Beidou_Utc_Model
{
public:
bool valid;
// UTC parameters
double d_A1; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s/s]
double d_A0; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s]
double d_t_OT; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200E) [s]
int i_WN_T; //!< UTC reference week number [weeks]
double d_DeltaT_LS; //!< delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac.
int i_WN_LSF; //!< Week number at the end of which the leap second becomes effective [weeks]
int i_DN; //!< Day number (DN) at the end of which the leap second becomes effective [days]
double d_DeltaT_LSF; //!< Scheduled future or recent past (relative to NAV message upload) value of the delta time due to leap seconds [s]
/*!
* Default constructor
*/
Beidou_Utc_Model();
template <class Archive>
/*
* \brief Serialize is a boost standard method to be called by the boost XML serialization. Here is used to save the ephemeris data on disk file.
*/
inline void serialize(Archive& archive, const unsigned int version)
{
using boost::serialization::make_nvp;
if (version)
{
};
archive& make_nvp("valid", valid);
archive& make_nvp("d_A1", d_A1);
archive& make_nvp("d_A0", d_A0);
archive& make_nvp("d_t_OT", d_t_OT);
archive& make_nvp("i_WN_T", i_WN_T);
archive& make_nvp("d_DeltaT_LS", d_DeltaT_LS);
archive& make_nvp("i_WN_LSF", i_WN_LSF);
archive& make_nvp("i_DN", i_DN);
archive& make_nvp("d_DeltaT_LSF", d_DeltaT_LSF);
}
/*!
* \brief Computes the Coordinated Universal Time (UTC) and
* returns it in [s] (IS-GPS-200E, 20.3.3.5.2.4)
*/
double utc_time(double beidoutime_corrected, int i_BEIDOU_week);
};
#endif

View File

@ -34,15 +34,15 @@ if ~exist('dll_pll_veml_read_tracking_dump.m', 'file')
addpath('./libs') addpath('./libs')
end end
samplingFreq = 5000000; %[Hz] samplingFreq = 25000000; %[Hz]
coherent_integration_time_ms = 20; %[ms] coherent_integration_time_ms = 1; %[ms]
channels = 5; % Number of channels channels = 8; % Number of channels
first_channel = 0; % Number of the first channel first_channel = 0; % Number of the first channel
path = '/dump_dir/'; %% CHANGE THIS PATH path = '/home/sergi/gnss/gnss-sdr/install/'; %% CHANGE THIS PATH
for N=1:1:channels for N=1:1:channels
tracking_log_path = [path 'track_ch_' num2str(N+first_channel-1) '.dat']; %% CHANGE track_ch_ BY YOUR dump_filename tracking_log_path = [path 'epl_tracking_ch_' num2str(N+first_channel-1) '.dat']; %% CHANGE track_ch_ BY YOUR dump_filename
GNSS_tracking(N) = dll_pll_veml_read_tracking_dump(tracking_log_path); GNSS_tracking(N) = dll_pll_veml_read_tracking_dump(tracking_log_path);
end end

View File

@ -38,7 +38,7 @@ samplingFreq = 6625000; %[Hz]
channels = 5; channels = 5;
first_channel = 0; first_channel = 0;
path = '/archive/'; %% CHANGE THIS PATH path = '/home/sergi/gnss/gnss-sdr/install/'; %% CHANGE THIS PATH
for N=1:1:channels for N=1:1:channels
tracking_log_path = [path 'epl_tracking_ch_' num2str(N+first_channel-1) '.dat']; %% CHANGE epl_tracking_ch_ BY YOUR dump_filename tracking_log_path = [path 'epl_tracking_ch_' num2str(N+first_channel-1) '.dat']; %% CHANGE epl_tracking_ch_ BY YOUR dump_filename
@ -65,7 +65,7 @@ for N=1:1:channels
trackResults(N).Q_L = zeros(1,length(GNSS_tracking(N).E)); trackResults(N).Q_L = zeros(1,length(GNSS_tracking(N).E));
trackResults(N).PRN = ones(1,length(GNSS_tracking(N).E)); trackResults(N).PRN = ones(1,length(GNSS_tracking(N).E));
trackResults(N).CNo = GNSS_tracking(N).CN0_SNV_dB_Hz.'; trackResults(N).CNo = GNSS_tracking(N).CN0_SNV_dB_Hz.';
% Use original MATLAB tracking plot function % Use original MATLAB tracking plot function
settings.numberOfChannels = channels; settings.numberOfChannels = channels;
settings.msToProcess = length(GNSS_tracking(N).E); settings.msToProcess = length(GNSS_tracking(N).E);

View File

@ -30,7 +30,7 @@
%clear all; %clear all;
samplingFreq = 64e6/16; %[Hz] samplingFreq = 64e6/16; %[Hz]
channels=4; channels=4;
path='/home/javier/workspace/gnss-sdr-ref/trunk/install/'; path='/home/sergi/gnss/gnss-sdr/install/';
clear PRN_absolute_sample_start; clear PRN_absolute_sample_start;
for N=1:1:channels for N=1:1:channels
telemetry_log_path=[path 'telemetry' num2str(N-1) '.dat']; telemetry_log_path=[path 'telemetry' num2str(N-1) '.dat'];

Binary file not shown.