Merge branch 'pocketsdr-source' of https://github.com/minhaj6/gnss-sdr into minhaj6-pocketsdr-source

This commit is contained in:
Carles Fernandez
2026-06-16 10:59:23 +02:00
7 changed files with 424 additions and 0 deletions
+31
View File
@@ -71,6 +71,8 @@ option(ENABLE_OSMOSDR "Enable the use of OsmoSDR and other front-ends (RTL-based
option(ENABLE_LIMESDR "Enable the use of LimeSDR and Custom LimeSDR as signal source" OFF)
option(ENABLE_POCKETSDR "Enable the use of Pocket SDR FE front-ends as signal source, requires gr-pocketsdr" OFF)
option(ENABLE_FMCOMMS2 "Enable the use of FMCOMMS4-EBZ + ZedBoard hardware, requires gr-iio" OFF)
option(ENABLE_PLUTOSDR "Enable the use of ADALM-PLUTO Evaluation Boards (Analog Devices Inc.), requires gr-iio" OFF)
@@ -2955,6 +2957,34 @@ endif()
################################################
# gr-pocketsdr - OPTIONAL
# https://github.com/minhaj6/gr-pocketsdr
################################################
find_package(GRPOCKETSDR)
set_package_properties(GRPOCKETSDR PROPERTIES
PURPOSE "Used for communication with Pocket SDR FE front-ends."
TYPE OPTIONAL
)
if(ENABLE_POCKETSDR)
if(GRPOCKETSDR_FOUND)
message(STATUS "The driver for Pocket SDR FE front-ends will be compiled.")
message(STATUS " You can disable it with 'cmake -DENABLE_POCKETSDR=OFF ..'")
else()
if(ENABLE_PACKAGING)
message(WARNING "gr-pocketsdr has not been found. Source blocks depending on it will NOT be built.")
else()
message(FATAL_ERROR "gr-pocketsdr required to build gnss-sdr with the optional POCKETSDR driver")
endif()
set(ENABLE_POCKETSDR OFF)
endif()
else()
message(STATUS "The (optional) driver for Pocket SDR FE front-ends is not enabled.")
message(STATUS " Enable it with 'cmake -DENABLE_POCKETSDR=ON ..' to add support for Pocket SDR FE front-ends.")
endif()
##############################################
# gr-iio - OPTIONAL
# IIO blocks for GNU Radio
@@ -3405,6 +3435,7 @@ add_subdirectory(utils)
add_feature_info(ENABLE_UHD ENABLE_UHD "Enables UHD_Signal_Source for using RF front-ends from the USRP family. Requires gr-uhd.")
add_feature_info(ENABLE_OSMOSDR ENABLE_OSMOSDR "Enables Osmosdr_Signal_Source and RtlTcp_Signal_Source for using RF front-ends compatible with the OsmoSDR driver. Requires gr-osmosdr.")
add_feature_info(ENABLE_LIMESDR ENABLE_LIMESDR "Enables Limesdr_Signal_Source. Requires gr-limesdr.")
add_feature_info(ENABLE_POCKETSDR ENABLE_POCKETSDR "Enables Pocket_SDR_Signal_Source. Requires gr-pocketsdr.")
add_feature_info(ENABLE_FMCOMMS2 ENABLE_FMCOMMS2 "Enables Fmcomms2_Signal_Source for FMCOMMS2/3/4 devices. Requires libiio, libad9361-dev, and gr-iio.")
add_feature_info(ENABLE_PLUTOSDR ENABLE_PLUTOSDR "Enables Plutosdr_Signal_Source and Ad936x_Custom_Signal_Source for using ADALM-PLUTO boards. Requires libiio, libad9361-dev, and gr-iio.")
add_feature_info(ENABLE_AD936X_SDR ENABLE_AD936X_SDR "Enables Ad936x_Custom_Signal_Source for using ADALM-PLUTO boards with custom firmware. Requires libiio and libad9361-dev.")
+98
View File
@@ -0,0 +1,98 @@
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
# This file is part of GNSS-SDR.
#
# SPDX-FileCopyrightText: 2011-2026 C. Fernandez-Prades cfernandez(at)cttc.es
# SPDX-License-Identifier: BSD-3-Clause
# Tries to find gr-pocketsdr.
#
# Usage of this module as follows:
#
# find_package(GRPOCKETSDR)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# GRPOCKETSDR_ROOT Set this variable to the root installation of
# gr-pocketsdr if the module has problems finding
# the proper installation path.
#
# Variables defined by this module:
#
# GRPOCKETSDR_FOUND System has gr-pocketsdr libs/headers
# GRPOCKETSDR_LIBRARIES The gr-pocketsdr libraries (gnuradio-pocketsdr)
# GRPOCKETSDR_INCLUDE_DIR The location of gr-pocketsdr headers
#
# Provides the following imported target:
# Gnuradio::pocketsdr
#
if(NOT COMMAND feature_summary)
include(FeatureSummary)
endif()
if(NOT PKG_CONFIG_FOUND)
include(FindPkgConfig)
endif()
if(NOT DEFINED GNSSSDR_LIB_PATHS)
include(GnsssdrFindPaths)
endif()
pkg_check_modules(GRPOCKETSDR_PKG QUIET gnuradio-pocketsdr)
if(NOT GRPOCKETSDR_ROOT)
set(GRPOCKETSDR_ROOT_USER_DEFINED /usr)
else()
set(GRPOCKETSDR_ROOT_USER_DEFINED ${GRPOCKETSDR_ROOT})
endif()
if(DEFINED ENV{GRPOCKETSDR_ROOT})
set(GRPOCKETSDR_ROOT_USER_DEFINED
${GRPOCKETSDR_ROOT_USER_DEFINED}
$ENV{GRPOCKETSDR_ROOT}
)
endif()
find_path(GRPOCKETSDR_INCLUDE_DIR
NAMES
gnuradio/pocketsdr/pocketsdr_source.h
gnuradio/pocketsdr/api.h
HINTS
${GRPOCKETSDR_PKG_INCLUDEDIR}
PATHS
${GRPOCKETSDR_ROOT_USER_DEFINED}/include
${GNSSSDR_INCLUDE_PATHS}
)
find_library(GRPOCKETSDR_LIBRARIES
NAMES
gnuradio-pocketsdr
HINTS
${GRPOCKETSDR_PKG_LIBDIR}
PATHS
${GRPOCKETSDR_ROOT_USER_DEFINED}/lib
${GRPOCKETSDR_ROOT_USER_DEFINED}/lib64
${GRPOCKETSDR_ROOT_USER_DEFINED}/lib/x86_64-linux-gnu
${GNSSSDR_LIB_PATHS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GRPOCKETSDR DEFAULT_MSG GRPOCKETSDR_LIBRARIES GRPOCKETSDR_INCLUDE_DIR)
set_package_properties(GRPOCKETSDR PROPERTIES
URL "https://github.com/minhaj6/gr-pocketsdr"
DESCRIPTION "Pocket SDR FE GNU Radio blocks"
)
if(GRPOCKETSDR_FOUND AND NOT TARGET Gnuradio::pocketsdr)
add_library(Gnuradio::pocketsdr SHARED IMPORTED)
set_target_properties(Gnuradio::pocketsdr PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${GRPOCKETSDR_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${GRPOCKETSDR_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${GRPOCKETSDR_LIBRARIES}"
)
message(STATUS "The (optional) gr-pocketsdr module has been found.")
endif()
mark_as_advanced(GRPOCKETSDR_LIBRARIES GRPOCKETSDR_INCLUDE_DIR)
@@ -101,6 +101,13 @@ if(ENABLE_LIMESDR)
endif()
endif()
if(ENABLE_POCKETSDR)
if(GRPOCKETSDR_FOUND)
list(APPEND OPT_DRIVER_SOURCES pocket_sdr_signal_source.cc)
list(APPEND OPT_DRIVER_HEADERS pocket_sdr_signal_source.h)
endif()
endif()
if(ENABLE_UHD)
list(APPEND OPT_DRIVER_SOURCES uhd_signal_source.cc)
list(APPEND OPT_DRIVER_HEADERS uhd_signal_source.h)
@@ -254,6 +261,13 @@ if(ENABLE_LIMESDR AND GRLIMESDR_FOUND)
)
endif()
if(ENABLE_POCKETSDR AND GRPOCKETSDR_FOUND)
target_link_libraries(signal_source_adapters
PUBLIC
Gnuradio::pocketsdr
)
endif()
if(LIBIIO_FOUND)
target_link_libraries(signal_source_adapters
PRIVATE
@@ -0,0 +1,181 @@
/*!
* \file pocket_sdr_signal_source.cc
* \brief Signal source for Pocket SDR front-ends
* \author Minhaj Ahmad, 2026. mahmad12(at)crimson.ua.edu
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#include "pocket_sdr_signal_source.h"
#include "configuration_interface.h"
#include "gnss_frequencies.h"
#include "gnss_sdr_string_literals.h"
#include "gnss_sdr_valve.h"
#include <cmath>
#include <iostream>
#include <stdexcept>
#include <vector>
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h>
#else
#include <absl/log/log.h>
#endif
using namespace std::string_literals;
PocketSdrSignalSource::PocketSdrSignalSource(const ConfigurationInterface* configuration,
const std::string& role,
unsigned int in_stream,
unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t>* queue)
: SignalSourceBase(configuration, role, "Pocket_SDR_Signal_Source"s),
item_type_(configuration->property(role + ".item_type", std::string("gr_complex"))),
dump_filename_(configuration->property(role + ".dump_filename", std::string("./data/signal_source.dat"))),
conf_file_(configuration->property(role + ".conf_file", std::string())),
sampling_frequency_(configuration->property(role + ".sampling_frequency", 0.0)),
freq_(configuration->property(role + ".freq", FREQ1)),
samples_(configuration->property(role + ".samples", int64_t(0))),
in_stream_(in_stream),
out_stream_(out_stream),
channel_(configuration->property(role + ".channel", 1)),
dump_(configuration->property(role + ".dump", false))
{
if (item_type_ != "gr_complex")
{
LOG(WARNING) << item_type_ << " unrecognized item type. Using gr_complex.";
item_type_ = std::string("gr_complex");
}
item_size_ = sizeof(gr_complex);
// 1. Make the driver instance: the device is configured with a standard
// PocketSDR configuration file (pocket_conf format); an empty conf_file
// keeps the current device settings
try
{
pocketsdr_source_ = gr::pocketsdr::pocketsdr_source::make(conf_file_, std::vector<int>{channel_});
}
catch (const std::exception& e)
{
LOG(WARNING) << "Exception creating gr-pocketsdr source: " << e.what();
throw std::invalid_argument("Wrong Pocket SDR arguments or device not found");
}
// 2. Read back the actual settings from the device
const double actual_sample_rate = pocketsdr_source_->get_sample_rate();
std::cout << "Actual RX Rate: " << actual_sample_rate << " [SPS]...\n";
LOG(INFO) << "Actual RX Rate: " << actual_sample_rate << " [SPS]...";
if (sampling_frequency_ > 0.0 && std::fabs(actual_sample_rate - sampling_frequency_) > 1.0)
{
std::cerr << "Warning: device sampling rate " << actual_sample_rate
<< " SPS does not match " << role << ".sampling_frequency="
<< sampling_frequency_ << " SPS in the configuration file\n";
LOG(WARNING) << "Device sampling rate " << actual_sample_rate
<< " SPS does not match configured " << sampling_frequency_ << " SPS";
}
const double actual_center_freq = pocketsdr_source_->get_center_freq(0);
std::cout << "Actual RX Freq: " << actual_center_freq << " [Hz]...\n";
LOG(INFO) << "Actual RX Freq: " << actual_center_freq << " [Hz]...";
if (std::fabs(actual_center_freq - freq_) > 1.0)
{
std::cerr << "Warning: device LO frequency " << actual_center_freq
<< " Hz does not match " << role << ".freq=" << freq_
<< " Hz in the configuration file\n";
LOG(WARNING) << "Device LO frequency " << actual_center_freq
<< " Hz does not match configured " << freq_ << " Hz";
}
if (samples_ != 0)
{
DLOG(INFO) << "Send STOP signal after " << samples_ << " samples";
valve_ = gnss_sdr_make_valve(item_size_, samples_, queue);
DLOG(INFO) << "valve(" << valve_->unique_id() << ")";
}
if (dump_)
{
DLOG(INFO) << "Dumping output into file " << dump_filename_;
file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str());
DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")";
}
if (in_stream_ > 0)
{
LOG(ERROR) << "A signal source does not have an input stream";
}
if (out_stream_ > 1)
{
LOG(ERROR) << "This implementation only supports one output stream";
}
}
void PocketSdrSignalSource::connect(gr::top_block_sptr top_block)
{
if (samples_ != 0)
{
top_block->connect(pocketsdr_source_, 0, valve_, 0);
DLOG(INFO) << "connected pocketsdr source to valve";
if (dump_)
{
top_block->connect(valve_, 0, file_sink_, 0);
DLOG(INFO) << "connected valve to file sink";
}
}
else
{
if (dump_)
{
top_block->connect(pocketsdr_source_, 0, file_sink_, 0);
DLOG(INFO) << "connected pocketsdr source to file sink";
}
}
}
void PocketSdrSignalSource::disconnect(gr::top_block_sptr top_block)
{
if (samples_ != 0)
{
top_block->disconnect(pocketsdr_source_, 0, valve_, 0);
if (dump_)
{
top_block->disconnect(valve_, 0, file_sink_, 0);
}
}
else
{
if (dump_)
{
top_block->disconnect(pocketsdr_source_, 0, file_sink_, 0);
}
}
}
gr::basic_block_sptr PocketSdrSignalSource::get_left_block()
{
LOG(WARNING) << "Trying to get signal source left block.";
return {};
}
gr::basic_block_sptr PocketSdrSignalSource::get_right_block()
{
if (samples_ != 0)
{
return valve_;
}
return pocketsdr_source_;
}
@@ -0,0 +1,86 @@
/*!
* \file pocket_sdr_signal_source.h
* \brief Signal source for Pocket SDR front-ends
* \author Minhaj Ahmad, 2026. mahmad12(at)crimson.ua.edu
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2026 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_POCKET_SDR_SIGNAL_SOURCE_H
#define GNSS_SDR_POCKET_SDR_SIGNAL_SOURCE_H
#include "concurrent_queue.h"
#include "gnss_block_interface.h"
#include "signal_source_base.h"
#include <gnuradio/blocks/file_sink.h>
#include <gnuradio/pocketsdr/pocketsdr_source.h>
#include <pmt/pmt.h>
#include <cstdint>
#include <memory>
#include <string>
/** \addtogroup Signal_Source
* \{ */
/** \addtogroup Signal_Source_adapters
* \{ */
class ConfigurationInterface;
/*!
* \brief This class instantiates the gr-pocketsdr signal source for the
* Pocket SDR FE 2CH/4CH/8CH GNSS RF front-ends.
*/
class PocketSdrSignalSource : public SignalSourceBase
{
public:
PocketSdrSignalSource(const ConfigurationInterface* configuration,
const std::string& role, unsigned int in_stream,
unsigned int out_stream, Concurrent_Queue<pmt::pmt_t>* queue);
~PocketSdrSignalSource() = default;
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;
private:
gr::pocketsdr::pocketsdr_source::sptr pocketsdr_source_;
gnss_shared_ptr<gr::block> valve_;
gr::blocks::file_sink::sptr file_sink_;
std::string item_type_;
std::string dump_filename_;
std::string conf_file_;
double sampling_frequency_;
double freq_;
size_t item_size_;
int64_t samples_;
unsigned int in_stream_;
unsigned int out_stream_;
int channel_;
bool dump_;
};
/** \} */
/** \} */
#endif // GNSS_SDR_POCKET_SDR_SIGNAL_SOURCE_H
+4
View File
@@ -124,6 +124,10 @@ if(ENABLE_LIMESDR)
target_compile_definitions(core_receiver PRIVATE -DLIMESDR_DRIVER=1)
endif()
if(ENABLE_POCKETSDR)
target_compile_definitions(core_receiver PRIVATE -DPOCKETSDR_DRIVER=1)
endif()
if(ENABLE_ARRAY)
target_compile_definitions(core_receiver PRIVATE -DRAW_ARRAY_DRIVER=1)
endif()
+10
View File
@@ -145,6 +145,10 @@
#include "limesdr_signal_source.h"
#endif
#if POCKETSDR_DRIVER
#include "pocket_sdr_signal_source.h"
#endif
#if FLEXIBAND_DRIVER
#include "flexiband_signal_source.h"
#endif
@@ -340,6 +344,12 @@ std::unique_ptr<SignalSourceInterface> get_signal_source_block(
return std::make_unique<LimesdrSignalSource>(configuration, role, in_streams, out_streams, queue);
}
#endif
#if POCKETSDR_DRIVER
else if (implementation == "Pocket_SDR_Signal_Source")
{
return std::make_unique<PocketSdrSignalSource>(configuration, role, in_streams, out_streams, queue);
}
#endif
#if PLUTOSDR_DRIVER
else if (implementation == "Plutosdr_Signal_Source")
{