1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-15 12:40:35 +00:00

Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into next

This commit is contained in:
Carles Fernandez 2019-07-08 11:01:45 +02:00
commit aa94ddf0a5
41 changed files with 783 additions and 969 deletions

View File

@ -42,34 +42,6 @@ Monitor_Pvt_Udp_Sink::Monitor_Pvt_Udp_Sink(const std::vector<std::string>& addre
boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port); boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port);
endpoints.push_back(endpoint); endpoints.push_back(endpoint);
} }
monitor_pvt.TOW_at_current_symbol_ms = 0U;
monitor_pvt.week = 0U;
monitor_pvt.RX_time = 0.0;
monitor_pvt.user_clk_offset = 0.0;
monitor_pvt.pos_x = 0.0;
monitor_pvt.pos_y = 0.0;
monitor_pvt.pos_z = 0.0;
monitor_pvt.vel_x = 0.0;
monitor_pvt.vel_y = 0.0;
monitor_pvt.vel_z = 0.0;
monitor_pvt.cov_xx = 0.0;
monitor_pvt.cov_yy = 0.0;
monitor_pvt.cov_zz = 0.0;
monitor_pvt.cov_xy = 0.0;
monitor_pvt.cov_yz = 0.0;
monitor_pvt.cov_zx = 0.0;
monitor_pvt.latitude = 0.0;
monitor_pvt.longitude = 0.0;
monitor_pvt.height = 0.0;
monitor_pvt.valid_sats = 0;
monitor_pvt.solution_status = 0;
monitor_pvt.solution_type = 0;
monitor_pvt.AR_ratio_factor = 0.0;
monitor_pvt.AR_ratio_threshold = 0.0;
monitor_pvt.gdop = 0.0;
monitor_pvt.pdop = 0.0;
monitor_pvt.hdop = 0.0;
monitor_pvt.vdop = 0.0;
use_protobuf = protobuf_enabled; use_protobuf = protobuf_enabled;
if (use_protobuf) if (use_protobuf)

View File

@ -53,7 +53,7 @@ private:
boost::asio::ip::udp::socket socket; boost::asio::ip::udp::socket socket;
boost::system::error_code error; boost::system::error_code error;
std::vector<boost::asio::ip::udp::endpoint> endpoints; std::vector<boost::asio::ip::udp::endpoint> endpoints;
Monitor_Pvt monitor_pvt; Monitor_Pvt monitor_pvt{};
Serdes_Monitor_Pvt serdes; Serdes_Monitor_Pvt serdes;
bool use_protobuf; bool use_protobuf;
}; };

View File

@ -77,16 +77,7 @@ Rtklib_Solver::Rtklib_Solver(int nchannels, std::string dump_filename, bool flag
count_valid_position = 0; count_valid_position = 0;
this->set_averaging_flag(false); this->set_averaging_flag(false);
rtk_ = rtk; rtk_ = rtk;
for (double &i : dop_)
{
i = 0.0;
}
pvt_sol = {{0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, '0', '0', '0', 0, 0, 0};
ssat_t ssat0 = {0, 0, {0.0}, {0.0}, {0.0}, {'0'}, {'0'}, {'0'}, {'0'}, {'0'}, {}, {}, {}, {}, 0.0, 0.0, 0.0, 0.0, {{{0, 0}}, {{0, 0}}}, {{}, {}}};
for (auto &i : pvt_ssat)
{
i = ssat0;
}
// ############# ENABLE DATA FILE LOG ################# // ############# ENABLE DATA FILE LOG #################
if (d_flag_dump_enabled == true) if (d_flag_dump_enabled == true)
{ {
@ -104,35 +95,6 @@ Rtklib_Solver::Rtklib_Solver(int nchannels, std::string dump_filename, bool flag
} }
} }
} }
// PVT MONITOR
monitor_pvt.TOW_at_current_symbol_ms = 0U;
monitor_pvt.week = 0U;
monitor_pvt.RX_time = 0.0;
monitor_pvt.user_clk_offset = 0.0;
monitor_pvt.pos_x = 0.0;
monitor_pvt.pos_y = 0.0;
monitor_pvt.pos_z = 0.0;
monitor_pvt.vel_x = 0.0;
monitor_pvt.vel_y = 0.0;
monitor_pvt.vel_z = 0.0;
monitor_pvt.cov_xx = 0.0;
monitor_pvt.cov_yy = 0.0;
monitor_pvt.cov_zz = 0.0;
monitor_pvt.cov_xy = 0.0;
monitor_pvt.cov_yz = 0.0;
monitor_pvt.cov_zx = 0.0;
monitor_pvt.latitude = 0.0;
monitor_pvt.longitude = 0.0;
monitor_pvt.height = 0.0;
monitor_pvt.valid_sats = 0;
monitor_pvt.solution_status = 0;
monitor_pvt.solution_type = 0;
monitor_pvt.AR_ratio_factor = 0.0;
monitor_pvt.AR_ratio_threshold = 0.0;
monitor_pvt.gdop = 0.0;
monitor_pvt.pdop = 0.0;
monitor_pvt.hdop = 0.0;
monitor_pvt.vdop = 0.0;
} }
bool Rtklib_Solver::save_matfile() bool Rtklib_Solver::save_matfile()
@ -450,9 +412,9 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
int valid_obs = 0; // valid observations counter int valid_obs = 0; // valid observations counter
int glo_valid_obs = 0; // GLONASS L1/L2 valid observations counter int glo_valid_obs = 0; // GLONASS L1/L2 valid observations counter
std::array<obsd_t, MAXOBS> obs_data; std::array<obsd_t, MAXOBS> obs_data{};
std::array<eph_t, MAXOBS> eph_data; std::array<eph_t, MAXOBS> eph_data{};
std::array<geph_t, MAXOBS> geph_data; std::array<geph_t, MAXOBS> geph_data{};
// Workaround for NAV/CNAV clash problem // Workaround for NAV/CNAV clash problem
bool gps_dual_band = false; bool gps_dual_band = false;

View File

@ -94,8 +94,8 @@ public:
bool get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_map, bool flag_averaging); bool get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_map, bool flag_averaging);
sol_t pvt_sol; sol_t pvt_sol{};
std::array<ssat_t, MAXSAT> pvt_ssat; std::array<ssat_t, MAXSAT> pvt_ssat{};
double get_hdop() const; double get_hdop() const;
double get_vdop() const; double get_vdop() const;
double get_pdop() const; double get_pdop() const;
@ -129,15 +129,15 @@ public:
int count_valid_position; int count_valid_position;
private: private:
rtk_t rtk_; rtk_t rtk_{};
std::string d_dump_filename; std::string d_dump_filename;
std::ofstream d_dump_file; std::ofstream d_dump_file;
bool save_matfile(); bool save_matfile();
bool d_flag_dump_enabled; bool d_flag_dump_enabled;
bool d_flag_dump_mat_enabled; bool d_flag_dump_mat_enabled;
int d_nchannels; // Number of available channels for positioning int d_nchannels; // Number of available channels for positioning
std::array<double, 4> dop_; std::array<double, 4> dop_{};
Monitor_Pvt monitor_pvt; Monitor_Pvt monitor_pvt{};
}; };
#endif #endif

View File

@ -48,7 +48,6 @@ public:
// Verify that the version of the library that we linked against is // Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against. // compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION; GOOGLE_PROTOBUF_VERIFY_VERSION;
monitor_.New();
} }
~Serdes_Monitor_Pvt() ~Serdes_Monitor_Pvt()
@ -56,6 +55,31 @@ public:
// google::protobuf::ShutdownProtobufLibrary(); // google::protobuf::ShutdownProtobufLibrary();
} }
inline Serdes_Monitor_Pvt(Serdes_Monitor_Pvt&& other) //!< Copy constructor
{
this->monitor_ = other.monitor_;
}
inline Serdes_Monitor_Pvt& operator=(const Serdes_Monitor_Pvt& rhs) //!< Copy assignment operator
{
this->monitor_ = rhs.monitor_;
return *this;
}
inline Serdes_Monitor_Pvt(const Serdes_Monitor_Pvt& other) //!< Move constructor
{
this->monitor_ = std::move(other.monitor_);
}
inline Serdes_Monitor_Pvt& operator=(Serdes_Monitor_Pvt&& other) //!< Move assignment operator
{
if (this != &other)
{
this->monitor_ = std::move(other.monitor_);
}
return *this;
}
inline std::string createProtobuffer(const Monitor_Pvt& monitor) //!< Serialization into a string inline std::string createProtobuffer(const Monitor_Pvt& monitor) //!< Serialization into a string
{ {
monitor_.Clear(); monitor_.Clear();
@ -132,7 +156,7 @@ public:
} }
private: private:
gnss_sdr::MonitorPvt monitor_; gnss_sdr::MonitorPvt monitor_{};
}; };
#endif // GNSS_SDR_SERDES_MONITOR_PVT_H_ #endif // GNSS_SDR_SERDES_MONITOR_PVT_H_

View File

@ -51,48 +51,37 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
in_streams_(in_streams), in_streams_(in_streams),
out_streams_(out_streams) out_streams_(out_streams)
{ {
Acq_Conf acq_parameters = Acq_Conf();
configuration_ = configuration; configuration_ = configuration;
std::string default_item_type = "gr_complex"; std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./data/acquisition.dat"; std::string default_dump_filename = "./acquisition.mat";
DLOG(INFO) << "role " << role; LOG(INFO) << "role " << role;
item_type_ = configuration_->property(role + ".item_type", default_item_type); item_type_ = configuration_->property(role + ".item_type", default_item_type);
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_; acq_parameters_.fs_in = fs_in_;
dump_ = configuration_->property(role + ".dump", false); dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_; acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true); blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_; acq_parameters_.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000); doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) if (FLAGS_doppler_max != 0)
{ {
doppler_max_ = FLAGS_doppler_max; doppler_max_ = FLAGS_doppler_max;
} }
acq_parameters.doppler_max = doppler_max_; acq_parameters_.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_; acq_parameters_.bit_transition_flag = bit_transition_flag_;
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1); max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_; acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_; acq_parameters_.dump_filename = dump_filename_;
//--- Find number of samples per spreading code ------------------------- acq_parameters_.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
code_length_ = static_cast<uint32_t>(std::round(static_cast<double>(fs_in_) / (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_;
if (bit_transition_flag_)
{
vector_length_ *= 2;
}
code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort") if (item_type_ == "cshort")
{ {
@ -102,18 +91,28 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
{ {
item_size_ = sizeof(gr_complex); item_size_ = sizeof(gr_complex);
} }
acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = code_length_;
acq_parameters.samples_per_code = code_length_;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); acq_parameters_.ms_per_code = 1;
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; acq_parameters_.it_size = item_size_;
num_codes_ = acq_parameters_.sampled_ms;
acq_parameters_.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters_.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters_.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
acq_parameters_.resampled_fs = fs_in_;
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / BEIDOU_B1I_CODE_RATE_HZ) * static_cast<float>(acq_parameters_.fs_in)));
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(BEIDOU_B1I_CODE_PERIOD * 1000.0);
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
if (item_type_ == "cbyte") if (item_type_ == "cbyte")
{ {
@ -208,7 +207,7 @@ void BeidouB1iPcpsAcquisition::set_local_code()
beidou_b1i_code_gen_complex_sampled(gsl::span<std::complex<float>>(code, code_length_), gnss_synchro_->PRN, fs_in_, 0); beidou_b1i_code_gen_complex_sampled(gsl::span<std::complex<float>>(code, code_length_), gnss_synchro_->PRN, fs_in_, 0);
gsl::span<gr_complex> code_span(code_.data(), vector_length_); gsl::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < sampled_ms_; i++) for (unsigned int i = 0; i < num_codes_; i++)
{ {
std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
} }
@ -233,15 +232,7 @@ float BeidouB1iPcpsAcquisition::calculate_threshold(float pfa)
{ {
//Calculate the threshold //Calculate the threshold
uint32_t frequency_bins = 0; uint32_t frequency_bins = 0;
/*
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
{
frequency_bins++;
}
*/
frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_; frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_;
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa; DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
uint32_t ncells = vector_length_ * frequency_bins; uint32_t ncells = vector_length_ * frequency_bins;
double exponent = 1 / static_cast<double>(ncells); double exponent = 1 / static_cast<double>(ncells);
@ -266,9 +257,11 @@ void BeidouB1iPcpsAcquisition::connect(gr::top_block_sptr top_block)
} }
else if (item_type_ == "cbyte") else if (item_type_ == "cbyte")
{ {
// Since a byte-based acq implementation is not available,
// we just convert cshorts to gr_complex
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); top_block->connect(float_to_complex_, 0, acquisition_, 0);
} }
else else
{ {
@ -289,11 +282,9 @@ void BeidouB1iPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
} }
else if (item_type_ == "cbyte") else if (item_type_ == "cbyte")
{ {
// Since a byte-based acq implementation is not available,
// we just convert cshorts to gr_complex
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); top_block->disconnect(float_to_complex_, 0, acquisition_, 0);
} }
else else
{ {

View File

@ -163,22 +163,21 @@ public:
private: private:
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_; pcps_acquisition_sptr acquisition_;
gr::blocks::stream_to_vector::sptr stream_to_vector_; Acq_Conf acq_parameters_;
gr::blocks::float_to_complex::sptr float_to_complex_; gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
size_t item_size_; size_t item_size_;
std::string item_type_; std::string item_type_;
uint32_t vector_length_; unsigned int vector_length_;
uint32_t code_length_; unsigned int code_length_;
bool bit_transition_flag_; bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_; bool use_CFAR_algorithm_flag_;
uint32_t channel_; unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_; std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_; float threshold_;
uint32_t doppler_max_; unsigned int doppler_max_;
uint32_t doppler_step_; unsigned int doppler_step_;
uint32_t sampled_ms_; unsigned int max_dwells_;
uint32_t max_dwells_;
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
bool blocking_; bool blocking_;
@ -186,8 +185,9 @@ private:
std::vector<std::complex<float>> code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
uint32_t in_streams_; unsigned int num_codes_;
uint32_t out_streams_; unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -49,49 +49,37 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
in_streams_(in_streams), in_streams_(in_streams),
out_streams_(out_streams) out_streams_(out_streams)
{ {
Acq_Conf acq_parameters = Acq_Conf();
configuration_ = configuration; configuration_ = configuration;
std::string default_item_type = "gr_complex"; std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./data/acquisition.dat"; std::string default_dump_filename = "./acquisition.mat";
DLOG(INFO) << "role " << role; LOG(INFO) << "role " << role;
item_type_ = configuration_->property(role + ".item_type", default_item_type); item_type_ = configuration_->property(role + ".item_type", default_item_type);
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_; acq_parameters_.fs_in = fs_in_;
dump_ = configuration_->property(role + ".dump", false); dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_; acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true); blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_; acq_parameters_.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000); doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) if (FLAGS_doppler_max != 0)
{ {
doppler_max_ = FLAGS_doppler_max; doppler_max_ = FLAGS_doppler_max;
} }
acq_parameters.doppler_max = doppler_max_; acq_parameters_.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_; acq_parameters_.bit_transition_flag = bit_transition_flag_;
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1); max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_; acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_; acq_parameters_.dump_filename = dump_filename_;
//--- Find number of samples per spreading code ------------------------- acq_parameters_.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / (BEIDOU_B3I_CODE_RATE_HZ / BEIDOU_B3I_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_;
if (bit_transition_flag_)
{
vector_length_ *= 2;
}
code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort") if (item_type_ == "cshort")
{ {
@ -101,18 +89,28 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
{ {
item_size_ = sizeof(gr_complex); item_size_ = sizeof(gr_complex);
} }
acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = code_length_;
acq_parameters.samples_per_code = code_length_;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); acq_parameters_.ms_per_code = 1;
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; acq_parameters_.it_size = item_size_;
num_codes_ = acq_parameters_.sampled_ms;
acq_parameters_.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters_.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters_.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
acq_parameters_.resampled_fs = fs_in_;
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (BEIDOU_B3I_CODE_RATE_HZ / BEIDOU_B3I_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / BEIDOU_B3I_CODE_RATE_HZ) * static_cast<float>(acq_parameters_.fs_in)));
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(BEIDOU_B3I_CODE_PERIOD * 1000.0);
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
if (item_type_ == "cbyte") if (item_type_ == "cbyte")
{ {
@ -146,8 +144,12 @@ void BeidouB3iPcpsAcquisition::stop_acquisition()
void BeidouB3iPcpsAcquisition::set_threshold(float threshold) void BeidouB3iPcpsAcquisition::set_threshold(float threshold)
{ {
float pfa = configuration_->property(role_ + ".pfa", 0.0); float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0);
if (pfa == 0.0)
{
pfa = configuration_->property(role_ + ".pfa", 0.0);
}
if (pfa == 0.0) if (pfa == 0.0)
{ {
threshold_ = threshold; threshold_ = threshold;
@ -196,7 +198,6 @@ signed int BeidouB3iPcpsAcquisition::mag()
void BeidouB3iPcpsAcquisition::init() void BeidouB3iPcpsAcquisition::init()
{ {
acquisition_->init(); acquisition_->init();
set_local_code();
} }
@ -207,7 +208,7 @@ void BeidouB3iPcpsAcquisition::set_local_code()
beidou_b3i_code_gen_complex_sampled(gsl::span<std::complex<float>>(code, code_length_), gnss_synchro_->PRN, fs_in_, 0); beidou_b3i_code_gen_complex_sampled(gsl::span<std::complex<float>>(code, code_length_), gnss_synchro_->PRN, fs_in_, 0);
gsl::span<gr_complex> code_span(code_.data(), vector_length_); gsl::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < sampled_ms_; i++) for (unsigned int i = 0; i < num_codes_; i++)
{ {
std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data()); std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
} }
@ -232,20 +233,12 @@ float BeidouB3iPcpsAcquisition::calculate_threshold(float pfa)
{ {
//Calculate the threshold //Calculate the threshold
unsigned int frequency_bins = 0; unsigned int frequency_bins = 0;
/*
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
{
frequency_bins++;
}
*/
frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_; frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_;
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa; DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
unsigned int ncells = vector_length_ * frequency_bins; unsigned int ncells = vector_length_ * frequency_bins;
double exponent = 1 / static_cast<double>(ncells); double exponent = 1.0 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent); double val = pow(1.0 - pfa, exponent);
auto lambda = static_cast<double>(vector_length_); auto lambda = double(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda); boost::math::exponential_distribution<double> mydist(lambda);
auto threshold = static_cast<float>(quantile(mydist, val)); auto threshold = static_cast<float>(quantile(mydist, val));
@ -265,9 +258,11 @@ void BeidouB3iPcpsAcquisition::connect(gr::top_block_sptr top_block)
} }
else if (item_type_ == "cbyte") else if (item_type_ == "cbyte")
{ {
// Since a byte-based acq implementation is not available,
// we just convert cshorts to gr_complex
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); top_block->connect(float_to_complex_, 0, acquisition_, 0);
} }
else else
{ {
@ -288,11 +283,9 @@ void BeidouB3iPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
} }
else if (item_type_ == "cbyte") else if (item_type_ == "cbyte")
{ {
// Since a byte-based acq implementation is not available,
// we just convert cshorts to gr_complex
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); top_block->disconnect(float_to_complex_, 0, acquisition_, 0);
} }
else else
{ {
@ -307,7 +300,7 @@ gr::basic_block_sptr BeidouB3iPcpsAcquisition::get_left_block()
{ {
return acquisition_; return acquisition_;
} }
else if (item_type_ == "cshort") if (item_type_ == "cshort")
{ {
return acquisition_; return acquisition_;
} }

View File

@ -162,7 +162,7 @@ public:
private: private:
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_; pcps_acquisition_sptr acquisition_;
gr::blocks::stream_to_vector::sptr stream_to_vector_; Acq_Conf acq_parameters_;
gr::blocks::float_to_complex::sptr float_to_complex_; gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
size_t item_size_; size_t item_size_;
@ -176,7 +176,6 @@ private:
float threshold_; float threshold_;
unsigned int doppler_max_; unsigned int doppler_max_;
unsigned int doppler_step_; unsigned int doppler_step_;
unsigned int sampled_ms_;
unsigned int max_dwells_; unsigned int max_dwells_;
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
@ -185,6 +184,7 @@ private:
std::vector<std::complex<float>> code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int num_codes_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);

View File

@ -31,11 +31,8 @@
#include "beamformer.h" #include "beamformer.h"
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <sstream>
#define GNSS_SDR_BEAMFORMER_CHANNELS 8
beamformer_sptr make_beamformer_sptr() beamformer_sptr make_beamformer_sptr()
{ {
return beamformer_sptr(new beamformer()); return beamformer_sptr(new beamformer());
@ -47,22 +44,6 @@ beamformer::beamformer()
gr::io_signature::make(GNSS_SDR_BEAMFORMER_CHANNELS, GNSS_SDR_BEAMFORMER_CHANNELS, sizeof(gr_complex)), gr::io_signature::make(GNSS_SDR_BEAMFORMER_CHANNELS, GNSS_SDR_BEAMFORMER_CHANNELS, sizeof(gr_complex)),
gr::io_signature::make(1, 1, sizeof(gr_complex))) gr::io_signature::make(1, 1, sizeof(gr_complex)))
{ {
//initialize weight vector
if (posix_memalign(reinterpret_cast<void **>(&weight_vector), 16, GNSS_SDR_BEAMFORMER_CHANNELS * sizeof(gr_complex)) == 0)
{
};
for (int i = 0; i < GNSS_SDR_BEAMFORMER_CHANNELS; i++)
{
weight_vector[i] = gr_complex(1, 0);
}
}
beamformer::~beamformer()
{
free(weight_vector);
} }
@ -86,7 +67,7 @@ int beamformer::work(int noutput_items, gr_vector_const_void_star &input_items,
for (int n = 0; n < noutput_items; n++) for (int n = 0; n < noutput_items; n++)
{ {
sum = gr_complex(0, 0); sum = gr_complex(0, 0);
for (int i = 0; i < GNSS_SDR_BEAMFORMER_CHANNELS; i++) for (unsigned int i = 0; i < weight_vector.size(); i++)
{ {
sum = sum + (reinterpret_cast<const gr_complex *>(input_items[i]))[n] * weight_vector[i]; sum = sum + (reinterpret_cast<const gr_complex *>(input_items[i]))[n] * weight_vector[i];
} }

View File

@ -32,26 +32,30 @@
#define GNSS_SDR_BEAMFORMER_H #define GNSS_SDR_BEAMFORMER_H
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
#include <vector>
class beamformer; class beamformer;
using beamformer_sptr = boost::shared_ptr<beamformer>; using beamformer_sptr = boost::shared_ptr<beamformer>;
beamformer_sptr make_beamformer_sptr(); beamformer_sptr make_beamformer_sptr();
const int GNSS_SDR_BEAMFORMER_CHANNELS = 8;
/*! /*!
* \brief This class implements a real-time software-defined spatial filter using the CTTC GNSS experimental antenna array input and a set of dynamically reloadable weights * \brief This class implements a real-time software-defined spatial filter using the CTTC GNSS experimental antenna array input and a set of dynamically reloadable weights
*/ */
class beamformer : public gr::sync_block class beamformer : public gr::sync_block
{ {
public: public:
~beamformer(); ~beamformer() = default;
int work(int noutput_items, gr_vector_const_void_star &input_items, int work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
private: private:
friend beamformer_sptr make_beamformer_sptr(); friend beamformer_sptr make_beamformer_sptr();
beamformer(); beamformer();
gr_complex *weight_vector; std::vector<gr_complex> weight_vector = std::vector<gr_complex>(GNSS_SDR_BEAMFORMER_CHANNELS, gr_complex(1.0, 0.0));
}; };
#endif #endif

View File

@ -67,7 +67,7 @@ DEFINE_int32(cn0_samples, 20, "Number of correlator outputs used for CN0 estimat
DEFINE_int32(cn0_min, 25, "Minimum valid CN0 (in dB-Hz)."); DEFINE_int32(cn0_min, 25, "Minimum valid CN0 (in dB-Hz).");
DEFINE_int32(max_carrier_lock_fail, 10000, "Maximum number of carrier lock failures before dropping a satellite."); DEFINE_int32(max_carrier_lock_fail, 5000, "Maximum number of carrier lock failures before dropping a satellite.");
DEFINE_int32(max_lock_fail, 50, "Maximum number of code lock failures before dropping a satellite."); DEFINE_int32(max_lock_fail, 50, "Maximum number of code lock failures before dropping a satellite.");

View File

@ -36,6 +36,7 @@
#include "beidou_dnav_ephemeris.h" #include "beidou_dnav_ephemeris.h"
#include "beidou_dnav_iono.h" #include "beidou_dnav_iono.h"
#include "beidou_dnav_utc_model.h" #include "beidou_dnav_utc_model.h"
#include "display.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include <glog/logging.h> #include <glog/logging.h>
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
@ -63,6 +64,8 @@ beidou_b1i_telemetry_decoder_gs::beidou_b1i_telemetry_decoder_gs(
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out // Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry")); this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block // Control messages to tracking block
@ -180,7 +183,7 @@ void beidou_b1i_telemetry_decoder_gs::decode_bch15_11_01(const int32_t *bits, in
err = errind[reg[0] + reg[1] * 2 + reg[2] * 4 + reg[3] * 8]; err = errind[reg[0] + reg[1] * 2 + reg[2] * 4 + reg[3] * 8];
if (err > 0) if (err > 0 and err < 16)
{ {
decbits[err - 1] *= -1; decbits[err - 1] *= -1;
} }
@ -260,11 +263,11 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
// 3. Check operation executed correctly // 3. Check operation executed correctly
if (d_nav.flag_crc_test == true) if (d_nav.flag_crc_test == true)
{ {
LOG(INFO) << "BeiDou DNAV CRC correct in channel " << d_channel << " from satellite " << d_satellite; DLOG(INFO) << "BeiDou DNAV CRC correct in channel " << d_channel << " from satellite " << d_satellite;
} }
else else
{ {
LOG(INFO) << "BeiDou DNAV CRC error in channel " << d_channel << " from satellite " << d_satellite; DLOG(INFO) << "BeiDou DNAV CRC error in channel " << d_channel << " from satellite " << d_satellite;
} }
// 4. Push the new navigation data to the queues // 4. Push the new navigation data to the queues
if (d_nav.have_new_ephemeris() == true) if (d_nav.have_new_ephemeris() == true)
@ -273,7 +276,7 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
std::shared_ptr<Beidou_Dnav_Ephemeris> tmp_obj = std::make_shared<Beidou_Dnav_Ephemeris>(d_nav.get_ephemeris()); std::shared_ptr<Beidou_Dnav_Ephemeris> tmp_obj = std::make_shared<Beidou_Dnav_Ephemeris>(d_nav.get_ephemeris());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel" << d_channel << " from satellite " << d_satellite; LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel" << d_channel << " from satellite " << d_satellite;
std::cout << "New BEIDOU B1I DNAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << std::endl; std::cout << TEXT_YELLOW << "New BEIDOU B1I DNAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << TEXT_RESET << std::endl;
} }
if (d_nav.have_new_utc_model() == true) if (d_nav.have_new_utc_model() == true)
{ {
@ -281,7 +284,7 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
std::shared_ptr<Beidou_Dnav_Utc_Model> tmp_obj = std::make_shared<Beidou_Dnav_Utc_Model>(d_nav.get_utc_model()); std::shared_ptr<Beidou_Dnav_Utc_Model> tmp_obj = std::make_shared<Beidou_Dnav_Utc_Model>(d_nav.get_utc_model());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV UTC Model have been received in channel" << d_channel << " from satellite " << d_satellite; LOG(INFO) << "BEIDOU DNAV UTC Model have been received in channel" << d_channel << " from satellite " << d_satellite;
std::cout << "New BEIDOU B1I DNAV utc model message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << std::endl; std::cout << TEXT_YELLOW << "New BEIDOU B1I DNAV utc model message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << TEXT_RESET << std::endl;
} }
if (d_nav.have_new_iono() == true) if (d_nav.have_new_iono() == true)
{ {
@ -289,7 +292,7 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
std::shared_ptr<Beidou_Dnav_Iono> tmp_obj = std::make_shared<Beidou_Dnav_Iono>(d_nav.get_iono()); std::shared_ptr<Beidou_Dnav_Iono> tmp_obj = std::make_shared<Beidou_Dnav_Iono>(d_nav.get_iono());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV Iono have been received in channel" << d_channel << " from satellite " << d_satellite; LOG(INFO) << "BEIDOU DNAV Iono have been received in channel" << d_channel << " from satellite " << d_satellite;
std::cout << "New BEIDOU B1I DNAV Iono message received in channel " << d_channel << ": Iono model parameters from satellite " << d_satellite << std::endl; std::cout << "New BEIDOU B1I DNAV Iono message received in channel " << d_channel << ": Iono model parameters from satellite " << d_satellite << TEXT_RESET << std::endl;
} }
if (d_nav.have_new_almanac() == true) if (d_nav.have_new_almanac() == true)
{ {
@ -297,7 +300,7 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
// std::shared_ptr<Beidou_Dnav_Almanac> tmp_obj = std::make_shared<Beidou_Dnav_Almanac>(d_nav.get_almanac(slot_nbr)); // std::shared_ptr<Beidou_Dnav_Almanac> tmp_obj = std::make_shared<Beidou_Dnav_Almanac>(d_nav.get_almanac(slot_nbr));
// this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); // this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV Almanac have been received in channel" << d_channel << " from satellite " << d_satellite << std::endl; LOG(INFO) << "BEIDOU DNAV Almanac have been received in channel" << d_channel << " from satellite " << d_satellite << std::endl;
std::cout << "New BEIDOU B1I DNAV almanac received in channel " << d_channel << " from satellite " << d_satellite << std::endl; std::cout << TEXT_YELLOW << "New BEIDOU B1I DNAV almanac received in channel " << d_channel << " from satellite " << d_satellite << TEXT_RESET << std::endl;
} }
} }

View File

@ -35,6 +35,7 @@
#include "beidou_dnav_ephemeris.h" #include "beidou_dnav_ephemeris.h"
#include "beidou_dnav_iono.h" #include "beidou_dnav_iono.h"
#include "beidou_dnav_utc_model.h" #include "beidou_dnav_utc_model.h"
#include "display.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include <glog/logging.h> #include <glog/logging.h>
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
@ -63,6 +64,8 @@ beidou_b3i_telemetry_decoder_gs::beidou_b3i_telemetry_decoder_gs(
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out // Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry")); this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block // Control messages to tracking block
@ -194,7 +197,7 @@ void beidou_b3i_telemetry_decoder_gs::decode_bch15_11_01(const int32_t *bits,
err = errind[reg[0] + reg[1] * 2 + reg[2] * 4 + reg[3] * 8]; err = errind[reg[0] + reg[1] * 2 + reg[2] * 4 + reg[3] * 8];
if (err > 0) if (err > 0 and err < 16)
{ {
decbits[err - 1] *= -1; decbits[err - 1] *= -1;
} }
@ -275,12 +278,12 @@ void beidou_b3i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
// 3. Check operation executed correctly // 3. Check operation executed correctly
if (d_nav.flag_crc_test == true) if (d_nav.flag_crc_test == true)
{ {
LOG(INFO) << "BeiDou DNAV CRC correct in channel " << d_channel DLOG(INFO) << "BeiDou DNAV CRC correct in channel " << d_channel
<< " from satellite " << d_satellite; << " from satellite " << d_satellite;
} }
else else
{ {
LOG(INFO) << "BeiDou DNAV CRC error in channel " << d_channel DLOG(INFO) << "BeiDou DNAV CRC error in channel " << d_channel
<< " from satellite " << d_satellite; << " from satellite " << d_satellite;
} }
// 4. Push the new navigation data to the queues // 4. Push the new navigation data to the queues
@ -292,8 +295,8 @@ void beidou_b3i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel" LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel"
<< d_channel << " from satellite " << d_satellite; << d_channel << " from satellite " << d_satellite;
std::cout << "New BEIDOU B3I DNAV message received in channel " << d_channel std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << std::endl; << ": ephemeris from satellite " << d_satellite << TEXT_RESET << std::endl;
} }
if (d_nav.have_new_utc_model() == true) if (d_nav.have_new_utc_model() == true)
{ {
@ -303,9 +306,9 @@ void beidou_b3i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV UTC Model have been received in channel" LOG(INFO) << "BEIDOU DNAV UTC Model have been received in channel"
<< d_channel << " from satellite " << d_satellite; << d_channel << " from satellite " << d_satellite;
std::cout << "New BEIDOU B3I DNAV utc model message received in channel " std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV utc model message received in channel "
<< d_channel << ": UTC model parameters from satellite " << d_channel << ": UTC model parameters from satellite "
<< d_satellite << std::endl; << d_satellite << TEXT_RESET << std::endl;
} }
if (d_nav.have_new_iono() == true) if (d_nav.have_new_iono() == true)
{ {
@ -315,9 +318,9 @@ void beidou_b3i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV Iono have been received in channel" << d_channel LOG(INFO) << "BEIDOU DNAV Iono have been received in channel" << d_channel
<< " from satellite " << d_satellite; << " from satellite " << d_satellite;
std::cout << "New BEIDOU B3I DNAV Iono message received in channel " std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV Iono message received in channel "
<< d_channel << ": Iono model parameters from satellite " << d_channel << ": Iono model parameters from satellite "
<< d_satellite << std::endl; << d_satellite << TEXT_RESET << std::endl;
} }
if (d_nav.have_new_almanac() == true) if (d_nav.have_new_almanac() == true)
{ {
@ -328,8 +331,8 @@ void beidou_b3i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
// pmt::make_any(tmp_obj)); // pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV Almanac have been received in channel" LOG(INFO) << "BEIDOU DNAV Almanac have been received in channel"
<< d_channel << " from satellite " << d_satellite << std::endl; << d_channel << " from satellite " << d_satellite << std::endl;
std::cout << "New BEIDOU B3I DNAV almanac received in channel " << d_channel std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV almanac received in channel " << d_channel
<< " from satellite " << d_satellite << std::endl; << " from satellite " << d_satellite << TEXT_RESET << std::endl;
} }
} }

View File

@ -66,6 +66,8 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
bool dump) : gr::block("galileo_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), bool dump) : gr::block("galileo_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out // Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry")); this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block // Control messages to tracking block
@ -85,15 +87,13 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
case 1: // INAV case 1: // INAV
{ {
d_PRN_code_period_ms = static_cast<uint32_t>(GALILEO_E1_CODE_PERIOD_MS); d_PRN_code_period_ms = static_cast<uint32_t>(GALILEO_E1_CODE_PERIOD_MS);
d_samples_per_symbol = GALILEO_E1_B_SAMPLES_PER_SYMBOL;
d_bits_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS; d_bits_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS;
// set the preamble // set the preamble
d_samples_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol; d_samples_per_preamble = GALILEO_INAV_PREAMBLE_LENGTH_BITS;
d_preamble_period_symbols = GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS; d_preamble_period_symbols = GALILEO_INAV_PREAMBLE_PERIOD_SYMBOLS;
d_required_symbols = static_cast<uint32_t>(GALILEO_INAV_PAGE_SYMBOLS) + d_samples_per_preamble; d_required_symbols = static_cast<uint32_t>(GALILEO_INAV_PAGE_SYMBOLS) + d_samples_per_preamble;
// preamble bits to sampled symbols // preamble bits to sampled symbols
d_preamble_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); d_preamble_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment()));
d_secondary_code_samples = nullptr;
d_frame_length_symbols = GALILEO_INAV_PAGE_PART_SYMBOLS - GALILEO_INAV_PREAMBLE_LENGTH_BITS; d_frame_length_symbols = GALILEO_INAV_PAGE_PART_SYMBOLS - GALILEO_INAV_PREAMBLE_LENGTH_BITS;
CodeLength = GALILEO_INAV_PAGE_PART_SYMBOLS - GALILEO_INAV_PREAMBLE_LENGTH_BITS; CodeLength = GALILEO_INAV_PAGE_PART_SYMBOLS - GALILEO_INAV_PREAMBLE_LENGTH_BITS;
DataLength = (CodeLength / nn) - mm; DataLength = (CodeLength / nn) - mm;
@ -103,31 +103,18 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
} }
case 2: // FNAV case 2: // FNAV
{ {
d_PRN_code_period_ms = static_cast<uint32_t>(GALILEO_E5A_CODE_PERIOD_MS); d_PRN_code_period_ms = static_cast<uint32_t>(GALILEO_E5A_CODE_PERIOD_MS * GALILEO_E5A_I_SECONDARY_CODE_LENGTH);
d_samples_per_symbol = GALILEO_FNAV_CODES_PER_SYMBOL;
d_bits_per_preamble = GALILEO_FNAV_PREAMBLE_LENGTH_BITS; d_bits_per_preamble = GALILEO_FNAV_PREAMBLE_LENGTH_BITS;
// set the preamble // set the preamble
d_samples_per_preamble = GALILEO_FNAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol; d_samples_per_preamble = GALILEO_FNAV_PREAMBLE_LENGTH_BITS;
d_preamble_period_symbols = GALILEO_FNAV_CODES_PER_PAGE; d_preamble_period_symbols = GALILEO_FNAV_SYMBOLS_PER_PAGE;
d_required_symbols = static_cast<uint32_t>(GALILEO_FNAV_SYMBOLS_PER_PAGE) * d_samples_per_symbol + d_samples_per_preamble; d_required_symbols = static_cast<uint32_t>(GALILEO_FNAV_SYMBOLS_PER_PAGE) + d_samples_per_preamble;
// preamble bits to sampled symbols // preamble bits to sampled symbols
d_preamble_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); d_preamble_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment()));
d_secondary_code_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(GALILEO_E5A_I_SECONDARY_CODE_LENGTH * sizeof(int32_t), volk_gnsssdr_get_alignment()));
d_frame_length_symbols = GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS; d_frame_length_symbols = GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS;
CodeLength = GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS; CodeLength = GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS;
DataLength = (CodeLength / nn) - mm; DataLength = (CodeLength / nn) - mm;
for (int32_t i = 0; i < GALILEO_E5A_I_SECONDARY_CODE_LENGTH; i++) d_max_symbols_without_valid_frame = GALILEO_FNAV_SYMBOLS_PER_PAGE * 5; //rise alarm 100 seconds without valid tlm
{
if (GALILEO_E5A_I_SECONDARY_CODE.at(i) == '1')
{
d_secondary_code_samples[i] = 1;
}
else
{
d_secondary_code_samples[i] = -1;
}
}
d_max_symbols_without_valid_frame = GALILEO_FNAV_CODES_PER_PAGE * 10; //rise alarm 100 seconds without valid tlm
break; break;
} }
default: default:
@ -135,8 +122,6 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
d_samples_per_preamble = 0; d_samples_per_preamble = 0;
d_preamble_period_symbols = 0; d_preamble_period_symbols = 0;
d_preamble_samples = nullptr; d_preamble_samples = nullptr;
d_secondary_code_samples = nullptr;
d_samples_per_symbol = 0U;
d_PRN_code_period_ms = 0U; d_PRN_code_period_ms = 0U;
d_required_symbols = 0U; d_required_symbols = 0U;
d_frame_length_symbols = 0U; d_frame_length_symbols = 0U;
@ -147,7 +132,6 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
} }
d_page_part_symbols = static_cast<double *>(volk_gnsssdr_malloc(d_frame_length_symbols * sizeof(double), volk_gnsssdr_get_alignment())); d_page_part_symbols = static_cast<double *>(volk_gnsssdr_malloc(d_frame_length_symbols * sizeof(double), volk_gnsssdr_get_alignment()));
int32_t n = 0;
for (int32_t i = 0; i < d_bits_per_preamble; i++) for (int32_t i = 0; i < d_bits_per_preamble; i++)
{ {
switch (d_frame_type) switch (d_frame_type)
@ -156,45 +140,23 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
{ {
if (GALILEO_INAV_PREAMBLE.at(i) == '1') if (GALILEO_INAV_PREAMBLE.at(i) == '1')
{ {
for (uint32_t j = 0; j < d_samples_per_symbol; j++) d_preamble_samples[i] = 1;
{
d_preamble_samples[n] = 1;
n++;
}
} }
else else
{ {
for (uint32_t j = 0; j < d_samples_per_symbol; j++) d_preamble_samples[i] = -1;
{
d_preamble_samples[n] = -1;
n++;
}
} }
break; break;
} }
case 2: // FNAV for E5a-I case 2: // FNAV for E5a-I
{ {
// Galileo E5a data channel (E5a-I) still has a secondary code
int m = 0;
if (GALILEO_FNAV_PREAMBLE.at(i) == '1') if (GALILEO_FNAV_PREAMBLE.at(i) == '1')
{ {
for (uint32_t j = 0; j < d_samples_per_symbol; j++) d_preamble_samples[i] = 1;
{
d_preamble_samples[n] = d_secondary_code_samples[m];
n++;
m++;
m = m % GALILEO_E5A_I_SECONDARY_CODE_LENGTH;
}
} }
else else
{ {
for (uint32_t j = 0; j < d_samples_per_symbol; j++) d_preamble_samples[i] = -1;
{
d_preamble_samples[n] = -d_secondary_code_samples[m];
n++;
m++;
m = m % GALILEO_E5A_I_SECONDARY_CODE_LENGTH;
}
} }
break; break;
} }
@ -235,10 +197,6 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
galileo_telemetry_decoder_gs::~galileo_telemetry_decoder_gs() galileo_telemetry_decoder_gs::~galileo_telemetry_decoder_gs()
{ {
volk_gnsssdr_free(d_preamble_samples); volk_gnsssdr_free(d_preamble_samples);
if (d_frame_type == 2)
{
volk_gnsssdr_free(d_secondary_code_samples);
}
volk_gnsssdr_free(d_page_part_symbols); volk_gnsssdr_free(d_page_part_symbols);
volk_gnsssdr_free(out0); volk_gnsssdr_free(out0);
volk_gnsssdr_free(out1); volk_gnsssdr_free(out1);
@ -497,7 +455,24 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
// 1. Copy the current tracking output // 1. Copy the current tracking output
current_symbol = in[0][0]; current_symbol = in[0][0];
// add new symbol to the symbol queue // add new symbol to the symbol queue
switch (d_frame_type)
{
case 1: // INAV
{
d_symbol_history.push_back(current_symbol.Prompt_I); d_symbol_history.push_back(current_symbol.Prompt_I);
break;
}
case 2: //FNAV
{
d_symbol_history.push_back(current_symbol.Prompt_Q);
break;
}
default:
{
d_symbol_history.push_back(current_symbol.Prompt_I);
break;
}
}
d_sample_counter++; // count for the processed symbols d_sample_counter++; // count for the processed symbols
consume_each(1); consume_each(1);
d_flag_preamble = false; d_flag_preamble = false;
@ -626,29 +601,21 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
// 0. fetch the symbols into an array // 0. fetch the symbols into an array
if (flag_PLL_180_deg_phase_locked == false) // normal PLL lock if (flag_PLL_180_deg_phase_locked == false) // normal PLL lock
{ {
int k = 0;
for (uint32_t i = 0; i < d_frame_length_symbols; i++) for (uint32_t i = 0; i < d_frame_length_symbols; i++)
{ {
d_page_part_symbols[i] = 0; for (uint32_t i = 0; i < d_frame_length_symbols; i++)
for (uint32_t m = 0; m < d_samples_per_symbol; m++)
{ {
d_page_part_symbols[i] += static_cast<float>(d_secondary_code_samples[k]) * d_symbol_history.at(i * d_samples_per_symbol + d_samples_per_preamble + m); // because last symbol of the preamble is just received now! d_page_part_symbols[i] = d_symbol_history.at(i + d_samples_per_preamble); // because last symbol of the preamble is just received now!
k++;
k = k % GALILEO_E5A_I_SECONDARY_CODE_LENGTH;
} }
} }
} }
else // 180 deg. inverted carrier phase PLL lock else // 180 deg. inverted carrier phase PLL lock
{ {
int k = 0;
for (uint32_t i = 0; i < d_frame_length_symbols; i++) for (uint32_t i = 0; i < d_frame_length_symbols; i++)
{ {
d_page_part_symbols[i] = 0; for (uint32_t i = 0; i < d_frame_length_symbols; i++)
for (uint32_t m = 0; m < d_samples_per_symbol; m++) // integrate samples into symbols
{ {
d_page_part_symbols[i] -= static_cast<float>(d_secondary_code_samples[k]) * d_symbol_history.at(i * d_samples_per_symbol + d_samples_per_preamble + m); // because last symbol of the preamble is just received now! d_page_part_symbols[i] = -d_symbol_history.at(i + d_samples_per_preamble); // because last symbol of the preamble is just received now!
k++;
k = k % GALILEO_E5A_I_SECONDARY_CODE_LENGTH;
} }
} }
} }
@ -658,12 +625,12 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
return -1; return -1;
break; break;
} }
d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P)
if (d_inav_nav.flag_CRC_test == true or d_fnav_nav.flag_CRC_test == true) if (d_inav_nav.flag_CRC_test == true or d_fnav_nav.flag_CRC_test == true)
{ {
d_CRC_error_counter = 0; d_CRC_error_counter = 0;
d_flag_preamble = true; // valid preamble indicator (initialized to false every work()) d_flag_preamble = true; // valid preamble indicator (initialized to false every work())
d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P) gr::thread::scoped_lock lock(d_setlock);
d_last_valid_preamble = d_sample_counter; d_last_valid_preamble = d_sample_counter;
if (!d_flag_frame_sync) if (!d_flag_frame_sync)
{ {
@ -674,7 +641,6 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
else else
{ {
d_CRC_error_counter++; d_CRC_error_counter++;
d_preamble_index = d_sample_counter; // record the preamble sample stamp
if (d_CRC_error_counter > CRC_ERROR_LIMIT) if (d_CRC_error_counter > CRC_ERROR_LIMIT)
{ {
DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite; DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite;
@ -732,7 +698,7 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
if (d_fnav_nav.flag_TOW_1 == true) if (d_fnav_nav.flag_TOW_1 == true)
{ {
d_TOW_at_Preamble_ms = static_cast<uint32_t>(d_fnav_nav.FNAV_TOW_1 * 1000.0); d_TOW_at_Preamble_ms = static_cast<uint32_t>(d_fnav_nav.FNAV_TOW_1 * 1000.0);
d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((d_required_symbols + 1) * GALILEO_E5A_CODE_PERIOD_MS); d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((d_required_symbols + 1) * GALILEO_FNAV_CODES_PER_SYMBOL * GALILEO_E5A_CODE_PERIOD_MS);
//d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS);
d_fnav_nav.flag_TOW_1 = false; d_fnav_nav.flag_TOW_1 = false;
} }
@ -740,26 +706,26 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
{ {
d_TOW_at_Preamble_ms = static_cast<uint32_t>(d_fnav_nav.FNAV_TOW_2 * 1000.0); d_TOW_at_Preamble_ms = static_cast<uint32_t>(d_fnav_nav.FNAV_TOW_2 * 1000.0);
//d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS);
d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((d_required_symbols + 1) * GALILEO_E5A_CODE_PERIOD_MS); d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((d_required_symbols + 1) * GALILEO_FNAV_CODES_PER_SYMBOL * GALILEO_E5A_CODE_PERIOD_MS);
d_fnav_nav.flag_TOW_2 = false; d_fnav_nav.flag_TOW_2 = false;
} }
else if (d_fnav_nav.flag_TOW_3 == true) else if (d_fnav_nav.flag_TOW_3 == true)
{ {
d_TOW_at_Preamble_ms = static_cast<uint32_t>(d_fnav_nav.FNAV_TOW_3 * 1000.0); d_TOW_at_Preamble_ms = static_cast<uint32_t>(d_fnav_nav.FNAV_TOW_3 * 1000.0);
//d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS);
d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((d_required_symbols + 1) * GALILEO_E5A_CODE_PERIOD_MS); d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((d_required_symbols + 1) * GALILEO_FNAV_CODES_PER_SYMBOL * GALILEO_E5A_CODE_PERIOD_MS);
d_fnav_nav.flag_TOW_3 = false; d_fnav_nav.flag_TOW_3 = false;
} }
else if (d_fnav_nav.flag_TOW_4 == true) else if (d_fnav_nav.flag_TOW_4 == true)
{ {
d_TOW_at_Preamble_ms = static_cast<uint32_t>(d_fnav_nav.FNAV_TOW_4 * 1000.0); d_TOW_at_Preamble_ms = static_cast<uint32_t>(d_fnav_nav.FNAV_TOW_4 * 1000.0);
//d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS); //d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((GALILEO_FNAV_CODES_PER_PAGE + GALILEO_FNAV_CODES_PER_PREAMBLE) * GALILEO_E5a_CODE_PERIOD_MS);
d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((d_required_symbols + 1) * GALILEO_E5A_CODE_PERIOD_MS); d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>((d_required_symbols + 1) * GALILEO_FNAV_CODES_PER_SYMBOL * GALILEO_E5A_CODE_PERIOD_MS);
d_fnav_nav.flag_TOW_4 = false; d_fnav_nav.flag_TOW_4 = false;
} }
else else
{ {
d_TOW_at_current_symbol_ms += static_cast<uint32_t>(GALILEO_E5A_CODE_PERIOD_MS); d_TOW_at_current_symbol_ms += static_cast<uint32_t>(GALILEO_FNAV_CODES_PER_SYMBOL * GALILEO_E5A_CODE_PERIOD_MS);
} }
break; break;
} }

View File

@ -85,8 +85,6 @@ private:
int32_t d_samples_per_preamble; int32_t d_samples_per_preamble;
int32_t d_preamble_period_symbols; int32_t d_preamble_period_symbols;
int32_t *d_preamble_samples; int32_t *d_preamble_samples;
int32_t *d_secondary_code_samples;
uint32_t d_samples_per_symbol;
uint32_t d_PRN_code_period_ms; uint32_t d_PRN_code_period_ms;
uint32_t d_required_symbols; uint32_t d_required_symbols;
uint32_t d_frame_length_symbols; uint32_t d_frame_length_symbols;

View File

@ -60,6 +60,8 @@ glonass_l1_ca_telemetry_decoder_gs::glonass_l1_ca_telemetry_decoder_gs(
bool dump) : gr::block("glonass_l1_ca_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), bool dump) : gr::block("glonass_l1_ca_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out // Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry")); this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block // Control messages to tracking block

View File

@ -60,6 +60,8 @@ glonass_l2_ca_telemetry_decoder_gs::glonass_l2_ca_telemetry_decoder_gs(
bool dump) : gr::block("glonass_l2_ca_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), bool dump) : gr::block("glonass_l2_ca_telemetry_decoder_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out // Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry")); this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block // Control messages to tracking block

View File

@ -62,6 +62,9 @@ gps_l1_ca_telemetry_decoder_gs::gps_l1_ca_telemetry_decoder_gs(
bool dump) : gr::block("gps_navigation_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), bool dump) : gr::block("gps_navigation_gs", gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out // Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry")); this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block // Control messages to tracking block
@ -76,34 +79,28 @@ gps_l1_ca_telemetry_decoder_gs::gps_l1_ca_telemetry_decoder_gs(
DLOG(INFO) << "Initializing GPS L1 TELEMETRY DECODER"; DLOG(INFO) << "Initializing GPS L1 TELEMETRY DECODER";
d_bits_per_preamble = GPS_CA_PREAMBLE_LENGTH_BITS; d_bits_per_preamble = GPS_CA_PREAMBLE_LENGTH_BITS;
d_samples_per_preamble = d_bits_per_preamble * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; d_samples_per_preamble = d_bits_per_preamble;
d_preamble_period_symbols = GPS_SUBFRAME_BITS * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; d_preamble_period_symbols = GPS_SUBFRAME_BITS;
// set the preamble // set the preamble
d_required_symbols = GPS_SUBFRAME_BITS * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; d_required_symbols = GPS_SUBFRAME_BITS;
// preamble bits to sampled symbols // preamble bits to sampled symbols
d_preamble_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment())); d_preamble_samples = static_cast<int32_t *>(volk_gnsssdr_malloc(d_samples_per_preamble * sizeof(int32_t), volk_gnsssdr_get_alignment()));
d_frame_length_symbols = GPS_SUBFRAME_BITS * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; d_frame_length_symbols = GPS_SUBFRAME_BITS * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT;
d_max_symbols_without_valid_frame = d_required_symbols * 10; // rise alarm 1 minute without valid tlm d_max_symbols_without_valid_frame = d_required_symbols * 20; // rise alarm 120 segs without valid tlm
int32_t n = 0; int32_t n = 0;
for (int32_t i = 0; i < d_bits_per_preamble; i++) for (int32_t i = 0; i < d_bits_per_preamble; i++)
{ {
if (GPS_CA_PREAMBLE.at(i) == '1') if (GPS_CA_PREAMBLE.at(i) == '1')
{
for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++)
{ {
d_preamble_samples[n] = 1; d_preamble_samples[n] = 1;
n++; n++;
} }
}
else else
{
for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++)
{ {
d_preamble_samples[n] = -1; d_preamble_samples[n] = -1;
n++; n++;
} }
} }
}
d_sample_counter = 0ULL; d_sample_counter = 0ULL;
d_stat = 0; d_stat = 0;
d_preamble_index = 0ULL; d_preamble_index = 0ULL;
@ -209,33 +206,18 @@ void gps_l1_ca_telemetry_decoder_gs::set_channel(int32_t channel)
bool gps_l1_ca_telemetry_decoder_gs::decode_subframe() bool gps_l1_ca_telemetry_decoder_gs::decode_subframe()
{ {
char subframe[GPS_SUBFRAME_LENGTH]; char subframe[GPS_SUBFRAME_LENGTH];
int32_t symbol_accumulator_counter = 0;
int32_t frame_bit_index = 0; int32_t frame_bit_index = 0;
int32_t word_index = 0; int32_t word_index = 0;
uint32_t GPS_frame_4bytes = 0; uint32_t GPS_frame_4bytes = 0;
float symbol_accumulator = 0;
bool subframe_synchro_confirmation = true; bool subframe_synchro_confirmation = true;
for (float subframe_symbol : d_symbol_history) for (float subframe_symbol : d_symbol_history)
{ {
// ******* SYMBOL TO BIT ******* // ******* SYMBOL TO BIT *******
// extended correlation to bit period is enabled in tracking!
symbol_accumulator += subframe_symbol; // accumulate the input value in d_symbol_accumulator
symbol_accumulator_counter++;
if (symbol_accumulator_counter == 20)
{
// symbol to bit // symbol to bit
if (symbol_accumulator > 0) if (subframe_symbol > 0)
{ {
GPS_frame_4bytes += 1; // insert the telemetry bit in LSB GPS_frame_4bytes += 1; // insert the telemetry bit in LSB
//std::cout << "1";
} }
else
{
//std::cout << "0";
}
symbol_accumulator = 0;
symbol_accumulator_counter = 0;
// ******* bits to words ****** // ******* bits to words ******
frame_bit_index++; frame_bit_index++;
@ -278,7 +260,6 @@ bool gps_l1_ca_telemetry_decoder_gs::decode_subframe()
GPS_frame_4bytes <<= 1; // shift 1 bit left the telemetry word GPS_frame_4bytes <<= 1; // shift 1 bit left the telemetry word
} }
} }
}
// decode subframe // decode subframe
// NEW GPS SUBFRAME HAS ARRIVED! // NEW GPS SUBFRAME HAS ARRIVED!
@ -378,10 +359,10 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__
{ {
// correlate with preamble // correlate with preamble
int32_t corr_value = 0; int32_t corr_value = 0;
if (d_symbol_history.size() >= GPS_CA_PREAMBLE_LENGTH_SYMBOLS) if (d_symbol_history.size() >= GPS_CA_PREAMBLE_LENGTH_BITS)
{ {
// ******* preamble correlation ******** // ******* preamble correlation ********
for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++) for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++)
{ {
if (d_symbol_history[i] < 0.0) // symbols clipping if (d_symbol_history[i] < 0.0) // symbols clipping
{ {
@ -397,6 +378,7 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__
{ {
d_preamble_index = d_sample_counter; // record the preamble sample stamp d_preamble_index = d_sample_counter; // record the preamble sample stamp
DLOG(INFO) << "Preamble detection for GPS L1 satellite " << this->d_satellite; DLOG(INFO) << "Preamble detection for GPS L1 satellite " << this->d_satellite;
decode_subframe();
d_stat = 1; // enter into frame pre-detection status d_stat = 1; // enter into frame pre-detection status
} }
flag_TOW_set = false; flag_TOW_set = false;
@ -407,10 +389,10 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__
// correlate with preamble // correlate with preamble
int32_t corr_value = 0; int32_t corr_value = 0;
int32_t preamble_diff = 0; int32_t preamble_diff = 0;
if (d_symbol_history.size() >= GPS_CA_PREAMBLE_LENGTH_SYMBOLS) if (d_symbol_history.size() >= GPS_CA_PREAMBLE_LENGTH_BITS)
{ {
// ******* preamble correlation ******** // ******* preamble correlation ********
for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_SYMBOLS; i++) for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++)
{ {
if (d_symbol_history[i] < 0.0) // symbols clipping if (d_symbol_history[i] < 0.0) // symbols clipping
{ {
@ -438,6 +420,7 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__
{ {
flag_PLL_180_deg_phase_locked = false; flag_PLL_180_deg_phase_locked = false;
} }
decode_subframe();
d_stat = 2; d_stat = 2;
} }
else else
@ -475,7 +458,6 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__
else else
{ {
d_CRC_error_counter++; d_CRC_error_counter++;
d_preamble_index = d_sample_counter; // record the preamble sample stamp
if (d_CRC_error_counter > 2) if (d_CRC_error_counter > 2)
{ {
DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite; DLOG(INFO) << "Lost of frame sync SAT " << this->d_satellite;
@ -510,7 +492,7 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__
{ {
if (flag_TOW_set == true) if (flag_TOW_set == true)
{ {
d_TOW_at_current_symbol_ms += GPS_L1_CA_CODE_PERIOD_MS; d_TOW_at_current_symbol_ms += GPS_L1_CA_BIT_PERIOD_MS;
} }
} }

View File

@ -60,6 +60,8 @@ gps_l2c_telemetry_decoder_gs::gps_l2c_telemetry_decoder_gs(
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out // Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry")); this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block // Control messages to tracking block

View File

@ -58,13 +58,15 @@ gps_l5_telemetry_decoder_gs::gps_l5_telemetry_decoder_gs(
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out // Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry")); this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block // Control messages to tracking block
this->message_port_register_out(pmt::mp("telemetry_to_trk")); this->message_port_register_out(pmt::mp("telemetry_to_trk"));
d_last_valid_preamble = 0; d_last_valid_preamble = 0;
d_sent_tlm_failed_msg = false; d_sent_tlm_failed_msg = false;
d_max_symbols_without_valid_frame = GPS_L5_CNAV_DATA_PAGE_BITS * GPS_L5_SAMPLES_PER_SYMBOL * GPS_L5_SYMBOLS_PER_BIT * 10; //rise alarm if 20 consecutive subframes have no valid CRC d_max_symbols_without_valid_frame = GPS_L5_CNAV_DATA_PAGE_BITS * GPS_L5_SYMBOLS_PER_BIT * 10; //rise alarm if 20 consecutive subframes have no valid CRC
// initialize internal vars // initialize internal vars
d_dump = dump; d_dump = dump;
@ -74,23 +76,8 @@ gps_l5_telemetry_decoder_gs::gps_l5_telemetry_decoder_gs(
d_flag_valid_word = false; d_flag_valid_word = false;
d_TOW_at_current_symbol_ms = 0U; d_TOW_at_current_symbol_ms = 0U;
d_TOW_at_Preamble_ms = 0U; d_TOW_at_Preamble_ms = 0U;
sym_hist.set_capacity(GPS_L5I_NH_CODE_LENGTH);
// initialize the CNAV frame decoder (libswiftcnav) // initialize the CNAV frame decoder (libswiftcnav)
cnav_msg_decoder_init(&d_cnav_decoder); cnav_msg_decoder_init(&d_cnav_decoder);
for (int32_t aux = 0; aux < GPS_L5I_NH_CODE_LENGTH; aux++)
{
if (GPS_L5I_NH_CODE[aux] == 0)
{
bits_NH[aux] = -1.0;
}
else
{
bits_NH[aux] = 1.0;
}
}
sync_NH = false;
new_sym = false;
d_sample_counter = 0; d_sample_counter = 0;
} }
@ -171,9 +158,6 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
// 1. Copy the current tracking output // 1. Copy the current tracking output
current_synchro_data = in[0]; current_synchro_data = in[0];
consume_each(1); // one by one consume_each(1); // one by one
sym_hist.push_back(in[0].Prompt_I);
int32_t corr_NH = 0;
int32_t symbol_value = 0;
// check if there is a problem with the telemetry of the current satellite // check if there is a problem with the telemetry of the current satellite
d_sample_counter++; // count for the processed symbols d_sample_counter++; // count for the processed symbols
@ -187,61 +171,18 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
} }
} }
// Search correlation with Neuman-Hofman Code (see IS-GPS-705D)
if (sym_hist.size() == GPS_L5I_NH_CODE_LENGTH)
{
for (int32_t i = 0; i < GPS_L5I_NH_CODE_LENGTH; i++)
{
if ((bits_NH[i] * sym_hist[i]) > 0.0)
{
corr_NH += 1;
}
else
{
corr_NH -= 1;
}
}
if (abs(corr_NH) == GPS_L5I_NH_CODE_LENGTH)
{
sync_NH = true;
if (corr_NH > 0)
{
symbol_value = 1;
}
else
{
symbol_value = -1;
}
new_sym = true;
//sym_hist.clear();
}
else
{
sync_NH = false;
new_sym = false;
}
}
bool flag_new_cnav_frame = false;
cnav_msg_t msg; cnav_msg_t msg;
uint32_t delay = 0; uint32_t delay;
uint8_t symbol_clip = static_cast<uint8_t>(current_synchro_data.Prompt_Q > 0) * 255;
// add the symbol to the decoder
if (new_sym)
{
uint8_t symbol_clip = static_cast<uint8_t>(symbol_value > 0) * 255;
flag_new_cnav_frame = cnav_msg_decoder_add_symbol(&d_cnav_decoder, symbol_clip, &msg, &delay);
new_sym = false;
}
// 2. Add the telemetry decoder information // 2. Add the telemetry decoder information
// check if new CNAV frame is available // check if new CNAV frame is available
if (flag_new_cnav_frame == true) if (cnav_msg_decoder_add_symbol(&d_cnav_decoder, symbol_clip, &msg, &delay) == true)
{ {
std::bitset<GPS_L5_CNAV_DATA_PAGE_BITS> raw_bits; std::bitset<GPS_L5_CNAV_DATA_PAGE_BITS> raw_bits;
// Expand packet bits to bitsets. Notice the reverse order of the bits sequence, required by the CNAV message decoder // Expand packet bits to bitsets. Notice the reverse order of the bits sequence, required by the CNAV message decoder
for (uint32_t i = 0; i < GPS_L5_CNAV_DATA_PAGE_BITS; i++) for (uint32_t i = 0; i < GPS_L5_CNAV_DATA_PAGE_BITS; i++)
{ {
raw_bits[GPS_L5_CNAV_DATA_PAGE_BITS - 1 - i] = ((msg.raw_msg[i / 8] >> (7 - i % 8)) & 1U); raw_bits[GPS_L5_CNAV_DATA_PAGE_BITS - 1 - i] = ((msg.raw_msg[i / 8] >> (7 - i % 8)) & 1u);
} }
d_CNAV_Message.decode_page(raw_bits); d_CNAV_Message.decode_page(raw_bits);
@ -279,7 +220,7 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
//check TOW update consistency //check TOW update consistency
uint32_t last_d_TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; uint32_t last_d_TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms;
d_TOW_at_current_symbol_ms = msg.tow * 6000 + (delay + 12) * GPS_L5I_SYMBOL_PERIOD_MS; d_TOW_at_current_symbol_ms = msg.tow * 6000 + (delay + 12) * GPS_L5I_SYMBOL_PERIOD_MS;
if (last_d_TOW_at_current_symbol_ms != 0 and abs(static_cast<int64_t>(d_TOW_at_current_symbol_ms) - int64_t(last_d_TOW_at_current_symbol_ms)) > 1) if (last_d_TOW_at_current_symbol_ms != 0 and abs(static_cast<int64_t>(d_TOW_at_current_symbol_ms) - int64_t(last_d_TOW_at_current_symbol_ms)) > GPS_L5I_SYMBOL_PERIOD_MS)
{ {
DLOG(INFO) << "Warning: GPS L5 TOW update in ch " << d_channel DLOG(INFO) << "Warning: GPS L5 TOW update in ch " << d_channel
<< " does not match the TLM TOW counter " << static_cast<int64_t>(d_TOW_at_current_symbol_ms) - int64_t(last_d_TOW_at_current_symbol_ms) << " ms " << " does not match the TLM TOW counter " << static_cast<int64_t>(d_TOW_at_current_symbol_ms) - int64_t(last_d_TOW_at_current_symbol_ms) << " ms "
@ -298,7 +239,7 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
{ {
if (d_flag_valid_word) if (d_flag_valid_word)
{ {
d_TOW_at_current_symbol_ms += GPS_L5I_PERIOD_MS; d_TOW_at_current_symbol_ms += GPS_L5I_SYMBOL_PERIOD_MS;
if (current_synchro_data.Flag_valid_symbol_output == false) if (current_synchro_data.Flag_valid_symbol_output == false)
{ {
d_flag_valid_word = false; d_flag_valid_word = false;

View File

@ -91,10 +91,6 @@ private:
uint32_t d_max_symbols_without_valid_frame; uint32_t d_max_symbols_without_valid_frame;
Gps_CNAV_Navigation_Message d_CNAV_Message; Gps_CNAV_Navigation_Message d_CNAV_Message;
float bits_NH[GPS_L5I_NH_CODE_LENGTH]{};
boost::circular_buffer<float> sym_hist;
bool sync_NH;
bool new_sym;
}; };

View File

@ -58,6 +58,8 @@ sbas_l1_telemetry_decoder_gs::sbas_l1_telemetry_decoder_gs(
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out // Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry")); this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block // Control messages to tracking block

View File

@ -58,22 +58,39 @@ BeidouB3iDllPllTracking::BeidouB3iDllPllTracking(
trk_param.fs_in = fs_in; trk_param.fs_in = fs_in;
bool dump = configuration->property(role + ".dump", false); bool dump = configuration->property(role + ".dump", false);
trk_param.dump = dump; trk_param.dump = dump;
std::string default_dump_filename = "./track_ch";
std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename);
trk_param.dump_filename = dump_filename;
bool dump_mat = configuration->property(role + ".dump_mat", true);
trk_param.dump_mat = dump_mat;
trk_param.high_dyn = configuration->property(role + ".high_dyn", false);
if (configuration->property(role + ".smoother_length", 10) < 1)
{
trk_param.smoother_length = 1;
std::cout << TEXT_RED << "WARNING: BEIDOU B3I. smoother_length must be bigger than 0. It has been set to 1" << TEXT_RESET << std::endl;
}
else
{
trk_param.smoother_length = configuration->property(role + ".smoother_length", 10);
}
float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0); float pll_bw_hz = configuration->property(role + ".pll_bw_hz", 50.0);
if (FLAGS_pll_bw_hz != 0.0) if (FLAGS_pll_bw_hz != 0.0)
{ {
pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz); pll_bw_hz = static_cast<float>(FLAGS_pll_bw_hz);
} }
trk_param.pll_bw_hz = pll_bw_hz; trk_param.pll_bw_hz = pll_bw_hz;
float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 20.0);
trk_param.pll_bw_narrow_hz = pll_bw_narrow_hz;
float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 2.0);
trk_param.dll_bw_narrow_hz = dll_bw_narrow_hz;
float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0); float dll_bw_hz = configuration->property(role + ".dll_bw_hz", 2.0);
if (FLAGS_dll_bw_hz != 0.0) if (FLAGS_dll_bw_hz != 0.0)
{ {
dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz); dll_bw_hz = static_cast<float>(FLAGS_dll_bw_hz);
} }
trk_param.dll_bw_hz = dll_bw_hz; trk_param.dll_bw_hz = dll_bw_hz;
float pll_bw_narrow_hz = configuration->property(role + ".pll_bw_narrow_hz", 2.0);
trk_param.pll_bw_narrow_hz = pll_bw_narrow_hz;
float dll_bw_narrow_hz = configuration->property(role + ".dll_bw_narrow_hz", 0.25);
trk_param.dll_bw_narrow_hz = dll_bw_narrow_hz;
float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
trk_param.early_late_space_chips = early_late_space_chips;
int dll_filter_order = configuration->property(role + ".dll_filter_order", 2); int dll_filter_order = configuration->property(role + ".dll_filter_order", 2);
if (dll_filter_order < 1) if (dll_filter_order < 1)
@ -116,16 +133,12 @@ BeidouB3iDllPllTracking::BeidouB3iDllPllTracking(
trk_param.fll_bw_hz = fll_bw_hz; trk_param.fll_bw_hz = fll_bw_hz;
trk_param.pull_in_time_s = configuration->property(role + ".pull_in_time_s", trk_param.pull_in_time_s); trk_param.pull_in_time_s = configuration->property(role + ".pull_in_time_s", trk_param.pull_in_time_s);
float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5); int vector_length = std::round(static_cast<double>(fs_in) / (BEIDOU_B3I_CODE_RATE_HZ / BEIDOU_B3I_CODE_LENGTH_CHIPS));
trk_param.early_late_space_chips = early_late_space_chips;
float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.5);
trk_param.early_late_space_narrow_chips = early_late_space_narrow_chips;
std::string default_dump_filename = "./track_ch";
std::string dump_filename = configuration->property(role + ".dump_filename", default_dump_filename);
trk_param.dump_filename = dump_filename;
int vector_length = std::round(fs_in / (BEIDOU_B3I_CODE_RATE_HZ / BEIDOU_B3I_CODE_LENGTH_CHIPS));
trk_param.vector_length = vector_length; trk_param.vector_length = vector_length;
int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1); int symbols_extended_correlator = configuration->property(role + ".extend_correlation_symbols", 1);
float early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", 0.5);
trk_param.early_late_space_narrow_chips = early_late_space_narrow_chips;
bool track_pilot = configuration->property(role + ".track_pilot", false);
if (symbols_extended_correlator < 1) if (symbols_extended_correlator < 1)
{ {
symbols_extended_correlator = 1; symbols_extended_correlator = 1;
@ -137,18 +150,9 @@ BeidouB3iDllPllTracking::BeidouB3iDllPllTracking(
std::cout << TEXT_RED << "WARNING: BEIDOU B3I. extend_correlation_symbols must be lower than 21. Coherent integration has been set to 20 symbols (20 ms)" << TEXT_RESET << std::endl; std::cout << TEXT_RED << "WARNING: BEIDOU B3I. extend_correlation_symbols must be lower than 21. Coherent integration has been set to 20 symbols (20 ms)" << TEXT_RESET << std::endl;
} }
trk_param.extend_correlation_symbols = symbols_extended_correlator; trk_param.extend_correlation_symbols = symbols_extended_correlator;
bool track_pilot = configuration->property(role + ".track_pilot", false); trk_param.track_pilot = track_pilot;
if (track_pilot)
{
std::cout << TEXT_RED << "WARNING: BEIDOU B3I does not have pilot signal. Data tracking has been enabled" << TEXT_RESET << std::endl;
}
if ((symbols_extended_correlator > 1) and (pll_bw_narrow_hz > pll_bw_hz or dll_bw_narrow_hz > dll_bw_hz))
{
std::cout << TEXT_RED << "WARNING: BEIDOU B3I. PLL or DLL narrow tracking bandwidth is higher than wide tracking one" << TEXT_RESET << std::endl;
}
trk_param.very_early_late_space_chips = 0.0; trk_param.very_early_late_space_chips = 0.0;
trk_param.very_early_late_space_narrow_chips = 0.0; trk_param.very_early_late_space_narrow_chips = 0.0;
trk_param.track_pilot = false;
trk_param.system = 'C'; trk_param.system = 'C';
char sig_[3] = "B3"; char sig_[3] = "B3";
std::memcpy(trk_param.signal, sig_, 3); std::memcpy(trk_param.signal, sig_, 3);

View File

@ -92,6 +92,8 @@ dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(const Dll_Pll_Conf &conf_)
dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::block("dll_pll_veml_tracking", gr::io_signature::make(1, 1, sizeof(gr_complex)), dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::block("dll_pll_veml_tracking", gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
trk_parameters = conf_; trk_parameters = conf_;
// Telemetry bit synchronization message port input // Telemetry bit synchronization message port input
this->message_port_register_out(pmt::mp("events")); this->message_port_register_out(pmt::mp("events"));
@ -102,13 +104,15 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
this->set_msg_handler(pmt::mp("telemetry_to_trk"), boost::bind(&dll_pll_veml_tracking::msg_handler_telemetry_to_trk, this, _1)); this->set_msg_handler(pmt::mp("telemetry_to_trk"), boost::bind(&dll_pll_veml_tracking::msg_handler_telemetry_to_trk, this, _1));
// initialize internal vars // initialize internal vars
d_dll_filt_history.set_capacity(2000); d_dll_filt_history.set_capacity(1000);
d_veml = false; d_veml = false;
d_cloop = true; d_cloop = true;
d_pull_in_transitory = true; d_pull_in_transitory = true;
d_code_chip_rate = 0.0; d_code_chip_rate = 0.0;
d_secondary_code_length = 0U; d_secondary_code_length = 0U;
d_secondary_code_string = nullptr; d_secondary_code_string = nullptr;
d_data_secondary_code_length = 0U;
d_data_secondary_code_string = nullptr;
d_preambles_symbols = nullptr; d_preambles_symbols = nullptr;
d_preamble_length_symbols = 0; d_preamble_length_symbols = 0;
signal_type = std::string(trk_parameters.signal); signal_type = std::string(trk_parameters.signal);
@ -134,39 +138,17 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
d_signal_carrier_freq = GPS_L1_FREQ_HZ; d_signal_carrier_freq = GPS_L1_FREQ_HZ;
d_code_period = GPS_L1_CA_CODE_PERIOD; d_code_period = GPS_L1_CA_CODE_PERIOD;
d_code_chip_rate = GPS_L1_CA_CODE_RATE_HZ; d_code_chip_rate = GPS_L1_CA_CODE_RATE_HZ;
d_symbols_per_bit = GPS_CA_TELEMETRY_SYMBOLS_PER_BIT;
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_code_samples_per_chip = 1; d_code_samples_per_chip = 1;
d_code_length_chips = static_cast<uint32_t>(GPS_L1_CA_CODE_LENGTH_CHIPS); d_code_length_chips = static_cast<uint32_t>(GPS_L1_CA_CODE_LENGTH_CHIPS);
// GPS L1 C/A does not have pilot component nor secondary code // GPS L1 C/A does not have pilot component nor secondary code
d_secondary = false; d_secondary = false;
trk_parameters.track_pilot = false; trk_parameters.track_pilot = false;
interchange_iq = false; // symbol integration: 20 trk symbols (20 ms) = 1 tlm bit
// set the preamble in the secondary code acquisition to obtain tlm symbol synchronization
// set the preamble d_secondary_code_length = static_cast<uint32_t>(GPS_CA_PREAMBLE_LENGTH_SYMBOLS);
uint16_t preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE; d_secondary_code_string = const_cast<std::string *>(&GPS_CA_PREAMBLE_SYMBOLS_STR);
d_symbols_per_bit = GPS_CA_TELEMETRY_SYMBOLS_PER_BIT;
// preamble bits to sampled symbols
d_preamble_length_symbols = GPS_CA_PREAMBLE_LENGTH_SYMBOLS;
d_preambles_symbols = static_cast<int32_t *>(volk_gnsssdr_malloc(GPS_CA_PREAMBLE_LENGTH_SYMBOLS * sizeof(int32_t), volk_gnsssdr_get_alignment()));
int32_t n = 0;
for (uint16_t preambles_bit : preambles_bits)
{
for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++)
{
if (preambles_bit == 1)
{
d_preambles_symbols[n] = 1;
}
else
{
d_preambles_symbols[n] = -1;
}
n++;
}
}
d_symbol_history.set_capacity(GPS_CA_PREAMBLE_LENGTH_SYMBOLS); // Change fixed buffer size
d_symbol_history.clear(); // Clear all the elements in the buffer
} }
else if (signal_type == "2S") else if (signal_type == "2S")
{ {
@ -174,19 +156,20 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
d_code_period = GPS_L2_M_PERIOD; d_code_period = GPS_L2_M_PERIOD;
d_code_chip_rate = GPS_L2_M_CODE_RATE_HZ; d_code_chip_rate = GPS_L2_M_CODE_RATE_HZ;
d_code_length_chips = static_cast<uint32_t>(GPS_L2_M_CODE_LENGTH_CHIPS); d_code_length_chips = static_cast<uint32_t>(GPS_L2_M_CODE_LENGTH_CHIPS);
// GPS L2C has 1 trk symbol (20 ms) per tlm bit, no symbol integration required
d_symbols_per_bit = GPS_L2_SAMPLES_PER_SYMBOL; d_symbols_per_bit = GPS_L2_SAMPLES_PER_SYMBOL;
d_correlation_length_ms = 20; d_correlation_length_ms = 20;
d_code_samples_per_chip = 1; d_code_samples_per_chip = 1;
// GPS L2 does not have pilot component nor secondary code // GPS L2 does not have pilot component nor secondary code
d_secondary = false; d_secondary = false;
trk_parameters.track_pilot = false; trk_parameters.track_pilot = false;
interchange_iq = false;
} }
else if (signal_type == "L5") else if (signal_type == "L5")
{ {
d_signal_carrier_freq = GPS_L5_FREQ_HZ; d_signal_carrier_freq = GPS_L5_FREQ_HZ;
d_code_period = GPS_L5I_PERIOD; d_code_period = GPS_L5I_PERIOD;
d_code_chip_rate = GPS_L5I_CODE_RATE_HZ; d_code_chip_rate = GPS_L5I_CODE_RATE_HZ;
// symbol integration: 10 trk symbols (10 ms) = 1 tlm bit
d_symbols_per_bit = GPS_L5_SAMPLES_PER_SYMBOL; d_symbols_per_bit = GPS_L5_SAMPLES_PER_SYMBOL;
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_code_samples_per_chip = 1; d_code_samples_per_chip = 1;
@ -194,17 +177,22 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
d_secondary = true; d_secondary = true;
if (trk_parameters.track_pilot) if (trk_parameters.track_pilot)
{ {
// synchronize pilot secondary code
d_secondary_code_length = static_cast<uint32_t>(GPS_L5Q_NH_CODE_LENGTH); d_secondary_code_length = static_cast<uint32_t>(GPS_L5Q_NH_CODE_LENGTH);
d_secondary_code_string = const_cast<std::string *>(&GPS_L5Q_NH_CODE_STR); d_secondary_code_string = const_cast<std::string *>(&GPS_L5Q_NH_CODE_STR);
// remove data secondary code
// remove Neuman-Hofman Code (see IS-GPS-705D)
d_data_secondary_code_length = static_cast<uint32_t>(GPS_L5I_NH_CODE_LENGTH);
d_data_secondary_code_string = const_cast<std::string *>(&GPS_L5I_NH_CODE_STR);
signal_pretty_name = signal_pretty_name + "Q"; signal_pretty_name = signal_pretty_name + "Q";
interchange_iq = true;
} }
else else
{ {
// synchronize and remove data secondary code
// remove Neuman-Hofman Code (see IS-GPS-705D)
d_secondary_code_length = static_cast<uint32_t>(GPS_L5I_NH_CODE_LENGTH); d_secondary_code_length = static_cast<uint32_t>(GPS_L5I_NH_CODE_LENGTH);
d_secondary_code_string = const_cast<std::string *>(&GPS_L5I_NH_CODE_STR); d_secondary_code_string = const_cast<std::string *>(&GPS_L5I_NH_CODE_STR);
signal_pretty_name = signal_pretty_name + "I"; signal_pretty_name = signal_pretty_name + "I";
interchange_iq = false;
} }
} }
else else
@ -213,7 +201,6 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
std::cerr << "Invalid Signal argument when instantiating tracking blocks" << std::endl; std::cerr << "Invalid Signal argument when instantiating tracking blocks" << std::endl;
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_secondary = false; d_secondary = false;
interchange_iq = false;
d_signal_carrier_freq = 0.0; d_signal_carrier_freq = 0.0;
d_code_period = 0.0; d_code_period = 0.0;
d_code_length_chips = 0U; d_code_length_chips = 0U;
@ -230,6 +217,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
d_code_period = GALILEO_E1_CODE_PERIOD; d_code_period = GALILEO_E1_CODE_PERIOD;
d_code_chip_rate = GALILEO_E1_CODE_CHIP_RATE_HZ; d_code_chip_rate = GALILEO_E1_CODE_CHIP_RATE_HZ;
d_code_length_chips = static_cast<uint32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS); d_code_length_chips = static_cast<uint32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS);
// Galileo E1b has 1 trk symbol (4 ms) per tlm bit, no symbol integration required
d_symbols_per_bit = 1; d_symbols_per_bit = 1;
d_correlation_length_ms = 4; d_correlation_length_ms = 4;
d_code_samples_per_chip = 2; // CBOC disabled: 2 samples per chip. CBOC enabled: 12 samples per chip d_code_samples_per_chip = 2; // CBOC disabled: 2 samples per chip. CBOC enabled: 12 samples per chip
@ -246,7 +234,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
d_secondary = false; d_secondary = false;
signal_pretty_name = signal_pretty_name + "B"; signal_pretty_name = signal_pretty_name + "B";
} }
interchange_iq = false; // Note that E1-B and E1-C are in anti-phase, NOT IN QUADRATURE. See Galileo ICD. // Note that E1-B and E1-C are in anti-phase, NOT IN QUADRATURE. See Galileo ICD.
} }
else if (signal_type == "5X") else if (signal_type == "5X")
{ {
@ -257,20 +245,22 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_code_samples_per_chip = 1; d_code_samples_per_chip = 1;
d_code_length_chips = static_cast<uint32_t>(GALILEO_E5A_CODE_LENGTH_CHIPS); d_code_length_chips = static_cast<uint32_t>(GALILEO_E5A_CODE_LENGTH_CHIPS);
d_secondary = true;
if (trk_parameters.track_pilot) if (trk_parameters.track_pilot)
{ {
d_secondary = true; // synchronize pilot secondary code
d_secondary_code_length = static_cast<uint32_t>(GALILEO_E5A_Q_SECONDARY_CODE_LENGTH); d_secondary_code_length = static_cast<uint32_t>(GALILEO_E5A_Q_SECONDARY_CODE_LENGTH);
signal_pretty_name = signal_pretty_name + "Q"; signal_pretty_name = signal_pretty_name + "Q";
interchange_iq = true; // remove data secondary code
d_data_secondary_code_length = static_cast<uint32_t>(GALILEO_E5A_I_SECONDARY_CODE_LENGTH);
d_data_secondary_code_string = const_cast<std::string *>(&GALILEO_E5A_I_SECONDARY_CODE);
} }
else else
{ {
//Do not acquire secondary code in data component. It is done in telemetry decoder // synchronize and remove data secondary code
d_secondary = false; d_secondary_code_length = static_cast<uint32_t>(GALILEO_E5A_I_SECONDARY_CODE_LENGTH);
d_secondary_code_string = const_cast<std::string *>(&GALILEO_E5A_I_SECONDARY_CODE);
signal_pretty_name = signal_pretty_name + "I"; signal_pretty_name = signal_pretty_name + "I";
interchange_iq = false;
} }
} }
else else
@ -279,7 +269,6 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
std::cout << "Invalid Signal argument when instantiating tracking blocks" << std::endl; std::cout << "Invalid Signal argument when instantiating tracking blocks" << std::endl;
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_secondary = false; d_secondary = false;
interchange_iq = false;
d_signal_carrier_freq = 0.0; d_signal_carrier_freq = 0.0;
d_code_period = 0.0; d_code_period = 0.0;
d_code_length_chips = 0U; d_code_length_chips = 0U;
@ -297,14 +286,17 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
d_code_period = BEIDOU_B1I_CODE_PERIOD; d_code_period = BEIDOU_B1I_CODE_PERIOD;
d_code_chip_rate = BEIDOU_B1I_CODE_RATE_HZ; d_code_chip_rate = BEIDOU_B1I_CODE_RATE_HZ;
d_code_length_chips = static_cast<uint32_t>(BEIDOU_B1I_CODE_LENGTH_CHIPS); d_code_length_chips = static_cast<uint32_t>(BEIDOU_B1I_CODE_LENGTH_CHIPS);
d_symbols_per_bit = BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT; //d_symbols_per_bit = BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT; //todo: enable after fixing beidou symbol synchronization
d_symbols_per_bit = 1;
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_code_samples_per_chip = 1; d_code_samples_per_chip = 1;
d_secondary = true; d_secondary = false;
trk_parameters.track_pilot = false; trk_parameters.track_pilot = false;
interchange_iq = false; // synchronize and remove data secondary code
d_secondary_code_length = static_cast<uint32_t>(BEIDOU_B1I_SECONDARY_CODE_LENGTH); d_secondary_code_length = static_cast<uint32_t>(BEIDOU_B1I_SECONDARY_CODE_LENGTH);
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_SECONDARY_CODE_STR); d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_SECONDARY_CODE_STR);
//d_data_secondary_code_length = static_cast<uint32_t>(BEIDOU_B1I_SECONDARY_CODE_LENGTH);
//d_data_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_SECONDARY_CODE_STR);
} }
else if (signal_type == "B3") else if (signal_type == "B3")
{ {
@ -313,14 +305,16 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
d_code_period = BEIDOU_B3I_CODE_PERIOD; d_code_period = BEIDOU_B3I_CODE_PERIOD;
d_code_chip_rate = BEIDOU_B3I_CODE_RATE_HZ; d_code_chip_rate = BEIDOU_B3I_CODE_RATE_HZ;
d_code_length_chips = static_cast<uint32_t>(BEIDOU_B3I_CODE_LENGTH_CHIPS); d_code_length_chips = static_cast<uint32_t>(BEIDOU_B3I_CODE_LENGTH_CHIPS);
d_symbols_per_bit = BEIDOU_B3I_TELEMETRY_SYMBOLS_PER_BIT; //d_symbols_per_bit = BEIDOU_B3I_TELEMETRY_SYMBOLS_PER_BIT; //todo: enable after fixing beidou symbol synchronization
d_symbols_per_bit = 1;
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_code_samples_per_chip = 1; d_code_samples_per_chip = 1;
d_secondary = true; d_secondary = false;
trk_parameters.track_pilot = false; trk_parameters.track_pilot = false;
interchange_iq = false;
d_secondary_code_length = static_cast<uint32_t>(BEIDOU_B3I_SECONDARY_CODE_LENGTH); d_secondary_code_length = static_cast<uint32_t>(BEIDOU_B3I_SECONDARY_CODE_LENGTH);
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B3I_SECONDARY_CODE_STR); d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B3I_SECONDARY_CODE_STR);
//d_data_secondary_code_length = static_cast<uint32_t>(BEIDOU_B3I_SECONDARY_CODE_LENGTH);
//d_data_secondary_code_string = const_cast<std::string *>(&BEIDOU_B3I_SECONDARY_CODE_STR);
} }
else else
{ {
@ -328,7 +322,6 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
std::cout << "Invalid Signal argument when instantiating tracking blocks" << std::endl; std::cout << "Invalid Signal argument when instantiating tracking blocks" << std::endl;
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_secondary = false; d_secondary = false;
interchange_iq = false;
d_signal_carrier_freq = 0.0; d_signal_carrier_freq = 0.0;
d_code_period = 0.0; d_code_period = 0.0;
d_code_length_chips = 0; d_code_length_chips = 0;
@ -343,7 +336,6 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::bl
std::cerr << "Invalid System argument when instantiating tracking blocks" << std::endl; std::cerr << "Invalid System argument when instantiating tracking blocks" << std::endl;
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_secondary = false; d_secondary = false;
interchange_iq = false;
d_signal_carrier_freq = 0.0; d_signal_carrier_freq = 0.0;
d_code_period = 0.0; d_code_period = 0.0;
d_code_length_chips = 0U; d_code_length_chips = 0U;
@ -554,11 +546,11 @@ void dll_pll_veml_tracking::msg_handler_telemetry_to_trk(const pmt::pmt_t &msg)
switch (tlm_event) switch (tlm_event)
{ {
case 1: //tlm fault in current channel case 1: // tlm fault in current channel
{ {
DLOG(INFO) << "Telemetry fault received in ch " << this->d_channel; DLOG(INFO) << "Telemetry fault received in ch " << this->d_channel;
gr::thread::scoped_lock lock(d_setlock); gr::thread::scoped_lock lock(d_setlock);
d_carrier_lock_fail_counter = 100000; //force loss-of-lock condition d_carrier_lock_fail_counter = 200000; //force loss-of-lock condition
break; break;
} }
default: default:
@ -578,7 +570,6 @@ void dll_pll_veml_tracking::msg_handler_telemetry_to_trk(const pmt::pmt_t &msg)
void dll_pll_veml_tracking::start_tracking() void dll_pll_veml_tracking::start_tracking()
{ {
gr::thread::scoped_lock l(d_setlock); gr::thread::scoped_lock l(d_setlock);
// correct the code phase according to the delay between acq and trk // correct the code phase according to the delay between acq and trk
d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples; d_acq_code_phase_samples = d_acquisition_gnss_synchro->Acq_delay_samples;
d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz; d_acq_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz;
@ -619,7 +610,6 @@ void dll_pll_veml_tracking::start_tracking()
if (trk_parameters.track_pilot) if (trk_parameters.track_pilot)
{ {
std::array<char, 3> pilot_signal = {{'1', 'C', '\0'}}; std::array<char, 3> pilot_signal = {{'1', 'C', '\0'}};
galileo_e1_code_gen_sinboc11_float(gsl::span<float>(d_tracking_code, 2 * d_code_length_chips), pilot_signal, d_acquisition_gnss_synchro->PRN); galileo_e1_code_gen_sinboc11_float(gsl::span<float>(d_tracking_code, 2 * d_code_length_chips), pilot_signal, d_acquisition_gnss_synchro->PRN);
galileo_e1_code_gen_sinboc11_float(gsl::span<float>(d_data_code, 2 * d_code_length_chips), Signal_, d_acquisition_gnss_synchro->PRN); galileo_e1_code_gen_sinboc11_float(gsl::span<float>(d_data_code, 2 * d_code_length_chips), Signal_, d_acquisition_gnss_synchro->PRN);
d_Prompt_Data[0] = gr_complex(0.0, 0.0); d_Prompt_Data[0] = gr_complex(0.0, 0.0);
@ -641,7 +631,7 @@ void dll_pll_veml_tracking::start_tracking()
for (uint32_t i = 0; i < d_code_length_chips; i++) for (uint32_t i = 0; i < d_code_length_chips; i++)
{ {
d_tracking_code[i] = aux_code[i].imag(); d_tracking_code[i] = aux_code[i].imag();
d_data_code[i] = aux_code[i].real(); //the same because it is generated the full signal (E5aI + E5aQ) d_data_code[i] = aux_code[i].real(); // the same because it is generated the full signal (E5aI + E5aQ)
} }
d_Prompt_Data[0] = gr_complex(0.0, 0.0); d_Prompt_Data[0] = gr_complex(0.0, 0.0);
correlator_data_cpu.set_local_code_and_taps(d_code_length_chips, d_data_code, d_prompt_data_shift); correlator_data_cpu.set_local_code_and_taps(d_code_length_chips, d_data_code, d_prompt_data_shift);
@ -658,40 +648,35 @@ void dll_pll_veml_tracking::start_tracking()
else if (systemName == "Beidou" and signal_type == "B1") else if (systemName == "Beidou" and signal_type == "B1")
{ {
beidou_b1i_code_gen_float(gsl::span<float>(d_tracking_code, 2 * d_code_length_chips), d_acquisition_gnss_synchro->PRN, 0); beidou_b1i_code_gen_float(gsl::span<float>(d_tracking_code, 2 * d_code_length_chips), d_acquisition_gnss_synchro->PRN, 0);
// Update secondary code settings for geo satellites // GEO Satellites use different secondary code
if (d_acquisition_gnss_synchro->PRN > 0 and d_acquisition_gnss_synchro->PRN < 6) if (d_acquisition_gnss_synchro->PRN > 0 and d_acquisition_gnss_synchro->PRN < 6)
{ {
d_symbols_per_bit = 2; //d_symbols_per_bit = BEIDOU_B1I_GEO_TELEMETRY_SYMBOLS_PER_BIT;//todo: enable after fixing beidou symbol synchronization
d_symbols_per_bit = 1;
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_code_samples_per_chip = 1; d_code_samples_per_chip = 1;
d_secondary = false; d_secondary = false;
trk_parameters.track_pilot = false; trk_parameters.track_pilot = false;
interchange_iq = false; // set the preamble in the secondary code acquisition
d_secondary_code_length = 0; d_secondary_code_length = static_cast<uint32_t>(BEIDOU_B1I_GEO_PREAMBLE_LENGTH_SYMBOLS);
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_D2_SECONDARY_CODE_STR); d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_GEO_PREAMBLE_SYMBOLS_STR);
d_data_secondary_code_length = 0;
// preamble bits to sampled symbols d_Prompt_circular_buffer.set_capacity(d_secondary_code_length);
d_preamble_length_symbols = 22;
d_preambles_symbols = static_cast<int32_t *>(volk_gnsssdr_malloc(22 * sizeof(int32_t), volk_gnsssdr_get_alignment()));
int32_t n = 0;
uint32_t preambles_bits[BEIDOU_B1I_PREAMBLE_LENGTH_BITS] = {1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0};
for (uint32_t preambles_bit : preambles_bits)
{
for (int32_t j = 0; j < d_symbols_per_bit; j++)
{
if (preambles_bit == 1)
{
d_preambles_symbols[n] = 1;
} }
else else
{ {
d_preambles_symbols[n] = -1; //d_symbols_per_bit = BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT;//todo: enable after fixing beidou symbol synchronization
} d_symbols_per_bit = 1;
n++; d_correlation_length_ms = 1;
} d_code_samples_per_chip = 1;
} d_secondary = false;
d_symbol_history.resize(22); // Change fixed buffer size trk_parameters.track_pilot = false;
d_symbol_history.clear(); // synchronize and remove data secondary code
d_secondary_code_length = static_cast<uint32_t>(BEIDOU_B1I_SECONDARY_CODE_LENGTH);
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_SECONDARY_CODE_STR);
//d_data_secondary_code_length = static_cast<uint32_t>(BEIDOU_B1I_SECONDARY_CODE_LENGTH);
//d_data_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_SECONDARY_CODE_STR);
d_Prompt_circular_buffer.set_capacity(d_secondary_code_length);
} }
} }
@ -701,37 +686,32 @@ void dll_pll_veml_tracking::start_tracking()
// Update secondary code settings for geo satellites // Update secondary code settings for geo satellites
if (d_acquisition_gnss_synchro->PRN > 0 and d_acquisition_gnss_synchro->PRN < 6) if (d_acquisition_gnss_synchro->PRN > 0 and d_acquisition_gnss_synchro->PRN < 6)
{ {
d_symbols_per_bit = 2; //d_symbols_per_bit = BEIDOU_B3I_GEO_TELEMETRY_SYMBOLS_PER_BIT;//todo: enable after fixing beidou symbol synchronization
d_symbols_per_bit = 1;
d_correlation_length_ms = 1; d_correlation_length_ms = 1;
d_code_samples_per_chip = 1; d_code_samples_per_chip = 1;
d_secondary = false; d_secondary = false;
trk_parameters.track_pilot = false; trk_parameters.track_pilot = false;
interchange_iq = false; // set the preamble in the secondary code acquisition
d_secondary_code_length = 0; d_secondary_code_length = static_cast<uint32_t>(BEIDOU_B3I_GEO_PREAMBLE_LENGTH_SYMBOLS);
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B3I_D2_SECONDARY_CODE_STR); d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B3I_GEO_PREAMBLE_SYMBOLS_STR);
d_data_secondary_code_length = 0;
// preamble bits to sampled symbols d_Prompt_circular_buffer.set_capacity(d_secondary_code_length);
d_preamble_length_symbols = 22;
d_preambles_symbols = static_cast<int32_t *>(volk_gnsssdr_malloc(22 * sizeof(int32_t), volk_gnsssdr_get_alignment()));
int32_t n = 0;
uint32_t preambles_bits[BEIDOU_B3I_PREAMBLE_LENGTH_BITS] = {1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0};
for (uint32_t preambles_bit : preambles_bits)
{
for (int32_t j = 0; j < d_symbols_per_bit; j++)
{
if (preambles_bit == 1)
{
d_preambles_symbols[n] = 1;
} }
else else
{ {
d_preambles_symbols[n] = -1; //d_symbols_per_bit = BEIDOU_B3I_TELEMETRY_SYMBOLS_PER_BIT; //todo: enable after fixing beidou symbol synchronization
} d_symbols_per_bit = 1;
n++; d_correlation_length_ms = 1;
} d_code_samples_per_chip = 1;
} d_secondary = false;
d_symbol_history.resize(22); // Change fixed buffer size trk_parameters.track_pilot = false;
d_symbol_history.clear(); // synchronize and remove data secondary code
d_secondary_code_length = static_cast<uint32_t>(BEIDOU_B3I_SECONDARY_CODE_LENGTH);
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B3I_SECONDARY_CODE_STR);
//d_data_secondary_code_length = static_cast<uint32_t>(BEIDOU_B3I_SECONDARY_CODE_LENGTH);
//d_data_secondary_code_string = const_cast<std::string *>(&BEIDOU_B3I_SECONDARY_CODE_STR);
d_Prompt_circular_buffer.set_capacity(d_secondary_code_length);
} }
} }
@ -890,11 +870,9 @@ bool dll_pll_veml_tracking::cn0_and_tracking_lock_status(double coh_integration_
d_CN0_SNV_dB_Hz = d_cn0_smoother.smooth(d_CN0_SNV_dB_Hz_raw); d_CN0_SNV_dB_Hz = d_cn0_smoother.smooth(d_CN0_SNV_dB_Hz_raw);
// Carrier lock indicator // Carrier lock indicator
d_carrier_lock_test = d_carrier_lock_test_smoother.smooth(carrier_lock_detector(d_Prompt_buffer.data(), 1)); d_carrier_lock_test = d_carrier_lock_test_smoother.smooth(carrier_lock_detector(d_Prompt_buffer.data(), 1));
//d_carrier_lock_test = carrier_lock_detector(d_Prompt_buffer, trk_parameters.cn0_samples);
// Loss of lock detection // Loss of lock detection
if (!d_pull_in_transitory) if (!d_pull_in_transitory)
{ {
//d_carrier_lock_test < d_carrier_lock_threshold or
if (d_carrier_lock_test < d_carrier_lock_threshold) if (d_carrier_lock_test < d_carrier_lock_threshold)
{ {
d_carrier_lock_fail_counter++; d_carrier_lock_fail_counter++;
@ -985,20 +963,20 @@ void dll_pll_veml_tracking::run_dll_pll()
if ((d_pull_in_transitory == true and trk_parameters.enable_fll_pull_in == true) or trk_parameters.enable_fll_steady_state) if ((d_pull_in_transitory == true and trk_parameters.enable_fll_pull_in == true) or trk_parameters.enable_fll_steady_state)
{ {
// FLL discriminator // FLL discriminator
//d_carr_freq_error_hz = fll_four_quadrant_atan(d_P_accu_old, d_P_accu, 0, d_current_correlation_time_s) / GPS_TWO_PI; // d_carr_freq_error_hz = fll_four_quadrant_atan(d_P_accu_old, d_P_accu, 0, d_current_correlation_time_s) / GPS_TWO_PI;
d_carr_freq_error_hz = fll_diff_atan(d_P_accu_old, d_P_accu, 0, d_current_correlation_time_s) / GPS_TWO_PI; d_carr_freq_error_hz = fll_diff_atan(d_P_accu_old, d_P_accu, 0, d_current_correlation_time_s) / GPS_TWO_PI;
d_P_accu_old = d_P_accu; d_P_accu_old = d_P_accu;
//std::cout << "d_carr_freq_error_hz: " << d_carr_freq_error_hz << std::endl; // std::cout << "d_carr_freq_error_hz: " << d_carr_freq_error_hz << std::endl;
// Carrier discriminator filter // Carrier discriminator filter
if ((d_pull_in_transitory == true and trk_parameters.enable_fll_pull_in == true)) if ((d_pull_in_transitory == true and trk_parameters.enable_fll_pull_in == true))
{ {
//pure FLL, disable PLL // pure FLL, disable PLL
d_carr_error_filt_hz = d_carrier_loop_filter.get_carrier_error(d_carr_freq_error_hz, 0, d_current_correlation_time_s); d_carr_error_filt_hz = d_carrier_loop_filter.get_carrier_error(d_carr_freq_error_hz, 0, d_current_correlation_time_s);
} }
else else
{ {
//FLL-aided PLL // FLL-aided PLL
d_carr_error_filt_hz = d_carrier_loop_filter.get_carrier_error(d_carr_freq_error_hz, d_carr_phase_error_hz, d_current_correlation_time_s); d_carr_error_filt_hz = d_carrier_loop_filter.get_carrier_error(d_carr_freq_error_hz, d_carr_phase_error_hz, d_current_correlation_time_s);
} }
} }
@ -1013,6 +991,7 @@ void dll_pll_veml_tracking::run_dll_pll()
// std::cout << "d_carrier_doppler_hz: " << d_carrier_doppler_hz << std::endl; // std::cout << "d_carrier_doppler_hz: " << d_carrier_doppler_hz << std::endl;
// std::cout << "d_CN0_SNV_dB_Hz: " << this->d_CN0_SNV_dB_Hz << std::endl; // std::cout << "d_CN0_SNV_dB_Hz: " << this->d_CN0_SNV_dB_Hz << std::endl;
// ################## DLL ########################################################## // ################## DLL ##########################################################
// DLL discriminator // DLL discriminator
if (d_veml) if (d_veml)
@ -1029,12 +1008,15 @@ void dll_pll_veml_tracking::run_dll_pll()
d_code_freq_chips = (1.0 + (d_carrier_doppler_hz / d_signal_carrier_freq)) * d_code_chip_rate - d_code_error_filt_chips; d_code_freq_chips = (1.0 + (d_carrier_doppler_hz / d_signal_carrier_freq)) * d_code_chip_rate - d_code_error_filt_chips;
// Experimental: detect Carrier Doppler vs. Code Doppler incoherence and correct the Carrier Doppler // Experimental: detect Carrier Doppler vs. Code Doppler incoherence and correct the Carrier Doppler
if (trk_parameters.enable_doppler_correction == true)
{
if (d_pull_in_transitory == false and d_corrected_doppler == false) if (d_pull_in_transitory == false and d_corrected_doppler == false)
{ {
d_dll_filt_history.push_back(static_cast<float>(d_code_error_filt_chips)); d_dll_filt_history.push_back(static_cast<float>(d_code_error_filt_chips));
if (d_dll_filt_history.full()) if (d_dll_filt_history.full())
{ {
float avg_code_error_chips_s = std::accumulate(d_dll_filt_history.begin(), d_dll_filt_history.end(), 0) / static_cast<float>(d_dll_filt_history.capacity()); float avg_code_error_chips_s = std::accumulate(d_dll_filt_history.begin(), d_dll_filt_history.end(), 0.0) / static_cast<float>(d_dll_filt_history.capacity());
if (fabs(avg_code_error_chips_s) > 1.0) if (fabs(avg_code_error_chips_s) > 1.0)
{ {
float carrier_doppler_error_hz = static_cast<float>(d_signal_carrier_freq) * avg_code_error_chips_s / static_cast<float>(d_code_chip_rate); float carrier_doppler_error_hz = static_cast<float>(d_signal_carrier_freq) * avg_code_error_chips_s / static_cast<float>(d_code_chip_rate);
@ -1042,6 +1024,8 @@ void dll_pll_veml_tracking::run_dll_pll()
d_carrier_loop_filter.initialize(d_carrier_doppler_hz - carrier_doppler_error_hz); d_carrier_loop_filter.initialize(d_carrier_doppler_hz - carrier_doppler_error_hz);
d_corrected_doppler = true; d_corrected_doppler = true;
} }
d_dll_filt_history.clear();
}
} }
} }
} }
@ -1053,6 +1037,7 @@ void dll_pll_veml_tracking::clear_tracking_vars()
if (trk_parameters.track_pilot) if (trk_parameters.track_pilot)
{ {
d_Prompt_Data[0] = gr_complex(0.0, 0.0); d_Prompt_Data[0] = gr_complex(0.0, 0.0);
d_P_data_accu = gr_complex(0.0, 0.0);
} }
d_P_accu_old = gr_complex(0.0, 0.0); d_P_accu_old = gr_complex(0.0, 0.0);
d_carr_phase_error_hz = 0.0; d_carr_phase_error_hz = 0.0;
@ -1061,6 +1046,7 @@ void dll_pll_veml_tracking::clear_tracking_vars()
d_code_error_chips = 0.0; d_code_error_chips = 0.0;
d_code_error_filt_chips = 0.0; d_code_error_filt_chips = 0.0;
d_current_symbol = 0; d_current_symbol = 0;
d_current_data_symbol = 0;
d_Prompt_circular_buffer.clear(); d_Prompt_circular_buffer.clear();
d_carrier_phase_rate_step_rad = 0.0; d_carrier_phase_rate_step_rad = 0.0;
d_code_phase_rate_step_chips = 0.0; d_code_phase_rate_step_chips = 0.0;
@ -1079,7 +1065,6 @@ void dll_pll_veml_tracking::update_tracking_vars()
// Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation // Compute the next buffer length based in the new period of the PRN sequence and the code phase error estimation
T_prn_samples = T_prn_seconds * trk_parameters.fs_in; T_prn_samples = T_prn_seconds * trk_parameters.fs_in;
K_blk_samples = T_prn_samples + d_rem_code_phase_samples; K_blk_samples = T_prn_samples + d_rem_code_phase_samples;
//d_current_prn_length_samples = static_cast<int32_t>(round(K_blk_samples)); // round to a discrete number of samples
d_current_prn_length_samples = static_cast<int32_t>(std::floor(K_blk_samples)); // round to a discrete number of samples d_current_prn_length_samples = static_cast<int32_t>(std::floor(K_blk_samples)); // round to a discrete number of samples
//################### PLL COMMANDS ################################################# //################### PLL COMMANDS #################################################
@ -1105,15 +1090,15 @@ void dll_pll_veml_tracking::update_tracking_vars()
d_carrier_phase_rate_step_rad = (tmp_cp2 - tmp_cp1) / tmp_samples; d_carrier_phase_rate_step_rad = (tmp_cp2 - tmp_cp1) / tmp_samples;
} }
} }
//std::cout << d_carrier_phase_rate_step_rad * trk_parameters.fs_in * trk_parameters.fs_in / PI_2 << std::endl; // std::cout << d_carrier_phase_rate_step_rad * trk_parameters.fs_in * trk_parameters.fs_in / PI_2 << std::endl;
// remnant carrier phase to prevent overflow in the code NCO // remnant carrier phase to prevent overflow in the code NCO
d_rem_carr_phase_rad += static_cast<float>(d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples) + 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples)); d_rem_carr_phase_rad += static_cast<float>(d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples) + 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples));
d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, PI_2); d_rem_carr_phase_rad = fmod(d_rem_carr_phase_rad, PI_2);
// carrier phase accumulator // carrier phase accumulator
//double a = d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples); // double a = d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples);
//double b = 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples); // double b = 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples);
//std::cout << fmod(b, PI_2) / fmod(a, PI_2) << std::endl; // std::cout << fmod(b, PI_2) / fmod(a, PI_2) << std::endl;
d_acc_carrier_phase_rad -= (d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples) + 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples)); d_acc_carrier_phase_rad -= (d_carrier_phase_step_rad * static_cast<double>(d_current_prn_length_samples) + 0.5 * d_carrier_phase_rate_step_rad * static_cast<double>(d_current_prn_length_samples) * static_cast<double>(d_current_prn_length_samples));
//################### DLL COMMANDS ################################################# //################### DLL COMMANDS #################################################
@ -1184,12 +1169,70 @@ void dll_pll_veml_tracking::save_correlation_results()
d_E_accu += *d_Early; d_E_accu += *d_Early;
d_P_accu += *d_Prompt; d_P_accu += *d_Prompt;
d_L_accu += *d_Late; d_L_accu += *d_Late;
d_current_symbol++;
d_current_symbol %= d_symbols_per_bit;
} }
// If tracking pilot, disable Costas loop
// data secondary code roll-up
if (d_symbols_per_bit > 1)
{
if (d_data_secondary_code_length > 0)
{
if (trk_parameters.track_pilot) if (trk_parameters.track_pilot)
{ {
if (d_data_secondary_code_string->at(d_current_data_symbol) == '0')
{
d_P_data_accu += *d_Prompt_Data;
}
else
{
d_P_data_accu -= *d_Prompt_Data;
}
}
else
{
if (d_data_secondary_code_string->at(d_current_data_symbol) == '0')
{
d_P_data_accu += *d_Prompt;
}
else
{
d_P_data_accu -= *d_Prompt;
}
}
d_current_data_symbol++;
// data secondary code roll-up
d_current_data_symbol %= d_data_secondary_code_length;
}
else
{
if (trk_parameters.track_pilot)
{
d_P_data_accu += *d_Prompt_Data;
}
else
{
d_P_data_accu += *d_Prompt;
//std::cout << "s[" << d_current_data_symbol << "]=" << (int)((*d_Prompt).real() > 0) << std::endl;
}
d_current_data_symbol++;
d_current_data_symbol %= d_symbols_per_bit;
}
}
else
{
if (trk_parameters.track_pilot)
{
d_P_data_accu = *d_Prompt_Data;
}
else
{
d_P_data_accu = *d_Prompt;
}
}
if (trk_parameters.track_pilot)
{
// If tracking pilot, disable Costas loop
d_cloop = false; d_cloop = false;
} }
else else
@ -1199,7 +1242,7 @@ void dll_pll_veml_tracking::save_correlation_results()
} }
void dll_pll_veml_tracking::log_data(bool integrating) void dll_pll_veml_tracking::log_data()
{ {
if (d_dump) if (d_dump)
{ {
@ -1211,31 +1254,15 @@ void dll_pll_veml_tracking::log_data(bool integrating)
double tmp_double; double tmp_double;
uint64_t tmp_long_int; uint64_t tmp_long_int;
if (trk_parameters.track_pilot) if (trk_parameters.track_pilot)
{
if (interchange_iq)
{
prompt_I = d_Prompt_Data->imag();
prompt_Q = d_Prompt_Data->real();
}
else
{ {
prompt_I = d_Prompt_Data->real(); prompt_I = d_Prompt_Data->real();
prompt_Q = d_Prompt_Data->imag(); prompt_Q = d_Prompt_Data->imag();
} }
}
else
{
if (interchange_iq)
{
prompt_I = d_Prompt->imag();
prompt_Q = d_Prompt->real();
}
else else
{ {
prompt_I = d_Prompt->real(); prompt_I = d_Prompt->real();
prompt_Q = d_Prompt->imag(); prompt_Q = d_Prompt->imag();
} }
}
if (d_veml) if (d_veml)
{ {
tmp_VE = std::abs<float>(d_VE_accu); tmp_VE = std::abs<float>(d_VE_accu);
@ -1249,20 +1276,6 @@ void dll_pll_veml_tracking::log_data(bool integrating)
tmp_E = std::abs<float>(d_E_accu); tmp_E = std::abs<float>(d_E_accu);
tmp_P = std::abs<float>(d_P_accu); tmp_P = std::abs<float>(d_P_accu);
tmp_L = std::abs<float>(d_L_accu); tmp_L = std::abs<float>(d_L_accu);
if (integrating)
{
//TODO: Improve this solution!
// It compensates the amplitude difference while integrating
if (d_extend_correlation_symbols_count > 0)
{
float scale_factor = static_cast<float>(trk_parameters.extend_correlation_symbols) / static_cast<float>(d_extend_correlation_symbols_count);
tmp_VE *= scale_factor;
tmp_E *= scale_factor;
tmp_P *= scale_factor;
tmp_L *= scale_factor;
tmp_VL *= scale_factor;
}
}
try try
{ {
@ -1383,7 +1396,6 @@ int32_t dll_pll_veml_tracking::save_matfile()
auto aux1 = std::vector<float>(num_epoch); auto aux1 = std::vector<float>(num_epoch);
auto aux2 = std::vector<double>(num_epoch); auto aux2 = std::vector<double>(num_epoch);
auto PRN = std::vector<uint32_t>(num_epoch); auto PRN = std::vector<uint32_t>(num_epoch);
try try
{ {
if (dump_file.is_open()) if (dump_file.is_open())
@ -1579,6 +1591,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
const auto *in = reinterpret_cast<const gr_complex *>(input_items[0]); const auto *in = reinterpret_cast<const gr_complex *>(input_items[0]);
auto **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]); auto **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]);
Gnss_Synchro current_synchro_data = Gnss_Synchro(); Gnss_Synchro current_synchro_data = Gnss_Synchro();
current_synchro_data.Flag_valid_symbol_output = false;
if (d_pull_in_transitory == true) if (d_pull_in_transitory == true)
{ {
@ -1642,6 +1655,13 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
d_P_accu = *d_Prompt; d_P_accu = *d_Prompt;
d_L_accu = *d_Late; d_L_accu = *d_Late;
//fail-safe: check if the secondary code or bit synchronization has not succedded in a limited time period
if (trk_parameters.bit_synchronization_time_limit_s < (d_sample_counter - d_acq_sample_stamp) / static_cast<int>(trk_parameters.fs_in))
{
d_carrier_lock_fail_counter = 300000; //force loss-of-lock condition
LOG(INFO) << systemName << " " << signal_pretty_name << " tracking synchronization time limit reached in channel " << d_channel
<< " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl;
}
// Check lock status // Check lock status
if (!cn0_and_tracking_lock_status(d_code_period)) if (!cn0_and_tracking_lock_status(d_code_period))
{ {
@ -1656,7 +1676,7 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
update_tracking_vars(); update_tracking_vars();
// enable write dump file this cycle (valid DLL/PLL cycle) // enable write dump file this cycle (valid DLL/PLL cycle)
log_data(false); log_data();
if (!d_pull_in_transitory) if (!d_pull_in_transitory)
{ {
@ -1678,42 +1698,18 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
} }
else if (d_symbols_per_bit > 1) //Signal does not have secondary code. Search a bit transition by sign change else if (d_symbols_per_bit > 1) //Signal does not have secondary code. Search a bit transition by sign change
{ {
float current_tracking_time_s = static_cast<float>(d_sample_counter - d_acq_sample_stamp) / trk_parameters.fs_in;
if (current_tracking_time_s > 10)
{
d_symbol_history.push_back(d_Prompt->real());
//******* preamble correlation ******** //******* preamble correlation ********
int32_t corr_value = 0; d_Prompt_circular_buffer.push_back(*d_Prompt);
if ((static_cast<int32_t>(d_symbol_history.size()) == d_preamble_length_symbols)) // and (d_make_correlation or !d_flag_frame_sync)) if (d_Prompt_circular_buffer.size() == d_secondary_code_length)
{ {
int i = 0; next_state = acquire_secondary();
for (const auto &iter : d_symbol_history) if (next_state)
{ {
if (iter < 0.0) // symbols clipping LOG(INFO) << systemName << " " << signal_pretty_name << " tracking bit synchronization locked in channel " << d_channel
{ << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl;
corr_value -= d_preambles_symbols[i]; std::cout << systemName << " " << signal_pretty_name << " tracking bit synchronization locked in channel " << d_channel
}
else
{
corr_value += d_preambles_symbols[i];
}
i++;
}
}
if (corr_value == d_preamble_length_symbols)
{
LOG(INFO) << systemName << " " << signal_pretty_name << " tracking preamble detected in channel " << d_channel
<< " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl; << " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl;
next_state = true;
} }
else
{
next_state = false;
}
}
else
{
next_state = false;
} }
} }
else else
@ -1725,52 +1721,17 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
{ {
next_state = false; //keep in state 2 during pull-in transitory next_state = false; //keep in state 2 during pull-in transitory
} }
// ########### Output the tracking results to Telemetry block ##########
if (interchange_iq)
{
if (trk_parameters.track_pilot)
{
// Note that data and pilot components are in quadrature. I and Q are interchanged
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).imag());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).real());
}
else
{
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).imag());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).real());
}
}
else
{
if (trk_parameters.track_pilot)
{
// Note that data and pilot components are in quadrature. I and Q are interchanged
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).real());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).imag());
}
else
{
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).real());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).imag());
}
}
current_synchro_data.Code_phase_samples = d_rem_code_phase_samples;
current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
current_synchro_data.Flag_valid_symbol_output = true;
current_synchro_data.correlation_length_ms = d_correlation_length_ms;
if (next_state) if (next_state)
{ // reset extended correlator { // reset extended correlator
d_VE_accu = gr_complex(0.0, 0.0); d_VE_accu = gr_complex(0.0, 0.0);
d_E_accu = gr_complex(0.0, 0.0); d_E_accu = gr_complex(0.0, 0.0);
d_P_accu = gr_complex(0.0, 0.0); d_P_accu = gr_complex(0.0, 0.0);
d_P_data_accu = gr_complex(0.0, 0.0);
d_L_accu = gr_complex(0.0, 0.0); d_L_accu = gr_complex(0.0, 0.0);
d_VL_accu = gr_complex(0.0, 0.0); d_VL_accu = gr_complex(0.0, 0.0);
d_Prompt_circular_buffer.clear(); d_Prompt_circular_buffer.clear();
d_current_symbol = 0; d_current_symbol = 0;
d_current_data_symbol = 0;
if (d_enable_extended_integration) if (d_enable_extended_integration)
{ {
@ -1811,48 +1772,26 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
} }
case 3: // coherent integration (correlation time extension) case 3: // coherent integration (correlation time extension)
{ {
// Fill the acquisition data
current_synchro_data = *d_acquisition_gnss_synchro;
// perform a correlation step // perform a correlation step
do_correlation_step(in); do_correlation_step(in);
update_tracking_vars();
save_correlation_results(); save_correlation_results();
update_tracking_vars();
if (d_current_data_symbol == 0)
{
log_data();
// ########### Output the tracking results to Telemetry block ########## // ########### Output the tracking results to Telemetry block ##########
if (interchange_iq) // Fill the acquisition data
{ current_synchro_data = *d_acquisition_gnss_synchro;
if (trk_parameters.track_pilot) current_synchro_data.Prompt_I = static_cast<double>(d_P_data_accu.real());
{ current_synchro_data.Prompt_Q = static_cast<double>(d_P_data_accu.imag());
// Note that data and pilot components are in quadrature. I and Q are interchanged
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).imag());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).real());
}
else
{
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).imag());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).real());
}
}
else
{
if (trk_parameters.track_pilot)
{
// Note that data and pilot components are in quadrature. I and Q are interchanged
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).real());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).imag());
}
else
{
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).real());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).imag());
}
}
current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Code_phase_samples = d_rem_code_phase_samples;
current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
current_synchro_data.Flag_valid_symbol_output = true;
current_synchro_data.correlation_length_ms = d_correlation_length_ms; current_synchro_data.correlation_length_ms = d_correlation_length_ms;
current_synchro_data.Flag_valid_symbol_output = true;
d_P_data_accu = gr_complex(0.0, 0.0);
}
d_extend_correlation_symbols_count++; d_extend_correlation_symbols_count++;
if (d_extend_correlation_symbols_count == (trk_parameters.extend_correlation_symbols - 1)) if (d_extend_correlation_symbols_count == (trk_parameters.extend_correlation_symbols - 1))
{ {
@ -1863,9 +1802,6 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
} }
case 4: // narrow tracking case 4: // narrow tracking
{ {
// Fill the acquisition data
current_synchro_data = *d_acquisition_gnss_synchro;
// perform a correlation step // perform a correlation step
do_correlation_step(in); do_correlation_step(in);
save_correlation_results(); save_correlation_results();
@ -1880,44 +1816,24 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
{ {
run_dll_pll(); run_dll_pll();
update_tracking_vars(); update_tracking_vars();
if (d_current_data_symbol == 0)
{
// enable write dump file this cycle (valid DLL/PLL cycle)
log_data();
// ########### Output the tracking results to Telemetry block ########## // ########### Output the tracking results to Telemetry block ##########
if (interchange_iq) // Fill the acquisition data
{ current_synchro_data = *d_acquisition_gnss_synchro;
if (trk_parameters.track_pilot) current_synchro_data.Prompt_I = static_cast<double>(d_P_data_accu.real());
{ current_synchro_data.Prompt_Q = static_cast<double>(d_P_data_accu.imag());
// Note that data and pilot components are in quadrature. I and Q are interchanged
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).imag());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).real());
}
else
{
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).imag());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).real());
}
}
else
{
if (trk_parameters.track_pilot)
{
// Note that data and pilot components are in quadrature. I and Q are interchanged
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt_Data).real());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt_Data).imag());
}
else
{
current_synchro_data.Prompt_I = static_cast<double>((*d_Prompt).real());
current_synchro_data.Prompt_Q = static_cast<double>((*d_Prompt).imag());
}
}
current_synchro_data.Code_phase_samples = d_rem_code_phase_samples; current_synchro_data.Code_phase_samples = d_rem_code_phase_samples;
current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad; current_synchro_data.Carrier_phase_rads = d_acc_carrier_phase_rad;
current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz; current_synchro_data.Carrier_Doppler_hz = d_carrier_doppler_hz;
current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz; current_synchro_data.CN0_dB_hz = d_CN0_SNV_dB_Hz;
current_synchro_data.Flag_valid_symbol_output = true;
current_synchro_data.correlation_length_ms = d_correlation_length_ms; current_synchro_data.correlation_length_ms = d_correlation_length_ms;
// enable write dump file this cycle (valid DLL/PLL cycle) current_synchro_data.Flag_valid_symbol_output = true;
log_data(false); d_P_data_accu = gr_complex(0.0, 0.0);
}
// reset extended correlator // reset extended correlator
d_VE_accu = gr_complex(0.0, 0.0); d_VE_accu = gr_complex(0.0, 0.0);
d_E_accu = gr_complex(0.0, 0.0); d_E_accu = gr_complex(0.0, 0.0);

View File

@ -85,7 +85,7 @@ private:
void update_tracking_vars(); void update_tracking_vars();
void clear_tracking_vars(); void clear_tracking_vars();
void save_correlation_results(); void save_correlation_results();
void log_data(bool integrating); void log_data();
int32_t save_matfile(); int32_t save_matfile();
// tracking configuration vars // tracking configuration vars
@ -97,22 +97,22 @@ private:
// Signal parameters // Signal parameters
bool d_secondary; bool d_secondary;
bool interchange_iq;
double d_signal_carrier_freq; double d_signal_carrier_freq;
double d_code_period; double d_code_period;
double d_code_chip_rate; double d_code_chip_rate;
uint32_t d_secondary_code_length; uint32_t d_secondary_code_length;
uint32_t d_data_secondary_code_length;
uint32_t d_code_length_chips; uint32_t d_code_length_chips;
uint32_t d_code_samples_per_chip; // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled) uint32_t d_code_samples_per_chip; // All signals have 1 sample per chip code except Gal. E1 which has 2 (CBOC disabled) or 12 (CBOC enabled)
int32_t d_symbols_per_bit; int32_t d_symbols_per_bit;
std::string systemName; std::string systemName;
std::string signal_type; std::string signal_type;
std::string *d_secondary_code_string; std::string *d_secondary_code_string;
std::string *d_data_secondary_code_string;
std::string signal_pretty_name; std::string signal_pretty_name;
int32_t *d_preambles_symbols; int32_t *d_preambles_symbols;
int32_t d_preamble_length_symbols; int32_t d_preamble_length_symbols;
boost::circular_buffer<float> d_symbol_history;
// dll filter buffer // dll filter buffer
boost::circular_buffer<float> d_dll_filt_history; boost::circular_buffer<float> d_dll_filt_history;
@ -129,6 +129,7 @@ private:
float *d_prompt_data_shift; float *d_prompt_data_shift;
Cpu_Multicorrelator_Real_Codes multicorrelator_cpu; Cpu_Multicorrelator_Real_Codes multicorrelator_cpu;
Cpu_Multicorrelator_Real_Codes correlator_data_cpu; //for data channel Cpu_Multicorrelator_Real_Codes correlator_data_cpu; //for data channel
/* TODO: currently the multicorrelator does not support adding extra correlator /* TODO: currently the multicorrelator does not support adding extra correlator
with different local code, thus we need extra multicorrelator instance. with different local code, thus we need extra multicorrelator instance.
Implement this functionality inside multicorrelator class Implement this functionality inside multicorrelator class
@ -144,6 +145,7 @@ private:
bool d_enable_extended_integration; bool d_enable_extended_integration;
int32_t d_extend_correlation_symbols_count; int32_t d_extend_correlation_symbols_count;
int32_t d_current_symbol; int32_t d_current_symbol;
int32_t d_current_data_symbol;
gr_complex d_VE_accu; gr_complex d_VE_accu;
gr_complex d_E_accu; gr_complex d_E_accu;
@ -152,6 +154,7 @@ private:
gr_complex d_L_accu; gr_complex d_L_accu;
gr_complex d_VL_accu; gr_complex d_VL_accu;
gr_complex d_P_data_accu;
gr_complex *d_Prompt_Data; gr_complex *d_Prompt_Data;
double d_code_phase_step_chips; double d_code_phase_step_chips;
@ -160,6 +163,7 @@ private:
double d_carrier_phase_step_rad; double d_carrier_phase_step_rad;
double d_carrier_phase_rate_step_rad; double d_carrier_phase_rate_step_rad;
boost::circular_buffer<std::pair<double, double>> d_carr_ph_history; boost::circular_buffer<std::pair<double, double>> d_carr_ph_history;
// remaining code phase and carrier phase between tracking loops // remaining code phase and carrier phase between tracking loops
double d_rem_code_phase_samples; double d_rem_code_phase_samples;
float d_rem_carr_phase_rad; float d_rem_carr_phase_rad;

View File

@ -47,6 +47,7 @@ Dll_Pll_Conf::Dll_Pll_Conf()
enable_fll_pull_in = false; enable_fll_pull_in = false;
enable_fll_steady_state = false; enable_fll_steady_state = false;
pull_in_time_s = 10; pull_in_time_s = 10;
bit_synchronization_time_limit_s = pull_in_time_s + 60;
fll_filter_order = 1; fll_filter_order = 1;
pll_filter_order = 3; pll_filter_order = 3;
dll_filter_order = 2; dll_filter_order = 2;
@ -68,6 +69,7 @@ Dll_Pll_Conf::Dll_Pll_Conf()
max_carrier_lock_fail = FLAGS_max_carrier_lock_fail; max_carrier_lock_fail = FLAGS_max_carrier_lock_fail;
max_code_lock_fail = FLAGS_max_lock_fail; max_code_lock_fail = FLAGS_max_lock_fail;
carrier_lock_th = FLAGS_carrier_lock_th; carrier_lock_th = FLAGS_carrier_lock_th;
enable_doppler_correction = false;
track_pilot = false; track_pilot = false;
system = 'G'; system = 'G';
char sig_[3] = "1C"; char sig_[3] = "1C";

View File

@ -45,6 +45,7 @@ public:
bool enable_fll_pull_in; bool enable_fll_pull_in;
bool enable_fll_steady_state; bool enable_fll_steady_state;
unsigned int pull_in_time_s; unsigned int pull_in_time_s;
unsigned int bit_synchronization_time_limit_s;
int pll_filter_order; int pll_filter_order;
int dll_filter_order; int dll_filter_order;
@ -74,6 +75,7 @@ public:
uint32_t smoother_length; uint32_t smoother_length;
double carrier_lock_th; double carrier_lock_th;
bool track_pilot; bool track_pilot;
bool enable_doppler_correction;
char system; char system;
char signal[3]{}; char signal[3]{};

View File

@ -48,9 +48,6 @@ Exponential_Smoother::Exponential_Smoother()
} }
Exponential_Smoother::~Exponential_Smoother() = default;
void Exponential_Smoother::set_alpha(float alpha) void Exponential_Smoother::set_alpha(float alpha)
{ {
alpha_ = alpha; alpha_ = alpha;

View File

@ -48,7 +48,7 @@ class Exponential_Smoother
{ {
public: public:
Exponential_Smoother(); //!< Constructor Exponential_Smoother(); //!< Constructor
~Exponential_Smoother(); //!< Destructor ~Exponential_Smoother() = default; //!< Destructor
void set_alpha(float alpha); //!< 0 < alpha < 1. The higher, the most responsive, but more variance. Default value: 0.001 void set_alpha(float alpha); //!< 0 < alpha < 1. The higher, the most responsive, but more variance. Default value: 0.001
void set_samples_for_initialization(int num_samples); //!< Number of samples averaged for initialization. Default value: 200 void set_samples_for_initialization(int num_samples); //!< Number of samples averaged for initialization. Default value: 200
void reset(); void reset();
@ -56,6 +56,8 @@ public:
void set_offset(float offset); void set_offset(float offset);
float smooth(float raw); float smooth(float raw);
double smooth(double raw); double smooth(double raw);
Exponential_Smoother(Exponential_Smoother&&) = default; //!< Move operator
Exponential_Smoother& operator=(Exponential_Smoother&& /*other*/) = default; //!< Move assignment operator
private: private:
float alpha_; // takes value 0.0001 if not set float alpha_; // takes value 0.0001 if not set
int samples_for_initialization_; int samples_for_initialization_;

View File

@ -68,9 +68,6 @@ Tracking_loop_filter::Tracking_loop_filter()
} }
Tracking_loop_filter::~Tracking_loop_filter() = default;
float Tracking_loop_filter::apply(float current_input) float Tracking_loop_filter::apply(float current_input)
{ {
// Now apply the filter coefficients: // Now apply the filter coefficients:
@ -234,6 +231,7 @@ void Tracking_loop_filter::set_update_interval(float update_interval)
update_coefficients(); update_coefficients();
} }
float Tracking_loop_filter::get_update_interval(void) const float Tracking_loop_filter::get_update_interval(void) const
{ {
return d_update_interval; return d_update_interval;

View File

@ -44,6 +44,16 @@
class Tracking_loop_filter class Tracking_loop_filter
{ {
public: public:
Tracking_loop_filter();
~Tracking_loop_filter() = default;
Tracking_loop_filter(float update_interval, float noise_bandwidth,
int loop_order = 2,
bool include_last_integrator = false);
Tracking_loop_filter(Tracking_loop_filter&&) = default; //!< Move operator
Tracking_loop_filter& operator=(Tracking_loop_filter&& /*other*/) = default; //!< Move assignment operator
float get_noise_bandwidth(void) const; float get_noise_bandwidth(void) const;
float get_update_interval(void) const; float get_update_interval(void) const;
bool get_include_last_integrator(void) const; bool get_include_last_integrator(void) const;
@ -57,13 +67,6 @@ public:
void initialize(float initial_output = 0.0); void initialize(float initial_output = 0.0);
float apply(float current_input); float apply(float current_input);
Tracking_loop_filter(float update_interval, float noise_bandwidth,
int loop_order = 2,
bool include_last_integrator = false);
Tracking_loop_filter();
~Tracking_loop_filter();
private: private:
// Store the last inputs and outputs: // Store the last inputs and outputs:
std::vector<float> d_inputs; std::vector<float> d_inputs;

View File

@ -50,7 +50,6 @@ public:
// Verify that the version of the library that we linked against is // Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against. // compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION; GOOGLE_PROTOBUF_VERIFY_VERSION;
observables.New();
} }
~Serdes_Gnss_Synchro() ~Serdes_Gnss_Synchro()
@ -58,6 +57,31 @@ public:
google::protobuf::ShutdownProtobufLibrary(); google::protobuf::ShutdownProtobufLibrary();
} }
inline Serdes_Gnss_Synchro(Serdes_Gnss_Synchro&& other) //!< Copy constructor
{
this->observables = other.observables;
}
inline Serdes_Gnss_Synchro& operator=(const Serdes_Gnss_Synchro& rhs) //!< Copy assignment operator
{
this->observables = rhs.observables;
return *this;
}
inline Serdes_Gnss_Synchro(const Serdes_Gnss_Synchro& other) //!< Move constructor
{
this->observables = std::move(other.observables);
}
inline Serdes_Gnss_Synchro& operator=(Serdes_Gnss_Synchro&& other) //!< Move assignment operator
{
if (this != &other)
{
this->observables = std::move(other.observables);
}
return *this;
}
inline std::string createProtobuffer(const std::vector<Gnss_Synchro>& vgs) //!< Serialization into a string inline std::string createProtobuffer(const std::vector<Gnss_Synchro>& vgs) //!< Serialization into a string
{ {
observables.Clear(); observables.Clear();
@ -150,7 +174,7 @@ public:
} }
private: private:
gnss_sdr::Observables observables; gnss_sdr::Observables observables{};
}; };
#endif // GNSS_SDR_SERDES_GNSS_SYNCHRO_H_ #endif // GNSS_SDR_SERDES_GNSS_SYNCHRO_H_

View File

@ -79,7 +79,7 @@ private:
std::shared_ptr<INIReader> ini_reader_; std::shared_ptr<INIReader> ini_reader_;
std::shared_ptr<InMemoryConfiguration> overrided_; std::shared_ptr<InMemoryConfiguration> overrided_;
std::unique_ptr<StringConverter> converter_; std::unique_ptr<StringConverter> converter_;
int error_; int error_{};
}; };
#endif /*GNSS_SDR_FILE_CONFIGURATION_H_*/ #endif /*GNSS_SDR_FILE_CONFIGURATION_H_*/

View File

@ -34,8 +34,7 @@
#include "MATH_CONSTANTS.h" #include "MATH_CONSTANTS.h"
#include <cstdint> #include <cstdint>
#include <utility> // std::pair #include <string>
#include <vector>
// Physical constants // Physical constants
const double BEIDOU_C_M_S = 299792458.0; //!< The speed of light, [m/s] const double BEIDOU_C_M_S = 299792458.0; //!< The speed of light, [m/s]
@ -48,22 +47,27 @@ const double BEIDOU_F = -4.442807309e-10; //!< Constant, [s/(m)^(1/2)
// carrier and code frequencies // carrier and code frequencies
const double BEIDOU_B1I_FREQ_HZ = 1.561098e9; //!< b1I [Hz] const double BEIDOU_B1I_FREQ_HZ = 1.561098e9; //!< B1I [Hz]
const double BEIDOU_B1I_CODE_RATE_HZ = 2.046e6; //!< beidou b1I code rate [chips/s] const double BEIDOU_B1I_CODE_RATE_HZ = 2.046e6; //!< Beidou B1I code rate [chips/s]
const double BEIDOU_B1I_CODE_LENGTH_CHIPS = 2046.0; //!< beidou b1I code length [chips] const double BEIDOU_B1I_CODE_LENGTH_CHIPS = 2046.0; //!< Beidou B1I code length [chips]
const double BEIDOU_B1I_CODE_PERIOD = 0.001; //!< beidou b1I code period [seconds] const double BEIDOU_B1I_CODE_PERIOD = 0.001; //!< Beidou B1I code period [seconds]
const uint32_t BEIDOU_B1I_CODE_PERIOD_MS = 1; //!< beidou b1I L1 C/A code period [ms] const uint32_t BEIDOU_B1I_CODE_PERIOD_MS = 1; //!< Beidou B1I code period [ms]
const double BEIDOU_B1I_CHIP_PERIOD = 4.8875e-07; //!< beidou b1I chip period [seconds] const double BEIDOU_B1I_CHIP_PERIOD = 4.8875e-07; //!< Beidou B1I chip period [seconds]
const int32_t BEIDOU_B1I_SECONDARY_CODE_LENGTH = 20; const int32_t BEIDOU_B1I_SECONDARY_CODE_LENGTH = 20;
const std::string BEIDOU_B1I_SECONDARY_CODE = "00000100110101001110"; const std::string BEIDOU_B1I_SECONDARY_CODE = "00000100110101001110";
const std::string BEIDOU_B1I_SECONDARY_CODE_STR = "00000100110101001110"; const std::string BEIDOU_B1I_SECONDARY_CODE_STR = "00000100110101001110";
const std::string BEIDOU_B1I_GEO_PREAMBLE_SYMBOLS_STR = {"1111110000001100001100"};
const int32_t BEIDOU_B1I_GEO_PREAMBLE_LENGTH_SYMBOLS = 22;
const std::string BEIDOU_B1I_D2_SECONDARY_CODE_STR = "00"; const std::string BEIDOU_B1I_D2_SECONDARY_CODE_STR = "00";
const int BEIDOU_B1I_PREAMBLE_LENGTH_BITS = 11; const int BEIDOU_B1I_PREAMBLE_LENGTH_BITS = 11;
const int BEIDOU_B1I_PREAMBLE_LENGTH_SYMBOLS = 220; // ************** const int BEIDOU_B1I_PREAMBLE_LENGTH_SYMBOLS = 220; // **************
const double BEIDOU_B1I_PREAMBLE_DURATION_S = 0.220; const double BEIDOU_B1I_PREAMBLE_DURATION_S = 0.220;
const int BEIDOU_B1I_PREAMBLE_DURATION_MS = 220; const int BEIDOU_B1I_PREAMBLE_DURATION_MS = 220;
const int BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND = 50; //!< D1 NAV message bit rate [bits/s] const int BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND = 50; //!< D1 NAV message bit rate [bits/s]
const int BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT = 20; // ************* const int BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT = 20;
const int BEIDOU_B1I_GEO_TELEMETRY_SYMBOLS_PER_BIT = 2;
const int BEIDOU_B1I_TELEMETRY_SYMBOL_PERIOD_MS = BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT * BEIDOU_B1I_CODE_PERIOD_MS;
const int BEIDOU_B1I_TELEMETRY_RATE_SYMBOLS_SECOND = BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND * BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT; //************!< NAV message bit rate [symbols/s] const int BEIDOU_B1I_TELEMETRY_RATE_SYMBOLS_SECOND = BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND * BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT; //************!< NAV message bit rate [symbols/s]
const int BEIDOU_WORD_LENGTH = 4; //**************!< CRC + BEIDOU WORD (-2 -1 0 ... 29) Bits = 4 bytes const int BEIDOU_WORD_LENGTH = 4; //**************!< CRC + BEIDOU WORD (-2 -1 0 ... 29) Bits = 4 bytes
const int BEIDOU_SUBFRAME_LENGTH = 40; //**************!< BEIDOU_WORD_LENGTH x 10 = 40 bytes const int BEIDOU_SUBFRAME_LENGTH = 40; //**************!< BEIDOU_WORD_LENGTH x 10 = 40 bytes

View File

@ -33,25 +33,27 @@
#include "MATH_CONSTANTS.h" #include "MATH_CONSTANTS.h"
#include <cstdint> #include <cstdint>
#include <utility> // std::pair #include <string>
#include <vector>
// carrier and code frequencies // carrier and code frequencies
const double BEIDOU_B3I_FREQ_HZ = 1.268520e9; //!< BeiDou B3I [Hz] const double BEIDOU_B3I_FREQ_HZ = 1.268520e9; //!< BeiDou B3I [Hz]
const double BEIDOU_B3I_CODE_RATE_HZ = 10.23e6; //!< BeiDou B3I code rate [chips/s] const double BEIDOU_B3I_CODE_RATE_HZ = 10.23e6; //!< BeiDou B3I code rate [chips/s]
const double BEIDOU_B3I_CODE_LENGTH_CHIPS = 10230.0; //!< BeiDou B3I code length [chips] const double BEIDOU_B3I_CODE_LENGTH_CHIPS = 10230.0; //!< BeiDou B3I code length [chips]
const double BEIDOU_B3I_CODE_PERIOD = 0.001; //!< BeiDou B3I code period [seconds] const double BEIDOU_B3I_CODE_PERIOD = 0.001; //!< BeiDou B3I code period [seconds]
const uint32_t BEIDOU_B3I_CODE_PERIOD_MS = 1; //!< GPS L1 C/A code period [ms] const uint32_t BEIDOU_B3I_CODE_PERIOD_MS = 1; //!< BeiDou B3I code period [ms]
const int32_t BEIDOU_B3I_SECONDARY_CODE_LENGTH = 20; const int32_t BEIDOU_B3I_SECONDARY_CODE_LENGTH = 20;
const std::string BEIDOU_B3I_SECONDARY_CODE = "00000100110101001110"; const std::string BEIDOU_B3I_SECONDARY_CODE = "00000100110101001110";
const std::string BEIDOU_B3I_SECONDARY_CODE_STR = "00000100110101001110"; const std::string BEIDOU_B3I_SECONDARY_CODE_STR = "00000100110101001110";
const std::string BEIDOU_B3I_GEO_PREAMBLE_SYMBOLS_STR = {"1111110000001100001100"};
const int32_t BEIDOU_B3I_GEO_PREAMBLE_LENGTH_SYMBOLS = 22;
const std::string BEIDOU_B3I_D2_SECONDARY_CODE_STR = "00"; const std::string BEIDOU_B3I_D2_SECONDARY_CODE_STR = "00";
const uint32_t BEIDOU_B3I_PREAMBLE_LENGTH_BITS = 11; const uint32_t BEIDOU_B3I_PREAMBLE_LENGTH_BITS = 11;
const uint32_t BEIDOU_B3I_PREAMBLE_LENGTH_SYMBOLS = 220; // ************** const uint32_t BEIDOU_B3I_PREAMBLE_LENGTH_SYMBOLS = 220; // **************
const double BEIDOU_B3I_PREAMBLE_DURATION_S = 0.220; const double BEIDOU_B3I_PREAMBLE_DURATION_S = 0.220;
const int32_t BEIDOU_B3I_PREAMBLE_DURATION_MS = 220; const int32_t BEIDOU_B3I_PREAMBLE_DURATION_MS = 220;
const int32_t BEIDOU_B3I_TELEMETRY_RATE_BITS_SECOND = 50; //!< D1 NAV message bit rate [bits/s] const int32_t BEIDOU_B3I_TELEMETRY_RATE_BITS_SECOND = 50; //!< D1 NAV message bit rate [bits/s]
const int32_t BEIDOU_B3I_TELEMETRY_SYMBOLS_PER_BIT = 20; // ************* const int32_t BEIDOU_B3I_TELEMETRY_SYMBOLS_PER_BIT = 20;
const int32_t BEIDOU_B3I_GEO_TELEMETRY_SYMBOLS_PER_BIT = 2; // *************
const int32_t BEIDOU_B3I_TELEMETRY_RATE_SYMBOLS_SECOND = BEIDOU_B3I_TELEMETRY_RATE_BITS_SECOND * BEIDOU_B3I_TELEMETRY_SYMBOLS_PER_BIT; //************!< NAV message bit rate [symbols/s] const int32_t BEIDOU_B3I_TELEMETRY_RATE_SYMBOLS_SECOND = BEIDOU_B3I_TELEMETRY_RATE_BITS_SECOND * BEIDOU_B3I_TELEMETRY_SYMBOLS_PER_BIT; //************!< NAV message bit rate [symbols/s]
#endif /* GNSS_SDR_BEIDOU_B3I_H_ */ #endif /* GNSS_SDR_BEIDOU_B3I_H_ */

View File

@ -55,6 +55,7 @@ const double GPS_L1_CA_CODE_RATE_HZ = 1.023e6; //!< GPS L1 C/A code rate [c
const double GPS_L1_CA_CODE_LENGTH_CHIPS = 1023.0; //!< GPS L1 C/A code length [chips] const double GPS_L1_CA_CODE_LENGTH_CHIPS = 1023.0; //!< GPS L1 C/A code length [chips]
const double GPS_L1_CA_CODE_PERIOD = 0.001; //!< GPS L1 C/A code period [seconds] const double GPS_L1_CA_CODE_PERIOD = 0.001; //!< GPS L1 C/A code period [seconds]
const uint32_t GPS_L1_CA_CODE_PERIOD_MS = 1U; //!< GPS L1 C/A code period [ms] const uint32_t GPS_L1_CA_CODE_PERIOD_MS = 1U; //!< GPS L1 C/A code period [ms]
const uint32_t GPS_L1_CA_BIT_PERIOD_MS = 20U; //!< GPS L1 C/A bit period [ms]
const double GPS_L1_CA_CHIP_PERIOD = 9.7752e-07; //!< GPS L1 C/A chip period [seconds] const double GPS_L1_CA_CHIP_PERIOD = 9.7752e-07; //!< GPS L1 C/A chip period [seconds]
//optimum parameters //optimum parameters
@ -84,6 +85,7 @@ const int32_t GPS_L1_CA_HISTORY_DEEP = 100;
1, 0, 0, 0, 1, 0, 1, 1 \ 1, 0, 0, 0, 1, 0, 1, 1 \
} }
const std::string GPS_CA_PREAMBLE = {"10001011"}; const std::string GPS_CA_PREAMBLE = {"10001011"};
const std::string GPS_CA_PREAMBLE_SYMBOLS_STR = {"1111111111111111111100000000000000000000000000000000000000000000000000000000000011111111111111111111000000000000000000001111111111111111111111111111111111111111"};
const int32_t GPS_CA_PREAMBLE_LENGTH_BITS = 8; const int32_t GPS_CA_PREAMBLE_LENGTH_BITS = 8;
const int32_t GPS_CA_PREAMBLE_LENGTH_SYMBOLS = 160; const int32_t GPS_CA_PREAMBLE_LENGTH_SYMBOLS = 160;
const double GPS_CA_PREAMBLE_DURATION_S = 0.160; const double GPS_CA_PREAMBLE_DURATION_S = 0.160;

View File

@ -47,17 +47,8 @@ Gnss_Satellite::Gnss_Satellite(const std::string& system_, uint32_t PRN_)
} }
Gnss_Satellite::~Gnss_Satellite() = default;
void Gnss_Satellite::reset() void Gnss_Satellite::reset()
{ {
system_set = {"GPS", "Glonass", "SBAS", "Galileo", "Beidou"};
satelliteSystem["GPS"] = "G";
satelliteSystem["Glonass"] = "R";
satelliteSystem["SBAS"] = "S";
satelliteSystem["Galileo"] = "E";
satelliteSystem["Beidou"] = "C";
PRN = 0; PRN = 0;
system = std::string(""); system = std::string("");
block = std::string(""); block = std::string("");
@ -88,30 +79,58 @@ bool operator==(const Gnss_Satellite& sat1, const Gnss_Satellite& sat2)
if (sat1.get_system() == sat2.get_system()) if (sat1.get_system() == sat2.get_system())
{ {
if (sat1.get_PRN() == sat2.get_PRN()) if (sat1.get_PRN() == sat2.get_PRN())
{
if (sat1.get_rf_link() == sat2.get_rf_link())
{ {
equal = true; equal = true;
} }
} }
}
return equal; return equal;
} }
/*
Gnss_Satellite& Gnss_Satellite::operator=(const Gnss_Satellite &rhs) {
// Copy constructor
Gnss_Satellite::Gnss_Satellite(Gnss_Satellite&& other)
{
*this = other;
}
// Copy assignment operator
Gnss_Satellite& Gnss_Satellite::operator=(const Gnss_Satellite& rhs)
{
// Only do assignment if RHS is a different object from this. // Only do assignment if RHS is a different object from this.
if (this != &rhs) { if (this != &rhs)
// Deallocate, allocate new space, copy values... {
const std::string system_ = rhs.get_system(); this->system = rhs.system;
const uint32_t PRN_ = rhs.get_PRN(); this->PRN = rhs.PRN;
const std::string block_ = rhs.get_block(); this->block = rhs.block;
// const int32_t rf_link_ = 0; this->rf_link = rhs.rf_link;
this->set_system(system_);
this->set_PRN(PRN_);
this->set_block(system_, PRN_);
//this.rf_link = rf_link_;
} }
return *this; return *this;
}*/ }
// Move constructor
Gnss_Satellite::Gnss_Satellite(const Gnss_Satellite& other)
{
*this = std::move(other);
}
// Move assignment operator
Gnss_Satellite& Gnss_Satellite::operator=(Gnss_Satellite&& other)
{
if (this != &other)
{
this->system = std::move(other.get_system());
this->PRN = other.get_PRN();
this->block = std::move(other.get_block());
this->rf_link = other.get_rf_link();
}
return *this;
}
void Gnss_Satellite::set_system(const std::string& system_) void Gnss_Satellite::set_system(const std::string& system_)
@ -260,6 +279,14 @@ int32_t Gnss_Satellite::get_rf_link() const
} }
void Gnss_Satellite::set_rf_link(int32_t rf_link_)
{
// Set satellite's rf link. Identifies the GLONASS Frequency Channel
rf_link = rf_link_;
return;
}
uint32_t Gnss_Satellite::get_PRN() const uint32_t Gnss_Satellite::get_PRN() const
{ {
// Get satellite's PRN // Get satellite's PRN
@ -625,7 +652,7 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_
if (system_ == "Beidou") if (system_ == "Beidou")
{ {
// Check https://en.wikipedia.org/wiki/List_of_BeiDou_satellites // Check https://en.wikipedia.org/wiki/List_of_BeiDou_satellites
switch ( PRN_ ) switch (PRN_)
{ {
case 1: case 1:
block_ = std::string("Compass-G1"); //!<GEO 140.0°E; launched 2010/01/16 block_ = std::string("Compass-G1"); //!<GEO 140.0°E; launched 2010/01/16

View File

@ -50,7 +50,7 @@ class Gnss_Satellite
public: public:
Gnss_Satellite(); //!< Default Constructor. Gnss_Satellite(); //!< Default Constructor.
Gnss_Satellite(const std::string& system_, uint32_t PRN_); //!< Concrete GNSS satellite Constructor. Gnss_Satellite(const std::string& system_, uint32_t PRN_); //!< Concrete GNSS satellite Constructor.
~Gnss_Satellite(); //!< Default Destructor. ~Gnss_Satellite() = default; //!< Default Destructor.
void update_PRN(uint32_t PRN); //!< Updates the PRN Number when information is decoded, only applies to GLONASS GNAV messages void update_PRN(uint32_t PRN); //!< Updates the PRN Number when information is decoded, only applies to GLONASS GNAV messages
uint32_t get_PRN() const; //!< Gets satellite's PRN uint32_t get_PRN() const; //!< Gets satellite's PRN
int32_t get_rf_link() const; //!< Gets the satellite's rf link int32_t get_rf_link() const; //!< Gets the satellite's rf link
@ -61,17 +61,23 @@ public:
friend bool operator==(const Gnss_Satellite& /*sat1*/, const Gnss_Satellite& /*sat2*/); //!< operator== for comparison friend bool operator==(const Gnss_Satellite& /*sat1*/, const Gnss_Satellite& /*sat2*/); //!< operator== for comparison
friend std::ostream& operator<<(std::ostream& /*out*/, const Gnss_Satellite& /*sat*/); //!< operator<< for pretty printing friend std::ostream& operator<<(std::ostream& /*out*/, const Gnss_Satellite& /*sat*/); //!< operator<< for pretty printing
//Gnss_Satellite& operator=(const Gnss_Satellite &);
Gnss_Satellite(Gnss_Satellite&& other); //!< Copy constructor
Gnss_Satellite& operator=(const Gnss_Satellite&); //!< Copy assignment operator
Gnss_Satellite(const Gnss_Satellite& other); //!< Move constructor
Gnss_Satellite& operator=(Gnss_Satellite&& other); //!< Move assignment operator
private: private:
uint32_t PRN; uint32_t PRN{};
std::string system; int32_t rf_link{};
std::map<std::string, std::string> satelliteSystem; std::string system{};
std::string block; std::string block{};
int32_t rf_link; const std::set<std::string> system_set = {"GPS", "Glonass", "SBAS", "Galileo", "Beidou"};
const std::map<std::string, std::string> satelliteSystem = {{"GPS", "G"}, {"Glonass", "R"}, {"SBAS", "S"}, {"Galileo", "E"}, {"Beidou", "C"}};
void set_system(const std::string& system); // Sets the satellite system {"GPS", "GLONASS", "SBAS", "Galileo", "Beidou"}. void set_system(const std::string& system); // Sets the satellite system {"GPS", "GLONASS", "SBAS", "Galileo", "Beidou"}.
void set_PRN(uint32_t PRN); // Sets satellite's PRN void set_PRN(uint32_t PRN); // Sets satellite's PRN
void set_block(const std::string& system_, uint32_t PRN_); void set_block(const std::string& system_, uint32_t PRN_);
std::set<std::string> system_set; // = {"GPS", "GLONASS", "SBAS", "Galileo", "Compass"};
void reset(); void reset();
void set_rf_link(int32_t rf_link_);
}; };
#endif #endif

View File

@ -50,9 +50,6 @@ Gnss_Signal::Gnss_Signal(const Gnss_Satellite& satellite_, const std::string& si
} }
Gnss_Signal::~Gnss_Signal() = default;
std::string Gnss_Signal::get_signal_str() const std::string Gnss_Signal::get_signal_str() const
{ {
return this->signal; return this->signal;

View File

@ -47,7 +47,7 @@ public:
Gnss_Signal(); Gnss_Signal();
Gnss_Signal(const std::string& signal_); Gnss_Signal(const std::string& signal_);
Gnss_Signal(const Gnss_Satellite& satellite_, const std::string& signal_); Gnss_Signal(const Gnss_Satellite& satellite_, const std::string& signal_);
~Gnss_Signal(); ~Gnss_Signal() = default;
std::string get_signal_str() const; //!< Get the satellite signal {"1C" for GPS L1 C/A, "2S" for GPS L2C (M), "L5" for GPS L5, "1G" for GLONASS L1 C/A, "1B" for Galileo E1B, "5X" for Galileo E5a. std::string get_signal_str() const; //!< Get the satellite signal {"1C" for GPS L1 C/A, "2S" for GPS L2C (M), "L5" for GPS L5, "1G" for GLONASS L1 C/A, "1B" for Galileo E1B, "5X" for Galileo E5a.
Gnss_Satellite get_satellite() const; //!< Get the Gnss_Satellite associated to the signal Gnss_Satellite get_satellite() const; //!< Get the Gnss_Satellite associated to the signal
@ -55,8 +55,8 @@ public:
friend std::ostream& operator<<(std::ostream& /*out*/, const Gnss_Signal& /*sig*/); //!< operator<< for pretty printing friend std::ostream& operator<<(std::ostream& /*out*/, const Gnss_Signal& /*sig*/); //!< operator<< for pretty printing
private: private:
Gnss_Satellite satellite; Gnss_Satellite satellite{};
std::string signal; std::string signal{};
}; };
#endif #endif