1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-10-05 18:30:51 +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);
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;
if (use_protobuf)

View File

@ -53,7 +53,7 @@ private:
boost::asio::ip::udp::socket socket;
boost::system::error_code error;
std::vector<boost::asio::ip::udp::endpoint> endpoints;
Monitor_Pvt monitor_pvt;
Monitor_Pvt monitor_pvt{};
Serdes_Monitor_Pvt serdes;
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;
this->set_averaging_flag(false);
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 #################
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()
@ -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 glo_valid_obs = 0; // GLONASS L1/L2 valid observations counter
std::array<obsd_t, MAXOBS> obs_data;
std::array<eph_t, MAXOBS> eph_data;
std::array<geph_t, MAXOBS> geph_data;
std::array<obsd_t, MAXOBS> obs_data{};
std::array<eph_t, MAXOBS> eph_data{};
std::array<geph_t, MAXOBS> geph_data{};
// Workaround for NAV/CNAV clash problem
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);
sol_t pvt_sol;
std::array<ssat_t, MAXSAT> pvt_ssat;
sol_t pvt_sol{};
std::array<ssat_t, MAXSAT> pvt_ssat{};
double get_hdop() const;
double get_vdop() const;
double get_pdop() const;
@ -129,15 +129,15 @@ public:
int count_valid_position;
private:
rtk_t rtk_;
rtk_t rtk_{};
std::string d_dump_filename;
std::ofstream d_dump_file;
bool save_matfile();
bool d_flag_dump_enabled;
bool d_flag_dump_mat_enabled;
int d_nchannels; // Number of available channels for positioning
std::array<double, 4> dop_;
Monitor_Pvt monitor_pvt;
std::array<double, 4> dop_{};
Monitor_Pvt monitor_pvt{};
};
#endif

View File

@ -48,7 +48,6 @@ public:
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;
monitor_.New();
}
~Serdes_Monitor_Pvt()
@ -56,6 +55,31 @@ public:
// 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
{
monitor_.Clear();
@ -132,7 +156,7 @@ public:
}
private:
gnss_sdr::MonitorPvt monitor_;
gnss_sdr::MonitorPvt monitor_{};
};
#endif // GNSS_SDR_SERDES_MONITOR_PVT_H_

View File

@ -51,48 +51,37 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
in_streams_(in_streams),
out_streams_(out_streams)
{
Acq_Conf acq_parameters = Acq_Conf();
configuration_ = configuration;
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);
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);
acq_parameters.fs_in = fs_in_;
acq_parameters_.fs_in = fs_in_;
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);
acq_parameters.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
acq_parameters_.blocking = blocking_;
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0)
{
doppler_max_ = FLAGS_doppler_max;
}
acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters_.doppler_max = doppler_max_;
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
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);
acq_parameters.max_dwells = max_dwells_;
acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code -------------------------
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_);
acq_parameters_.dump_filename = dump_filename_;
acq_parameters_.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
if (item_type_ == "cshort")
{
@ -102,18 +91,28 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
{
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_);
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
acq_parameters_.ms_per_code = 1;
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")
{
@ -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);
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());
}
@ -233,15 +232,7 @@ float BeidouB1iPcpsAcquisition::calculate_threshold(float pfa)
{
//Calculate the threshold
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_;
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
uint32_t ncells = vector_length_ * frequency_bins;
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")
{
// 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_, 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
{
@ -289,11 +282,9 @@ void BeidouB1iPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
}
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_, 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
{

View File

@ -163,22 +163,21 @@ public:
private:
ConfigurationInterface* configuration_;
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_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
size_t item_size_;
std::string item_type_;
uint32_t vector_length_;
uint32_t code_length_;
unsigned int vector_length_;
unsigned int code_length_;
bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_;
uint32_t channel_;
unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_;
uint32_t doppler_max_;
uint32_t doppler_step_;
uint32_t sampled_ms_;
uint32_t max_dwells_;
unsigned int doppler_max_;
unsigned int doppler_step_;
unsigned int max_dwells_;
int64_t fs_in_;
bool dump_;
bool blocking_;
@ -186,8 +185,9 @@ private:
std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_;
std::string role_;
uint32_t in_streams_;
uint32_t out_streams_;
unsigned int num_codes_;
unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa);
};

View File

@ -49,49 +49,37 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
in_streams_(in_streams),
out_streams_(out_streams)
{
Acq_Conf acq_parameters = Acq_Conf();
configuration_ = configuration;
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);
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);
acq_parameters.fs_in = fs_in_;
acq_parameters_.fs_in = fs_in_;
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);
acq_parameters.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000);
acq_parameters_.blocking = blocking_;
doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0)
{
doppler_max_ = FLAGS_doppler_max;
}
acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters_.doppler_max = doppler_max_;
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
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);
acq_parameters.max_dwells = max_dwells_;
acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_;
//--- Find number of samples per spreading code -------------------------
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_);
acq_parameters_.dump_filename = dump_filename_;
acq_parameters_.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
if (item_type_ == "cshort")
{
@ -101,18 +89,28 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
{
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_);
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")";
acq_parameters_.ms_per_code = 1;
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")
{
@ -146,8 +144,12 @@ void BeidouB3iPcpsAcquisition::stop_acquisition()
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)
{
threshold_ = threshold;
@ -196,7 +198,6 @@ signed int BeidouB3iPcpsAcquisition::mag()
void BeidouB3iPcpsAcquisition::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);
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());
}
@ -232,20 +233,12 @@ float BeidouB3iPcpsAcquisition::calculate_threshold(float pfa)
{
//Calculate the threshold
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_;
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
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);
auto lambda = static_cast<double>(vector_length_);
auto lambda = double(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda);
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")
{
// 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_, 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
{
@ -288,11 +283,9 @@ void BeidouB3iPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
}
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_, 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
{
@ -307,7 +300,7 @@ gr::basic_block_sptr BeidouB3iPcpsAcquisition::get_left_block()
{
return acquisition_;
}
else if (item_type_ == "cshort")
if (item_type_ == "cshort")
{
return acquisition_;
}

View File

@ -162,7 +162,7 @@ public:
private:
ConfigurationInterface* configuration_;
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_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
size_t item_size_;
@ -176,7 +176,6 @@ private:
float threshold_;
unsigned int doppler_max_;
unsigned int doppler_step_;
unsigned int sampled_ms_;
unsigned int max_dwells_;
int64_t fs_in_;
bool dump_;
@ -185,6 +184,7 @@ private:
std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_;
std::string role_;
unsigned int num_codes_;
unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa);

View File

@ -31,11 +31,8 @@
#include "beamformer.h"
#include <gnuradio/io_signature.h>
#include <sstream>
#define GNSS_SDR_BEAMFORMER_CHANNELS 8
beamformer_sptr make_beamformer_sptr()
{
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(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++)
{
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];
}

View File

@ -32,26 +32,30 @@
#define GNSS_SDR_BEAMFORMER_H
#include <gnuradio/sync_block.h>
#include <vector>
class beamformer;
using beamformer_sptr = boost::shared_ptr<beamformer>;
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
*/
class beamformer : public gr::sync_block
{
public:
~beamformer();
~beamformer() = default;
int work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
private:
friend beamformer_sptr make_beamformer_sptr();
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

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(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.");

View File

@ -36,6 +36,7 @@
#include "beidou_dnav_ephemeris.h"
#include "beidou_dnav_iono.h"
#include "beidou_dnav_utc_model.h"
#include "display.h"
#include "gnss_synchro.h"
#include <glog/logging.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)))
{
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry"));
// 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];
if (err > 0)
if (err > 0 and err < 16)
{
decbits[err - 1] *= -1;
}
@ -260,11 +263,11 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
// 3. Check operation executed correctly
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
{
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
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());
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;
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)
{
@ -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());
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;
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)
{
@ -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());
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;
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)
{
@ -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));
// 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;
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;
}
}
@ -312,7 +315,7 @@ void beidou_b1i_telemetry_decoder_gs::set_satellite(const Gnss_Satellite &satell
// Update satellite information for DNAV decoder
sat_prn = d_satellite.get_PRN();
d_nav.i_satellite_PRN = sat_prn;
d_nav.i_signal_type = 1; //!< BDS: data source (0:unknown,1:B1I,2:B1Q,3:B2I,4:B2Q,5:B3I,6:B3Q)
d_nav.i_signal_type = 1; //!< BDS: data source (0:unknown,1:B1I,2:B1Q,3:B2I,4:B2Q,5:B3I,6:B3Q)
// Update tel dec parameters for D2 NAV Messages
if (sat_prn > 0 and sat_prn < 6)

View File

@ -35,6 +35,7 @@
#include "beidou_dnav_ephemeris.h"
#include "beidou_dnav_iono.h"
#include "beidou_dnav_utc_model.h"
#include "display.h"
#include "gnss_synchro.h"
#include <glog/logging.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)))
{
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry"));
// 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];
if (err > 0)
if (err > 0 and err < 16)
{
decbits[err - 1] *= -1;
}
@ -275,13 +278,13 @@ void beidou_b3i_telemetry_decoder_gs::decode_subframe(double *frame_symbols)
// 3. Check operation executed correctly
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
{
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
if (d_nav.have_new_ephemeris() == true)
@ -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));
LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel"
<< d_channel << " from satellite " << d_satellite;
std::cout << "New BEIDOU B3I DNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << std::endl;
std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << TEXT_RESET << std::endl;
}
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));
LOG(INFO) << "BEIDOU DNAV UTC Model have been received in channel"
<< 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_satellite << std::endl;
<< d_satellite << TEXT_RESET << std::endl;
}
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));
LOG(INFO) << "BEIDOU DNAV Iono have been received in channel" << d_channel
<< " 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_satellite << std::endl;
<< d_satellite << TEXT_RESET << std::endl;
}
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));
LOG(INFO) << "BEIDOU DNAV Almanac have been received in channel"
<< d_channel << " from satellite " << d_satellite << std::endl;
std::cout << "New BEIDOU B3I DNAV almanac received in channel " << d_channel
<< " from satellite " << d_satellite << std::endl;
std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV almanac received in channel " << d_channel
<< " 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)),
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
this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block
@ -85,15 +87,13 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
case 1: // INAV
{
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;
// 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_required_symbols = static_cast<uint32_t>(GALILEO_INAV_PAGE_SYMBOLS) + d_samples_per_preamble;
// 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_secondary_code_samples = nullptr;
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;
DataLength = (CodeLength / nn) - mm;
@ -103,31 +103,18 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
}
case 2: // FNAV
{
d_PRN_code_period_ms = static_cast<uint32_t>(GALILEO_E5A_CODE_PERIOD_MS);
d_samples_per_symbol = GALILEO_FNAV_CODES_PER_SYMBOL;
d_PRN_code_period_ms = static_cast<uint32_t>(GALILEO_E5A_CODE_PERIOD_MS * GALILEO_E5A_I_SECONDARY_CODE_LENGTH);
d_bits_per_preamble = GALILEO_FNAV_PREAMBLE_LENGTH_BITS;
// set the preamble
d_samples_per_preamble = GALILEO_FNAV_PREAMBLE_LENGTH_BITS * d_samples_per_symbol;
d_preamble_period_symbols = GALILEO_FNAV_CODES_PER_PAGE;
d_required_symbols = static_cast<uint32_t>(GALILEO_FNAV_SYMBOLS_PER_PAGE) * d_samples_per_symbol + d_samples_per_preamble;
d_samples_per_preamble = GALILEO_FNAV_PREAMBLE_LENGTH_BITS;
d_preamble_period_symbols = GALILEO_FNAV_SYMBOLS_PER_PAGE;
d_required_symbols = static_cast<uint32_t>(GALILEO_FNAV_SYMBOLS_PER_PAGE) + d_samples_per_preamble;
// 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_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;
CodeLength = GALILEO_FNAV_SYMBOLS_PER_PAGE - GALILEO_FNAV_PREAMBLE_LENGTH_BITS;
DataLength = (CodeLength / nn) - mm;
for (int32_t i = 0; i < GALILEO_E5A_I_SECONDARY_CODE_LENGTH; i++)
{
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
d_max_symbols_without_valid_frame = GALILEO_FNAV_SYMBOLS_PER_PAGE * 5; //rise alarm 100 seconds without valid tlm
break;
}
default:
@ -135,8 +122,6 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
d_samples_per_preamble = 0;
d_preamble_period_symbols = 0;
d_preamble_samples = nullptr;
d_secondary_code_samples = nullptr;
d_samples_per_symbol = 0U;
d_PRN_code_period_ms = 0U;
d_required_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()));
int32_t n = 0;
for (int32_t i = 0; i < d_bits_per_preamble; i++)
{
switch (d_frame_type)
@ -156,45 +140,23 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
{
if (GALILEO_INAV_PREAMBLE.at(i) == '1')
{
for (uint32_t j = 0; j < d_samples_per_symbol; j++)
{
d_preamble_samples[n] = 1;
n++;
}
d_preamble_samples[i] = 1;
}
else
{
for (uint32_t j = 0; j < d_samples_per_symbol; j++)
{
d_preamble_samples[n] = -1;
n++;
}
d_preamble_samples[i] = -1;
}
break;
}
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')
{
for (uint32_t j = 0; j < d_samples_per_symbol; j++)
{
d_preamble_samples[n] = d_secondary_code_samples[m];
n++;
m++;
m = m % GALILEO_E5A_I_SECONDARY_CODE_LENGTH;
}
d_preamble_samples[i] = 1;
}
else
{
for (uint32_t j = 0; j < d_samples_per_symbol; j++)
{
d_preamble_samples[n] = -d_secondary_code_samples[m];
n++;
m++;
m = m % GALILEO_E5A_I_SECONDARY_CODE_LENGTH;
}
d_preamble_samples[i] = -1;
}
break;
}
@ -235,10 +197,6 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
galileo_telemetry_decoder_gs::~galileo_telemetry_decoder_gs()
{
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(out0);
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
current_symbol = in[0][0];
// add new symbol to the symbol queue
d_symbol_history.push_back(current_symbol.Prompt_I);
switch (d_frame_type)
{
case 1: // INAV
{
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
consume_each(1);
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
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++)
{
d_page_part_symbols[i] = 0;
for (uint32_t m = 0; m < d_samples_per_symbol; m++)
for (uint32_t i = 0; i < d_frame_length_symbols; i++)
{
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!
k++;
k = k % GALILEO_E5A_I_SECONDARY_CODE_LENGTH;
d_page_part_symbols[i] = d_symbol_history.at(i + d_samples_per_preamble); // because last symbol of the preamble is just received now!
}
}
}
else // 180 deg. inverted carrier phase PLL lock
{
int k = 0;
for (uint32_t i = 0; i < d_frame_length_symbols; i++)
{
d_page_part_symbols[i] = 0;
for (uint32_t m = 0; m < d_samples_per_symbol; m++) // integrate samples into symbols
for (uint32_t i = 0; i < d_frame_length_symbols; i++)
{
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!
k++;
k = k % GALILEO_E5A_I_SECONDARY_CODE_LENGTH;
d_page_part_symbols[i] = -d_symbol_history.at(i + d_samples_per_preamble); // because last symbol of the preamble is just received now!
}
}
}
@ -658,12 +625,12 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
return -1;
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)
{
d_CRC_error_counter = 0;
d_flag_preamble = true; // valid preamble indicator (initialized to false every work())
d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P)
d_flag_preamble = true; // valid preamble indicator (initialized to false every work())
gr::thread::scoped_lock lock(d_setlock);
d_last_valid_preamble = d_sample_counter;
if (!d_flag_frame_sync)
{
@ -674,7 +641,6 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
else
{
d_CRC_error_counter++;
d_preamble_index = d_sample_counter; // record the preamble sample stamp
if (d_CRC_error_counter > CRC_ERROR_LIMIT)
{
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)
{
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_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_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;
}
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_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;
}
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_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;
}
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;
}

View File

@ -85,8 +85,6 @@ private:
int32_t d_samples_per_preamble;
int32_t d_preamble_period_symbols;
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_required_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)),
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
this->message_port_register_out(pmt::mp("telemetry"));
// 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)),
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
this->message_port_register_out(pmt::mp("telemetry"));
// 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)),
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
this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block
@ -76,32 +79,26 @@ gps_l1_ca_telemetry_decoder_gs::gps_l1_ca_telemetry_decoder_gs(
DLOG(INFO) << "Initializing GPS L1 TELEMETRY DECODER";
d_bits_per_preamble = GPS_CA_PREAMBLE_LENGTH_BITS;
d_samples_per_preamble = d_bits_per_preamble * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT;
d_preamble_period_symbols = GPS_SUBFRAME_BITS * GPS_CA_TELEMETRY_SYMBOLS_PER_BIT;
d_samples_per_preamble = d_bits_per_preamble;
d_preamble_period_symbols = GPS_SUBFRAME_BITS;
// 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
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_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;
for (int32_t i = 0; i < d_bits_per_preamble; i++)
{
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;
n++;
}
d_preamble_samples[n] = 1;
n++;
}
else
{
for (uint32_t j = 0; j < GPS_CA_TELEMETRY_SYMBOLS_PER_BIT; j++)
{
d_preamble_samples[n] = -1;
n++;
}
d_preamble_samples[n] = -1;
n++;
}
}
d_sample_counter = 0ULL;
@ -209,74 +206,58 @@ void gps_l1_ca_telemetry_decoder_gs::set_channel(int32_t channel)
bool gps_l1_ca_telemetry_decoder_gs::decode_subframe()
{
char subframe[GPS_SUBFRAME_LENGTH];
int32_t symbol_accumulator_counter = 0;
int32_t frame_bit_index = 0;
int32_t word_index = 0;
uint32_t GPS_frame_4bytes = 0;
float symbol_accumulator = 0;
bool subframe_synchro_confirmation = true;
for (float subframe_symbol : d_symbol_history)
{
// ******* 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
if (subframe_symbol > 0)
{
// symbol to bit
if (symbol_accumulator > 0)
{
GPS_frame_4bytes += 1; // insert the telemetry bit in LSB
//std::cout << "1";
}
else
{
//std::cout << "0";
}
symbol_accumulator = 0;
symbol_accumulator_counter = 0;
GPS_frame_4bytes += 1; // insert the telemetry bit in LSB
}
// ******* bits to words ******
frame_bit_index++;
if (frame_bit_index == 30)
// ******* bits to words ******
frame_bit_index++;
if (frame_bit_index == 30)
{
frame_bit_index = 0;
// parity check
// Each word in wordbuff is composed of:
// Bits 0 to 29 = the GPS data word
// Bits 30 to 31 = 2 LSBs of the GPS word ahead.
// prepare the extended frame [-2 -1 0 ... 30]
if (d_prev_GPS_frame_4bytes & 0x00000001)
{
frame_bit_index = 0;
// parity check
// Each word in wordbuff is composed of:
// Bits 0 to 29 = the GPS data word
// Bits 30 to 31 = 2 LSBs of the GPS word ahead.
// prepare the extended frame [-2 -1 0 ... 30]
if (d_prev_GPS_frame_4bytes & 0x00000001)
{
GPS_frame_4bytes = GPS_frame_4bytes | 0x40000000;
}
if (d_prev_GPS_frame_4bytes & 0x00000002)
{
GPS_frame_4bytes = GPS_frame_4bytes | 0x80000000;
}
// Check that the 2 most recently logged words pass parity. Have to first
// invert the data bits according to bit 30 of the previous word.
if (GPS_frame_4bytes & 0x40000000)
{
GPS_frame_4bytes ^= 0x3FFFFFC0; // invert the data bits (using XOR)
}
// check parity. If ANY word inside the subframe fails the parity, set subframe_synchro_confirmation = false
if (not gps_l1_ca_telemetry_decoder_gs::gps_word_parityCheck(GPS_frame_4bytes))
{
subframe_synchro_confirmation = false;
}
// add word to subframe
// insert the word in the correct position of the subframe
std::memcpy(&subframe[word_index * GPS_WORD_LENGTH], &GPS_frame_4bytes, sizeof(uint32_t));
word_index++;
d_prev_GPS_frame_4bytes = GPS_frame_4bytes; // save the actual frame
GPS_frame_4bytes = 0;
GPS_frame_4bytes = GPS_frame_4bytes | 0x40000000;
}
else
if (d_prev_GPS_frame_4bytes & 0x00000002)
{
GPS_frame_4bytes <<= 1; // shift 1 bit left the telemetry word
GPS_frame_4bytes = GPS_frame_4bytes | 0x80000000;
}
// Check that the 2 most recently logged words pass parity. Have to first
// invert the data bits according to bit 30 of the previous word.
if (GPS_frame_4bytes & 0x40000000)
{
GPS_frame_4bytes ^= 0x3FFFFFC0; // invert the data bits (using XOR)
}
// check parity. If ANY word inside the subframe fails the parity, set subframe_synchro_confirmation = false
if (not gps_l1_ca_telemetry_decoder_gs::gps_word_parityCheck(GPS_frame_4bytes))
{
subframe_synchro_confirmation = false;
}
// add word to subframe
// insert the word in the correct position of the subframe
std::memcpy(&subframe[word_index * GPS_WORD_LENGTH], &GPS_frame_4bytes, sizeof(uint32_t));
word_index++;
d_prev_GPS_frame_4bytes = GPS_frame_4bytes; // save the actual frame
GPS_frame_4bytes = 0;
}
else
{
GPS_frame_4bytes <<= 1; // shift 1 bit left the telemetry word
}
}
@ -378,10 +359,10 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__
{
// correlate with preamble
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 ********
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
{
@ -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
DLOG(INFO) << "Preamble detection for GPS L1 satellite " << this->d_satellite;
decode_subframe();
d_stat = 1; // enter into frame pre-detection status
}
flag_TOW_set = false;
@ -407,10 +389,10 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__
// correlate with preamble
int32_t corr_value = 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 ********
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
{
@ -438,6 +420,7 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__
{
flag_PLL_180_deg_phase_locked = false;
}
decode_subframe();
d_stat = 2;
}
else
@ -475,7 +458,6 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__
else
{
d_CRC_error_counter++;
d_preamble_index = d_sample_counter; // record the preamble sample stamp
if (d_CRC_error_counter > 2)
{
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)
{
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)))
{
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry"));
// 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)))
{
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block
this->message_port_register_out(pmt::mp("telemetry_to_trk"));
d_last_valid_preamble = 0;
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
d_dump = dump;
@ -74,23 +76,8 @@ gps_l5_telemetry_decoder_gs::gps_l5_telemetry_decoder_gs(
d_flag_valid_word = false;
d_TOW_at_current_symbol_ms = 0U;
d_TOW_at_Preamble_ms = 0U;
sym_hist.set_capacity(GPS_L5I_NH_CODE_LENGTH);
// initialize the CNAV frame decoder (libswiftcnav)
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;
}
@ -171,9 +158,6 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
// 1. Copy the current tracking output
current_synchro_data = in[0];
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
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;
uint32_t delay = 0;
// 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;
}
uint32_t delay;
uint8_t symbol_clip = static_cast<uint8_t>(current_synchro_data.Prompt_Q > 0) * 255;
// 2. Add the telemetry decoder information
// 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;
// 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++)
{
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);
@ -279,7 +220,7 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
//check TOW update consistency
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;
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
<< " 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)
{
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)
{
d_flag_valid_word = false;

View File

@ -91,10 +91,6 @@ private:
uint32_t d_max_symbols_without_valid_frame;
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)))
{
//prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1);
// Ephemeris data port out
this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block

View File

@ -58,22 +58,39 @@ BeidouB3iDllPllTracking::BeidouB3iDllPllTracking(
trk_param.fs_in = fs_in;
bool dump = configuration->property(role + ".dump", false);
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);
if (FLAGS_pll_bw_hz != 0.0)
{
pll_bw_hz = static_cast<float>(FLAGS_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);
if (FLAGS_dll_bw_hz != 0.0)
{
dll_bw_hz = static_cast<float>(FLAGS_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);
if (dll_filter_order < 1)
@ -116,16 +133,12 @@ BeidouB3iDllPllTracking::BeidouB3iDllPllTracking(
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);
float early_late_space_chips = configuration->property(role + ".early_late_space_chips", 0.5);
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));
int vector_length = std::round(static_cast<double>(fs_in) / (BEIDOU_B3I_CODE_RATE_HZ / BEIDOU_B3I_CODE_LENGTH_CHIPS));
trk_param.vector_length = vector_length;
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)
{
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;
}
trk_param.extend_correlation_symbols = symbols_extended_correlator;
bool track_pilot = configuration->property(role + ".track_pilot", false);
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.track_pilot = track_pilot;
trk_param.very_early_late_space_chips = 0.0;
trk_param.very_early_late_space_narrow_chips = 0.0;
trk_param.track_pilot = false;
trk_param.system = 'C';
char sig_[3] = "B3";
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)),
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_;
// Telemetry bit synchronization message port input
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));
// initialize internal vars
d_dll_filt_history.set_capacity(2000);
d_dll_filt_history.set_capacity(1000);
d_veml = false;
d_cloop = true;
d_pull_in_transitory = true;
d_code_chip_rate = 0.0;
d_secondary_code_length = 0U;
d_secondary_code_string = nullptr;
d_data_secondary_code_length = 0U;
d_data_secondary_code_string = nullptr;
d_preambles_symbols = nullptr;
d_preamble_length_symbols = 0;
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_code_period = GPS_L1_CA_CODE_PERIOD;
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_code_samples_per_chip = 1;
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
d_secondary = false;
trk_parameters.track_pilot = false;
interchange_iq = false;
// set the preamble
uint16_t preambles_bits[GPS_CA_PREAMBLE_LENGTH_BITS] = GPS_PREAMBLE;
// 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
// symbol integration: 20 trk symbols (20 ms) = 1 tlm bit
// set the preamble in the secondary code acquisition to obtain tlm symbol synchronization
d_secondary_code_length = static_cast<uint32_t>(GPS_CA_PREAMBLE_LENGTH_SYMBOLS);
d_secondary_code_string = const_cast<std::string *>(&GPS_CA_PREAMBLE_SYMBOLS_STR);
d_symbols_per_bit = GPS_CA_TELEMETRY_SYMBOLS_PER_BIT;
}
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_chip_rate = GPS_L2_M_CODE_RATE_HZ;
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_correlation_length_ms = 20;
d_code_samples_per_chip = 1;
// GPS L2 does not have pilot component nor secondary code
d_secondary = false;
trk_parameters.track_pilot = false;
interchange_iq = false;
}
else if (signal_type == "L5")
{
d_signal_carrier_freq = GPS_L5_FREQ_HZ;
d_code_period = GPS_L5I_PERIOD;
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_correlation_length_ms = 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;
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_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";
interchange_iq = true;
}
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_string = const_cast<std::string *>(&GPS_L5I_NH_CODE_STR);
signal_pretty_name = signal_pretty_name + "I";
interchange_iq = false;
}
}
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;
d_correlation_length_ms = 1;
d_secondary = false;
interchange_iq = false;
d_signal_carrier_freq = 0.0;
d_code_period = 0.0;
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_chip_rate = GALILEO_E1_CODE_CHIP_RATE_HZ;
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_correlation_length_ms = 4;
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;
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")
{
@ -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_code_samples_per_chip = 1;
d_code_length_chips = static_cast<uint32_t>(GALILEO_E5A_CODE_LENGTH_CHIPS);
d_secondary = true;
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);
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
{
//Do not acquire secondary code in data component. It is done in telemetry decoder
d_secondary = false;
// synchronize and remove data secondary code
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";
interchange_iq = false;
}
}
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;
d_correlation_length_ms = 1;
d_secondary = false;
interchange_iq = false;
d_signal_carrier_freq = 0.0;
d_code_period = 0.0;
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_chip_rate = BEIDOU_B1I_CODE_RATE_HZ;
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_code_samples_per_chip = 1;
d_secondary = true;
d_secondary = 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_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")
{
@ -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_chip_rate = BEIDOU_B3I_CODE_RATE_HZ;
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_code_samples_per_chip = 1;
d_secondary = true;
d_secondary = 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_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
{
@ -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;
d_correlation_length_ms = 1;
d_secondary = false;
interchange_iq = false;
d_signal_carrier_freq = 0.0;
d_code_period = 0.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;
d_correlation_length_ms = 1;
d_secondary = false;
interchange_iq = false;
d_signal_carrier_freq = 0.0;
d_code_period = 0.0;
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)
{
case 1: //tlm fault in current channel
case 1: // tlm fault in current channel
{
DLOG(INFO) << "Telemetry fault received in ch " << this->d_channel;
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;
}
default:
@ -578,8 +570,7 @@ void dll_pll_veml_tracking::msg_handler_telemetry_to_trk(const pmt::pmt_t &msg)
void dll_pll_veml_tracking::start_tracking()
{
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_carrier_doppler_hz = d_acquisition_gnss_synchro->Acq_doppler_hz;
d_acq_sample_stamp = d_acquisition_gnss_synchro->Acq_samplestamp_samples;
@ -619,7 +610,6 @@ void dll_pll_veml_tracking::start_tracking()
if (trk_parameters.track_pilot)
{
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_data_code, 2 * d_code_length_chips), Signal_, d_acquisition_gnss_synchro->PRN);
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++)
{
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);
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")
{
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)
{
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_code_samples_per_chip = 1;
d_secondary = false;
trk_parameters.track_pilot = false;
interchange_iq = false;
d_secondary_code_length = 0;
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_D2_SECONDARY_CODE_STR);
// preamble bits to sampled symbols
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
{
d_preambles_symbols[n] = -1;
}
n++;
}
}
d_symbol_history.resize(22); // Change fixed buffer size
d_symbol_history.clear();
// set the preamble in the secondary code acquisition
d_secondary_code_length = static_cast<uint32_t>(BEIDOU_B1I_GEO_PREAMBLE_LENGTH_SYMBOLS);
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B1I_GEO_PREAMBLE_SYMBOLS_STR);
d_data_secondary_code_length = 0;
d_Prompt_circular_buffer.set_capacity(d_secondary_code_length);
}
else
{
//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_code_samples_per_chip = 1;
d_secondary = false;
trk_parameters.track_pilot = false;
// 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
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_code_samples_per_chip = 1;
d_secondary = false;
trk_parameters.track_pilot = false;
interchange_iq = false;
d_secondary_code_length = 0;
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B3I_D2_SECONDARY_CODE_STR);
// preamble bits to sampled symbols
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
{
d_preambles_symbols[n] = -1;
}
n++;
}
}
d_symbol_history.resize(22); // Change fixed buffer size
d_symbol_history.clear();
// set the preamble in the secondary code acquisition
d_secondary_code_length = static_cast<uint32_t>(BEIDOU_B3I_GEO_PREAMBLE_LENGTH_SYMBOLS);
d_secondary_code_string = const_cast<std::string *>(&BEIDOU_B3I_GEO_PREAMBLE_SYMBOLS_STR);
d_data_secondary_code_length = 0;
d_Prompt_circular_buffer.set_capacity(d_secondary_code_length);
}
else
{
//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_code_samples_per_chip = 1;
d_secondary = false;
trk_parameters.track_pilot = false;
// 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);
// 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 = carrier_lock_detector(d_Prompt_buffer, trk_parameters.cn0_samples);
// Loss of lock detection
if (!d_pull_in_transitory)
{
//d_carrier_lock_test < d_carrier_lock_threshold or
if (d_carrier_lock_test < d_carrier_lock_threshold)
{
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)
{
// 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_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
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);
}
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);
}
}
@ -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_CN0_SNV_dB_Hz: " << this->d_CN0_SNV_dB_Hz << std::endl;
// ################## DLL ##########################################################
// DLL discriminator
if (d_veml)
@ -1029,18 +1008,23 @@ 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;
// Experimental: detect Carrier Doppler vs. Code Doppler incoherence and correct the Carrier Doppler
if (d_pull_in_transitory == false and d_corrected_doppler == false)
if (trk_parameters.enable_doppler_correction == true)
{
d_dll_filt_history.push_back(static_cast<float>(d_code_error_filt_chips));
if (d_dll_filt_history.full())
if (d_pull_in_transitory == false and d_corrected_doppler == false)
{
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());
if (fabs(avg_code_error_chips_s) > 1.0)
d_dll_filt_history.push_back(static_cast<float>(d_code_error_filt_chips));
if (d_dll_filt_history.full())
{
float carrier_doppler_error_hz = static_cast<float>(d_signal_carrier_freq) * avg_code_error_chips_s / static_cast<float>(d_code_chip_rate);
LOG(INFO) << "Detected and corrected carrier doppler error: " << carrier_doppler_error_hz << " [Hz] on sat " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN);
d_carrier_loop_filter.initialize(d_carrier_doppler_hz - carrier_doppler_error_hz);
d_corrected_doppler = true;
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)
{
float carrier_doppler_error_hz = static_cast<float>(d_signal_carrier_freq) * avg_code_error_chips_s / static_cast<float>(d_code_chip_rate);
LOG(INFO) << "Detected and corrected carrier doppler error: " << carrier_doppler_error_hz << " [Hz] on sat " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN);
d_carrier_loop_filter.initialize(d_carrier_doppler_hz - carrier_doppler_error_hz);
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)
{
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_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_filt_chips = 0.0;
d_current_symbol = 0;
d_current_data_symbol = 0;
d_Prompt_circular_buffer.clear();
d_carrier_phase_rate_step_rad = 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
T_prn_samples = T_prn_seconds * trk_parameters.fs_in;
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
//################### 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;
}
}
//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
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);
// carrier phase accumulator
//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);
//std::cout << fmod(b, PI_2) / fmod(a, PI_2) << std::endl;
// 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);
// 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));
//################### DLL COMMANDS #################################################
@ -1184,12 +1169,70 @@ void dll_pll_veml_tracking::save_correlation_results()
d_E_accu += *d_Early;
d_P_accu += *d_Prompt;
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 (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;
}
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)
{
@ -1212,29 +1255,13 @@ void dll_pll_veml_tracking::log_data(bool integrating)
uint64_t tmp_long_int;
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_Q = d_Prompt_Data->imag();
}
prompt_I = d_Prompt_Data->real();
prompt_Q = d_Prompt_Data->imag();
}
else
{
if (interchange_iq)
{
prompt_I = d_Prompt->imag();
prompt_Q = d_Prompt->real();
}
else
{
prompt_I = d_Prompt->real();
prompt_Q = d_Prompt->imag();
}
prompt_I = d_Prompt->real();
prompt_Q = d_Prompt->imag();
}
if (d_veml)
{
@ -1249,20 +1276,6 @@ void dll_pll_veml_tracking::log_data(bool integrating)
tmp_E = std::abs<float>(d_E_accu);
tmp_P = std::abs<float>(d_P_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
{
@ -1383,7 +1396,6 @@ int32_t dll_pll_veml_tracking::save_matfile()
auto aux1 = std::vector<float>(num_epoch);
auto aux2 = std::vector<double>(num_epoch);
auto PRN = std::vector<uint32_t>(num_epoch);
try
{
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]);
auto **out = reinterpret_cast<Gnss_Synchro **>(&output_items[0]);
Gnss_Synchro current_synchro_data = Gnss_Synchro();
current_synchro_data.Flag_valid_symbol_output = false;
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_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
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();
// enable write dump file this cycle (valid DLL/PLL cycle)
log_data(false);
log_data();
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
{
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)
//******* preamble correlation ********
d_Prompt_circular_buffer.push_back(*d_Prompt);
if (d_Prompt_circular_buffer.size() == d_secondary_code_length)
{
d_symbol_history.push_back(d_Prompt->real());
//******* preamble correlation ********
int32_t corr_value = 0;
if ((static_cast<int32_t>(d_symbol_history.size()) == d_preamble_length_symbols)) // and (d_make_correlation or !d_flag_frame_sync))
next_state = acquire_secondary();
if (next_state)
{
int i = 0;
for (const auto &iter : d_symbol_history)
{
if (iter < 0.0) // symbols clipping
{
corr_value -= d_preambles_symbols[i];
}
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
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;
std::cout << systemName << " " << signal_pretty_name << " tracking bit synchronization locked in channel " << d_channel
<< " for satellite " << Gnss_Satellite(systemName, d_acquisition_gnss_synchro->PRN) << std::endl;
next_state = true;
}
else
{
next_state = false;
}
}
else
{
next_state = false;
}
}
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
}
// ########### 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)
{ // reset extended correlator
d_VE_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_data_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_Prompt_circular_buffer.clear();
d_current_symbol = 0;
d_current_data_symbol = 0;
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)
{
// Fill the acquisition data
current_synchro_data = *d_acquisition_gnss_synchro;
// perform a correlation step
do_correlation_step(in);
update_tracking_vars();
save_correlation_results();
// ########### Output the tracking results to Telemetry block ##########
if (interchange_iq)
update_tracking_vars();
if (d_current_data_symbol == 0)
{
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());
}
log_data();
// ########### Output the tracking results to Telemetry block ##########
// Fill the acquisition data
current_synchro_data = *d_acquisition_gnss_synchro;
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());
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.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);
}
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;
d_extend_correlation_symbols_count++;
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
{
// Fill the acquisition data
current_synchro_data = *d_acquisition_gnss_synchro;
// perform a correlation step
do_correlation_step(in);
save_correlation_results();
@ -1880,44 +1816,24 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused)
{
run_dll_pll();
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 ##########
// Fill the acquisition data
current_synchro_data = *d_acquisition_gnss_synchro;
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());
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.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);
}
// ########### 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;
// enable write dump file this cycle (valid DLL/PLL cycle)
log_data(false);
// reset extended correlator
d_VE_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 clear_tracking_vars();
void save_correlation_results();
void log_data(bool integrating);
void log_data();
int32_t save_matfile();
// tracking configuration vars
@ -97,22 +97,22 @@ private:
// Signal parameters
bool d_secondary;
bool interchange_iq;
double d_signal_carrier_freq;
double d_code_period;
double d_code_chip_rate;
uint32_t d_secondary_code_length;
uint32_t d_data_secondary_code_length;
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)
int32_t d_symbols_per_bit;
std::string systemName;
std::string signal_type;
std::string *d_secondary_code_string;
std::string *d_data_secondary_code_string;
std::string signal_pretty_name;
int32_t *d_preambles_symbols;
int32_t d_preamble_length_symbols;
boost::circular_buffer<float> d_symbol_history;
// dll filter buffer
boost::circular_buffer<float> d_dll_filt_history;
@ -129,6 +129,7 @@ private:
float *d_prompt_data_shift;
Cpu_Multicorrelator_Real_Codes multicorrelator_cpu;
Cpu_Multicorrelator_Real_Codes correlator_data_cpu; //for data channel
/* TODO: currently the multicorrelator does not support adding extra correlator
with different local code, thus we need extra multicorrelator instance.
Implement this functionality inside multicorrelator class
@ -144,6 +145,7 @@ private:
bool d_enable_extended_integration;
int32_t d_extend_correlation_symbols_count;
int32_t d_current_symbol;
int32_t d_current_data_symbol;
gr_complex d_VE_accu;
gr_complex d_E_accu;
@ -152,6 +154,7 @@ private:
gr_complex d_L_accu;
gr_complex d_VL_accu;
gr_complex d_P_data_accu;
gr_complex *d_Prompt_Data;
double d_code_phase_step_chips;
@ -160,6 +163,7 @@ private:
double d_carrier_phase_step_rad;
double d_carrier_phase_rate_step_rad;
boost::circular_buffer<std::pair<double, double>> d_carr_ph_history;
// remaining code phase and carrier phase between tracking loops
double d_rem_code_phase_samples;
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_steady_state = false;
pull_in_time_s = 10;
bit_synchronization_time_limit_s = pull_in_time_s + 60;
fll_filter_order = 1;
pll_filter_order = 3;
dll_filter_order = 2;
@ -68,6 +69,7 @@ Dll_Pll_Conf::Dll_Pll_Conf()
max_carrier_lock_fail = FLAGS_max_carrier_lock_fail;
max_code_lock_fail = FLAGS_max_lock_fail;
carrier_lock_th = FLAGS_carrier_lock_th;
enable_doppler_correction = false;
track_pilot = false;
system = 'G';
char sig_[3] = "1C";

View File

@ -45,6 +45,7 @@ public:
bool enable_fll_pull_in;
bool enable_fll_steady_state;
unsigned int pull_in_time_s;
unsigned int bit_synchronization_time_limit_s;
int pll_filter_order;
int dll_filter_order;
@ -74,6 +75,7 @@ public:
uint32_t smoother_length;
double carrier_lock_th;
bool track_pilot;
bool enable_doppler_correction;
char system;
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)
{
alpha_ = alpha;

View File

@ -47,15 +47,17 @@
class Exponential_Smoother
{
public:
Exponential_Smoother(); //!< Constructor
~Exponential_Smoother(); //!< Destructor
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
Exponential_Smoother(); //!< Constructor
~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_samples_for_initialization(int num_samples); //!< Number of samples averaged for initialization. Default value: 200
void reset();
void set_min_value(float value);
void set_offset(float offset);
float smooth(float raw);
double smooth(double raw);
Exponential_Smoother(Exponential_Smoother&&) = default; //!< Move operator
Exponential_Smoother& operator=(Exponential_Smoother&& /*other*/) = default; //!< Move assignment operator
private:
float alpha_; // takes value 0.0001 if not set
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)
{
// Now apply the filter coefficients:
@ -234,6 +231,7 @@ void Tracking_loop_filter::set_update_interval(float update_interval)
update_coefficients();
}
float Tracking_loop_filter::get_update_interval(void) const
{
return d_update_interval;

View File

@ -44,6 +44,16 @@
class Tracking_loop_filter
{
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_update_interval(void) const;
bool get_include_last_integrator(void) const;
@ -57,13 +67,6 @@ public:
void initialize(float initial_output = 0.0);
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:
// Store the last inputs and outputs:
std::vector<float> d_inputs;

View File

@ -50,7 +50,6 @@ public:
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;
observables.New();
}
~Serdes_Gnss_Synchro()
@ -58,6 +57,31 @@ public:
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
{
observables.Clear();
@ -150,7 +174,7 @@ public:
}
private:
gnss_sdr::Observables observables;
gnss_sdr::Observables observables{};
};
#endif // GNSS_SDR_SERDES_GNSS_SYNCHRO_H_

View File

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

View File

@ -34,8 +34,7 @@
#include "MATH_CONSTANTS.h"
#include <cstdint>
#include <utility> // std::pair
#include <vector>
#include <string>
// Physical constants
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
const double BEIDOU_B1I_FREQ_HZ = 1.561098e9; //!< b1I [Hz]
const double BEIDOU_B1I_CODE_RATE_HZ = 2.046e6; //!< beidou b1I code rate [chips/s]
const double BEIDOU_B1I_CODE_LENGTH_CHIPS = 2046.0; //!< beidou b1I code length [chips]
const double BEIDOU_B1I_CODE_PERIOD = 0.001; //!< beidou b1I code period [seconds]
const uint32_t BEIDOU_B1I_CODE_PERIOD_MS = 1; //!< beidou b1I L1 C/A code period [ms]
const double BEIDOU_B1I_CHIP_PERIOD = 4.8875e-07; //!< beidou b1I chip period [seconds]
const double BEIDOU_B1I_FREQ_HZ = 1.561098e9; //!< B1I [Hz]
const double BEIDOU_B1I_CODE_RATE_HZ = 2.046e6; //!< Beidou B1I code rate [chips/s]
const double BEIDOU_B1I_CODE_LENGTH_CHIPS = 2046.0; //!< Beidou B1I code length [chips]
const double BEIDOU_B1I_CODE_PERIOD = 0.001; //!< Beidou B1I code period [seconds]
const 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 int32_t BEIDOU_B1I_SECONDARY_CODE_LENGTH = 20;
const std::string BEIDOU_B1I_SECONDARY_CODE = "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 int BEIDOU_B1I_PREAMBLE_LENGTH_BITS = 11;
const int BEIDOU_B1I_PREAMBLE_LENGTH_SYMBOLS = 220; // **************
const double BEIDOU_B1I_PREAMBLE_DURATION_S = 0.220;
const int BEIDOU_B1I_PREAMBLE_DURATION_MS = 220;
const int BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND = 50; //!< D1 NAV message bit rate [bits/s]
const int BEIDOU_B1I_TELEMETRY_SYMBOLS_PER_BIT = 20; // *************
const int BEIDOU_B1I_TELEMETRY_RATE_BITS_SECOND = 50; //!< D1 NAV message bit rate [bits/s]
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_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

View File

@ -33,25 +33,27 @@
#include "MATH_CONSTANTS.h"
#include <cstdint>
#include <utility> // std::pair
#include <vector>
#include <string>
// carrier and code frequencies
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_LENGTH_CHIPS = 10230.0; //!< BeiDou B3I code length [chips]
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 std::string BEIDOU_B3I_SECONDARY_CODE = "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 uint32_t BEIDOU_B3I_PREAMBLE_LENGTH_BITS = 11;
const uint32_t BEIDOU_B3I_PREAMBLE_LENGTH_SYMBOLS = 220; // **************
const double BEIDOU_B3I_PREAMBLE_DURATION_S = 0.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_SYMBOLS_PER_BIT = 20; // *************
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_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]
#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_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_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]
//optimum parameters
@ -84,6 +85,7 @@ const int32_t GPS_L1_CA_HISTORY_DEEP = 100;
1, 0, 0, 0, 1, 0, 1, 1 \
}
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_SYMBOLS = 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()
{
system_set = {"GPS", "Glonass", "SBAS", "Galileo", "Beidou"};
satelliteSystem["GPS"] = "G";
satelliteSystem["Glonass"] = "R";
satelliteSystem["SBAS"] = "S";
satelliteSystem["Galileo"] = "E";
satelliteSystem["Beidou"] = "C";
PRN = 0;
system = std::string("");
block = std::string("");
@ -89,29 +80,57 @@ bool operator==(const Gnss_Satellite& sat1, const Gnss_Satellite& sat2)
{
if (sat1.get_PRN() == sat2.get_PRN())
{
equal = true;
if (sat1.get_rf_link() == sat2.get_rf_link())
{
equal = true;
}
}
}
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.
if (this != &rhs) {
// Deallocate, allocate new space, copy values...
const std::string system_ = rhs.get_system();
const uint32_t PRN_ = rhs.get_PRN();
const std::string block_ = rhs.get_block();
// const int32_t rf_link_ = 0;
this->set_system(system_);
this->set_PRN(PRN_);
this->set_block(system_, PRN_);
//this.rf_link = rf_link_;
}
if (this != &rhs)
{
this->system = rhs.system;
this->PRN = rhs.PRN;
this->block = rhs.block;
this->rf_link = rhs.rf_link;
}
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_)
@ -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
{
// Get satellite's PRN
@ -625,100 +652,100 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_
if (system_ == "Beidou")
{
// Check https://en.wikipedia.org/wiki/List_of_BeiDou_satellites
switch ( PRN_ )
{
case 1:
block_ = std::string("Compass-G1"); //!<GEO 140.0°E; launched 2010/01/16
break;
case 2:
block_ = std::string("Compass-G6"); //!<GEO 80°E; launched 2012/10/25
break;
case 3:
block_ = std::string("Compass-G7"); //!<GEO 110.5°E; launched 2016/06/12
break;
case 4:
block_ = std::string("Compass-G4"); //!<GEO 160.0°E; launched 2010/10/31
break;
case 5:
block_ = std::string("Compass-G5"); //!<GEO 58.75°E; launched 2012/02/24
break;
case 6:
block_ = std::string("Compass-IGS01"); //!<55° inclination IGSO 118°E; launched 2010/07/31
break;
case 7:
block_ = std::string("Compass-IGS02"); //!<55° inclination IGSO 118°E; launched 2010/12/17
break;
case 8:
block_ = std::string("Compass-IGS03"); //!<55° inclination IGSO 118°E; launched 2011/04/09
break;
case 9:
block_ = std::string("Compass-IGS04"); //!<55° inclination IGSO 95°E; launched 2011/07/27
break;
case 10:
block_ = std::string("Compass-IGS05"); //!<55° inclination IGSO 118°E; launched 2011/12/01
break;
case 11:
block_ = std::string("Compass-M3"); //!<Slot A07; launched 2012/04/29
break;
case 12:
block_ = std::string("Compass-M4"); //!<Slot A08; launched 2012/04/29
break;
case 19:
block_ = std::string("BEIDOU-3 M1"); //!<Slot B-7; launched 2017/11/05
break;
case 20:
block_ = std::string("BEIDOU-3 M2"); //!<Slot B-5; launched 2017/11/05
break;
case 21:
block_ = std::string("BEIDOU 3M5"); //!<Slot B-?; launched 2018/02/12
break;
case 22:
block_ = std::string("BEIDOU 3M6"); //!<Slot B-6; launched 2018/02/12
break;
case 23:
block_ = std::string("BEIDOU 3M9"); //!<Slot C-7; launched 2018/07/29
break;
case 24:
block_ = std::string("BEIDOU 3M10"); //!<Slot C-1; launched 2018/07/29
break;
case 25:
block_ = std::string("BEIDOU 3M12"); //!<Slot C-8; launched 2018/08/24
break;
case 26:
block_ = std::string("BEIDOU 3M11"); //!<Slot C-2; launched 2018/08/24
break;
case 27:
block_ = std::string("BEIDOU 3M3"); //!<Slot A-?; launched 2018/01/11
break;
case 28:
block_ = std::string("BEIDOU 3M4"); //!<Slot A-?; launched 2018/01/11
break;
case 29:
block_ = std::string("BEIDOU 3M7"); //!<Slot A-?; launched 2018/03/29
break;
case 30:
block_ = std::string("BEIDOU 3M8"); //!<Slot A-?; launched 2018/03/29
break;
case 32:
block_ = std::string("BEIDOU 3M13"); //!<Slot B-1?; launched 2018/09/19
break;
case 33:
block_ = std::string("BEIDOU 3M14"); //!<Slot B-3; launched 2018/09/19
break;
case 34:
block_ = std::string("BEIDOU 3M15"); //!<Slot B-3; launched 2018/10/15
break;
case 35:
block_ = std::string("BEIDOU 3M16"); //!<Slot B-3; launched 2018/10/15
break;
case 36:
block_ = std::string("BEIDOU 3M17"); //!<Slot B-3; launched 2018/11/18
break;
case 37:
block_ = std::string("BEIDOU 3M18"); //!<Slot B-3; launched 2018/11/18
break;
default:
block_ = std::string("Unknown(Simulated)");
switch (PRN_)
{
case 1:
block_ = std::string("Compass-G1"); //!<GEO 140.0°E; launched 2010/01/16
break;
case 2:
block_ = std::string("Compass-G6"); //!<GEO 80°E; launched 2012/10/25
break;
case 3:
block_ = std::string("Compass-G7"); //!<GEO 110.5°E; launched 2016/06/12
break;
case 4:
block_ = std::string("Compass-G4"); //!<GEO 160.0°E; launched 2010/10/31
break;
case 5:
block_ = std::string("Compass-G5"); //!<GEO 58.75°E; launched 2012/02/24
break;
case 6:
block_ = std::string("Compass-IGS01"); //!<55° inclination IGSO 118°E; launched 2010/07/31
break;
case 7:
block_ = std::string("Compass-IGS02"); //!<55° inclination IGSO 118°E; launched 2010/12/17
break;
case 8:
block_ = std::string("Compass-IGS03"); //!<55° inclination IGSO 118°E; launched 2011/04/09
break;
case 9:
block_ = std::string("Compass-IGS04"); //!<55° inclination IGSO 95°E; launched 2011/07/27
break;
case 10:
block_ = std::string("Compass-IGS05"); //!<55° inclination IGSO 118°E; launched 2011/12/01
break;
case 11:
block_ = std::string("Compass-M3"); //!<Slot A07; launched 2012/04/29
break;
case 12:
block_ = std::string("Compass-M4"); //!<Slot A08; launched 2012/04/29
break;
case 19:
block_ = std::string("BEIDOU-3 M1"); //!<Slot B-7; launched 2017/11/05
break;
case 20:
block_ = std::string("BEIDOU-3 M2"); //!<Slot B-5; launched 2017/11/05
break;
case 21:
block_ = std::string("BEIDOU 3M5"); //!<Slot B-?; launched 2018/02/12
break;
case 22:
block_ = std::string("BEIDOU 3M6"); //!<Slot B-6; launched 2018/02/12
break;
case 23:
block_ = std::string("BEIDOU 3M9"); //!<Slot C-7; launched 2018/07/29
break;
case 24:
block_ = std::string("BEIDOU 3M10"); //!<Slot C-1; launched 2018/07/29
break;
case 25:
block_ = std::string("BEIDOU 3M12"); //!<Slot C-8; launched 2018/08/24
break;
case 26:
block_ = std::string("BEIDOU 3M11"); //!<Slot C-2; launched 2018/08/24
break;
case 27:
block_ = std::string("BEIDOU 3M3"); //!<Slot A-?; launched 2018/01/11
break;
case 28:
block_ = std::string("BEIDOU 3M4"); //!<Slot A-?; launched 2018/01/11
break;
case 29:
block_ = std::string("BEIDOU 3M7"); //!<Slot A-?; launched 2018/03/29
break;
case 30:
block_ = std::string("BEIDOU 3M8"); //!<Slot A-?; launched 2018/03/29
break;
case 32:
block_ = std::string("BEIDOU 3M13"); //!<Slot B-1?; launched 2018/09/19
break;
case 33:
block_ = std::string("BEIDOU 3M14"); //!<Slot B-3; launched 2018/09/19
break;
case 34:
block_ = std::string("BEIDOU 3M15"); //!<Slot B-3; launched 2018/10/15
break;
case 35:
block_ = std::string("BEIDOU 3M16"); //!<Slot B-3; launched 2018/10/15
break;
case 36:
block_ = std::string("BEIDOU 3M17"); //!<Slot B-3; launched 2018/11/18
break;
case 37:
block_ = std::string("BEIDOU 3M18"); //!<Slot B-3; launched 2018/11/18
break;
default:
block_ = std::string("Unknown(Simulated)");
}
}
return block_;

View File

@ -50,7 +50,7 @@ class Gnss_Satellite
public:
Gnss_Satellite(); //!< Default 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
uint32_t get_PRN() const; //!< Gets satellite's PRN
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 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:
uint32_t PRN;
std::string system;
std::map<std::string, std::string> satelliteSystem;
std::string block;
int32_t rf_link;
uint32_t PRN{};
int32_t rf_link{};
std::string system{};
std::string block{};
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_PRN(uint32_t PRN); // Sets satellite's 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 set_rf_link(int32_t rf_link_);
};
#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
{
return this->signal;

View File

@ -47,7 +47,7 @@ public:
Gnss_Signal();
Gnss_Signal(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.
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
private:
Gnss_Satellite satellite;
std::string signal;
Gnss_Satellite satellite{};
std::string signal{};
};
#endif