Adding FPGA accelerators support in gnss-sdr configuration options

This commit is contained in:
Javier Arribas 2017-05-05 16:37:29 +02:00
parent eccbd0f97a
commit 2ee29af3bd
5 changed files with 490 additions and 338 deletions

View File

@ -0,0 +1,83 @@
; You can define your own receiver and invoke it by doing
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
;
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
GNSS-SDR.internal_fs_hz=4000000
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=Pass_Through
SignalSource.filename=/datalogger/signals/Agilent/New York/4msps.dat ; <- PUT YOUR FILE HERE
SignalSource.item_type=ishort
SignalSource.sampling_frequency=4000000
SignalSource.freq=1575420000
SignalSource.repeat=false
SignalSource.dump=false
SignalSource.dump_filename=../data/signal_source.dat
SignalSource.enable_throttle_control=false
SignalSource.enable_FPGA=true
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Pass_Through
SignalConditioner.item_type=cshort
SignalConditioner.enable_FPGA=true
;######### CHANNELS GLOBAL CONFIG ############
Channels_1C.count=8
Channels.in_acquisition=1
Channel.signal=1C
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1C.dump=false
Acquisition_1C.dump_filename=./acq_dump.dat
Acquisition_1C.item_type=cshort
Acquisition_1C.if=0
Acquisition_1C.sampled_ms=1
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition_Fpga
Acquisition_1C.threshold=0.005
;Acquisition_1C.pfa=0.01
Acquisition_1C.doppler_max=10000
Acquisition_1C.doppler_step=500
;######### TRACKING GLOBAL CONFIG ############
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_C_Aid_Tracking_Fpga
Tracking_1C.item_type=cshort
Tracking_1C.if=0
Tracking_1C.dump=false
Tracking_1C.dump_filename=../data/epl_tracking_ch_
Tracking_1C.pll_bw_hz=45.0;
Tracking_1C.dll_bw_hz=2.0;
Tracking_1C.order=3;
;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_1C.dump=false
TelemetryDecoder_1C.decimation_factor=1;
;######### OBSERVABLES CONFIG ############
Observables.implementation=GPS_L1_CA_Observables
Observables.dump=false
Observables.dump_filename=./observables.dat
;######### PVT CONFIG ############
PVT.implementation=GPS_L1_CA_PVT
PVT.averaging_depth=100
PVT.flag_averaging=false
PVT.output_rate_ms=10
PVT.display_rate_ms=500
PVT.dump_filename=./PVT
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
PVT.flag_nmea_tty_port=false;
PVT.nmea_dump_devname=/dev/pts/4
PVT.flag_rtcm_server=false
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1
PVT.dump=false

View File

@ -70,7 +70,7 @@ public:
*/
std::string implementation()
{
return "GPS_L1_CA_PCPS_Acquisition";
return "GPS_L1_CA_PCPS_Acquisition_Fpga";
}
size_t item_size()
{

View File

@ -36,6 +36,10 @@ if(ENABLE_CUDA)
set(OPT_RECEIVER_INCLUDE_DIRS ${OPT_RECEIVER_INCLUDE_DIRS} ${CUDA_INCLUDE_DIRS})
endif(ENABLE_CUDA)
if(ENABLE_FPGA)
add_definitions(-DENABLE_FPGA=1)
endif(ENABLE_FPGA)
include_directories(
$(CMAKE_CURRENT_SOURCE_DIR)

View File

@ -98,6 +98,11 @@
#include "galileo_e1_pvt.h"
#include "hybrid_pvt.h"
#if ENABLE_FPGA
#include "gps_l1_ca_dll_pll_c_aid_tracking_fpga.h"
#include "gps_l1_ca_pcps_acquisition_fpga.h"
#endif
#if OPENCL_BLOCKS
#include "gps_l1_ca_pcps_opencl_acquisition.h"
#endif
@ -892,6 +897,15 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
out_streams));
block = std::move(block_);
}
#if ENABLE_FPGA
else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fpga") == 0)
{
std::unique_ptr<GNSSBlockInterface> block_(new GpsL1CaPcpsAcquisitionFpga(configuration.get(), role, in_streams,
out_streams));
block = std::move(block_);
}
#endif
else if (implementation.compare("GPS_L1_CA_PCPS_Assisted_Acquisition") == 0)
{
std::unique_ptr<GNSSBlockInterface> block_(new GpsL1CaPcpsAssistedAcquisition(configuration.get(), role, in_streams,
@ -985,6 +999,14 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
out_streams));
block = std::move(block_);
}
#if ENABLE_FPGA
else if (implementation.compare("GPS_L1_CA_DLL_PLL_C_Aid_Tracking_Fpga") == 0)
{
std::unique_ptr<TrackingInterface> block_(new GpsL1CaDllPllCAidTrackingFpga(configuration.get(), role, in_streams,
out_streams));
block = std::move(block_);
}
#endif
else if (implementation.compare("GPS_L1_CA_TCP_CONNECTOR_Tracking") == 0)
{
std::unique_ptr<GNSSBlockInterface> block_(new GpsL1CaTcpConnectorTracking(configuration.get(), role, in_streams,
@ -1137,6 +1159,14 @@ std::unique_ptr<AcquisitionInterface> GNSSBlockFactory::GetAcqBlock(
out_streams));
block = std::move(block_);
}
#if ENABLE_FPGA
else if (implementation.compare("GPS_L1_CA_PCPS_Acquisition_Fpga") == 0)
{
std::unique_ptr<AcquisitionInterface> block_(new GpsL1CaPcpsAcquisitionFpga(configuration.get(), role, in_streams,
out_streams));
block = std::move(block_);
}
#endif
else if (implementation.compare("GPS_L1_CA_PCPS_Assisted_Acquisition") == 0)
{
std::unique_ptr<AcquisitionInterface> block_(new GpsL1CaPcpsAssistedAcquisition(configuration.get(), role, in_streams,
@ -1250,6 +1280,14 @@ std::unique_ptr<TrackingInterface> GNSSBlockFactory::GetTrkBlock(
out_streams));
block = std::move(block_);
}
#if ENABLE_FPGA
else if (implementation.compare("GPS_L1_CA_DLL_PLL_C_Aid_Tracking_Fpga") == 0)
{
std::unique_ptr<TrackingInterface> block_(new GpsL1CaDllPllCAidTrackingFpga(configuration.get(), role, in_streams,
out_streams));
block = std::move(block_);
}
#endif
else if (implementation.compare("GPS_L1_CA_TCP_CONNECTOR_Tracking") == 0)
{
std::unique_ptr<TrackingInterface> block_(new GpsL1CaTcpConnectorTracking(configuration.get(), role, in_streams,

View File

@ -70,20 +70,20 @@ GNSSFlowgraph::~GNSSFlowgraph()
void GNSSFlowgraph::start()
{
if (running_)
{
LOG(WARNING) << "Already running";
return;
}
{
LOG(WARNING) << "Already running";
return;
}
try
{
top_block_->start();
top_block_->start();
}
catch (std::exception& e)
{
LOG(WARNING) << "Unable to start flowgraph";
LOG(ERROR) << e.what();
return;
LOG(WARNING) << "Unable to start flowgraph";
LOG(ERROR) << e.what();
return;
}
running_ = true;
@ -111,226 +111,253 @@ void GNSSFlowgraph::connect()
*/
LOG(INFO) << "Connecting flowgraph";
if (connected_)
{
LOG(WARNING) << "flowgraph already connected";
return;
}
{
LOG(WARNING) << "flowgraph already connected";
return;
}
for (int i = 0; i < sources_count_; i++)
{
if (configuration_->property(sig_source_.at(i)->role() + ".enable_FPGA", false)==false)
{
try
{
sig_source_.at(i)->connect(top_block_);
sig_source_.at(i)->connect(top_block_);
}
catch (std::exception& e)
{
LOG(INFO) << "Can't connect signal source block " << i << " internally";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
LOG(INFO) << "Can't connect signal source block " << i << " internally";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
}
}else{
DLOG(INFO)<<"Disabled signal source "<<i<<" due to FPGA accelerator";
}
}
// Signal Source > Signal conditioner >
for (unsigned int i = 0; i < sig_conditioner_.size(); i++)
{
if (configuration_->property(sig_conditioner_.at(i)->role() + ".enable_FPGA", false)==false)
{
try
{
sig_conditioner_.at(i)->connect(top_block_);
sig_conditioner_.at(i)->connect(top_block_);
}
catch (std::exception& e)
{
LOG(INFO) << "Can't connect signal conditioner block " << i << " internally";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
LOG(INFO) << "Can't connect signal conditioner block " << i << " internally";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
}
}else{
DLOG(INFO)<<"Disabled signal conditioner "<<i<<" due to FPGA accelerator";
}
}
for (unsigned int i = 0; i < channels_count_; i++)
{
try
{
try
{
channels_.at(i)->connect(top_block_);
}
catch (std::exception& e)
{
LOG(WARNING) << "Can't connect channel " << i << " internally";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
}
channels_.at(i)->connect(top_block_);
}
try
{
observables_->connect(top_block_);
}
catch (std::exception& e)
{
LOG(WARNING) << "Can't connect observables block internally";
catch (std::exception& e)
{
LOG(WARNING) << "Can't connect channel " << i << " internally";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
}
}
try
{
observables_->connect(top_block_);
}
catch (std::exception& e)
{
LOG(WARNING) << "Can't connect observables block internally";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
}
// Signal Source > Signal conditioner >> Channels >> Observables > PVT
try
{
pvt_->connect(top_block_);
pvt_->connect(top_block_);
}
catch (std::exception& e)
{
LOG(WARNING) << "Can't connect PVT block internally";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
LOG(WARNING) << "Can't connect PVT block internally";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
}
DLOG(INFO) << "blocks connected internally";
// Signal Source (i) > Signal conditioner (i) >
int RF_Channels = 0;
int signal_conditioner_ID = 0;
for (int i = 0; i < sources_count_; i++)
{
//FPGA Accelerators do not need signal sources or conditioners
//as the samples are feed directly to the FPGA fabric, so, if enabled, do not connect any source
if (configuration_->property(sig_source_.at(i)->role() + ".enable_FPGA", false)==false)
{
try
{
//TODO: Remove this array implementation and create generic multistream connector
//(if a signal source has more than 1 stream, then connect it to the multistream signal conditioner)
if(sig_source_.at(i)->implementation().compare("Raw_Array_Signal_Source") == 0)
//TODO: Remove this array implementation and create generic multistream connector
//(if a signal source has more than 1 stream, then connect it to the multistream signal conditioner)
if(sig_source_.at(i)->implementation().compare("Raw_Array_Signal_Source") == 0)
{
//Multichannel Array
std::cout << "ARRAY MODE" << std::endl;
for (int j = 0; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS; j++)
{
std::cout << "connecting ch " << j << std::endl;
top_block_->connect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(i)->get_left_block(), j);
}
}
else
{
//TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
//Include GetRFChannels in the interface to avoid read config parameters here
//read the number of RF channels for each front-end
RF_Channels = configuration_->property(sig_source_.at(i)->role() + ".RF_channels", 1);
for (int j = 0; j < RF_Channels; j++)
{
//Connect the multichannel signal source to multiple signal conditioners
// GNURADIO max_streams=-1 means infinite ports!
LOG(INFO) << "sig_source_.at(i)->get_right_block()->output_signature()->max_streams()=" << sig_source_.at(i)->get_right_block()->output_signature()->max_streams();
LOG(INFO) << "sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()=" << sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()->max_streams();
if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1)
{
//Multichannel Array
std::cout << "ARRAY MODE" << std::endl;
for (int j = 0; j < GNSS_SDR_ARRAY_SIGNAL_CONDITIONER_CHANNELS; j++)
{
std::cout << "connecting ch " << j << std::endl;
top_block_->connect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(i)->get_left_block(), j);
}
LOG(INFO) << "connecting sig_source_ " << i << " stream " << j << " to conditioner " << j;
top_block_->connect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0);
}
else
else
{
//TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
//Include GetRFChannels in the interface to avoid read config parameters here
//read the number of RF channels for each front-end
RF_Channels = configuration_->property(sig_source_.at(i)->role() + ".RF_channels", 1);
for (int j = 0; j < RF_Channels; j++)
{
//Connect the multichannel signal source to multiple signal conditioners
// GNURADIO max_streams=-1 means infinite ports!
LOG(INFO) << "sig_source_.at(i)->get_right_block()->output_signature()->max_streams()=" << sig_source_.at(i)->get_right_block()->output_signature()->max_streams();
LOG(INFO) << "sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()=" << sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()->max_streams();
if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1)
{
LOG(INFO) << "connecting sig_source_ " << i << " stream " << j << " to conditioner " << j;
top_block_->connect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0);
}
else
{
if (j == 0)
{
// RF_channel 0 backward compatibility with single channel sources
LOG(INFO) << "connecting sig_source_ " << i << " stream " << 0 << " to conditioner " << j;
top_block_->connect(sig_source_.at(i)->get_right_block(), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0);
}
else
{
// Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call)
LOG(INFO) << "connecting sig_source_ " << i << " stream " << j << " to conditioner " << j;
top_block_->connect(sig_source_.at(i)->get_right_block(j), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0);
}
}
signal_conditioner_ID++;
}
if (j == 0)
{
// RF_channel 0 backward compatibility with single channel sources
LOG(INFO) << "connecting sig_source_ " << i << " stream " << 0 << " to conditioner " << j;
top_block_->connect(sig_source_.at(i)->get_right_block(), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0);
}
else
{
// Multiple channel sources using multiple output blocks of single channel (requires RF_channel selector in call)
LOG(INFO) << "connecting sig_source_ " << i << " stream " << j << " to conditioner " << j;
top_block_->connect(sig_source_.at(i)->get_right_block(j), 0, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0);
}
}
signal_conditioner_ID++;
}
}
}
catch (std::exception& e)
{
LOG(WARNING) << "Can't connect signal source " << i << " to signal conditioner " << i;
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
LOG(WARNING) << "Can't connect signal source " << i << " to signal conditioner " << i;
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
}
}else{
DLOG(INFO) << "Signal source "<<i<<"disabled by FPGA";
}
}
DLOG(INFO) << "Signal source connected to signal conditioner";
// Signal conditioner (selected_signal_source) >> channels (i) (dependent of their associated SignalSource_ID)
int selected_signal_conditioner_ID;
for (unsigned int i = 0; i < channels_count_; i++)
{
selected_signal_conditioner_ID = configuration_->property("Channel" + boost::lexical_cast<std::string>(i) + ".RF_channel_ID", 0);
//FPGA Accelerators do not need signal sources or conditioners
//as the samples are feed directly to the FPGA fabric, so, if enabled, do not connect any source
if (configuration_->property(sig_conditioner_.at(selected_signal_conditioner_ID)->role() + ".enable_FPGA", false)==false)
{
selected_signal_conditioner_ID = configuration_->property("Channel" + boost::lexical_cast<std::string>(i) + ".RF_channel_ID", 0);
try
{
top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
channels_.at(i)->get_left_block(), 0);
top_block_->connect(sig_conditioner_.at(selected_signal_conditioner_ID)->get_right_block(), 0,
channels_.at(i)->get_left_block(), 0);
}
catch (std::exception& e)
{
LOG(WARNING) << "Can't connect signal conditioner " << selected_signal_conditioner_ID << " to channel " << i;
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
LOG(WARNING) << "Can't connect signal conditioner " << selected_signal_conditioner_ID << " to channel " << i;
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
}
DLOG(INFO) << "signal conditioner " << selected_signal_conditioner_ID << " connected to channel " << i;
// Signal Source > Signal conditioner >> Channels >> Observables
try
{
top_block_->connect(channels_.at(i)->get_right_block(), 0,
observables_->get_left_block(), i);
}
catch (std::exception& e)
{
LOG(WARNING) << "Can't connect channel " << i << " to observables";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
}
std::string gnss_signal = channels_.at(i)->get_signal().get_signal_str(); // use channel's implicit signal!
while (gnss_signal.compare(available_GNSS_signals_.front().get_signal_str()) != 0 )
{
available_GNSS_signals_.push_back(available_GNSS_signals_.front());
available_GNSS_signals_.pop_front();
}
channels_.at(i)->set_signal(available_GNSS_signals_.front());
if (channels_state_[i] == 1)
{
channels_.at(i)->start_acquisition();
available_GNSS_signals_.pop_front();
LOG(INFO) << "Channel " << i << " assigned to " << available_GNSS_signals_.front();
LOG(INFO) << "Channel " << i << " connected to observables and ready for acquisition";
}
else
{
LOG(INFO) << "Channel " << i << " connected to observables in standby mode";
}
}else{
DLOG(INFO) << "signal conditioner disabled by FPGA in channel " << i;
}
// Signal Source > Signal conditioner >> Channels >> Observables
try
{
top_block_->connect(channels_.at(i)->get_right_block(), 0,
observables_->get_left_block(), i);
}
catch (std::exception& e)
{
LOG(WARNING) << "Can't connect channel " << i << " to observables";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
}
std::string gnss_signal = channels_.at(i)->get_signal().get_signal_str(); // use channel's implicit signal!
while (gnss_signal.compare(available_GNSS_signals_.front().get_signal_str()) != 0 )
{
available_GNSS_signals_.push_back(available_GNSS_signals_.front());
available_GNSS_signals_.pop_front();
}
channels_.at(i)->set_signal(available_GNSS_signals_.front());
if (channels_state_[i] == 1)
{
channels_.at(i)->start_acquisition();
available_GNSS_signals_.pop_front();
LOG(INFO) << "Channel " << i << " assigned to " << available_GNSS_signals_.front();
LOG(INFO) << "Channel " << i << " connected to observables and ready for acquisition";
}
else
{
LOG(INFO) << "Channel " << i << " connected to observables in standby mode";
}
}
/*
* Connect the observables output of each channel to the PVT block
*/
try
{
for (unsigned int i = 0; i < channels_count_; i++)
{
top_block_->connect(observables_->get_right_block(), i, pvt_->get_left_block(), i);
top_block_->msg_connect(channels_.at(i)->get_right_block(), pmt::mp("telemetry"), pvt_->get_left_block(), pmt::mp("telemetry"));
}
for (unsigned int i = 0; i < channels_count_; i++)
{
top_block_->connect(observables_->get_right_block(), i, pvt_->get_left_block(), i);
top_block_->msg_connect(channels_.at(i)->get_right_block(), pmt::mp("telemetry"), pvt_->get_left_block(), pmt::mp("telemetry"));
}
}
catch (std::exception& e)
{
LOG(WARNING) << "Can't connect observables to PVT";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
LOG(WARNING) << "Can't connect observables to PVT";
LOG(ERROR) << e.what();
top_block_->disconnect_all();
return;
}
connected_ = true;
@ -342,10 +369,10 @@ void GNSSFlowgraph::connect()
void GNSSFlowgraph::wait()
{
if (!running_)
{
LOG(WARNING) << "Can't apply wait. Flowgraph is not running";
return;
}
{
LOG(WARNING) << "Can't apply wait. Flowgraph is not running";
return;
}
top_block_->wait();
DLOG(INFO) << "Flowgraph finished calculations";
running_ = false;
@ -377,10 +404,10 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
available_GNSS_signals_.push_back(channels_.at(who)->get_signal());
//TODO: Optimize the channel and signal matching!
while ( channels_.at(who)->get_signal().get_signal_str().compare(available_GNSS_signals_.front().get_signal_str()) != 0 )
{
available_GNSS_signals_.push_back(available_GNSS_signals_.front());
available_GNSS_signals_.pop_front();
}
{
available_GNSS_signals_.push_back(available_GNSS_signals_.front());
available_GNSS_signals_.pop_front();
}
channels_.at(who)->set_signal(available_GNSS_signals_.front());
available_GNSS_signals_.pop_front();
usleep(100);
@ -391,42 +418,42 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
channels_state_[who] = 2;
acq_channels_count_--;
if (!available_GNSS_signals_.empty() && acq_channels_count_ < max_acq_channels_)
{
for (unsigned int i = 0; i < channels_count_; i++)
{
for (unsigned int i = 0; i < channels_count_; i++)
if (channels_state_[i] == 0)
{
channels_state_[i] = 1;
while (channels_.at(i)->get_signal().get_signal_str().compare(available_GNSS_signals_.front().get_signal_str()) != 0 )
{
if (channels_state_[i] == 0)
{
channels_state_[i] = 1;
while (channels_.at(i)->get_signal().get_signal_str().compare(available_GNSS_signals_.front().get_signal_str()) != 0 )
{
available_GNSS_signals_.push_back(available_GNSS_signals_.front());
available_GNSS_signals_.pop_front();
}
channels_.at(i)->set_signal(available_GNSS_signals_.front());
available_GNSS_signals_.pop_front();
acq_channels_count_++;
channels_.at(i)->start_acquisition();
break;
}
DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i];
available_GNSS_signals_.push_back(available_GNSS_signals_.front());
available_GNSS_signals_.pop_front();
}
channels_.at(i)->set_signal(available_GNSS_signals_.front());
available_GNSS_signals_.pop_front();
acq_channels_count_++;
channels_.at(i)->start_acquisition();
break;
}
DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i];
}
}
break;
case 2:
LOG(INFO) << "Channel " << who << " TRK FAILED satellite " << channels_.at(who)->get_signal().get_satellite();
if (acq_channels_count_ < max_acq_channels_)
{
channels_state_[who] = 1;
acq_channels_count_++;
channels_.at(who)->start_acquisition();
}
{
channels_state_[who] = 1;
acq_channels_count_++;
channels_.at(who)->start_acquisition();
}
else
{
channels_state_[who] = 0;
available_GNSS_signals_.push_back( channels_.at(who)->get_signal() );
}
{
channels_state_[who] = 0;
available_GNSS_signals_.push_back( channels_.at(who)->get_signal() );
}
// for (unsigned int i = 0; i < channels_count_; i++)
// {
@ -445,15 +472,15 @@ void GNSSFlowgraph::apply_action(unsigned int who, unsigned int what)
void GNSSFlowgraph::set_configuration(std::shared_ptr<ConfigurationInterface> configuration)
{
if (running_)
{
LOG(WARNING) << "Unable to update configuration while flowgraph running";
return;
}
{
LOG(WARNING) << "Unable to update configuration while flowgraph running";
return;
}
if (connected_)
{
LOG(WARNING) << "Unable to update configuration while flowgraph connected";
}
{
LOG(WARNING) << "Unable to update configuration while flowgraph connected";
}
configuration_ = configuration;
}
@ -473,45 +500,45 @@ void GNSSFlowgraph::init()
int signal_conditioner_ID = 0;
if (sources_count_ > 1)
{
for (int i = 0; i < sources_count_; i++)
{
for (int i = 0; i < sources_count_; i++)
{
std::cout << "Creating source " << i << std::endl;
sig_source_.push_back(block_factory_->GetSignalSource(configuration_, queue_, i));
//TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
//Include GetRFChannels in the interface to avoid read config parameters here
//read the number of RF channels for each front-end
RF_Channels = configuration_->property(sig_source_.at(i)->role() + ".RF_channels", 1);
std::cout << "RF Channels " << RF_Channels << std::endl;
for (int j = 0; j < RF_Channels; j++)
{
sig_conditioner_.push_back(block_factory_->GetSignalConditioner(configuration_, signal_conditioner_ID));
signal_conditioner_ID++;
}
}
}
else
{
//backwards compatibility for old config files
sig_source_.push_back(block_factory_->GetSignalSource(configuration_, queue_, -1));
std::cout << "Creating source " << i << std::endl;
sig_source_.push_back(block_factory_->GetSignalSource(configuration_, queue_, i));
//TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
//Include GetRFChannels in the interface to avoid read config parameters here
//read the number of RF channels for each front-end
RF_Channels = configuration_->property(sig_source_.at(0)->role() + ".RF_channels", 0);
if (RF_Channels != 0)
{
for (int j = 0; j < RF_Channels; j++)
{
sig_conditioner_.push_back(block_factory_->GetSignalConditioner(configuration_, signal_conditioner_ID));
signal_conditioner_ID++;
}
}
else
{
//old config file, single signal source and single channel, not specified
sig_conditioner_.push_back(block_factory_->GetSignalConditioner(configuration_, -1));
}
RF_Channels = configuration_->property(sig_source_.at(i)->role() + ".RF_channels", 1);
std::cout << "RF Channels " << RF_Channels << std::endl;
for (int j = 0; j < RF_Channels; j++)
{
sig_conditioner_.push_back(block_factory_->GetSignalConditioner(configuration_, signal_conditioner_ID));
signal_conditioner_ID++;
}
}
}
else
{
//backwards compatibility for old config files
sig_source_.push_back(block_factory_->GetSignalSource(configuration_, queue_, -1));
//TODO: Create a class interface for SignalSources, derived from GNSSBlockInterface.
//Include GetRFChannels in the interface to avoid read config parameters here
//read the number of RF channels for each front-end
RF_Channels = configuration_->property(sig_source_.at(0)->role() + ".RF_channels", 0);
if (RF_Channels != 0)
{
for (int j = 0; j < RF_Channels; j++)
{
sig_conditioner_.push_back(block_factory_->GetSignalConditioner(configuration_, signal_conditioner_ID));
signal_conditioner_ID++;
}
}
else
{
//old config file, single signal source and single channel, not specified
sig_conditioner_.push_back(block_factory_->GetSignalConditioner(configuration_, -1));
}
}
observables_ = block_factory_->GetObservables(configuration_);
pvt_ = block_factory_->GetPVT(configuration_);
@ -521,10 +548,10 @@ void GNSSFlowgraph::init()
//todo:check smart pointer coherence...
channels_count_ = channels->size();
for (unsigned int i = 0; i < channels_count_; i++)
{
std::shared_ptr<GNSSBlockInterface> chan_ = std::move(channels->at(i));
channels_.push_back(std::dynamic_pointer_cast<ChannelInterface>(chan_));
}
{
std::shared_ptr<GNSSBlockInterface> chan_ = std::move(channels->at(i));
channels_.push_back(std::dynamic_pointer_cast<ChannelInterface>(chan_));
}
top_block_ = gr::make_top_block("GNSSFlowgraph");
@ -564,133 +591,133 @@ void GNSSFlowgraph::set_signals_list()
*/
std::set<unsigned int> available_gps_prn = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32 };
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32 };
std::set<unsigned int> available_sbas_prn = {120, 124, 126};
std::set<unsigned int> available_galileo_prn = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36};
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36};
std::string sv_list = configuration_->property("Galileo.prns", std::string("") );
if( sv_list.length() > 0 )
{
// Reset the available prns:
std::set< unsigned int > tmp_set;
boost::tokenizer<> tok( sv_list );
std::transform( tok.begin(), tok.end(), std::inserter( tmp_set, tmp_set.begin() ),
boost::lexical_cast<unsigned int, std::string> );
{
// Reset the available prns:
std::set< unsigned int > tmp_set;
boost::tokenizer<> tok( sv_list );
std::transform( tok.begin(), tok.end(), std::inserter( tmp_set, tmp_set.begin() ),
boost::lexical_cast<unsigned int, std::string> );
if( tmp_set.size() > 0 )
{
available_galileo_prn = tmp_set;
}
if( tmp_set.size() > 0 )
{
available_galileo_prn = tmp_set;
}
}
sv_list = configuration_->property("GPS.prns", std::string("") );
if( sv_list.length() > 0 )
{
// Reset the available prns:
std::set< unsigned int > tmp_set;
boost::tokenizer<> tok( sv_list );
std::transform( tok.begin(), tok.end(), std::inserter( tmp_set, tmp_set.begin() ),
boost::lexical_cast<unsigned int, std::string> );
{
// Reset the available prns:
std::set< unsigned int > tmp_set;
boost::tokenizer<> tok( sv_list );
std::transform( tok.begin(), tok.end(), std::inserter( tmp_set, tmp_set.begin() ),
boost::lexical_cast<unsigned int, std::string> );
if( tmp_set.size() > 0 )
{
available_gps_prn = tmp_set;
}
if( tmp_set.size() > 0 )
{
available_gps_prn = tmp_set;
}
}
sv_list = configuration_->property("SBAS.prns", std::string("") );
if( sv_list.length() > 0 )
{
// Reset the available prns:
std::set< unsigned int > tmp_set;
boost::tokenizer<> tok( sv_list );
std::transform( tok.begin(), tok.end(), std::inserter( tmp_set, tmp_set.begin() ),
boost::lexical_cast<unsigned int, std::string> );
{
// Reset the available prns:
std::set< unsigned int > tmp_set;
boost::tokenizer<> tok( sv_list );
std::transform( tok.begin(), tok.end(), std::inserter( tmp_set, tmp_set.begin() ),
boost::lexical_cast<unsigned int, std::string> );
if( tmp_set.size() > 0 )
{
available_sbas_prn = tmp_set;
}
if( tmp_set.size() > 0 )
{
available_sbas_prn = tmp_set;
}
}
if (configuration_->property("Channels_1C.count", 0) > 0 )
{
/*
* Loop to create GPS L1 C/A signals
*/
for (available_gnss_prn_iter = available_gps_prn.begin();
available_gnss_prn_iter != available_gps_prn.end();
available_gnss_prn_iter++)
{
/*
* Loop to create GPS L1 C/A signals
*/
for (available_gnss_prn_iter = available_gps_prn.begin();
available_gnss_prn_iter != available_gps_prn.end();
available_gnss_prn_iter++)
{
available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("GPS"),
*available_gnss_prn_iter), std::string("1C")));
}
available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("GPS"),
*available_gnss_prn_iter), std::string("1C")));
}
}
if (configuration_->property("Channels_2S.count", 0) > 0)
{
/*
* Loop to create GPS L2C M signals
*/
for (available_gnss_prn_iter = available_gps_prn.begin();
available_gnss_prn_iter != available_gps_prn.end();
available_gnss_prn_iter++)
{
/*
* Loop to create GPS L2C M signals
*/
for (available_gnss_prn_iter = available_gps_prn.begin();
available_gnss_prn_iter != available_gps_prn.end();
available_gnss_prn_iter++)
{
available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("GPS"),
*available_gnss_prn_iter), std::string("2S")));
}
available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("GPS"),
*available_gnss_prn_iter), std::string("2S")));
}
}
if (configuration_->property("Channels_SBAS.count", 0) > 0)
{
/*
* Loop to create SBAS L1 C/A signals
*/
for (available_gnss_prn_iter = available_sbas_prn.begin();
available_gnss_prn_iter != available_sbas_prn.end();
available_gnss_prn_iter++)
{
/*
* Loop to create SBAS L1 C/A signals
*/
for (available_gnss_prn_iter = available_sbas_prn.begin();
available_gnss_prn_iter != available_sbas_prn.end();
available_gnss_prn_iter++)
{
available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("SBAS"),
*available_gnss_prn_iter), std::string("1C")));
}
available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("SBAS"),
*available_gnss_prn_iter), std::string("1C")));
}
}
if (configuration_->property("Channels_1B.count", 0) > 0)
{
/*
* Loop to create the list of Galileo E1 B signals
*/
for (available_gnss_prn_iter = available_galileo_prn.begin();
available_gnss_prn_iter != available_galileo_prn.end();
available_gnss_prn_iter++)
{
/*
* Loop to create the list of Galileo E1 B signals
*/
for (available_gnss_prn_iter = available_galileo_prn.begin();
available_gnss_prn_iter != available_galileo_prn.end();
available_gnss_prn_iter++)
{
available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("Galileo"),
*available_gnss_prn_iter), std::string("1B")));
}
available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("Galileo"),
*available_gnss_prn_iter), std::string("1B")));
}
}
if (configuration_->property("Channels_5X.count", 0) > 0 )
{
/*
* Loop to create the list of Galileo E1 B signals
*/
for (available_gnss_prn_iter = available_galileo_prn.begin();
available_gnss_prn_iter != available_galileo_prn.end();
available_gnss_prn_iter++)
{
/*
* Loop to create the list of Galileo E1 B signals
*/
for (available_gnss_prn_iter = available_galileo_prn.begin();
available_gnss_prn_iter != available_galileo_prn.end();
available_gnss_prn_iter++)
{
available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("Galileo"),
*available_gnss_prn_iter), std::string("5X")));
}
available_GNSS_signals_.push_back(Gnss_Signal(Gnss_Satellite(std::string("Galileo"),
*available_gnss_prn_iter), std::string("5X")));
}
}
/*
* Ordering the list of signals from configuration file
*/
@ -699,24 +726,24 @@ void GNSSFlowgraph::set_signals_list()
// Pre-assignation if not defined at ChannelX.signal=1C ...? In what order?
for (unsigned int i = 0; i < total_channels; i++)
{
std::string gnss_signal = (configuration_->property("Channel" + boost::lexical_cast<std::string>(i) + ".signal", std::string("1C")));
std::string gnss_system;
if((gnss_signal.compare("1C") == 0) or (gnss_signal.compare("2S") == 0) ) gnss_system = "GPS";
if((gnss_signal.compare("1B") == 0) or (gnss_signal.compare("5X") == 0) ) gnss_system = "Galileo";
unsigned int sat = configuration_->property("Channel" + boost::lexical_cast<std::string>(i) + ".satellite", 0);
LOG(INFO) << "Channel " << i << " system " << gnss_system << ", signal " << gnss_signal <<", sat "<<sat;
if (sat == 0) // 0 = not PRN in configuration file
{
std::string gnss_signal = (configuration_->property("Channel" + boost::lexical_cast<std::string>(i) + ".signal", std::string("1C")));
std::string gnss_system;
if((gnss_signal.compare("1C") == 0) or (gnss_signal.compare("2S") == 0) ) gnss_system = "GPS";
if((gnss_signal.compare("1B") == 0) or (gnss_signal.compare("5X") == 0) ) gnss_system = "Galileo";
unsigned int sat = configuration_->property("Channel" + boost::lexical_cast<std::string>(i) + ".satellite", 0);
LOG(INFO) << "Channel " << i << " system " << gnss_system << ", signal " << gnss_signal <<", sat "<<sat;
if (sat == 0) // 0 = not PRN in configuration file
{
gnss_it++;
}
else
{
Gnss_Signal signal_value = Gnss_Signal(Gnss_Satellite(gnss_system, sat), gnss_signal);
available_GNSS_signals_.remove(signal_value);
available_GNSS_signals_.insert(gnss_it, signal_value);
}
gnss_it++;
}
else
{
Gnss_Signal signal_value = Gnss_Signal(Gnss_Satellite(gnss_system, sat), gnss_signal);
available_GNSS_signals_.remove(signal_value);
available_GNSS_signals_.insert(gnss_it, signal_value);
}
}
// **** FOR DEBUGGING THE LIST OF GNSS SIGNALS ****
// std::list<Gnss_Signal>::iterator available_gnss_list_iter;
@ -732,21 +759,21 @@ void GNSSFlowgraph::set_channels_state()
{
max_acq_channels_ = (configuration_->property("Channels.in_acquisition", channels_count_));
if (max_acq_channels_ > channels_count_)
{
max_acq_channels_ = channels_count_;
LOG(WARNING) << "Channels_in_acquisition is bigger than number of channels. Variable acq_channels_count_ is set to " << channels_count_;
}
{
max_acq_channels_ = channels_count_;
LOG(WARNING) << "Channels_in_acquisition is bigger than number of channels. Variable acq_channels_count_ is set to " << channels_count_;
}
channels_state_.reserve(channels_count_);
for (unsigned int i = 0; i < channels_count_; i++)
{
if (i < max_acq_channels_)
{
if (i < max_acq_channels_)
{
channels_state_.push_back(1);
}
else
channels_state_.push_back(0);
DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i];
channels_state_.push_back(1);
}
else
channels_state_.push_back(0);
DLOG(INFO) << "Channel " << i << " in state " << channels_state_[i];
}
acq_channels_count_ = max_acq_channels_;
DLOG(INFO) << acq_channels_count_ << " channels in acquisition state";
}