diff --git a/conf/gnss-sdr_BEIDOU_B1I_ishort.conf b/conf/gnss-sdr_BEIDOU_B1I_ishort.conf index 96a59b620..f3f6dfb2e 100644 --- a/conf/gnss-sdr_BEIDOU_B1I_ishort.conf +++ b/conf/gnss-sdr_BEIDOU_B1I_ishort.conf @@ -38,7 +38,7 @@ Resampler.sample_freq_out=25000000 Resampler.item_type=gr_complex ;######### CHANNELS GLOBAL CONFIG ############ -Channels_B1.count=8 +Channels_B1.count=1 Channels.in_acquisition=1 Channel.signal=B1 @@ -47,10 +47,10 @@ Channel.signal=B1 Acquisition_B1.implementation=BEIDOU_B1I_PCPS_Acquisition Acquisition_B1.item_type=gr_complex Acquisition_B1.coherent_integration_time_ms=1 -Acquisition_B1.threshold=18 +Acquisition_B1.threshold=20 ;Acquisition_B1.pfa=0.000001 Acquisition_B1.doppler_max=10000 -Acquisition_B1.doppler_step=250 +Acquisition_B1.doppler_step=2500 Acquisition_B1.dump=true Acquisition_B1.dump_filename=./acq_dump.dat Acquisition_B1.blocking=false; @@ -60,7 +60,7 @@ Acquisition_B1.use_CFAR_algorithm=false Tracking_B1.implementation=BEIDOU_B1I_DLL_PLL_Tracking Tracking_B1.item_type=gr_complex 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.dump=true; Tracking_B1.dump_filename=./epl_tracking_ch_ @@ -68,7 +68,7 @@ Tracking_B1.dump_filename=./epl_tracking_ch_ ;######### TELEMETRY DECODER GPS CONFIG ############ TelemetryDecoder_B1.implementation=BEIDOU_B1I_Telemetry_Decoder -TelemetryDecoder_B1.dump=false +TelemetryDecoder_B1.dump=true ;######### OBSERVABLES CONFIG ############ diff --git a/conf/gnss-sdr_GPS_L1_ishort.conf b/conf/gnss-sdr_GPS_L1_ishort.conf index 9f27aab86..d160f728a 100644 --- a/conf/gnss-sdr_GPS_L1_ishort.conf +++ b/conf/gnss-sdr_GPS_L1_ishort.conf @@ -29,13 +29,14 @@ SignalSource.enable_throttle_control=false ;######### SIGNAL_CONDITIONER CONFIG ############ SignalConditioner.implementation=Signal_Conditioner -DataTypeAdapter.implementation=Ishort_To_Cshort +DataTypeAdapter.implementation=Ishort_To_Complex InputFilter.implementation=Pass_Through -InputFilter.item_type=cshort +InputFilter.item_type=gr_complex Resampler.implementation=Direct_Resampler Resampler.sample_freq_in=4000000 Resampler.sample_freq_out=2000000 -Resampler.item_type=cshort +Resampler.item_type=gr_complex + ;######### CHANNELS GLOBAL CONFIG ############ Channels_1C.count=8 @@ -45,7 +46,7 @@ Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ 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.threshold=0.008 ;Acquisition_1C.pfa=0.000001 @@ -56,8 +57,8 @@ Acquisition_1C.dump_filename=./acq_dump.dat Acquisition_1C.blocking=false; ;######### TRACKING GLOBAL CONFIG ############ -Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking -Tracking_1C.item_type=cshort +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; Tracking_1C.order=3; diff --git a/conf/prova.conf b/conf/prova.conf new file mode 100644 index 000000000..a481302cf --- /dev/null +++ b/conf/prova.conf @@ -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 + + diff --git a/src/algorithms/libs/NHbeidou.cc b/src/algorithms/libs/NHbeidou.cc new file mode 100644 index 000000000..99ff92712 --- /dev/null +++ b/src/algorithms/libs/NHbeidou.cc @@ -0,0 +1,179 @@ +void decodeBCHBeidou(std::list *firstBranch_encoded, std::list *output) +{ + bool input[15]; + std::copy(firstBranch_encoded.begin(),firstBranch_encoded.end(),input); + std::array D_register = {0,0,0,0}; + std::array stage_buffer; + std::array 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 firstBranch_encoded; + std::list firstBranch_decoded; + std::list secondBranch_encoded; + std::list secondBranch_decoded; + std::list 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); +} diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc index 5a41d6c3d..dd81b2d59 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.cc @@ -30,19 +30,19 @@ */ -#include "gps_l1_ca_telemetry_decoder.h" +#include "beidou_b1i_telemetry_decoder.h" #include "configuration_interface.h" -#include "gps_ephemeris.h" -#include "gps_almanac.h" -#include "gps_iono.h" -#include "gps_utc_model.h" +#include "beidou_ephemeris.h" +#include "beidou_almanac.h" +#include "beidou_iono.h" +#include "beidou_utc_model.h" #include #include using google::LogMessage; -GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder(ConfigurationInterface* configuration, +BeidouB1iTelemetryDecoder::BeidouB1iTelemetryDecoder(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams) : role_(role), @@ -54,7 +54,7 @@ GpsL1CaTelemetryDecoder::GpsL1CaTelemetryDecoder(ConfigurationInterface* configu dump_ = configuration->property(role + ".dump", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); // 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() << ")"; channel_ = 0; 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()); 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) { /* 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) { /* 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_; } -gr::basic_block_sptr GpsL1CaTelemetryDecoder::get_right_block() +gr::basic_block_sptr BeidouB1iTelemetryDecoder::get_right_block() { return telemetry_decoder_; } diff --git a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h index 5d499e299..5b39f3d3b 100644 --- a/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h +++ b/src/algorithms/telemetry_decoder/adapters/beidou_b1i_telemetry_decoder.h @@ -30,10 +30,10 @@ */ -#ifndef GNSS_SDR_GPS_L1_CA_TELEMETRY_DECODER_H_ -#define GNSS_SDR_GPS_L1_CA_TELEMETRY_DECODER_H_ +#ifndef GNSS_SDR_BEIDOU_B1I_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 @@ -42,15 +42,15 @@ class ConfigurationInterface; /*! * \brief This class implements a NAV data decoder for GPS L1 C/A */ -class GpsL1CaTelemetryDecoder : public TelemetryDecoderInterface +class BeidouB1iTelemetryDecoder : public TelemetryDecoderInterface { public: - GpsL1CaTelemetryDecoder(ConfigurationInterface* configuration, + BeidouB1iTelemetryDecoder(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams); - virtual ~GpsL1CaTelemetryDecoder(); + virtual ~BeidouB1iTelemetryDecoder(); inline std::string role() override { @@ -82,7 +82,7 @@ public: } private: - gps_l1_ca_telemetry_decoder_cc_sptr telemetry_decoder_; + beidou_b1i_telemetry_decoder_cc_sptr telemetry_decoder_; Gnss_Satellite satellite_; int channel_; bool dump_; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.cc index 78ff3aaa9..40d7e2c2a 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.cc @@ -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 * 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 #include @@ -43,18 +43,19 @@ using google::LogMessage; -gps_l1_ca_telemetry_decoder_cc_sptr -gps_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump) +beidou_b1i_telemetry_decoder_cc_sptr +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, - 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))) { + // Ephemeris data port out this->message_port_register_out(pmt::mp("telemetry")); // 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()); // 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 - d_preambles_symbols = static_cast(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int), volk_gnsssdr_get_alignment())); + d_preambles_symbols = static_cast(volk_gnsssdr_malloc(BEIDOU_B1I_PREAMBLE_LENGTH_SYMBOLS * sizeof(int), volk_gnsssdr_get_alignment())); 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) { 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; } n++; - } } d_stat = 0; d_symbol_accumulator = 0; d_symbol_accumulator_counter = 0; d_frame_bit_index = 0; d_flag_frame_sync = false; - d_GPS_frame_4bytes = 0; - d_prev_GPS_frame_4bytes = 0; + d_BEIDOU_frame_4bytes = 0; + d_prev_BEIDOU_frame_4bytes = 0; d_flag_parity = false; d_TOW_at_Preamble_ms = 0; flag_TOW_set = false; d_flag_preamble = false; d_flag_new_tow_available = false; - d_word_number = 0; + word_number = 0; d_channel = 0; flag_PLL_180_deg_phase_locked = false; d_preamble_time_samples = 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_nh_history.clear(); + d_bit_buffer.clear(); d_make_correlation = true; 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); 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; /* 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 check algorithm described in IS-GPS-200E. This avoids lengthy shift- and-xor loops. */ - d1 = gpsword & 0xFBFFBF00; - d2 = _rotl(gpsword, 1) & 0x07FFBF01; - d3 = _rotl(gpsword, 2) & 0xFC0F8100; - d4 = _rotl(gpsword, 3) & 0xF81FFE02; - d5 = _rotl(gpsword, 4) & 0xFC00000E; - d6 = _rotl(gpsword, 5) & 0x07F00001; - d7 = _rotl(gpsword, 6) & 0x00003000; + d1 = beidouword & 0xFBFFBF00; + d2 = _rotl(beidouword, 1) & 0x07FFBF01; + d3 = _rotl(beidouword, 2) & 0xFC0F8100; + d4 = _rotl(beidouword, 3) & 0xF81FFE02; + d5 = _rotl(beidouword, 4) & 0xFC00000E; + d6 = _rotl(beidouword, 5) & 0x07F00001; + d7 = _rotl(beidouword, 6) & 0x00003000; t = d1 ^ d2 ^ d3 ^ d4 ^ d5 ^ d6 ^ d7; // 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 = parity & 0x3F; - if (parity == (gpsword & 0x3F)) + if (parity == (beidouword & 0x3F)) return (true); else 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()); 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; } -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_GPS_FSM.i_channel_ID = channel; + d_BEIDOU_FSM.i_channel_ID = channel; DLOG(INFO) << "Navigation channel set to " << channel; // ############# ENABLE DATA FILE LOG ################# 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 *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) { int corr_value = 0; int preamble_diff_ms = 0; - + int corr_NH = 0; Gnss_Synchro **out = reinterpret_cast(&output_items[0]); // Get the output buffer pointer const Gnss_Synchro **in = reinterpret_cast(&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 //1. Copy the current tracking output current_symbol = in[0][0]; - d_symbol_history.push_back(current_symbol); //add new symbol to the symbol queue + 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); - unsigned int required_symbols = GPS_CA_PREAMBLE_LENGTH_SYMBOLS; - d_flag_preamble = false; + if (d_symbol_nh_history.size() == BEIDOU_B1I_NH_CODE_LENGTH) + { + 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 ******** - 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).Prompt_I < 0) // symbols clipping + if (d_symbol_history.at(i) < 0) // symbols clipping { 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]; } - } } - 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++; } } - //******* frame sync ****************** - if (std::abs(corr_value) == GPS_CA_PREAMBLE_LENGTH_SYMBOLS) + /*if (new_sym and ) { + 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 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 - d_preamble_time_samples = d_symbol_history.at(0).Tracking_sample_counter; // 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; + d_preamble_time_samples = current_time_samples; // record the preamble sample stamp + DLOG(INFO) << "Preamble detection for SAT " << this->d_satellite << "current_time_samples=" << current_time_samples; //sync the symbol to bits integrator d_symbol_accumulator = 0; d_symbol_accumulator_counter = 0; - d_frame_bit_index = 0; d_stat = 1; // enter into frame pre-detection status } else if (d_stat == 1) //check 6 seconds of preamble separation { - preamble_diff_ms = std::round(((static_cast(d_symbol_history.at(0).Tracking_sample_counter) - d_preamble_time_samples) / static_cast(d_symbol_history.at(0).fs)) * 1000.0); - if (std::abs(preamble_diff_ms - GPS_SUBFRAME_MS) < 1) + // std::cout << "6 SECONDS" << std::endl; + + preamble_diff_ms = std::round(((static_cast(current_time_samples) - d_preamble_time_samples) / static_cast(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; - d_GPS_FSM.Event_gps_word_preamble(); + d_BEIDOU_FSM.Event_beidou_word_preamble(); d_flag_preamble = true; d_make_correlation = false; 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) { 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; } DLOG(INFO) << " Frame sync SAT " << this->d_satellite << " with preamble start at " - << static_cast(d_preamble_time_samples) / static_cast(d_symbol_history.at(0).fs) << " [s]"; + << static_cast(d_preamble_time_samples) / static_cast(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 { 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; } if (d_stat == 1) { - preamble_diff_ms = round(((static_cast(d_symbol_history.at(0).Tracking_sample_counter) - static_cast(d_preamble_time_samples)) / static_cast(d_symbol_history.at(0).fs)) * 1000.0); - if (preamble_diff_ms > GPS_SUBFRAME_MS + 1) + preamble_diff_ms = round(((static_cast(current_time_samples) - static_cast(d_preamble_time_samples)) / static_cast(current_samples_fs)) * 1000.0); + if (preamble_diff_ms > BEIDOU_SUBFRAME_MS + 1) { DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite << " preamble_diff= " << preamble_diff_ms; d_stat = 0; //lost of frame sync @@ -293,73 +470,52 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__ } } } - - //******* SYMBOL TO BIT ******* - if (d_symbol_history.at(0).Flag_valid_symbol_output == true) - { - // extended correlation to bit period is enabled in tracking! - d_symbol_accumulator += d_symbol_history.at(0).Prompt_I; // accumulate the input value in d_symbol_accumulator - d_symbol_accumulator_counter += d_symbol_history.at(0).correlation_length_ms; - } - if (d_symbol_accumulator_counter >= 20) - { - 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; + if (d_flag_frame_sync and new_sym) + { +// std::cout << symbol_value << std::endl; + if (flag_PLL_180_deg_phase_locked) + { + d_bit_buffer.push_back(-symbol_value); + } + else + { + d_bit_buffer.push_back(symbol_value); + } //******* bits to words ****** d_frame_bit_index++; 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; - // parity check - // Each word in wordbuff is composed of: - // Bits 0 to 29 = the GPS data word - // 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(); + memcpy(&d_BEIDOU_FSM.d_BEIDOU_frame_4bytes, &d_BEIDOU_frame_4bytes, sizeof(char) * 4); + //d_BEIDOU_FSM.d_preamble_time_ms = d_preamble_time_seconds * 1000.0; + d_BEIDOU_FSM.Event_beidou_word_valid(); // 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 - 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) - std::shared_ptr tmp_obj = std::make_shared(d_GPS_FSM.d_nav.get_ephemeris()); + std::shared_ptr tmp_obj = std::make_shared(d_BEIDOU_FSM.d_nav.get_ephemeris()); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); } break; 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 tmp_obj = std::make_shared(d_GPS_FSM.d_nav.get_iono()); + std::shared_ptr tmp_obj = std::make_shared(d_BEIDOU_FSM.d_nav.get_iono()); 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 tmp_obj = std::make_shared(d_GPS_FSM.d_nav.get_utc_model()); + std::shared_ptr tmp_obj = std::make_shared(d_BEIDOU_FSM.d_nav.get_utc_model()); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); } break; @@ -370,37 +526,22 @@ int gps_l1_ca_telemetry_decoder_cc::general_work(int noutput_items __attribute__ default: break; } - d_GPS_FSM.clear_flag_new_subframe(); + d_BEIDOU_FSM.clear_flag_new_subframe(); 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 if (this->d_flag_preamble == true and d_flag_new_tow_available == true) { - d_TOW_at_current_symbol_ms = static_cast(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(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; flag_TOW_set = true; d_flag_new_tow_available = false; } 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; @@ -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) { //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) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.h index 52f1f1049..90ccc1151 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/beidou_b1i_telemetry_decoder_cc.h @@ -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 * 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) @@ -28,11 +28,11 @@ * ------------------------------------------------------------------------- */ -#ifndef GNSS_SDR_GPS_L1_CA_TELEMETRY_DECODER_CC_H -#define GNSS_SDR_GPS_L1_CA_TELEMETRY_DECODER_CC_H +#ifndef GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_CC_H +#define GNSS_SDR_BEIDOU_B1I_TELEMETRY_DECODER_CC_H -#include "GPS_L1_CA.h" -#include "gps_l1_ca_subframe_fsm.h" +#include "beidou_b1I.h" +#include "beidou_b1i_subframe_fsm.h" #include "gnss_satellite.h" #include "gnss_synchro.h" #include @@ -40,23 +40,25 @@ #include #include -class gps_l1_ca_telemetry_decoder_cc; +class beidou_b1i_telemetry_decoder_cc; -typedef boost::shared_ptr gps_l1_ca_telemetry_decoder_cc_sptr; +typedef boost::shared_ptr beidou_b1i_telemetry_decoder_cc_sptr; -gps_l1_ca_telemetry_decoder_cc_sptr -gps_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); +beidou_b1i_telemetry_decoder_cc_sptr +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 * */ -class gps_l1_ca_telemetry_decoder_cc : public gr::block +class beidou_b1i_telemetry_decoder_cc : public gr::block { public: - ~gps_l1_ca_telemetry_decoder_cc(); + ~beidou_b1i_telemetry_decoder_cc(); 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 *d_bit_buffer, unsigned int& d_BEIDOU_frame_4bytes); + /*! * \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); private: - friend gps_l1_ca_telemetry_decoder_cc_sptr - gps_l1_ca_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump); + friend beidou_b1i_telemetry_decoder_cc_sptr + 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 @@ -79,7 +81,9 @@ private: bool d_flag_frame_sync; // symbols - boost::circular_buffer d_symbol_history; + boost::circular_buffer d_symbol_history; + boost::circular_buffer d_symbol_nh_history; + boost::circular_buffer d_bit_buffer; double d_symbol_accumulator; short int d_symbol_accumulator_counter; @@ -90,16 +94,17 @@ private: //bits and frame unsigned short int d_frame_bit_index; - unsigned int d_GPS_frame_4bytes; - unsigned int d_prev_GPS_frame_4bytes; + double bits_NH[BEIDOU_B1I_NH_CODE_LENGTH]; + unsigned int d_BEIDOU_frame_4bytes; + unsigned int d_prev_BEIDOU_frame_4bytes; bool d_flag_parity; bool d_flag_preamble; bool d_flag_new_tow_available; int d_word_number; // navigation message vars - Gps_Navigation_Message d_nav; - GpsL1CaSubframeFsm d_GPS_FSM; + Beidou_Navigation_Message_D1 d_nav; + BeidouB1iSubframeFsm d_BEIDOU_FSM; bool d_dump; Gnss_Satellite d_satellite; @@ -109,12 +114,15 @@ private: unsigned int d_TOW_at_Preamble_ms; unsigned int d_TOW_at_current_symbol_ms; - + unsigned int word_number; bool flag_TOW_set; bool flag_PLL_180_deg_phase_locked; std::string d_dump_filename; std::ofstream d_dump_file; + bool sync_NH; + bool new_sym; + }; #endif diff --git a/src/algorithms/telemetry_decoder/libs/CMakeLists.txt b/src/algorithms/telemetry_decoder/libs/CMakeLists.txt index 523ef2df2..3a4e04a1d 100644 --- a/src/algorithms/telemetry_decoder/libs/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/libs/CMakeLists.txt @@ -19,7 +19,8 @@ add_subdirectory(libswiftcnav) 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 ) diff --git a/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.cc b/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.cc new file mode 100644 index 000000000..48ccd8bbe --- /dev/null +++ b/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.cc @@ -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 . + * + * ------------------------------------------------------------------------- + */ + +#include "beidou_b1i_subframe_fsm.h" +#include "gnss_satellite.h" +#include +#include +#include +#include +#include +#include +#include + +//************ GPS WORD TO SUBFRAME DECODER STATE MACHINE ********** +struct Ev_beidou_word_valid : sc::event +{ +}; + + +struct Ev_beidou_word_invalid : sc::event +{ +}; + + +struct Ev_beidou_word_preamble : sc::event +{ +}; + + +struct beidou_subframe_fsm_S0 : public sc::state +{ +public: + // sc::transition(event,next_status) + typedef sc::transition reactions; + beidou_subframe_fsm_S0(my_context ctx) : my_base(ctx) + { + //std::cout<<"Enter S0 "< +{ +public: + typedef mpl::list, + sc::transition > + reactions; + + beidou_subframe_fsm_S1(my_context ctx) : my_base(ctx) + { + //std::cout<<"Enter S1 "< +{ +public: + typedef mpl::list, + sc::transition > + reactions; + + beidou_subframe_fsm_S2(my_context ctx) : my_base(ctx) + { + //std::cout<<"Enter S2 "<().beidou_word_to_subframe(0); + } +}; + + +struct beidou_subframe_fsm_S3 : public sc::state +{ +public: + typedef mpl::list, + sc::transition > + reactions; + + beidou_subframe_fsm_S3(my_context ctx) : my_base(ctx) + { + //std::cout<<"Enter S3 "<().beidou_word_to_subframe(1); + } +}; + + +struct beidou_subframe_fsm_S4 : public sc::state +{ +public: + typedef mpl::list, + sc::transition > + reactions; + + beidou_subframe_fsm_S4(my_context ctx) : my_base(ctx) + { + //std::cout<<"Enter S4 "<().beidou_word_to_subframe(2); + } +}; + + +struct beidou_subframe_fsm_S5 : public sc::state +{ +public: + typedef mpl::list, + sc::transition > + reactions; + + beidou_subframe_fsm_S5(my_context ctx) : my_base(ctx) + { + //std::cout<<"Enter S5 "<().beidou_word_to_subframe(3); + } +}; + + +struct beidou_subframe_fsm_S6 : public sc::state +{ +public: + typedef mpl::list, + sc::transition > + reactions; + + beidou_subframe_fsm_S6(my_context ctx) : my_base(ctx) + { + //std::cout<<"Enter S6 "<().beidou_word_to_subframe(4); + } +}; + + +struct beidou_subframe_fsm_S7 : public sc::state +{ +public: + typedef mpl::list, + sc::transition > + reactions; + + beidou_subframe_fsm_S7(my_context ctx) : my_base(ctx) + { + //std::cout<<"Enter S7 "<().beidou_word_to_subframe(5); + } +}; + + +struct beidou_subframe_fsm_S8 : public sc::state +{ +public: + typedef mpl::list, + sc::transition > + reactions; + + beidou_subframe_fsm_S8(my_context ctx) : my_base(ctx) + { + //std::cout<<"Enter S8 "<().beidou_word_to_subframe(6); + } +}; + + +struct beidou_subframe_fsm_S9 : public sc::state +{ +public: + typedef mpl::list, + sc::transition > + reactions; + + beidou_subframe_fsm_S9(my_context ctx) : my_base(ctx) + { + //std::cout<<"Enter S9 "<().beidou_word_to_subframe(7); + } +}; + + +struct beidou_subframe_fsm_S10 : public sc::state +{ +public: + typedef mpl::list, + sc::transition > + reactions; + + beidou_subframe_fsm_S10(my_context ctx) : my_base(ctx) + { + //std::cout<<"Enter S10 "<().beidou_word_to_subframe(8); + } +}; + + +struct beidou_subframe_fsm_S11 : public sc::state +{ +public: + typedef sc::transition reactions; + + beidou_subframe_fsm_S11(my_context ctx) : my_base(ctx) + { + //std::cout<<"Completed GPS Subframe!"<().beidou_word_to_subframe(9); + context().beidou_subframe_to_nav_msg(); //decode the subframe + // DECODE SUBFRAME + //std::cout<<"Enter S11"<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()); +} diff --git a/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.h b/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.h new file mode 100644 index 000000000..e8f2f4400 --- /dev/null +++ b/src/algorithms/telemetry_decoder/libs/beidou_b1i_subframe_fsm.h @@ -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 . + * + * ------------------------------------------------------------------------- + */ + + +#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 + +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 +{ +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 diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index b255d4b30..3fa9aa175 100755 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -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_correlation_length_ms = 1; d_code_samples_per_chip = 1; - d_secondary = false; + d_secondary = true; trk_parameters.track_pilot = false; interchange_iq = false; + d_secondary_code_length = static_cast(BEIDOU_B1I_NH_CODE_LENGTH); + d_secondary_code_string = const_cast(&BEIDOU_B1I_NH_CODE_STR); + } else { diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index bcb1366ea..5cc056b4e 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -1712,7 +1712,7 @@ std::unique_ptr GNSSBlockFactory::GetBlock( } else if (implementation.compare("BEIDOU_B1I_Telemetry_Decoder") == 0) { - std::unique_ptr block_(new GpsL1CaTelemetryDecoder(configuration.get(), role, in_streams, + std::unique_ptr block_(new BeidouB1iTelemetryDecoder(configuration.get(), role, in_streams, out_streams)); block = std::move(block_); } @@ -2061,7 +2061,7 @@ std::unique_ptr GNSSBlockFactory::GetTlmBlock( } else if (implementation.compare("BEIDOU_B1I_Telemetry_Decoder") == 0) { - std::unique_ptr block_(new GpsL1CaTelemetryDecoder(configuration.get(), role, in_streams, + std::unique_ptr block_(new BeidouB1iTelemetryDecoder(configuration.get(), role, in_streams, out_streams)); block = std::move(block_); } diff --git a/src/core/system_parameters/.beidou_b1I.h.swo b/src/core/system_parameters/.beidou_b1I.h.swo new file mode 100644 index 000000000..6bac9f2bf Binary files /dev/null and b/src/core/system_parameters/.beidou_b1I.h.swo differ diff --git a/src/core/system_parameters/CMakeLists.txt b/src/core/system_parameters/CMakeLists.txt index 2d7c10f23..fa4f53068 100644 --- a/src/core/system_parameters/CMakeLists.txt +++ b/src/core/system_parameters/CMakeLists.txt @@ -32,6 +32,11 @@ set(SYSTEM_PARAMETERS_SOURCES galileo_almanac.cc galileo_iono.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 galileo_fnav_message.cc gps_cnav_ephemeris.cc diff --git a/src/core/system_parameters/beidou_almanac.cc b/src/core/system_parameters/beidou_almanac.cc new file mode 100644 index 000000000..e2890d403 --- /dev/null +++ b/src/core/system_parameters/beidou_almanac.cc @@ -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 . + * + * ------------------------------------------------------------------------- + */ + +#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; +} diff --git a/src/core/system_parameters/beidou_almanac.h b/src/core/system_parameters/beidou_almanac.h new file mode 100644 index 000000000..b25e55c76 --- /dev/null +++ b/src/core/system_parameters/beidou_almanac.h @@ -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 . + * + * ------------------------------------------------------------------------- + */ + + +#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 diff --git a/src/core/system_parameters/beidou_b1I.h b/src/core/system_parameters/beidou_b1I.h index e587eef4d..848649511 100644 --- a/src/core/system_parameters/beidou_b1I.h +++ b/src/core/system_parameters/beidou_b1I.h @@ -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_LENGTH_CHIPS = 2046.0; //!< beidou b1I code length [chips] 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] /*! @@ -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} 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_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] @@ -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_MS = 6000; //!< Subframe duration [miliseconds] 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 @@ -91,6 +97,8 @@ const int BEIDOU_WORD_BITS = 30; //!< Number of bits per w const std::vector > D1_PRE( { {1,11} } ); const std::vector > D1_FRAID( { {16,3} } ); const std::vector > D1_SOW( { {19,8},{31,12} } ); +const std::vector > D1_PNUM( { {44,7} } ); + // SUBFRAME 1 const std::vector > D1_SAT_H1( { {43,1} } ); const std::vector > D1_AODC( { {44,5} } ); diff --git a/src/core/system_parameters/beidou_ephemeris.cc b/src/core/system_parameters/beidou_ephemeris.cc index 297d94a36..f442e45fe 100644 --- a/src/core/system_parameters/beidou_ephemeris.cc +++ b/src/core/system_parameters/beidou_ephemeris.cc @@ -60,10 +60,10 @@ Beidou_Ephemeris::Beidou_Ephemeris() i_SV_health = 0; d_AODE = 0; d_TGD1 = 0; - d_TGD2 = 0: + d_TGD2 = 0; 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] - + 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. d_spare1 = 0; d_spare2 = 0; diff --git a/src/core/system_parameters/beidou_ephemeris.h b/src/core/system_parameters/beidou_ephemeris.h index 0d2b978ab..0dc26a291 100644 --- a/src/core/system_parameters/beidou_ephemeris.h +++ b/src/core/system_parameters/beidou_ephemeris.h @@ -155,10 +155,10 @@ public: 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_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_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_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] @@ -199,7 +199,7 @@ public: /*! * Default constructor */ - Gps_Ephemeris(); + Beidou_Ephemeris(); }; #endif diff --git a/src/core/system_parameters/beidou_navigation_message.cc b/src/core/system_parameters/beidou_navigation_message.cc index d6b906dd9..cc571af74 100644 --- a/src/core/system_parameters/beidou_navigation_message.cc +++ b/src/core/system_parameters/beidou_navigation_message.cc @@ -35,15 +35,15 @@ m * \file beidou_navigation_message.cc #include -void Beidou_Navigation_Message::reset() +void Beidou_Navigation_Message_D1::reset() { b_valid_ephemeris_set_flag = false; - d_TOW = 0; - d_TOW_SF1 = 0; - d_TOW_SF2 = 0; - d_TOW_SF3 = 0; - d_TOW_SF4 = 0; - d_TOW_SF5 = 0; + d_SOW = 0; + d_SOW_SF1 = 0; + d_SOW_SF2 = 0; + d_SOW_SF3 = 0; + d_SOW_SF4 = 0; + d_SOW_SF5 = 0; d_AODE = 0; d_Crs = 0; d_Delta_n = 0; @@ -65,7 +65,8 @@ void Beidou_Navigation_Message::reset() i_BEIDOU_week = 0; i_SV_accuracy = 0; i_SV_health = 0; - d_TGD = 0; + d_TGD1 = 0; + d_TGD2 = 0; d_AODC = -1; // i_AODO = 0; @@ -111,8 +112,8 @@ void Beidou_Navigation_Message::reset() d_beta1 = 0; d_beta2 = 0; d_beta3 = 0; - d_A1 = 0; - d_A0 = 0; + d_A1UTC = 0; + d_A0UTC = 0; d_t_OT = 0; i_WN_T = 0; d_DeltaT_LS = 0; @@ -132,6 +133,28 @@ void Beidou_Navigation_Message::reset() d_satvel_X = 0; d_satvel_Y = 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(); 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(); } -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 << 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 bits, const std::vector> parameter) +bool Beidou_Navigation_Message_D1::read_navigation_bool(std::bitset bits, const std::vector> parameter) { bool value; @@ -175,7 +198,7 @@ bool Beidou_Navigation_Message::read_navigation_bool(std::bitset bits, const std::vector> parameter) +unsigned long int Beidou_Navigation_Message_D1::read_navigation_unsigned(std::bitset bits, const std::vector> parameter) { unsigned long int value = 0; int num_of_slices = parameter.size(); @@ -193,7 +216,7 @@ unsigned long int Beidou_Navigation_Message::read_navigation_unsigned(std::bitse return value; } -signed long int Beidou_Navigation_Message::read_navigation_signed(std::bitset bits, const std::vector> parameter) +signed long int Beidou_Navigation_Message_D1::read_navigation_signed(std::bitset bits, const std::vector> parameter) { signed long int value = 0; int num_of_slices = parameter.size(); @@ -252,7 +275,7 @@ signed long int Beidou_Navigation_Message::read_navigation_signed(std::bitset 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; @@ -394,10 +425,17 @@ int Beidou_Navigation_Message::subframe_decoder(char *subframe) for (int j = 0; j < BEIDOU_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(read_navigation_unsigned(subframe_bits, SUBFRAME_ID)); + std::cout << std::endl; + subframe_ID = static_cast(read_navigation_unsigned(subframe_bits, D1_FRAID)); // Decode all 5 sub-frames switch (subframe_ID) @@ -405,100 +443,203 @@ int Beidou_Navigation_Message::subframe_decoder(char *subframe) //--- Decode the sub-frame id ------------------------------------------ case 1: //--- It is subframe 1 ------------------------------------- - // Compute the time of week (TOW) of the first sub-frames in the array ==== - // The transmitted TOW is actual TOW of the next subframe + // Compute the time of week (SOW) of the first sub-frames in the array ==== + // The transmitted SOW is actual SOW of the next subframe // (the variable subframe at this point contains bits of the last subframe). - //TOW = bin2dec(subframe(31:47)) * 6; - d_TOW_SF1 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); - //we are in the first subframe (the transmitted TOW is the start time of the next subframe) ! - d_TOW_SF1 = d_TOW_SF1 * 6; - d_TOW = d_TOW_SF1; // 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); - i_GPS_week = static_cast(read_navigation_unsigned(subframe_bits, GPS_WEEK)); - i_SV_accuracy = static_cast(read_navigation_unsigned(subframe_bits, SV_ACCURACY)); // (20.3.3.3.1.3) - i_SV_health = static_cast(read_navigation_unsigned(subframe_bits, SV_HEALTH)); - b_L2_P_data_flag = read_navigation_bool(subframe_bits, L2_P_DATA_FLAG); // - i_code_on_L2 = static_cast(read_navigation_unsigned(subframe_bits, CA_OR_P_ON_L2)); - d_TGD = static_cast(read_navigation_signed(subframe_bits, T_GD)); - d_TGD = d_TGD * T_GD_LSB; - d_IODC = static_cast(read_navigation_unsigned(subframe_bits, IODC)); - d_Toc = static_cast(read_navigation_unsigned(subframe_bits, T_OC)); - d_Toc = d_Toc * T_OC_LSB; - d_A_f0 = static_cast(read_navigation_signed(subframe_bits, A_F0)); - d_A_f0 = d_A_f0 * A_F0_LSB; - d_A_f1 = static_cast(read_navigation_signed(subframe_bits, A_F1)); - d_A_f1 = d_A_f1 * A_F1_LSB; - d_A_f2 = static_cast(read_navigation_signed(subframe_bits, A_F2)); - d_A_f2 = d_A_f2 * A_F2_LSB; + //SOW = bin2dec(subframe(31:47)) * 6; + //we are in the first subframe (the transmitted SOW is the start time of the next subframe) ! + //d_SOW_SF1 = d_SOW_SF1 * 6; + //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); + //i_SV_accuracy = static_cast(read_navigation_unsigned(subframe_bits, SV_ACCURACY)); // (20.3.3.3.1.3) + // b_L2_P_data_flag = read_navigation_bool(subframe_bits, L2_P_DATA_FLAG); // + //i_code_on_L2 = static_cast(read_navigation_unsigned(subframe_bits, CA_OR_P_ON_L2)); + + + d_SOW_SF1 = static_cast(read_navigation_unsigned(subframe_bits, D1_SOW)); + d_SOW = d_SOW_SF1; // Set transmission time + +std::cout << "I decoded subframe 1" << std::endl; +std::cout << "TOW: " << d_SOW_SF1 << std::endl; + + i_SV_health = static_cast(read_navigation_unsigned(subframe_bits, D1_SAT_H1)); + + d_AODC = static_cast(read_navigation_unsigned(subframe_bits, D1_AODC)); + i_SV_accuracy = static_cast(read_navigation_unsigned(subframe_bits, D1_URAI)); // (20.3.3.3.1.3) + + i_BEIDOU_week = static_cast(read_navigation_unsigned(subframe_bits, D1_WN)); + + d_Toc = static_cast(read_navigation_unsigned(subframe_bits, D1_TOC)); + d_Toc = d_Toc * D1_TOC_LSB; + + d_TGD1 = static_cast(read_navigation_signed(subframe_bits, D1_TGD1)); + d_TGD1 = d_TGD1 * D1_TGD1_LSB; + + d_TGD2 = static_cast(read_navigation_signed(subframe_bits, D1_TGD2)); + d_TGD2 = d_TGD2 * D1_TGD2_LSB; + + d_alpha0 = static_cast(read_navigation_signed(subframe_bits, D1_ALPHA0)); + d_alpha0 = d_alpha0 * D1_ALPHA0_LSB; + + d_alpha1 = static_cast(read_navigation_signed(subframe_bits, D1_ALPHA1)); + d_alpha1 = d_alpha1 * D1_ALPHA1_LSB; + d_alpha2 = static_cast(read_navigation_signed(subframe_bits, D1_ALPHA2)); + d_alpha2 = d_alpha2 * D1_ALPHA2_LSB; + d_alpha3 = static_cast(read_navigation_signed(subframe_bits, D1_ALPHA3)); + d_alpha3 = d_alpha3 * D1_ALPHA3_LSB; + d_beta0 = static_cast(read_navigation_signed(subframe_bits, D1_BETA0)); + d_beta0 = d_beta0 * D1_BETA0_LSB; + d_beta1 = static_cast(read_navigation_signed(subframe_bits, D1_BETA1)); + d_beta1 = d_beta1 * D1_BETA1_LSB; + d_beta2 = static_cast(read_navigation_signed(subframe_bits, D1_BETA2)); + d_beta2 = d_beta2 * D1_BETA2_LSB; + d_beta3 = static_cast(read_navigation_signed(subframe_bits, D1_BETA3)); + d_beta3 = d_beta3 * D1_BETA3_LSB; + + d_A2 = static_cast(read_navigation_signed(subframe_bits, D1_A2)); + d_A2 = d_A2 * D1_A2_LSB; + + d_A0 = static_cast(read_navigation_signed(subframe_bits, D1_A0)); + d_A0 = d_A0 * D1_A0_LSB; + + d_A1 = static_cast(read_navigation_signed(subframe_bits, D1_A1)); + d_A1 = d_A1 * D1_A1_LSB; + + d_AODE_SF1 = static_cast(read_navigation_unsigned(subframe_bits, D1_AODE)); + + //d_A_f0 = static_cast(read_navigation_signed(subframe_bits, A_F0)); + //d_A_f0 = d_A_f0 * A_F0_LSB; + //d_A_f1 = static_cast(read_navigation_signed(subframe_bits, A_F1)); + //d_A_f1 = d_A_f1 * A_F1_LSB; + //d_A_f2 = static_cast(read_navigation_signed(subframe_bits, A_F2)); + //d_A_f2 = d_A_f2 * A_F2_LSB; break; case 2: //--- It is subframe 2 ------------------- - d_TOW_SF2 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); - d_TOW_SF2 = d_TOW_SF2 * 6; - d_TOW = d_TOW_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); - d_IODE_SF2 = static_cast(read_navigation_unsigned(subframe_bits, IODE_SF2)); - d_Crs = static_cast(read_navigation_signed(subframe_bits, C_RS)); - d_Crs = d_Crs * C_RS_LSB; - d_Delta_n = static_cast(read_navigation_signed(subframe_bits, DELTA_N)); - d_Delta_n = d_Delta_n * DELTA_N_LSB; - d_M_0 = static_cast(read_navigation_signed(subframe_bits, M_0)); - d_M_0 = d_M_0 * M_0_LSB; - d_Cuc = static_cast(read_navigation_signed(subframe_bits, C_UC)); - d_Cuc = d_Cuc * C_UC_LSB; - d_e_eccentricity = static_cast(read_navigation_unsigned(subframe_bits, E)); - d_e_eccentricity = d_e_eccentricity * E_LSB; - d_Cus = static_cast(read_navigation_signed(subframe_bits, C_US)); - d_Cus = d_Cus * C_US_LSB; - d_sqrt_A = static_cast(read_navigation_unsigned(subframe_bits, SQRT_A)); - d_sqrt_A = d_sqrt_A * SQRT_A_LSB; - d_Toe = static_cast(read_navigation_unsigned(subframe_bits, T_OE)); - d_Toe = d_Toe * T_OE_LSB; - b_fit_interval_flag = read_navigation_bool(subframe_bits, FIT_INTERVAL_FLAG); - i_AODO = static_cast(read_navigation_unsigned(subframe_bits, AODO)); - i_AODO = i_AODO * AODO_LSB; + + + d_SOW_SF2 = static_cast(read_navigation_unsigned(subframe_bits, D1_SOW)); + d_SOW = d_SOW_SF2; // Set transmission time + +std::cout << "I decoded subframe 2" << std::endl; +std::cout << "TOW: " << d_SOW_SF2 << std::endl; + + d_Cuc = static_cast(read_navigation_signed(subframe_bits, D1_CUC)); + d_Cuc = d_Cuc * D1_CUC_LSB; + + d_M_0 = static_cast(read_navigation_signed(subframe_bits, D1_M0)); + d_M_0 = d_M_0 * D1_M0_LSB; + + d_e_eccentricity = static_cast(read_navigation_unsigned(subframe_bits, D1_E)); + d_e_eccentricity = d_e_eccentricity * D1_E_LSB; + + d_Cus = static_cast(read_navigation_signed(subframe_bits, D1_CUS)); + d_Cus = d_Cus * D1_CUS_LSB; + + d_Crc = static_cast(read_navigation_signed(subframe_bits, D1_CRC)); + d_Crc = d_Crc * D1_CRC_LSB; + + d_Crs = static_cast(read_navigation_signed(subframe_bits, D1_CRS)); + d_Crs = d_Crs * D1_CRS_LSB; + + d_sqrt_A = static_cast(read_navigation_unsigned(subframe_bits, D1_SQRT_A)); + d_sqrt_A = d_sqrt_A * D1_SQRT_A_LSB; + + d_Toe = static_cast(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(read_navigation_unsigned(subframe_bits, AODO)); +// i_AODO = i_AODO * AODO_LSB; break; case 3: // --- It is subframe 3 ------------------------------------- - d_TOW_SF3 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); - d_TOW_SF3 = d_TOW_SF3 * 6; - d_TOW = d_TOW_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_Cic = static_cast(read_navigation_signed(subframe_bits, C_IC)); - d_Cic = d_Cic * C_IC_LSB; - d_OMEGA0 = static_cast(read_navigation_signed(subframe_bits, OMEGA_0)); - d_OMEGA0 = d_OMEGA0 * OMEGA_0_LSB; - d_Cis = static_cast(read_navigation_signed(subframe_bits, C_IS)); - d_Cis = d_Cis * C_IS_LSB; - d_i_0 = static_cast(read_navigation_signed(subframe_bits, I_0)); - d_i_0 = d_i_0 * I_0_LSB; - d_Crc = static_cast(read_navigation_signed(subframe_bits, C_RC)); - d_Crc = d_Crc * C_RC_LSB; - d_OMEGA = static_cast(read_navigation_signed(subframe_bits, OMEGA)); - d_OMEGA = d_OMEGA * OMEGA_LSB; - d_OMEGA_DOT = static_cast(read_navigation_signed(subframe_bits, OMEGA_DOT)); - d_OMEGA_DOT = d_OMEGA_DOT * OMEGA_DOT_LSB; - d_IODE_SF3 = static_cast(read_navigation_unsigned(subframe_bits, IODE_SF3)); - d_IDOT = static_cast(read_navigation_signed(subframe_bits, I_DOT)); - d_IDOT = d_IDOT * I_DOT_LSB; + + d_SOW_SF3 = static_cast(read_navigation_unsigned(subframe_bits, D1_SOW)); + d_SOW = d_SOW_SF3; // Set transmission time + +std::cout << "I decoded subframe 3" << std::endl; +std::cout << "TOW: " << d_SOW_SF3 << std::endl; + + d_Toe = d_Toe * D1_TOE_LSB; + + d_i_0 = static_cast(read_navigation_signed(subframe_bits, D1_I0)); + d_i_0 = d_i_0 * D1_I0_LSB; + + d_Cic = static_cast(read_navigation_signed(subframe_bits, D1_CIC)); + d_Cic = d_Cic * D1_CIC_LSB; + + d_OMEGA_DOT = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA_DOT)); + d_OMEGA_DOT = d_OMEGA_DOT * D1_OMEGA_DOT_LSB; + + d_Cis = static_cast(read_navigation_signed(subframe_bits, D1_CIS)); + d_Cis = d_Cis * D1_CIS_LSB; + + d_IDOT = static_cast(read_navigation_signed(subframe_bits, D1_IDOT)); + d_IDOT = d_IDOT * D1_IDOT_LSB; + + d_OMEGA0 = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA0)); + d_OMEGA0 = d_OMEGA0 * D1_OMEGA0_LSB; + + d_OMEGA = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA)); + d_OMEGA = d_OMEGA * D1_OMEGA_LSB; + + //d_SOW_SF3 = static_cast(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(read_navigation_unsigned(subframe_bits, AODE_SF3)); break; case 4: // --- It is subframe 4 ---------- Almanac, ionospheric model, UTC parameters, SV health (PRN: 25-32) - int SV_data_ID; - int SV_page; - d_TOW_SF4 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); - d_TOW_SF4 = d_TOW_SF4 * 6; - d_TOW = d_TOW_SF4; // Set transmission time - b_integrity_status_flag = read_navigation_bool(subframe_bits, INTEGRITY_STATUS_FLAG); + d_SOW_SF4 = static_cast(read_navigation_unsigned(subframe_bits, D1_SOW)); + d_SOW = d_SOW_SF4; // Set transmission time + +std::cout << "I decoded subframe 4" << std::endl; +std::cout << "TOW: " << d_SOW_SF4 << std::endl; + + d_SQRT_A_ALMANAC = static_cast(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(read_navigation_signed(subframe_bits, D1_A1_ALMANAC)); + d_A1_ALMANAC = d_A1_ALMANAC * D1_A1_ALMANAC_LSB; + + d_A0_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_A0_ALMANAC)); + d_A0_ALMANAC = d_A0_ALMANAC * D1_A0_ALMANAC_LSB; + + d_OMEGA0_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA0_ALMANAC)); + d_OMEGA0_ALMANAC = d_OMEGA0_ALMANAC * D1_OMEGA0_ALMANAC_LSB; + + d_E_ALMANAC = static_cast(read_navigation_unsigned(subframe_bits, D1_E)); + d_E_ALMANAC = d_E_ALMANAC * D1_E_ALMANAC_LSB; + + d_DELTA_I = static_cast(read_navigation_signed(subframe_bits, D1_DELTA_I)); + d_DELTA_I = D1_DELTA_I_LSB; + + d_TOA = static_cast(read_navigation_unsigned(subframe_bits, D1_TOA)); + d_TOA = d_TOA * D1_TOA_LSB; + + d_OMEGA_DOT_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA_DOT_ALMANAC)); + d_OMEGA_DOT_ALMANAC = D1_OMEGA_DOT_ALMANAC_LSB; + + d_OMEGA_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA_ALMANAC)); + d_OMEGA_ALMANAC = d_OMEGA_ALMANAC * D1_OMEGA_ALMANAC_LSB; + + d_M0_ALMANAC = static_cast(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_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG); SV_data_ID = static_cast(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) { // Page 18 - Ionospheric and UTC data - d_alpha0 = static_cast(read_navigation_signed(subframe_bits, ALPHA_0)); - d_alpha0 = d_alpha0 * ALPHA_0_LSB; - d_alpha1 = static_cast(read_navigation_signed(subframe_bits, ALPHA_1)); - d_alpha1 = d_alpha1 * ALPHA_1_LSB; - d_alpha2 = static_cast(read_navigation_signed(subframe_bits, ALPHA_2)); - d_alpha2 = d_alpha2 * ALPHA_2_LSB; - d_alpha3 = static_cast(read_navigation_signed(subframe_bits, ALPHA_3)); - d_alpha3 = d_alpha3 * ALPHA_3_LSB; - d_beta0 = static_cast(read_navigation_signed(subframe_bits, BETA_0)); - d_beta0 = d_beta0 * BETA_0_LSB; - d_beta1 = static_cast(read_navigation_signed(subframe_bits, BETA_1)); - d_beta1 = d_beta1 * BETA_1_LSB; - d_beta2 = static_cast(read_navigation_signed(subframe_bits, BETA_2)); - d_beta2 = d_beta2 * BETA_2_LSB; - d_beta3 = static_cast(read_navigation_signed(subframe_bits, BETA_3)); - d_beta3 = d_beta3 * BETA_3_LSB; - d_A1 = static_cast(read_navigation_signed(subframe_bits, A_1)); - d_A1 = d_A1 * A_1_LSB; - d_A0 = static_cast(read_navigation_signed(subframe_bits, A_0)); - d_A0 = d_A0 * A_0_LSB; d_t_OT = static_cast(read_navigation_unsigned(subframe_bits, T_OT)); d_t_OT = d_t_OT * T_OT_LSB; i_WN_T = static_cast(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) //! \TODO Read Anti-Spoofing, SV config - almanacHealth[25] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV25)); - almanacHealth[26] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV26)); - almanacHealth[27] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV27)); - almanacHealth[28] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV28)); - almanacHealth[29] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV29)); - almanacHealth[30] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV30)); - almanacHealth[31] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV31)); - almanacHealth[32] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV32)); + almanacHealth[25] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA25)); + almanacHealth[26] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA26)); + almanacHealth[27] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA27)); + almanacHealth[28] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA28)); + almanacHealth[29] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA29)); + almanacHealth[30] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA30)); + almanacHealth[31] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA31)); + almanacHealth[32] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA32)); } break; - +*/ 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; - d_TOW_SF5 = static_cast(read_navigation_unsigned(subframe_bits, TOW)); - d_TOW_SF5 = d_TOW_SF5 * 6; - d_TOW = d_TOW_SF5; // 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); - SV_data_ID_5 = static_cast(read_navigation_unsigned(subframe_bits, SV_DATA_ID)); - SV_page_5 = static_cast(read_navigation_unsigned(subframe_bits, SV_PAGE)); - if (SV_page_5 < 25) + d_SOW_SF5 = static_cast(read_navigation_unsigned(subframe_bits, D1_SOW)); + d_SOW = d_SOW_SF5; // Set transmission time + +std::cout << "I decoded subframe 5" << std::endl; +std::cout << "TOW: " << d_SOW_SF5 << std::endl; + + + SV_page_5 = static_cast(read_navigation_unsigned(subframe_bits, D1_PNUM)); + + if (SV_page_5 < 7) + { + d_SOW_SF4 = static_cast(read_navigation_unsigned(subframe_bits, D1_SOW)); + d_SQRT_A_ALMANAC = static_cast(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(read_navigation_signed(subframe_bits, D1_A1_ALMANAC)); + d_A1UTC = d_A1UTC * D1_A1_ALMANAC_LSB; + + d_A0_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_A0_ALMANAC)); + d_A0_ALMANAC = d_A0_ALMANAC * D1_A0_ALMANAC_LSB; + + d_OMEGA0_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA0_ALMANAC)); + d_OMEGA0_ALMANAC = d_OMEGA0_ALMANAC * D1_OMEGA0_ALMANAC_LSB; + + d_E_ALMANAC = static_cast(read_navigation_unsigned(subframe_bits, D1_E)); + d_E_ALMANAC = d_E_ALMANAC * D1_E_ALMANAC_LSB; + + d_DELTA_I = static_cast(read_navigation_signed(subframe_bits, D1_DELTA_I)); + d_DELTA_I = D1_DELTA_I_LSB; + + d_TOA = static_cast(read_navigation_unsigned(subframe_bits, D1_TOA)); + d_TOA = d_TOA * D1_TOA_LSB; + + d_OMEGA_DOT_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA_DOT_ALMANAC)); + d_OMEGA_DOT_ALMANAC = D1_OMEGA_DOT_ALMANAC_LSB; + + d_OMEGA_ALMANAC = static_cast(read_navigation_signed(subframe_bits, D1_OMEGA_ALMANAC)); + d_OMEGA_ALMANAC = d_OMEGA_ALMANAC * D1_OMEGA_ALMANAC_LSB; + + d_M0_ALMANAC = static_cast(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 - if(SV_data_ID_5){} + almanacHealth[1] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA1)); + almanacHealth[2] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA2)); + almanacHealth[3] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA3)); + almanacHealth[4] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA4)); + almanacHealth[5] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA5)); + almanacHealth[6] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA6)); + almanacHealth[7] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA7)); + almanacHealth[8] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA8)); + almanacHealth[9] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA9)); + almanacHealth[10] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA10)); + almanacHealth[11] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA11)); + almanacHealth[12] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA12)); + almanacHealth[13] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA13)); + almanacHealth[14] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA14)); + almanacHealth[15] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA15)); + almanacHealth[16] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA16)); + almanacHealth[17] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA17)); + almanacHealth[18] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA18)); + almanacHealth[19] = static_cast(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(read_navigation_unsigned(subframe_bits, T_OA)); - d_Toa = d_Toa * T_OA_LSB; - i_WN_A = static_cast(read_navigation_unsigned(subframe_bits, WN_A)); - almanacHealth[1] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV1)); - almanacHealth[2] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV2)); - almanacHealth[3] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV3)); - almanacHealth[4] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV4)); - almanacHealth[5] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV5)); - almanacHealth[6] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV6)); - almanacHealth[7] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV7)); - almanacHealth[8] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV8)); - almanacHealth[9] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV9)); - almanacHealth[10] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV10)); - almanacHealth[11] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV11)); - almanacHealth[12] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV12)); - almanacHealth[13] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV13)); - almanacHealth[14] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV14)); - almanacHealth[15] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV15)); - almanacHealth[16] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV16)); - almanacHealth[17] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV17)); - almanacHealth[18] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV18)); - almanacHealth[19] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV19)); - almanacHealth[20] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV20)); - almanacHealth[21] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV21)); - almanacHealth[22] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV22)); - almanacHealth[23] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV23)); - almanacHealth[24] = static_cast(read_navigation_unsigned(subframe_bits, HEALTH_SV24)); + almanacHealth[20] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA20)); + almanacHealth[21] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA21)); + almanacHealth[22] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA22)); + almanacHealth[23] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA23)); + almanacHealth[24] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA24)); + almanacHealth[25] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA25)); + almanacHealth[26] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA26)); + almanacHealth[27] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA27)); + almanacHealth[28] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA28)); + almanacHealth[29] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA29)); + almanacHealth[30] = static_cast(read_navigation_unsigned(subframe_bits, D1_HEA30)); + almanac_WN = static_cast(read_navigation_unsigned(subframe_bits, D1_WNA)); + d_toa2 = static_cast(read_navigation_unsigned(subframe_bits, D1_TOA2)); + } + + 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(read_navigation_unsigned(subframe_bits, D1_A0GPS)); + d_A0GPS = d_A0GPS * D1_A0GPS_LSB; + + d_A1GPS = static_cast(read_navigation_unsigned(subframe_bits, D1_A1GPS)); + d_A1GPS = d_A1GPS * D1_A1GPS_LSB; + + d_A0GAL = static_cast(read_navigation_unsigned(subframe_bits, D1_A0GAL)); + d_A0GAL = d_A0GAL * D1_A0GAL_LSB; + + d_A1GAL = static_cast(read_navigation_unsigned(subframe_bits, D1_A1GAL)); + d_A1GAL = d_A1GAL* D1_A1GAL_LSB; + + d_A0GLO = static_cast(read_navigation_unsigned(subframe_bits, D1_A0GLO)); + d_A0GLO = d_A0GLO * D1_A0GLO_LSB; + + d_A1GLO = static_cast(read_navigation_unsigned(subframe_bits, D1_A1GLO)); + d_A1GLO = d_A1GLO* D1_A1GLO_LSB; + } + if (SV_page_5 == 10) + { + d_DeltaT_LS = static_cast(read_navigation_signed(subframe_bits, D1_DELTA_T_LS)); + + } + + + break; 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_daytime; - double Delta_t_UTC = d_DeltaT_LS + d_A0 + d_A1 * (gpstime_corrected - d_t_OT + 604800 * static_cast((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 - int weeksToLeapSecondEvent = i_WN_LSF - i_GPS_week; + int weeksToLeapSecondEvent = i_WN_LSF - i_BEIDOU_week; 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; 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 { - if (std::abs(gpstime_corrected - secondOfLeapSecondEvent) > 21600) + if ((beidoutime_corrected - secondOfLeapSecondEvent) < (2/3) * 24 * 60 * 60) { - /* 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(gpstime_corrected - Delta_t_UTC, 86400); + 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(gpstime_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 ( (gpstime_corrected - secondOfLeapSecondEvent) > 21600) - { - Delta_t_UTC = d_DeltaT_LSF + d_A0 + d_A1 * (gpstime_corrected - d_t_OT + 604800 * static_cast((i_GPS_week - i_WN_T))); - t_utc_daytime = fmod(gpstime_corrected - Delta_t_UTC, 86400); + if ((beidoutime_corrected - secondOfLeapSecondEvent) < (5/4) * 24 * 60 * 60) + { + int W = fmod(beidoutime_corrected - Delta_t_UTC - 43200, 86400) + 43200; + t_utc_daytime = fmod(W, 86400 + d_DeltaT_LSF - d_DeltaT_LS); + } + else + { + 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 * (gpstime_corrected - d_t_OT + 604800 * static_cast((i_GPS_week - i_WN_T))); - t_utc_daytime = fmod(gpstime_corrected - Delta_t_UTC, 86400); + t_utc_daytime = fmod(beidoutime_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; 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.d_TOW = d_TOW; + ephemeris.d_TOW = d_SOW; ephemeris.d_Crs = d_Crs; ephemeris.d_Delta_n = d_Delta_n; 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_Cus = d_Cus; ephemeris.d_sqrt_A = d_sqrt_A; - ephemeris.d_Toe = d_Toe; + ephemeris.d_Toe =static_cast( (static_cast(d_Toe) << 15) | static_cast(d_Toe2)) ; ephemeris.d_Toc = d_Toc; ephemeris.d_Cic = d_Cic; ephemeris.d_OMEGA0 = d_OMEGA0; @@ -715,16 +887,14 @@ Gps_Ephemeris Beidou_Navigation_Message::get_ephemeris() ephemeris.d_OMEGA = d_OMEGA; ephemeris.d_OMEGA_DOT = d_OMEGA_DOT; ephemeris.d_IDOT = d_IDOT; - ephemeris.i_code_on_L2 = i_code_on_L2; - ephemeris.i_GPS_week = i_GPS_week; - ephemeris.b_L2_P_data_flag = b_L2_P_data_flag; + ephemeris.i_BEIDOU_week = i_BEIDOU_week; ephemeris.i_SV_accuracy = i_SV_accuracy; ephemeris.i_SV_health = i_SV_health; - ephemeris.d_TGD = d_TGD; - ephemeris.d_IODC = d_IODC; - ephemeris.d_IODE_SF2 = d_IODE_SF2; - ephemeris.d_IODE_SF3 = d_IODE_SF3; - ephemeris.i_AODO = i_AODO; + ephemeris.d_TGD1 = d_TGD1; + ephemeris.d_AODC = d_AODC; + //ephemeris.d_AODE_SF2 = d_AODE_SF2; + //ephemeris.d_AODE_SF3 = d_AODE_SF3; + //ephemeris.i_AODO = i_AODO; ephemeris.b_fit_interval_flag = b_fit_interval_flag; ephemeris.d_spare1 = d_spare1; 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_alpha1 = d_alpha1; 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 parameters - utc_model.d_A1 = d_A1; + utc_model.d_A1 = d_A1UTC; utc_model.d_A0 = d_A0; utc_model.d_t_OT = d_t_OT; 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; b_valid_ephemeris_set_flag = false; // 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) - 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; b_valid_ephemeris_set_flag = true; diff --git a/src/core/system_parameters/beidou_navigation_message.h b/src/core/system_parameters/beidou_navigation_message.h index 62e95d9b9..c63f6da85 100644 --- a/src/core/system_parameters/beidou_navigation_message.h +++ b/src/core/system_parameters/beidou_navigation_message.h @@ -70,12 +70,12 @@ private: public: bool b_valid_ephemeris_set_flag; // flag indicating that this ephemeris set have passed the validation check //broadcast orbit 1 - double d_TOW; //!< Time of BeiDou Week of the ephemeris set (taken from subframes TOW) [s] - double d_TOW_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_TOW_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_TOW_SF5; //!< Time of BeiDou Week from HOW word of Subframe 5 [s] + double d_SOW; //!< Time of BeiDou Week of the ephemeris set (taken from subframes SOW) [s] + double d_SOW_SF1; //!< Time of BeiDou Week from HOW word of Subframe 1 [s] + double d_SOW_SF2; //!< Time of BeiDou Week from HOW word of Subframe 2 [s] + double d_SOW_SF3; //!< Time of BeiDou Week from HOW word of Subframe 3 [s] + double d_SOW_SF4; //!< Time of BeiDou Week from HOW word of Subframe 4 [s] + double d_SOW_SF5; //!< Time of BeiDou Week from HOW word of Subframe 5 [s] double d_AODE; 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)] //broadcast orbit 3 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_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] @@ -117,6 +118,9 @@ public: 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_A0; + double d_A1; + double d_A2; // Almanac double d_Toa; //!< Almanac reference time [s] @@ -172,37 +176,65 @@ public: // UTC parameters 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_A0; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200E) [s] + double d_A2UTC; + 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] 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] + 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 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_Z; //!< Earth-fixed velocity coordinate z of the satellite [m] + // public functions void reset(); /*! * \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 */ - Gps_Iono get_iono(); + Beidou_Iono get_iono(); /*! * \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(); /*! diff --git a/src/core/system_parameters/beidou_utc_model.cc b/src/core/system_parameters/beidou_utc_model.cc new file mode 100644 index 000000000..c9cc7414a --- /dev/null +++ b/src/core/system_parameters/beidou_utc_model.cc @@ -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 . + * + * ------------------------------------------------------------------------- + */ + +#include "beidou_utc_model.h" +#include + + +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(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(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(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; +} diff --git a/src/core/system_parameters/beidou_utc_model.h b/src/core/system_parameters/beidou_utc_model.h new file mode 100644 index 000000000..4a8e5be55 --- /dev/null +++ b/src/core/system_parameters/beidou_utc_model.h @@ -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 . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_BEIDOU_UTC_MODEL_H_ +#define GNSS_SDR_BEIDOU_UTC_MODEL_H_ + +#include +#include + + +/*! + * \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 + /* + * \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 diff --git a/src/utils/matlab/dll_pll_veml_plot_sample.m b/src/utils/matlab/dll_pll_veml_plot_sample.m index 011044a9f..8d4cf62d4 100644 --- a/src/utils/matlab/dll_pll_veml_plot_sample.m +++ b/src/utils/matlab/dll_pll_veml_plot_sample.m @@ -34,15 +34,15 @@ if ~exist('dll_pll_veml_read_tracking_dump.m', 'file') addpath('./libs') end -samplingFreq = 5000000; %[Hz] -coherent_integration_time_ms = 20; %[ms] -channels = 5; % Number of channels +samplingFreq = 25000000; %[Hz] +coherent_integration_time_ms = 1; %[ms] +channels = 8; % Number of channels 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 - 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); end diff --git a/src/utils/matlab/gps_l1_ca_dll_pll_plot_sample.m b/src/utils/matlab/gps_l1_ca_dll_pll_plot_sample.m index e2f1f544b..f78151a36 100644 --- a/src/utils/matlab/gps_l1_ca_dll_pll_plot_sample.m +++ b/src/utils/matlab/gps_l1_ca_dll_pll_plot_sample.m @@ -38,7 +38,7 @@ samplingFreq = 6625000; %[Hz] channels = 5; first_channel = 0; -path = '/archive/'; %% CHANGE THIS PATH +path = '/home/sergi/gnss/gnss-sdr/install/'; %% CHANGE THIS PATH 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 @@ -65,7 +65,7 @@ for N=1:1:channels trackResults(N).Q_L = zeros(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.'; - + % Use original MATLAB tracking plot function settings.numberOfChannels = channels; settings.msToProcess = length(GNSS_tracking(N).E); diff --git a/src/utils/matlab/gps_l1_ca_telemetry_plot_sample.m b/src/utils/matlab/gps_l1_ca_telemetry_plot_sample.m index f25ab5d21..1d56cb60d 100644 --- a/src/utils/matlab/gps_l1_ca_telemetry_plot_sample.m +++ b/src/utils/matlab/gps_l1_ca_telemetry_plot_sample.m @@ -30,7 +30,7 @@ %clear all; samplingFreq = 64e6/16; %[Hz] channels=4; -path='/home/javier/workspace/gnss-sdr-ref/trunk/install/'; +path='/home/sergi/gnss/gnss-sdr/install/'; clear PRN_absolute_sample_start; for N=1:1:channels telemetry_log_path=[path 'telemetry' num2str(N-1) '.dat']; diff --git a/src/utils/matlab/octave-workspace b/src/utils/matlab/octave-workspace new file mode 100644 index 000000000..97ac6a5bf Binary files /dev/null and b/src/utils/matlab/octave-workspace differ