mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-14 20:20:35 +00:00
Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into next
This commit is contained in:
commit
3cb2874522
@ -702,14 +702,25 @@ if(NOT ${FILESYSTEM_FOUND})
|
||||
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} filesystem)
|
||||
endif()
|
||||
find_package(Boost ${GNSSSDR_BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
|
||||
|
||||
if(NOT Boost_FOUND)
|
||||
message(FATAL_ERROR "Fatal error: Boost (version >=${GNSSSDR_BOOST_MIN_VERSION}) required.")
|
||||
endif()
|
||||
|
||||
set_package_properties(Boost PROPERTIES
|
||||
URL "https://www.boost.org"
|
||||
DESCRIPTION "Portable C++ source libraries"
|
||||
PURPOSE "Used widely across the source code."
|
||||
TYPE REQUIRED
|
||||
)
|
||||
if(NOT Boost_FOUND)
|
||||
message(FATAL_ERROR "Fatal error: Boost (version >=${GNSSSDR_BOOST_MIN_VERSION}) required.")
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.14)
|
||||
set_package_properties(Boost PROPERTIES
|
||||
DESCRIPTION "Portable C++ source libraries (found: ${Boost_VERSION_STRING})"
|
||||
)
|
||||
else()
|
||||
set_package_properties(Boost PROPERTIES
|
||||
DESCRIPTION "Portable C++ source libraries (found: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION})"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.5)
|
||||
@ -1669,6 +1680,10 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS
|
||||
set_package_properties(MATIO PROPERTIES
|
||||
PURPOSE "Matio v${GNSSSDR_MATIO_LOCAL_VERSION} will be downloaded and built when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'."
|
||||
)
|
||||
else()
|
||||
set_package_properties(MATIO PROPERTIES
|
||||
DESCRIPTION "MATLAB MAT File I/O Library (found: v.${MATIO_VERSION_STRING})"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@ -1796,6 +1811,13 @@ if(Protobuf_FOUND AND CMAKE_VERSION VERSION_LESS 3.9)
|
||||
set(Protobuf_VERSION "${_PROTOBUF_MAJOR_VERSION}.${_PROTOBUF_MINOR_VERSION}.${_PROTOBUF_SUBMINOR_VERSION}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Protobuf_FOUND)
|
||||
set_package_properties(Protobuf PROPERTIES
|
||||
DESCRIPTION "Structured data serialization mechanism (found: v${Protobuf_VERSION})"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(Protobuf_FOUND AND CMAKE_CROSSCOMPILING)
|
||||
find_program(PROTOC_EXECUTABLE protoc)
|
||||
if(NOT PROTOC_EXECUTABLE)
|
||||
@ -1815,6 +1837,7 @@ if(Protobuf_FOUND AND CMAKE_CROSSCOMPILING)
|
||||
message(FATAL_ERROR "Please install the Protocol Buffers compiler v${Protobuf_VERSION} in the host machine")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if((NOT Protobuf_FOUND) OR (NOT Protobuf_PROTOC_EXECUTABLE) OR (${Protobuf_VERSION} VERSION_LESS ${GNSSSDR_PROTOBUF_MIN_VERSION}))
|
||||
unset(Protobuf_PROTOC_EXECUTABLE)
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
|
@ -85,7 +85,6 @@ find_library(LOG4CPP_LIBRARY
|
||||
/usr/lib/alpha-linux-gnu
|
||||
/usr/lib64
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
${LOG4CPP_ROOT}/lib
|
||||
$ENV{LOG4CPP_ROOT}/lib
|
||||
|
@ -64,8 +64,9 @@
|
||||
- The receiver now admits FPGA off-loading, allowing for real time operation at high sampling rates and higher number of signals and channels.
|
||||
- Fixed program termination (avoiding hangs and segfaults in some platforms/configurations).
|
||||
- The Labsat_Signal_Source now terminates the receiver's execution when the end of file(s) is reached. It now accepts LabSat 2 filenames and series of LabSat 3 files.
|
||||
- CMake now generates a summary of enabled/disabled features. This info is also stored in a file called features.log in the building directory.
|
||||
- Added configuration parameters to set the annotation rate in KML, GPX, GeoJSON and NMEA outputs, set by default to 1 s.
|
||||
- New parameter PVT.show_local_time_zone displays time in the local time zone. Subject to the proper system configuration of the machine running the software receiver.
|
||||
- CMake now generates a summary of enabled/disabled features. This info is also stored in a file called features.log in the building directory.
|
||||
- Improved information provided to the user in case of failure.
|
||||
|
||||
|
||||
|
@ -138,6 +138,11 @@ Rtklib_Pvt::Rtklib_Pvt(ConfigurationInterface* configuration,
|
||||
pvt_output_parameters.rtcm_msg_rate_ms[k] = rtcm_MT1097_rate_ms;
|
||||
}
|
||||
|
||||
pvt_output_parameters.kml_rate_ms = bc::lcm(configuration->property(role + ".kml_rate_ms", pvt_output_parameters.kml_rate_ms), pvt_output_parameters.output_rate_ms);
|
||||
pvt_output_parameters.gpx_rate_ms = bc::lcm(configuration->property(role + ".gpx_rate_ms", pvt_output_parameters.gpx_rate_ms), pvt_output_parameters.output_rate_ms);
|
||||
pvt_output_parameters.geojson_rate_ms = bc::lcm(configuration->property(role + ".geojson_rate_ms", pvt_output_parameters.geojson_rate_ms), pvt_output_parameters.output_rate_ms);
|
||||
pvt_output_parameters.nmea_rate_ms = bc::lcm(configuration->property(role + ".nmea_rate_ms", pvt_output_parameters.nmea_rate_ms), pvt_output_parameters.output_rate_ms);
|
||||
|
||||
// Infer the type of receiver
|
||||
/*
|
||||
* TYPE | RECEIVER
|
||||
|
@ -178,6 +178,11 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
|
||||
std::string kml_dump_filename;
|
||||
kml_dump_filename = d_dump_filename;
|
||||
d_kml_output_enabled = conf_.kml_output_enabled;
|
||||
d_kml_rate_ms = conf_.kml_rate_ms;
|
||||
if (d_kml_rate_ms == 0)
|
||||
{
|
||||
d_kml_output_enabled = false;
|
||||
}
|
||||
if (d_kml_output_enabled)
|
||||
{
|
||||
d_kml_dump = std::make_shared<Kml_Printer>(conf_.kml_output_path);
|
||||
@ -192,6 +197,11 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
|
||||
std::string gpx_dump_filename;
|
||||
gpx_dump_filename = d_dump_filename;
|
||||
d_gpx_output_enabled = conf_.gpx_output_enabled;
|
||||
d_gpx_rate_ms = conf_.gpx_rate_ms;
|
||||
if (d_gpx_rate_ms == 0)
|
||||
{
|
||||
d_gpx_output_enabled = false;
|
||||
}
|
||||
if (d_gpx_output_enabled)
|
||||
{
|
||||
d_gpx_dump = std::make_shared<Gpx_Printer>(conf_.gpx_output_path);
|
||||
@ -206,6 +216,11 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
|
||||
std::string geojson_dump_filename;
|
||||
geojson_dump_filename = d_dump_filename;
|
||||
d_geojson_output_enabled = conf_.geojson_output_enabled;
|
||||
d_geojson_rate_ms = conf_.geojson_rate_ms;
|
||||
if (d_geojson_rate_ms == 0)
|
||||
{
|
||||
d_geojson_output_enabled = false;
|
||||
}
|
||||
if (d_geojson_output_enabled)
|
||||
{
|
||||
d_geojson_printer = std::make_shared<GeoJSON_Printer>(conf_.geojson_output_path);
|
||||
@ -218,6 +233,12 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
|
||||
|
||||
// initialize nmea_printer
|
||||
d_nmea_output_file_enabled = (conf_.nmea_output_file_enabled or conf_.flag_nmea_tty_port);
|
||||
d_nmea_rate_ms = conf_.nmea_rate_ms;
|
||||
if (d_nmea_rate_ms == 0)
|
||||
{
|
||||
d_nmea_output_file_enabled = false;
|
||||
}
|
||||
|
||||
if (d_nmea_output_file_enabled)
|
||||
{
|
||||
d_nmea_printer = std::make_shared<Nmea_Printer>(conf_.nmea_dump_filename, conf_.nmea_output_file_enabled, conf_.flag_nmea_tty_port, conf_.nmea_dump_devname, conf_.nmea_output_file_path);
|
||||
@ -1798,21 +1819,33 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
|
||||
first_fix = false;
|
||||
}
|
||||
if (d_kml_output_enabled)
|
||||
{
|
||||
if (current_RX_time_ms % d_kml_rate_ms == 0)
|
||||
{
|
||||
d_kml_dump->print_position(d_pvt_solver, false);
|
||||
}
|
||||
}
|
||||
if (d_gpx_output_enabled)
|
||||
{
|
||||
if (current_RX_time_ms % d_gpx_rate_ms == 0)
|
||||
{
|
||||
d_gpx_dump->print_position(d_pvt_solver, false);
|
||||
}
|
||||
}
|
||||
if (d_geojson_output_enabled)
|
||||
{
|
||||
if (current_RX_time_ms % d_geojson_rate_ms == 0)
|
||||
{
|
||||
d_geojson_printer->print_position(d_pvt_solver, false);
|
||||
}
|
||||
}
|
||||
if (d_nmea_output_file_enabled)
|
||||
{
|
||||
if (current_RX_time_ms % d_nmea_rate_ms == 0)
|
||||
{
|
||||
d_nmea_printer->Print_Nmea_Line(d_pvt_solver, false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TYPE | RECEIVER
|
||||
|
@ -106,6 +106,11 @@ private:
|
||||
int32_t d_rtcm_MT1097_rate_ms; // Galileo MSM7. The type 7 Multiple Signal Message format for Europe’s Galileo system
|
||||
int32_t d_rtcm_MSM_rate_ms;
|
||||
|
||||
int32_t d_kml_rate_ms;
|
||||
int32_t d_gpx_rate_ms;
|
||||
int32_t d_geojson_rate_ms;
|
||||
int32_t d_nmea_rate_ms;
|
||||
|
||||
int32_t d_last_status_print_seg; // for status printer
|
||||
|
||||
uint32_t d_nchannels;
|
||||
|
@ -35,6 +35,10 @@ Pvt_Conf::Pvt_Conf()
|
||||
type_of_receiver = 0U;
|
||||
output_rate_ms = 0;
|
||||
display_rate_ms = 0;
|
||||
kml_rate_ms = 1000;
|
||||
gpx_rate_ms = 1000;
|
||||
geojson_rate_ms = 1000;
|
||||
nmea_rate_ms = 1000;
|
||||
|
||||
rinex_version = 0;
|
||||
rinexobs_rate_ms = 0;
|
||||
|
@ -41,6 +41,10 @@ public:
|
||||
uint32_t type_of_receiver;
|
||||
int32_t output_rate_ms;
|
||||
int32_t display_rate_ms;
|
||||
int32_t kml_rate_ms;
|
||||
int32_t gpx_rate_ms;
|
||||
int32_t geojson_rate_ms;
|
||||
int32_t nmea_rate_ms;
|
||||
|
||||
int32_t rinex_version;
|
||||
int32_t rinexobs_rate_ms;
|
||||
|
@ -129,6 +129,7 @@ endif()
|
||||
|
||||
set(SIGNAL_SOURCE_ADAPTER_SOURCES
|
||||
file_signal_source.cc
|
||||
multichannel_file_signal_source.cc
|
||||
gen_signal_source.cc
|
||||
nsr_file_signal_source.cc
|
||||
spir_file_signal_source.cc
|
||||
@ -142,6 +143,7 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES
|
||||
|
||||
set(SIGNAL_SOURCE_ADAPTER_HEADERS
|
||||
file_signal_source.h
|
||||
multichannel_file_signal_source.h
|
||||
gen_signal_source.h
|
||||
nsr_file_signal_source.h
|
||||
spir_file_signal_source.h
|
||||
|
@ -0,0 +1,311 @@
|
||||
/*!
|
||||
* \file multichannel_file_signal_source.cc
|
||||
* \brief Implementation of a class that reads signals samples from files at
|
||||
* different frequency band and adapts it to a SignalSourceInterface
|
||||
* \author Javier Arribas, 2019 jarribas(at)cttc.es
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
*
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GNSS-SDR is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "multichannel_file_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "gnss_sdr_flags.h"
|
||||
#include "gnss_sdr_valve.h"
|
||||
#include <glog/logging.h>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream> // for std::cerr
|
||||
#include <utility>
|
||||
|
||||
|
||||
MultichannelFileSignalSource::MultichannelFileSignalSource(ConfigurationInterface* configuration,
|
||||
const std::string& role, unsigned int in_streams, unsigned int out_streams,
|
||||
boost::shared_ptr<gr::msg_queue> queue) : role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(std::move(queue))
|
||||
{
|
||||
std::string default_filename = "./example_capture.dat";
|
||||
std::string default_item_type = "short";
|
||||
std::string default_dump_filename = "./my_capture.dat";
|
||||
|
||||
double default_seconds_to_skip = 0.0;
|
||||
size_t header_size = 0;
|
||||
samples_ = configuration->property(role + ".samples", 0);
|
||||
sampling_frequency_ = configuration->property(role + ".sampling_frequency", 0);
|
||||
n_channels_ = configuration->property(role + ".total_channels", 1);
|
||||
|
||||
for (unsigned int n = 0; n < n_channels_; n++)
|
||||
{
|
||||
filename_vec_.push_back(configuration->property(role + ".filename" + std::to_string(n), default_filename));
|
||||
}
|
||||
|
||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||
repeat_ = configuration->property(role + ".repeat", false);
|
||||
enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false);
|
||||
|
||||
double seconds_to_skip = configuration->property(role + ".seconds_to_skip", default_seconds_to_skip);
|
||||
header_size = configuration->property(role + ".header_size", 0);
|
||||
int64_t samples_to_skip = 0;
|
||||
|
||||
bool is_complex = false;
|
||||
|
||||
if (item_type_ == "gr_complex")
|
||||
{
|
||||
item_size_ = sizeof(gr_complex);
|
||||
}
|
||||
else if (item_type_ == "float")
|
||||
{
|
||||
item_size_ = sizeof(float);
|
||||
}
|
||||
else if (item_type_ == "short")
|
||||
{
|
||||
item_size_ = sizeof(int16_t);
|
||||
}
|
||||
else if (item_type_ == "ishort")
|
||||
{
|
||||
item_size_ = sizeof(int16_t);
|
||||
is_complex = true;
|
||||
}
|
||||
else if (item_type_ == "byte")
|
||||
{
|
||||
item_size_ = sizeof(int8_t);
|
||||
}
|
||||
else if (item_type_ == "ibyte")
|
||||
{
|
||||
item_size_ = sizeof(int8_t);
|
||||
is_complex = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << item_type_
|
||||
<< " unrecognized item type. Using gr_complex.";
|
||||
item_size_ = sizeof(gr_complex);
|
||||
}
|
||||
try
|
||||
{
|
||||
for (unsigned int n = 0; n < n_channels_; n++)
|
||||
{
|
||||
file_source_vec_.push_back(gr::blocks::file_source::make(item_size_, filename_vec_.at(n).c_str(), repeat_));
|
||||
|
||||
if (seconds_to_skip > 0)
|
||||
{
|
||||
samples_to_skip = static_cast<int64_t>(seconds_to_skip * sampling_frequency_);
|
||||
|
||||
if (is_complex)
|
||||
{
|
||||
samples_to_skip *= 2;
|
||||
}
|
||||
}
|
||||
if (header_size > 0)
|
||||
{
|
||||
samples_to_skip += header_size;
|
||||
}
|
||||
|
||||
if (samples_to_skip > 0)
|
||||
{
|
||||
LOG(INFO) << "Skipping " << samples_to_skip << " samples of the input file #" << n;
|
||||
if (not file_source_vec_.back()->seek(samples_to_skip, SEEK_SET))
|
||||
{
|
||||
LOG(INFO) << "Error skipping bytes!";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
if (filename_vec_.at(0) == default_filename)
|
||||
{
|
||||
std::cerr
|
||||
<< "The configuration file has not been found."
|
||||
<< std::endl
|
||||
<< "Please create a configuration file based on the examples at the 'conf/' folder "
|
||||
<< std::endl
|
||||
<< "and then generate your own GNSS Software Defined Receiver by doing:"
|
||||
<< std::endl
|
||||
<< "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf"
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr
|
||||
<< "The receiver was configured to work with a file signal source "
|
||||
<< std::endl
|
||||
<< "but the specified file is unreachable by GNSS-SDR."
|
||||
<< std::endl
|
||||
<< "Please modify your configuration file"
|
||||
<< std::endl
|
||||
<< "and point SignalSource.filename to a valid raw data file. Then:"
|
||||
<< std::endl
|
||||
<< "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf"
|
||||
<< std::endl
|
||||
<< "Examples of configuration files available at:"
|
||||
<< std::endl
|
||||
<< GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
LOG(INFO) << "file_signal_source: Unable to open the samples file "
|
||||
<< filename_vec_.at(0).c_str() << ", exiting the program.";
|
||||
throw(e);
|
||||
}
|
||||
|
||||
//todo from here.... add mux demux also
|
||||
if (samples_ == 0) // read all file
|
||||
{
|
||||
/*!
|
||||
* BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File.
|
||||
* A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the
|
||||
* valve block
|
||||
*/
|
||||
std::ifstream file(filename_vec_.at(0).c_str(), std::ios::in | std::ios::binary | std::ios::ate);
|
||||
std::ifstream::pos_type size;
|
||||
|
||||
if (file.is_open())
|
||||
{
|
||||
size = file.tellg();
|
||||
DLOG(INFO) << "Total samples in the file= " << floor(static_cast<double>(size) / static_cast<double>(item_size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "file_signal_source: Unable to open the samples file " << filename_vec_.at(0).c_str() << std::endl;
|
||||
LOG(ERROR) << "file_signal_source: Unable to open the samples file " << filename_vec_.at(0).c_str();
|
||||
}
|
||||
std::streamsize ss = std::cout.precision();
|
||||
std::cout << std::setprecision(16);
|
||||
std::cout << "Processing file " << filename_vec_.at(0) << ", which contains " << static_cast<double>(size) << " [bytes]" << std::endl;
|
||||
std::cout.precision(ss);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
int64_t bytes_to_skip = samples_to_skip * item_size_;
|
||||
int64_t bytes_to_process = static_cast<int64_t>(size) - bytes_to_skip;
|
||||
samples_ = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size()) - ceil(0.002 * static_cast<double>(sampling_frequency_))); // process all the samples available in the file excluding at least the last 1 ms
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(samples_ > 0) << "File does not contain enough samples to process.";
|
||||
double signal_duration_s;
|
||||
signal_duration_s = static_cast<double>(samples_) * (1 / static_cast<double>(sampling_frequency_));
|
||||
|
||||
if (is_complex)
|
||||
{
|
||||
signal_duration_s /= 2.0;
|
||||
}
|
||||
|
||||
DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
|
||||
std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]" << std::endl;
|
||||
|
||||
valve_ = gnss_sdr_make_valve(item_size_, samples_ * n_channels_, queue_);
|
||||
DLOG(INFO) << "valve(" << valve_->unique_id() << ")";
|
||||
|
||||
if (enable_throttle_control_)
|
||||
{
|
||||
for (unsigned int n = 0; n < n_channels_; n++)
|
||||
{
|
||||
throttle_vec_.push_back(gr::blocks::throttle::make(item_size_, sampling_frequency_));
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int n = 0; n < n_channels_; n++)
|
||||
{
|
||||
LOG(INFO) << "Multichanne File source filename #" << n << filename_vec_.at(n);
|
||||
}
|
||||
|
||||
DLOG(INFO) << "Samples " << samples_;
|
||||
DLOG(INFO) << "Sampling frequency " << sampling_frequency_;
|
||||
DLOG(INFO) << "Item type " << item_type_;
|
||||
DLOG(INFO) << "Item size " << item_size_;
|
||||
DLOG(INFO) << "Repeat " << repeat_;
|
||||
|
||||
if (in_streams_ > 0)
|
||||
{
|
||||
LOG(ERROR) << "A signal source does not have an input stream";
|
||||
}
|
||||
if (out_streams_ > 1)
|
||||
{
|
||||
LOG(ERROR) << "This implementation only supports one output stream";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MultichannelFileSignalSource::~MultichannelFileSignalSource() = default;
|
||||
|
||||
|
||||
void MultichannelFileSignalSource::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
for (unsigned int n = 0; n < n_channels_; n++)
|
||||
{
|
||||
top_block->connect(file_source_vec_.at(n), 0, throttle_vec_.at(n), 0);
|
||||
DLOG(INFO) << "connected file_source #" << n << " to throttle";
|
||||
top_block->connect(throttle_vec_.at(n), 0, valve_, n);
|
||||
DLOG(INFO) << "connected throttle #" << n << " to valve_";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int n = 0; n < n_channels_; n++)
|
||||
{
|
||||
top_block->connect(file_source_vec_.at(n), 0, valve_, n);
|
||||
DLOG(INFO) << "connected file_source #" << n << " to valve_";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MultichannelFileSignalSource::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
if (enable_throttle_control_ == true)
|
||||
{
|
||||
for (unsigned int n = 0; n < n_channels_; n++)
|
||||
{
|
||||
top_block->disconnect(file_source_vec_.at(n), 0, throttle_vec_.at(n), 0);
|
||||
DLOG(INFO) << "disconnected file_source #" << n << " to throttle";
|
||||
top_block->disconnect(throttle_vec_.at(n), 0, valve_, n);
|
||||
DLOG(INFO) << "disconnected throttle #" << n << " to valve_";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int n = 0; n < n_channels_; n++)
|
||||
{
|
||||
top_block->disconnect(file_source_vec_.at(n), 0, valve_, n);
|
||||
DLOG(INFO) << "disconnected file_source #" << n << " to valve_";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr MultichannelFileSignalSource::get_left_block()
|
||||
{
|
||||
LOG(WARNING) << "Left block of a signal source should not be retrieved";
|
||||
return gr::blocks::file_source::sptr();
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr MultichannelFileSignalSource::get_right_block()
|
||||
{
|
||||
return valve_;
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
/*!
|
||||
* \file multichannel_file_signal_source.h
|
||||
* \brief Implementation of a class that reads signals samples from files at
|
||||
* different frequency band and adapts it to a SignalSourceInterface
|
||||
* \author Javier Arribas, 2019 jarribas(at)cttc.es
|
||||
*
|
||||
* This class represents a file signal source. Internally it uses a GNU Radio's
|
||||
* gr_file_source as a connector to the data.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
*
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* GNSS-SDR is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GNSS-SDR is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_MULTICHANNEL_FILE_SIGNAL_SOURCE_H_
|
||||
#define GNSS_SDR_MULTICHANNEL_FILE_SIGNAL_SOURCE_H_
|
||||
|
||||
#include "gnss_block_interface.h"
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief Class that reads signals samples from files at different frequency bands
|
||||
* and adapts it to a SignalSourceInterface
|
||||
*/
|
||||
class MultichannelFileSignalSource : public GNSSBlockInterface
|
||||
{
|
||||
public:
|
||||
MultichannelFileSignalSource(ConfigurationInterface* configuration, const std::string& role,
|
||||
unsigned int in_streams, unsigned int out_streams,
|
||||
boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
virtual ~MultichannelFileSignalSource();
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "Multichannel_File_Signal_Source".
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "Multichannel_File_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
void connect(gr::top_block_sptr top_block) override;
|
||||
void disconnect(gr::top_block_sptr top_block) override;
|
||||
gr::basic_block_sptr get_left_block() override;
|
||||
gr::basic_block_sptr get_right_block() override;
|
||||
|
||||
inline std::string filename() const
|
||||
{
|
||||
return filename_vec_.at(0);
|
||||
}
|
||||
|
||||
inline std::string item_type() const
|
||||
{
|
||||
return item_type_;
|
||||
}
|
||||
|
||||
inline bool repeat() const
|
||||
{
|
||||
return repeat_;
|
||||
}
|
||||
|
||||
inline int64_t sampling_frequency() const
|
||||
{
|
||||
return sampling_frequency_;
|
||||
}
|
||||
|
||||
inline uint64_t samples() const
|
||||
{
|
||||
return samples_;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t samples_;
|
||||
int64_t sampling_frequency_;
|
||||
uint32_t n_channels_;
|
||||
std::vector<std::string> filename_vec_;
|
||||
std::string item_type_;
|
||||
bool repeat_;
|
||||
std::string role_;
|
||||
uint32_t in_streams_;
|
||||
uint32_t out_streams_;
|
||||
std::vector<gr::blocks::file_source::sptr> file_source_vec_;
|
||||
boost::shared_ptr<gr::block> valve_;
|
||||
gr::blocks::file_sink::sptr sink_;
|
||||
std::vector<gr::blocks::throttle::sptr> throttle_vec_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
size_t item_size_;
|
||||
// Throttle control
|
||||
bool enable_throttle_control_;
|
||||
};
|
||||
|
||||
#endif /* GNSS_SDR_MULTICHANNEL_FILE_SIGNAL_SOURCE_H_ */
|
@ -44,8 +44,8 @@ Gnss_Sdr_Valve::Gnss_Sdr_Valve(size_t sizeof_stream_item,
|
||||
uint64_t nitems,
|
||||
gr::msg_queue::sptr queue,
|
||||
bool stop_flowgraph) : gr::sync_block("valve",
|
||||
gr::io_signature::make(1, 1, sizeof_stream_item),
|
||||
gr::io_signature::make(1, 1, sizeof_stream_item)),
|
||||
gr::io_signature::make(1, 20, sizeof_stream_item),
|
||||
gr::io_signature::make(1, 20, sizeof_stream_item)),
|
||||
d_nitems(nitems),
|
||||
d_ncopied_items(0),
|
||||
d_queue(std::move(queue)),
|
||||
@ -99,11 +99,17 @@ int Gnss_Sdr_Valve::work(int noutput_items,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
memcpy(output_items[0], input_items[0], n * input_signature()->sizeof_stream_item(0));
|
||||
//multichannel support
|
||||
for (int ch = 0; ch < output_items.size(); ch++)
|
||||
{
|
||||
memcpy(output_items[ch], input_items[ch], n * input_signature()->sizeof_stream_item(ch));
|
||||
}
|
||||
d_ncopied_items += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
memcpy(output_items[0], input_items[0], noutput_items * input_signature()->sizeof_stream_item(0));
|
||||
for (int ch = 0; ch < output_items.size(); ch++)
|
||||
{
|
||||
memcpy(output_items[ch], input_items[ch], noutput_items * input_signature()->sizeof_stream_item(ch));
|
||||
}
|
||||
return noutput_items;
|
||||
}
|
||||
|
@ -97,6 +97,7 @@
|
||||
#include "ishort_to_cshort.h"
|
||||
#include "labsat_signal_source.h"
|
||||
#include "mmse_resampler_conditioner.h"
|
||||
#include "multichannel_file_signal_source.h"
|
||||
#include "notch_filter.h"
|
||||
#include "notch_filter_lite.h"
|
||||
#include "nsr_file_signal_source.h"
|
||||
@ -1261,6 +1262,21 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
block = std::move(block_);
|
||||
}
|
||||
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "GNSS-SDR program ended." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if (implementation == "Multichannel_File_Signal_Source")
|
||||
{
|
||||
try
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_(new MultichannelFileSignalSource(configuration.get(), role, in_streams,
|
||||
out_streams, queue));
|
||||
block = std::move(block_);
|
||||
}
|
||||
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "GNSS-SDR program ended." << std::endl;
|
||||
|
@ -249,11 +249,14 @@ void GNSSFlowgraph::connect()
|
||||
DLOG(INFO) << "sig_source_.at(i)->get_right_block()->output_signature()->max_streams()=" << sig_source_.at(i)->get_right_block()->output_signature()->max_streams();
|
||||
DLOG(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)
|
||||
if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1 or sig_source_.at(i)->get_right_block()->output_signature()->max_streams() == -1)
|
||||
{
|
||||
if (sig_conditioner_.size() > signal_conditioner_ID)
|
||||
{
|
||||
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)
|
||||
@ -819,7 +822,7 @@ void GNSSFlowgraph::disconnect()
|
||||
|
||||
for (int j = 0; j < RF_Channels; j++)
|
||||
{
|
||||
if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1)
|
||||
if (sig_source_.at(i)->get_right_block()->output_signature()->max_streams() > 1 or sig_source_.at(i)->get_right_block()->output_signature()->max_streams() == -1)
|
||||
{
|
||||
top_block_->disconnect(sig_source_.at(i)->get_right_block(), j, sig_conditioner_.at(signal_conditioner_ID)->get_left_block(), 0);
|
||||
}
|
||||
|
@ -99,3 +99,5 @@ else()
|
||||
message(STATUS "Boost Iostreams library not found.")
|
||||
message(STATUS " rinex2assist will not be built.")
|
||||
endif()
|
||||
|
||||
set(Boost_FOUND TRUE) # trick for summary report
|
||||
|
Loading…
Reference in New Issue
Block a user