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

Merge branch 'next' into bds_b3i_bug_fix

This commit is contained in:
Damian Miralles 2019-07-10 09:21:54 -05:00
commit 81ad7484bd
No known key found for this signature in database
GPG Key ID: 8A92BA854ED245E1
266 changed files with 7189 additions and 4896 deletions

View File

@ -97,9 +97,16 @@ option(ENABLE_SYSTEM_TESTING "Build system tests" OFF)
option(ENABLE_SYSTEM_TESTING_EXTRA "Download external tools and build extra system tests" OFF) option(ENABLE_SYSTEM_TESTING_EXTRA "Download external tools and build extra system tests" OFF)
option(ENABLE_GNSS_SIM_INSTALL "Enable the installation of gnss_sim on the fly" ON)
if(NOT (ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA))
set(ENABLE_GNSS_SIM_INSTALL OFF)
endif()
if(ENABLE_SYSTEM_TESTING_EXTRA) if(ENABLE_SYSTEM_TESTING_EXTRA)
set(ENABLE_SYSTEM_TESTING ON) set(ENABLE_SYSTEM_TESTING ON)
endif() endif()
option(ENABLE_OWN_GPSTK "Force to download, build and link GPSTk for system tests, even if it is already installed" OFF) option(ENABLE_OWN_GPSTK "Force to download, build and link GPSTk for system tests, even if it is already installed" OFF)
option(ENABLE_INSTALL_TESTS "Install QA code system-wide" OFF) option(ENABLE_INSTALL_TESTS "Install QA code system-wide" OFF)
@ -2026,7 +2033,7 @@ if(DOXYGEN_FOUND)
else() else()
message(STATUS " Doxygen has not been found in your system.") message(STATUS " Doxygen has not been found in your system.")
message(STATUS " You can get nice code documentation by using it!") message(STATUS " You can get nice code documentation by using it!")
message(STATUS " Get it from http://www.stack.nl/~dimitri/doxygen/index.html") message(STATUS " Get it from http://www.doxygen.nl/download.html")
if(OS_IS_LINUX) if(OS_IS_LINUX)
if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
message(STATUS " or simply by doing 'sudo yum install doxygen-latex'.") message(STATUS " or simply by doing 'sudo yum install doxygen-latex'.")
@ -2466,6 +2473,7 @@ add_feature_info(ENABLE_UNIT_TESTING_EXTRA ENABLE_UNIT_TESTING_EXTRA "Enables bu
add_feature_info(ENABLE_SYSTEM_TESTING ENABLE_SYSTEM_TESTING "Enables building of System Tests.") add_feature_info(ENABLE_SYSTEM_TESTING ENABLE_SYSTEM_TESTING "Enables building of System Tests.")
add_feature_info(ENABLE_SYSTEM_TESTING_EXTRA ENABLE_SYSTEM_TESTING_EXTRA "Enables building of Extra System Tests and downloading of external tools.") add_feature_info(ENABLE_SYSTEM_TESTING_EXTRA ENABLE_SYSTEM_TESTING_EXTRA "Enables building of Extra System Tests and downloading of external tools.")
add_feature_info(ENABLE_OWN_GPSTK ENABLE_OWN_GPSTK "Forces the downloading and building of GPSTk for system tests.") add_feature_info(ENABLE_OWN_GPSTK ENABLE_OWN_GPSTK "Forces the downloading and building of GPSTk for system tests.")
add_feature_info(ENABLE_GNSS_SIM_INSTALL ENABLE_GNSS_SIM_INSTALL "Enables downloading and building of gnss-sim.")
add_feature_info(ENABLE_INSTALL_TESTS ENABLE_INSTALL_TESTS "Install test binaries when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME} install'.") add_feature_info(ENABLE_INSTALL_TESTS ENABLE_INSTALL_TESTS "Install test binaries when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME} install'.")
message(STATUS "") message(STATUS "")

View File

@ -100,7 +100,8 @@ include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GROSMOSDR DEFAULT_MSG GROSMOSDR_LIBRARIES GROSMOSDR_INCLUDE_DIR) find_package_handle_standard_args(GROSMOSDR DEFAULT_MSG GROSMOSDR_LIBRARIES GROSMOSDR_INCLUDE_DIR)
if(GROSMOSDR_PKG_VERSION) if(GROSMOSDR_PKG_VERSION)
set(GROSMOSDR_VERSION ${GROSMOSDR_PKG_VERSION}) set(GROSMOSDR_VERSION_AUX ${GROSMOSDR_PKG_VERSION})
string(REGEX REPLACE "^v" "" GROSMOSDR_VERSION ${GROSMOSDR_VERSION_AUX})
endif() endif()
set_package_properties(GROSMOSDR PROPERTIES set_package_properties(GROSMOSDR PROPERTIES

View File

@ -1,98 +0,0 @@
# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors)
#
# 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/>.
# Tries to find libosmosdr.
#
# Usage of this module as follows:
#
# find_package(LIBOSMOSDR)
#
#
# Variables defined by this module:
#
# LIBOSMOSDR_FOUND System has libosmosdr libs/headers
# LIBOSMOSDR_LIBRARIES The libosmosdr libraries
# LIBOSMOSDR_INCLUDE_DIR The location of libosmosdr headers
#
# Provides the following imported target:
# Osmosdr::osmosdr
#
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
include(FindPkgConfig)
pkg_check_modules(LIBOSMOSDR_PKG libosmosdr)
find_path(LIBOSMOSDR_INCLUDE_DIR NAMES osmosdr.h
PATHS
${LIBOSMOSDR_PKG_INCLUDE_DIRS}
/usr/include
/usr/local/include
${LIBOSMOSDR_ROOT}/include
$ENV{LIBOSMOSDR_ROOT}/include
${LIBOSMOSDR_PKG_INCLUDEDIR}
)
find_library(LIBOSMOSDR_LIBRARIES NAMES osmosdr
PATHS
${LIBOSMOSDR_PKG_LIBRARY_DIRS}
/usr/lib
/usr/local/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/i386-linux-gnu
/usr/lib/arm-linux-gnueabihf
/usr/lib/arm-linux-gnueabi
/usr/lib/aarch64-linux-gnu
/usr/lib/mipsel-linux-gnu
/usr/lib/mips-linux-gnu
/usr/lib/mips64el-linux-gnuabi64
/usr/lib/powerpc-linux-gnu
/usr/lib/powerpc64-linux-gnu
/usr/lib/powerpc64le-linux-gnu
/usr/lib/powerpc-linux-gnuspe
/usr/lib/hppa-linux-gnu
/usr/lib/s390x-linux-gnu
/usr/lib/i386-gnu
/usr/lib/hppa-linux-gnu
/usr/lib/x86_64-kfreebsd-gnu
/usr/lib/i386-kfreebsd-gnu
/usr/lib/m68k-linux-gnu
/usr/lib/sh4-linux-gnu
/usr/lib/sparc64-linux-gnu
/usr/lib/x86_64-linux-gnux32
/usr/lib/alpha-linux-gnu
/usr/lib64
${LIBOSMOSDR_ROOT}/lib
$ENV{LIBOSMOSDR_ROOT}/lib
${LIBOSMOSDR_ROOT}/lib64
$ENV{LIBOSMOSDR_ROOT}/lib64
${LIBOSMOSDR_PKG_LIBDIR}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LIBOSMOSDR DEFAULT_MSG LIBOSMOSDR_INCLUDE_DIR LIBOSMOSDR_LIBRARIES)
if(LIBOSMOSDR_FOUND AND NOT TARGET Osmosdr::osmosdr)
add_library(Osmosdr::osmosdr SHARED IMPORTED)
set_target_properties(Osmosdr::osmosdr PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${LIBOSMOSDR_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${LIBOSMOSDR_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${LIBOSMOSDR_LIBRARIES}"
)
endif()
mark_as_advanced(LIBOSMOSDR_INCLUDE_DIR LIBOSMOSDR_LIBRARIES)

View File

@ -1,49 +0,0 @@
# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors)
#
# 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/>.
# - Try to find OpenBLAS library (not headers!)
#
# The following environment variable is optionally searched
# OPENBLAS_HOME: Base directory where all OpenBlas components are found
set(OPEN_BLAS_SEARCH_PATHS
/lib
/lib64/
/usr/lib
/usr/lib64
/usr/local/lib
/usr/local/lib64
/opt/OpenBLAS/lib
/opt/local/lib
/usr/lib/openblas-base
$ENV{OPENBLAS_HOME}/lib
${OPENBLAS_ROOT}/lib
$ENV{OPENBLAS_ROOT}/lib
${OPENBLAS_ROOT}/lib64
$ENV{OPENBLAS_ROOT}/lib64
)
find_library(OPENBLAS NAMES openblas PATHS ${OPEN_BLAS_SEARCH_PATHS})
if(OPENBLAS)
set(OPENBLAS_FOUND ON)
message(STATUS "Found OpenBLAS")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OPENBLAS DEFAULT_MSG OPENBLAS)
mark_as_advanced(OPENBLAS)

View File

@ -1,55 +0,0 @@
# Copyright (C) 2011-2018 (see AUTHORS file for a list of contributors)
#
# 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/>.
###############################################################################
# Test for availability of SSE
#
# - Anthony Arnold
###############################################################################
function(test_for_sse h_file result_var name)
if(NOT DEFINED ${result_var})
execute_process(COMMAND echo "#include <${h_file}>"
COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -c -x c++ -
RESULT_VARIABLE COMPILE_RESULT
OUTPUT_QUIET ERROR_QUIET)
set(detected 0)
if(COMPILE_RESULT EQUAL 0)
message(STATUS "Detected ${name}")
set(detected 1)
endif()
set(${result_var} ${detected} CACHE INTERNAL "${name} Available")
endif()
endfunction()
message(STATUS "Testing for SIMD extensions")
enable_language(C)
test_for_sse("ammintrin.h" SSE4A_AVAILABLE "SSE4A")
test_for_sse("nmmintrin.h" SSE4_2_AVAILABLE "SSE4.2")
test_for_sse("smmintrin.h" SSE4_1_AVAILABLE "SSE4.1")
test_for_sse("tmmintrin.h" SSSE3_AVAILABLE "SSSE3")
test_for_sse("pmmintrin.h" SSE3_AVAILABLE "SSE3")
test_for_sse("emmintrin.h" SSE2_AVAILABLE "SSE2")
test_for_sse("xmmintrin.h" SSE_AVAILABLE "SSE1")
test_for_sse("mmintrin.h" MMX_AVAILABLE "MMX")
test_for_sse("wmmintrin.h" AES_AVAILABLE "AES")
test_for_sse("immintrin.h" AVX_AVAILABLE "AVX")
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/-.o")

View File

@ -56,6 +56,7 @@
### Improvements in Reliability ### Improvements in Reliability
- Included the Guidelines Support Library. General improvement of memory management, replacement of raw pointers by containers or smart pointers.
- Applied clang-tidy checks and fixes related to High Integrity C++: performance-move-const-arg, modernize-use-auto, modernize-use-equals-default, modernize-use-equals-delete, modernize-use-noexcept, modernize-use-nullptr, cert-dcl21-cpp, misc-new-delete-overloads, cert-dcl58-cpp, cert-err52-cpp, cert-err60-cpp. - Applied clang-tidy checks and fixes related to High Integrity C++: performance-move-const-arg, modernize-use-auto, modernize-use-equals-default, modernize-use-equals-delete, modernize-use-noexcept, modernize-use-nullptr, cert-dcl21-cpp, misc-new-delete-overloads, cert-dcl58-cpp, cert-err52-cpp, cert-err60-cpp.

View File

@ -77,6 +77,57 @@ rtklib_pvt_gs_sptr rtklib_make_pvt_gs(uint32_t nchannels,
*/ */
class rtklib_pvt_gs : public gr::sync_block class rtklib_pvt_gs : public gr::sync_block
{ {
public:
~rtklib_pvt_gs(); //!< Default destructor
/*!
* \brief Get latest set of GPS ephemeris from PVT block
*/
std::map<int, Gps_Ephemeris> get_gps_ephemeris_map() const;
/*!
* \brief Get latest set of GPS almanac from PVT block
*/
std::map<int, Gps_Almanac> get_gps_almanac_map() const;
/*!
* \brief Get latest set of Galileo ephemeris from PVT block
*/
std::map<int, Galileo_Ephemeris> get_galileo_ephemeris_map() const;
/*!
* \brief Get latest set of Galileo almanac from PVT block
*/
std::map<int, Galileo_Almanac> get_galileo_almanac_map() const;
/*!
* \brief Get latest set of BeiDou DNAV ephemeris from PVT block
*/
std::map<int, Beidou_Dnav_Ephemeris> get_beidou_dnav_ephemeris_map() const;
/*!
* \brief Get latest set of BeiDou DNAV almanac from PVT block
*/
std::map<int, Beidou_Dnav_Almanac> get_beidou_dnav_almanac_map() const;
/*!
* \brief Clear all ephemeris information and the almanacs for GPS and Galileo
*/
void clear_ephemeris();
/*!
* \brief Get the latest Position WGS84 [deg], Ground Velocity, Course over Ground, and UTC Time, if available
*/
bool get_latest_PVT(double* longitude_deg,
double* latitude_deg,
double* height_m,
double* ground_speed_kmh,
double* course_over_ground_deg,
time_t* UTC_time) const;
int work(int noutput_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items); //!< PVT Signal Processing
private: private:
friend rtklib_pvt_gs_sptr rtklib_make_pvt_gs(uint32_t nchannels, friend rtklib_pvt_gs_sptr rtklib_make_pvt_gs(uint32_t nchannels,
const Pvt_Conf& conf_, const Pvt_Conf& conf_,
@ -169,57 +220,6 @@ private:
bool d_show_local_time_zone; bool d_show_local_time_zone;
std::string d_local_time_str; std::string d_local_time_str;
boost::posix_time::time_duration d_utc_diff_time; boost::posix_time::time_duration d_utc_diff_time;
public:
~rtklib_pvt_gs(); //!< Default destructor
/*!
* \brief Get latest set of GPS ephemeris from PVT block
*/
std::map<int, Gps_Ephemeris> get_gps_ephemeris_map() const;
/*!
* \brief Get latest set of GPS almanac from PVT block
*/
std::map<int, Gps_Almanac> get_gps_almanac_map() const;
/*!
* \brief Get latest set of Galileo ephemeris from PVT block
*/
std::map<int, Galileo_Ephemeris> get_galileo_ephemeris_map() const;
/*!
* \brief Get latest set of Galileo almanac from PVT block
*/
std::map<int, Galileo_Almanac> get_galileo_almanac_map() const;
/*!
* \brief Get latest set of BeiDou DNAV ephemeris from PVT block
*/
std::map<int, Beidou_Dnav_Ephemeris> get_beidou_dnav_ephemeris_map() const;
/*!
* \brief Get latest set of BeiDou DNAV almanac from PVT block
*/
std::map<int, Beidou_Dnav_Almanac> get_beidou_dnav_almanac_map() const;
/*!
* \brief Clear all ephemeris information and the almanacs for GPS and Galileo
*/
void clear_ephemeris();
/*!
* \brief Get the latest Position WGS84 [deg], Ground Velocity, Course over Ground, and UTC Time, if available
*/
bool get_latest_PVT(double* longitude_deg,
double* latitude_deg,
double* height_m,
double* ground_speed_kmh,
double* course_over_ground_deg,
time_t* UTC_time) const;
int work(int noutput_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items); //!< PVT Signal Processing
}; };
#endif #endif

View File

@ -47,18 +47,18 @@ class Pvt_Solution;
*/ */
class GeoJSON_Printer class GeoJSON_Printer
{ {
private:
std::ofstream geojson_file;
bool first_pos;
std::string filename_;
std::string geojson_base_path;
public: public:
GeoJSON_Printer(const std::string& base_path = "."); GeoJSON_Printer(const std::string& base_path = ".");
~GeoJSON_Printer(); ~GeoJSON_Printer();
bool set_headers(const std::string& filename, bool time_tag_name = true); bool set_headers(const std::string& filename, bool time_tag_name = true);
bool print_position(const std::shared_ptr<Pvt_Solution>& position, bool print_average_values); bool print_position(const std::shared_ptr<Pvt_Solution>& position, bool print_average_values);
bool close_file(); bool close_file();
private:
std::ofstream geojson_file;
bool first_pos;
std::string filename_;
std::string geojson_base_path;
}; };
#endif #endif

View File

@ -47,19 +47,19 @@ class Rtklib_Solver;
*/ */
class Gpx_Printer class Gpx_Printer
{ {
private:
std::ofstream gpx_file;
bool positions_printed;
std::string gpx_filename;
std::string indent;
std::string gpx_base_path;
public: public:
Gpx_Printer(const std::string& base_path = "."); Gpx_Printer(const std::string& base_path = ".");
~Gpx_Printer(); ~Gpx_Printer();
bool set_headers(const std::string& filename, bool time_tag_name = true); bool set_headers(const std::string& filename, bool time_tag_name = true);
bool print_position(const std::shared_ptr<Rtklib_Solver>& position, bool print_average_values); bool print_position(const std::shared_ptr<Rtklib_Solver>& position, bool print_average_values);
bool close_file(); bool close_file();
private:
std::ofstream gpx_file;
bool positions_printed;
std::string gpx_filename;
std::string indent;
std::string gpx_base_path;
}; };
#endif #endif

View File

@ -48,14 +48,6 @@
*/ */
class Hybrid_Ls_Pvt : public Ls_Pvt class Hybrid_Ls_Pvt : public Ls_Pvt
{ {
private:
int count_valid_position;
bool d_flag_dump_enabled;
std::string d_dump_filename;
std::ofstream d_dump_file;
int d_nchannels; // Number of available channels for positioning
double d_galileo_current_time;
public: public:
Hybrid_Ls_Pvt(int nchannels, std::string dump_filename, bool flag_dump_to_file); Hybrid_Ls_Pvt(int nchannels, std::string dump_filename, bool flag_dump_to_file);
~Hybrid_Ls_Pvt(); ~Hybrid_Ls_Pvt();
@ -75,6 +67,14 @@ public:
Gps_CNAV_Iono gps_cnav_iono; Gps_CNAV_Iono gps_cnav_iono;
Gps_CNAV_Utc_Model gps_cnav_utc_model; Gps_CNAV_Utc_Model gps_cnav_utc_model;
private:
int count_valid_position;
bool d_flag_dump_enabled;
std::string d_dump_filename;
std::ofstream d_dump_file;
int d_nchannels; // Number of available channels for positioning
double d_galileo_current_time;
}; };
#endif #endif

View File

@ -46,6 +46,13 @@ class Rtklib_Solver;
*/ */
class Kml_Printer class Kml_Printer
{ {
public:
Kml_Printer(const std::string& base_path = std::string("."));
~Kml_Printer();
bool set_headers(const std::string& filename, bool time_tag_name = true);
bool print_position(const std::shared_ptr<Rtklib_Solver>& position, bool print_average_values);
bool close_file();
private: private:
std::ofstream kml_file; std::ofstream kml_file;
std::ofstream tmp_file; std::ofstream tmp_file;
@ -55,13 +62,6 @@ private:
std::string tmp_file_str; std::string tmp_file_str;
unsigned int point_id; unsigned int point_id;
std::string indent; std::string indent;
public:
Kml_Printer(const std::string& base_path = std::string("."));
~Kml_Printer();
bool set_headers(const std::string& filename, bool time_tag_name = true);
bool print_position(const std::shared_ptr<Rtklib_Solver>& position, bool print_average_values);
bool close_file();
}; };
#endif #endif

View File

@ -41,12 +41,6 @@
*/ */
class Ls_Pvt : public Pvt_Solution class Ls_Pvt : public Pvt_Solution
{ {
private:
/*!
* \brief Computes the Lorentz inner product between two vectors
*/
double lorentz(const arma::vec& x, const arma::vec& y);
public: public:
Ls_Pvt(); Ls_Pvt();
@ -59,6 +53,12 @@ public:
* \brief Computes the Weighted Least Squares position solution * \brief Computes the Weighted Least Squares position solution
*/ */
arma::vec leastSquarePos(const arma::mat& satpos, const arma::vec& obs, const arma::vec& w_vec); arma::vec leastSquarePos(const arma::mat& satpos, const arma::vec& obs, const arma::vec& w_vec);
private:
/*!
* \brief Computes the Lorentz inner product between two vectors
*/
double lorentz(const arma::vec& x, const arma::vec& y);
}; };
#endif #endif

View File

@ -35,41 +35,13 @@
#include <sstream> #include <sstream>
Monitor_Pvt_Udp_Sink::Monitor_Pvt_Udp_Sink(std::vector<std::string> addresses, const uint16_t& port, bool protobuf_enabled) : socket{io_context} Monitor_Pvt_Udp_Sink::Monitor_Pvt_Udp_Sink(const std::vector<std::string>& addresses, const uint16_t& port, bool protobuf_enabled) : socket{io_context}
{ {
for (const auto& address : addresses) for (const auto& address : addresses)
{ {
boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port); boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(address, error), port);
endpoints.push_back(endpoint); endpoints.push_back(endpoint);
} }
monitor_pvt.TOW_at_current_symbol_ms = 0U;
monitor_pvt.week = 0U;
monitor_pvt.RX_time = 0.0;
monitor_pvt.user_clk_offset = 0.0;
monitor_pvt.pos_x = 0.0;
monitor_pvt.pos_y = 0.0;
monitor_pvt.pos_z = 0.0;
monitor_pvt.vel_x = 0.0;
monitor_pvt.vel_y = 0.0;
monitor_pvt.vel_z = 0.0;
monitor_pvt.cov_xx = 0.0;
monitor_pvt.cov_yy = 0.0;
monitor_pvt.cov_zz = 0.0;
monitor_pvt.cov_xy = 0.0;
monitor_pvt.cov_yz = 0.0;
monitor_pvt.cov_zx = 0.0;
monitor_pvt.latitude = 0.0;
monitor_pvt.longitude = 0.0;
monitor_pvt.height = 0.0;
monitor_pvt.valid_sats = 0;
monitor_pvt.solution_status = 0;
monitor_pvt.solution_type = 0;
monitor_pvt.AR_ratio_factor = 0.0;
monitor_pvt.AR_ratio_threshold = 0.0;
monitor_pvt.gdop = 0.0;
monitor_pvt.pdop = 0.0;
monitor_pvt.hdop = 0.0;
monitor_pvt.vdop = 0.0;
use_protobuf = protobuf_enabled; use_protobuf = protobuf_enabled;
if (use_protobuf) if (use_protobuf)

View File

@ -45,7 +45,7 @@ using b_io_context = boost::asio::io_service;
class Monitor_Pvt_Udp_Sink class Monitor_Pvt_Udp_Sink
{ {
public: public:
Monitor_Pvt_Udp_Sink(std::vector<std::string> addresses, const uint16_t &port, bool protobuf_enabled); Monitor_Pvt_Udp_Sink(const std::vector<std::string>& addresses, const uint16_t &port, bool protobuf_enabled);
bool write_monitor_pvt(const Monitor_Pvt &monitor_pvt); bool write_monitor_pvt(const Monitor_Pvt &monitor_pvt);
private: private:
@ -53,7 +53,7 @@ private:
boost::asio::ip::udp::socket socket; boost::asio::ip::udp::socket socket;
boost::system::error_code error; boost::system::error_code error;
std::vector<boost::asio::ip::udp::endpoint> endpoints; std::vector<boost::asio::ip::udp::endpoint> endpoints;
Monitor_Pvt monitor_pvt; Monitor_Pvt monitor_pvt{};
Serdes_Monitor_Pvt serdes; Serdes_Monitor_Pvt serdes;
bool use_protobuf; bool use_protobuf;
}; };

View File

@ -283,7 +283,7 @@ bool Nmea_Printer::Print_Nmea_Line(const std::shared_ptr<Rtklib_Solver>& pvt_dat
} }
char Nmea_Printer::checkSum(std::string sentence) char Nmea_Printer::checkSum(const std::string& sentence)
{ {
char check = 0; char check = 0;
// iterate over the string, XOR each byte with the total sum: // iterate over the string, XOR each byte with the total sum:
@ -441,7 +441,7 @@ std::string Nmea_Printer::get_GPGSA()
// GSA-GNSS DOP and Active Satellites // GSA-GNSS DOP and Active Satellites
std::stringstream sentence_str; std::stringstream sentence_str;
unsigned char buff[1024] = {0}; unsigned char buff[1024] = {0};
outnmea_gsa(buff, &d_PVT_data->pvt_sol, d_PVT_data->pvt_ssat); outnmea_gsa(buff, &d_PVT_data->pvt_sol, d_PVT_data->pvt_ssat.data());
sentence_str << buff; sentence_str << buff;
return sentence_str.str(); return sentence_str.str();
} }
@ -454,7 +454,7 @@ std::string Nmea_Printer::get_GPGSV()
// Notice that NMEA 2.1 only supports 12 channels // Notice that NMEA 2.1 only supports 12 channels
std::stringstream sentence_str; std::stringstream sentence_str;
unsigned char buff[1024] = {0}; unsigned char buff[1024] = {0};
outnmea_gsv(buff, &d_PVT_data->pvt_sol, d_PVT_data->pvt_ssat); outnmea_gsv(buff, &d_PVT_data->pvt_sol, d_PVT_data->pvt_ssat.data());
sentence_str << buff; sentence_str << buff;
return sentence_str.str(); return sentence_str.str();
} }

View File

@ -83,7 +83,7 @@ private:
std::string get_UTC_NMEA_time(boost::posix_time::ptime d_position_UTC_time); std::string get_UTC_NMEA_time(boost::posix_time::ptime d_position_UTC_time);
std::string longitude_to_hm(double longitude); std::string longitude_to_hm(double longitude);
std::string latitude_to_hm(double lat); std::string latitude_to_hm(double lat);
char checkSum(std::string sentence); char checkSum(const std::string& sentence);
bool print_avg_pos; bool print_avg_pos;
bool d_flag_nmea_output_file; bool d_flag_nmea_output_file;
}; };

View File

@ -44,32 +44,6 @@
*/ */
class Pvt_Solution class Pvt_Solution
{ {
private:
double d_rx_dt_s; // RX time offset [s]
double d_latitude_d; // RX position Latitude WGS84 [deg]
double d_longitude_d; // RX position Longitude WGS84 [deg]
double d_height_m; // RX position height WGS84 [m]
double d_speed_over_ground_m_s; // RX speed over ground [m/s]
double d_course_over_ground_d; // RX course over ground [deg]
double d_avg_latitude_d; // Averaged latitude in degrees
double d_avg_longitude_d; // Averaged longitude in degrees
double d_avg_height_m; // Averaged height [m]
bool b_valid_position;
std::deque<double> d_hist_latitude_d;
std::deque<double> d_hist_longitude_d;
std::deque<double> d_hist_height_m;
bool d_flag_averaging;
int d_averaging_depth; // Length of averaging window
arma::vec d_rx_pos;
boost::posix_time::ptime d_position_UTC_time;
int d_valid_observations;
public: public:
Pvt_Solution(); Pvt_Solution();
@ -111,46 +85,73 @@ public:
arma::vec rotateSatellite(double traveltime, const arma::vec &X_sat); arma::vec rotateSatellite(double traveltime, const arma::vec &X_sat);
/*! /*!
* \brief Conversion of Cartesian coordinates (X,Y,Z) to geographical * \brief Conversion of Cartesian coordinates (X,Y,Z) to geographical
* coordinates (d_latitude_d, d_longitude_d, d_height_m) on a selected reference ellipsoid. * coordinates (d_latitude_d, d_longitude_d, d_height_m) on a selected reference ellipsoid.
* *
* \param[in] X [m] Cartesian coordinate * \param[in] X [m] Cartesian coordinate
* \param[in] Y [m] Cartesian coordinate * \param[in] Y [m] Cartesian coordinate
* \param[in] Z [m] Cartesian coordinate * \param[in] Z [m] Cartesian coordinate
* \param[in] elipsoid_selection. Choices of Reference Ellipsoid for Geographical Coordinates: * \param[in] elipsoid_selection. Choices of Reference Ellipsoid for Geographical Coordinates:
* 0 - International Ellipsoid 1924. * 0 - International Ellipsoid 1924.
* 1 - International Ellipsoid 1967. * 1 - International Ellipsoid 1967.
* 2 - World Geodetic System 1972. * 2 - World Geodetic System 1972.
* 3 - Geodetic Reference System 1980. * 3 - Geodetic Reference System 1980.
* 4 - World Geodetic System 1984. * 4 - World Geodetic System 1984.
* *
*/ */
int cart2geo(double X, double Y, double Z, int elipsoid_selection); int cart2geo(double X, double Y, double Z, int elipsoid_selection);
/*! /*!
* \brief Tropospheric correction * \brief Tropospheric correction
* *
* \param[in] sinel - sin of elevation angle of satellite * \param[in] sinel - sin of elevation angle of satellite
* \param[in] hsta_km - height of station in km * \param[in] hsta_km - height of station in km
* \param[in] p_mb - atmospheric pressure in mb at height hp_km * \param[in] p_mb - atmospheric pressure in mb at height hp_km
* \param[in] t_kel - surface temperature in degrees Kelvin at height htkel_km * \param[in] t_kel - surface temperature in degrees Kelvin at height htkel_km
* \param[in] hum - humidity in % at height hhum_km * \param[in] hum - humidity in % at height hhum_km
* \param[in] hp_km - height of pressure measurement in km * \param[in] hp_km - height of pressure measurement in km
* \param[in] htkel_km - height of temperature measurement in km * \param[in] htkel_km - height of temperature measurement in km
* \param[in] hhum_km - height of humidity measurement in km * \param[in] hhum_km - height of humidity measurement in km
* *
* \param[out] ddr_m - range correction (meters) * \param[out] ddr_m - range correction (meters)
* *
* *
* Reference: * Reference:
* Goad, C.C. & Goodman, L. (1974) A Modified Hopfield Tropospheric * Goad, C.C. & Goodman, L. (1974) A Modified Hopfield Tropospheric
* Refraction Correction Model. Paper presented at the * Refraction Correction Model. Paper presented at the
* American Geophysical Union Annual Fall Meeting, San * American Geophysical Union Annual Fall Meeting, San
* Francisco, December 12-17 * Francisco, December 12-17
* *
* Translated to C++ by Carles Fernandez from a Matlab implementation by Kai Borre * Translated to C++ by Carles Fernandez from a Matlab implementation by Kai Borre
*/ */
int tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km); int tropo(double *ddr_m, double sinel, double hsta_km, double p_mb, double t_kel, double hum, double hp_km, double htkel_km, double hhum_km);
private:
double d_rx_dt_s; // RX time offset [s]
double d_latitude_d; // RX position Latitude WGS84 [deg]
double d_longitude_d; // RX position Longitude WGS84 [deg]
double d_height_m; // RX position height WGS84 [m]
double d_speed_over_ground_m_s; // RX speed over ground [m/s]
double d_course_over_ground_d; // RX course over ground [deg]
double d_avg_latitude_d; // Averaged latitude in degrees
double d_avg_longitude_d; // Averaged longitude in degrees
double d_avg_height_m; // Averaged height [m]
bool b_valid_position;
std::deque<double> d_hist_latitude_d;
std::deque<double> d_hist_longitude_d;
std::deque<double> d_hist_height_m;
bool d_flag_averaging;
int d_averaging_depth; // Length of averaging window
arma::vec d_rx_pos;
boost::posix_time::ptime d_position_UTC_time;
int d_valid_observations;
}; };
#endif #endif

View File

@ -140,7 +140,7 @@ bool Rtcm::is_server_running() const
std::string Rtcm::add_CRC(const std::string& message_without_crc) const std::string Rtcm::add_CRC(const std::string& message_without_crc) const
{ {
// ****** Computes Qualcomm CRC-24Q ****** // ****** Computes Qualcomm CRC-24Q ******
boost::crc_optimal<24, 0x1864CFBu, 0x0, 0x0, false, false> CRC_RTCM; boost::crc_optimal<24, 0x1864CFBU, 0x0, 0x0, false, false> CRC_RTCM;
// 1) Converts the string to a vector of uint8_t: // 1) Converts the string to a vector of uint8_t:
boost::dynamic_bitset<uint8_t> frame_bits(message_without_crc); boost::dynamic_bitset<uint8_t> frame_bits(message_without_crc);
std::vector<uint8_t> bytes; std::vector<uint8_t> bytes;
@ -159,7 +159,7 @@ std::string Rtcm::add_CRC(const std::string& message_without_crc) const
bool Rtcm::check_CRC(const std::string& message) const bool Rtcm::check_CRC(const std::string& message) const
{ {
boost::crc_optimal<24, 0x1864CFBu, 0x0, 0x0, false, false> CRC_RTCM_CHECK; boost::crc_optimal<24, 0x1864CFBU, 0x0, 0x0, false, false> CRC_RTCM_CHECK;
// Convert message to binary // Convert message to binary
std::string message_bin = Rtcm::binary_data_to_bin(message); std::string message_bin = Rtcm::binary_data_to_bin(message);
// Check CRC // Check CRC
@ -2419,7 +2419,7 @@ std::string Rtcm::get_MSM_1_content_sat_data(const std::map<int32_t, Gnss_Synchr
if (it == pos.end()) if (it == pos.end())
{ {
pos.push_back(65 - gnss_synchro_iter->second.PRN); pos.push_back(65 - gnss_synchro_iter->second.PRN);
observables_vector.push_back(*gnss_synchro_iter); observables_vector.emplace_back(*gnss_synchro_iter);
} }
} }
@ -2448,7 +2448,7 @@ std::string Rtcm::get_MSM_1_content_signal_data(const std::map<int32_t, Gnss_Syn
map_iter != observables.cend(); map_iter != observables.cend();
map_iter++) map_iter++)
{ {
observables_vector.push_back(*map_iter); observables_vector.emplace_back(*map_iter);
} }
std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector);
@ -2556,7 +2556,7 @@ std::string Rtcm::get_MSM_2_content_signal_data(const Gps_Ephemeris& ephNAV,
map_iter != observables.cend(); map_iter != observables.cend();
map_iter++) map_iter++)
{ {
observables_vector.push_back(*map_iter); observables_vector.emplace_back(*map_iter);
} }
std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector);
@ -2670,7 +2670,7 @@ std::string Rtcm::get_MSM_3_content_signal_data(const Gps_Ephemeris& ephNAV,
map_iter != observables.cend(); map_iter != observables.cend();
map_iter++) map_iter++)
{ {
observables_vector.push_back(*map_iter); observables_vector.emplace_back(*map_iter);
} }
std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector);
@ -2786,7 +2786,7 @@ std::string Rtcm::get_MSM_4_content_sat_data(const std::map<int32_t, Gnss_Synchr
if (it == pos.end()) if (it == pos.end())
{ {
pos.push_back(65 - gnss_synchro_iter->second.PRN); pos.push_back(65 - gnss_synchro_iter->second.PRN);
observables_vector.push_back(*gnss_synchro_iter); observables_vector.emplace_back(*gnss_synchro_iter);
} }
} }
@ -2827,7 +2827,7 @@ std::string Rtcm::get_MSM_4_content_signal_data(const Gps_Ephemeris& ephNAV,
map_iter != observables.cend(); map_iter != observables.cend();
map_iter++) map_iter++)
{ {
observables_vector.push_back(*map_iter); observables_vector.emplace_back(*map_iter);
} }
std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector);
@ -2947,7 +2947,7 @@ std::string Rtcm::get_MSM_5_content_sat_data(const std::map<int32_t, Gnss_Synchr
if (it == pos.end()) if (it == pos.end())
{ {
pos.push_back(65 - gnss_synchro_iter->second.PRN); pos.push_back(65 - gnss_synchro_iter->second.PRN);
observables_vector.push_back(*gnss_synchro_iter); observables_vector.emplace_back(*gnss_synchro_iter);
} }
} }
@ -2993,7 +2993,7 @@ std::string Rtcm::get_MSM_5_content_signal_data(const Gps_Ephemeris& ephNAV,
map_iter != observables.cend(); map_iter != observables.cend();
map_iter++) map_iter++)
{ {
observables_vector.push_back(*map_iter); observables_vector.emplace_back(*map_iter);
} }
std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector);
@ -3114,7 +3114,7 @@ std::string Rtcm::get_MSM_6_content_signal_data(const Gps_Ephemeris& ephNAV,
map_iter != observables.cend(); map_iter != observables.cend();
map_iter++) map_iter++)
{ {
observables_vector.push_back(*map_iter); observables_vector.emplace_back(*map_iter);
} }
std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector);
@ -3234,7 +3234,7 @@ std::string Rtcm::get_MSM_7_content_signal_data(const Gps_Ephemeris& ephNAV,
map_iter != observables.cend(); map_iter != observables.cend();
map_iter++) map_iter++)
{ {
observables_vector.push_back(*map_iter); observables_vector.emplace_back(*map_iter);
} }
std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector); std::vector<std::pair<int32_t, Gnss_Synchro> > ordered_by_signal = Rtcm::sort_by_signal(observables_vector);
@ -3685,7 +3685,7 @@ uint32_t Rtcm::msm_extended_lock_time_indicator(uint32_t lock_time_period_s)
if( 16777216 <= lock_time_period_s && lock_time_period_s < 33554432 ) return (640 + (lock_time_period_s - 16777216) / 524288 ); if( 16777216 <= lock_time_period_s && lock_time_period_s < 33554432 ) return (640 + (lock_time_period_s - 16777216) / 524288 );
if( 33554432 <= lock_time_period_s && lock_time_period_s < 67108864 ) return (672 + (lock_time_period_s - 33554432) / 1048576); if( 33554432 <= lock_time_period_s && lock_time_period_s < 67108864 ) return (672 + (lock_time_period_s - 33554432) / 1048576);
if( 67108864 <= lock_time_period_s ) return (704 ); if( 67108864 <= lock_time_period_s ) return (704 );
return 1023; // will never happen return 1023; // will never happen
} }
// clang-format on // clang-format on
@ -5330,7 +5330,7 @@ int32_t Rtcm::set_DF398(const Gnss_Synchro& gnss_synchro)
} }
else else
{ {
rr_mod_ms = static_cast<uint32_t>(std::floor(rough_range_m / meters_to_miliseconds / TWO_N10) + 0.5) & 0x3FFu; rr_mod_ms = static_cast<uint32_t>(std::floor(rough_range_m / meters_to_miliseconds / TWO_N10) + 0.5) & 0x3FFU;
} }
DF398 = std::bitset<10>(rr_mod_ms); DF398 = std::bitset<10>(rr_mod_ms);
return 0; return 0;

View File

@ -64,6 +64,7 @@
#include <matio.h> #include <matio.h>
#include <exception> #include <exception>
#include <utility> #include <utility>
#include <vector>
Rtklib_Solver::Rtklib_Solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, bool flag_dump_to_mat, const rtk_t &rtk) Rtklib_Solver::Rtklib_Solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, bool flag_dump_to_mat, const rtk_t &rtk)
@ -76,16 +77,7 @@ Rtklib_Solver::Rtklib_Solver(int nchannels, std::string dump_filename, bool flag
count_valid_position = 0; count_valid_position = 0;
this->set_averaging_flag(false); this->set_averaging_flag(false);
rtk_ = rtk; rtk_ = rtk;
for (double &i : dop_)
{
i = 0.0;
}
pvt_sol = {{0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, '0', '0', '0', 0, 0, 0};
ssat_t ssat0 = {0, 0, {0.0}, {0.0}, {0.0}, {'0'}, {'0'}, {'0'}, {'0'}, {'0'}, {}, {}, {}, {}, 0.0, 0.0, 0.0, 0.0, {{{0, 0}}, {{0, 0}}}, {{}, {}}};
for (auto &i : pvt_ssat)
{
i = ssat0;
}
// ############# ENABLE DATA FILE LOG ################# // ############# ENABLE DATA FILE LOG #################
if (d_flag_dump_enabled == true) if (d_flag_dump_enabled == true)
{ {
@ -103,35 +95,6 @@ Rtklib_Solver::Rtklib_Solver(int nchannels, std::string dump_filename, bool flag
} }
} }
} }
// PVT MONITOR
monitor_pvt.TOW_at_current_symbol_ms = 0U;
monitor_pvt.week = 0U;
monitor_pvt.RX_time = 0.0;
monitor_pvt.user_clk_offset = 0.0;
monitor_pvt.pos_x = 0.0;
monitor_pvt.pos_y = 0.0;
monitor_pvt.pos_z = 0.0;
monitor_pvt.vel_x = 0.0;
monitor_pvt.vel_y = 0.0;
monitor_pvt.vel_z = 0.0;
monitor_pvt.cov_xx = 0.0;
monitor_pvt.cov_yy = 0.0;
monitor_pvt.cov_zz = 0.0;
monitor_pvt.cov_xy = 0.0;
monitor_pvt.cov_yz = 0.0;
monitor_pvt.cov_zx = 0.0;
monitor_pvt.latitude = 0.0;
monitor_pvt.longitude = 0.0;
monitor_pvt.height = 0.0;
monitor_pvt.valid_sats = 0;
monitor_pvt.solution_status = 0;
monitor_pvt.solution_type = 0;
monitor_pvt.AR_ratio_factor = 0.0;
monitor_pvt.AR_ratio_threshold = 0.0;
monitor_pvt.gdop = 0.0;
monitor_pvt.pdop = 0.0;
monitor_pvt.hdop = 0.0;
monitor_pvt.vdop = 0.0;
} }
bool Rtklib_Solver::save_matfile() bool Rtklib_Solver::save_matfile()
@ -172,34 +135,34 @@ bool Rtklib_Solver::save_matfile()
return false; return false;
} }
auto *TOW_at_current_symbol_ms = new uint32_t[num_epoch]; auto TOW_at_current_symbol_ms = std::vector<uint32_t>(num_epoch);
auto *week = new uint32_t[num_epoch]; auto week = std::vector<uint32_t>(num_epoch);
auto *RX_time = new double[num_epoch]; auto RX_time = std::vector<double>(num_epoch);
auto *user_clk_offset = new double[num_epoch]; auto user_clk_offset = std::vector<double>(num_epoch);
auto *pos_x = new double[num_epoch]; auto pos_x = std::vector<double>(num_epoch);
auto *pos_y = new double[num_epoch]; auto pos_y = std::vector<double>(num_epoch);
auto *pos_z = new double[num_epoch]; auto pos_z = std::vector<double>(num_epoch);
auto *vel_x = new double[num_epoch]; auto vel_x = std::vector<double>(num_epoch);
auto *vel_y = new double[num_epoch]; auto vel_y = std::vector<double>(num_epoch);
auto *vel_z = new double[num_epoch]; auto vel_z = std::vector<double>(num_epoch);
auto *cov_xx = new double[num_epoch]; auto cov_xx = std::vector<double>(num_epoch);
auto *cov_yy = new double[num_epoch]; auto cov_yy = std::vector<double>(num_epoch);
auto *cov_zz = new double[num_epoch]; auto cov_zz = std::vector<double>(num_epoch);
auto *cov_xy = new double[num_epoch]; auto cov_xy = std::vector<double>(num_epoch);
auto *cov_yz = new double[num_epoch]; auto cov_yz = std::vector<double>(num_epoch);
auto *cov_zx = new double[num_epoch]; auto cov_zx = std::vector<double>(num_epoch);
auto *latitude = new double[num_epoch]; auto latitude = std::vector<double>(num_epoch);
auto *longitude = new double[num_epoch]; auto longitude = std::vector<double>(num_epoch);
auto *height = new double[num_epoch]; auto height = std::vector<double>(num_epoch);
auto *valid_sats = new uint8_t[num_epoch]; auto valid_sats = std::vector<uint8_t>(num_epoch);
auto *solution_status = new uint8_t[num_epoch]; auto solution_status = std::vector<uint8_t>(num_epoch);
auto *solution_type = new uint8_t[num_epoch]; auto solution_type = std::vector<uint8_t>(num_epoch);
auto *AR_ratio_factor = new float[num_epoch]; auto AR_ratio_factor = std::vector<float>(num_epoch);
auto *AR_ratio_threshold = new float[num_epoch]; auto AR_ratio_threshold = std::vector<float>(num_epoch);
auto *gdop = new double[num_epoch]; auto gdop = std::vector<double>(num_epoch);
auto *pdop = new double[num_epoch]; auto pdop = std::vector<double>(num_epoch);
auto *hdop = new double[num_epoch]; auto hdop = std::vector<double>(num_epoch);
auto *vdop = new double[num_epoch]; auto vdop = std::vector<double>(num_epoch);
try try
{ {
@ -242,35 +205,6 @@ bool Rtklib_Solver::save_matfile()
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Problem reading dump file:" << e.what() << std::endl; std::cerr << "Problem reading dump file:" << e.what() << std::endl;
delete[] TOW_at_current_symbol_ms;
delete[] week;
delete[] RX_time;
delete[] user_clk_offset;
delete[] pos_x;
delete[] pos_y;
delete[] pos_z;
delete[] vel_x;
delete[] vel_y;
delete[] vel_z;
delete[] cov_xx;
delete[] cov_yy;
delete[] cov_zz;
delete[] cov_xy;
delete[] cov_yz;
delete[] cov_zx;
delete[] latitude;
delete[] longitude;
delete[] height;
delete[] valid_sats;
delete[] solution_status;
delete[] solution_type;
delete[] AR_ratio_factor;
delete[] AR_ratio_threshold;
delete[] gdop;
delete[] pdop;
delete[] hdop;
delete[] vdop;
return false; return false;
} }
@ -284,149 +218,120 @@ bool Rtklib_Solver::save_matfile()
if (reinterpret_cast<int64_t *>(matfp) != nullptr) if (reinterpret_cast<int64_t *>(matfp) != nullptr)
{ {
size_t dims[2] = {1, static_cast<size_t>(num_epoch)}; size_t dims[2] = {1, static_cast<size_t>(num_epoch)};
matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_UINT32, MAT_T_UINT32, 2, dims, TOW_at_current_symbol_ms, 0); matvar = Mat_VarCreate("TOW_at_current_symbol_ms", MAT_C_UINT32, MAT_T_UINT32, 2, dims, TOW_at_current_symbol_ms.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("week", MAT_C_UINT32, MAT_T_UINT32, 2, dims, week, 0); matvar = Mat_VarCreate("week", MAT_C_UINT32, MAT_T_UINT32, 2, dims, week.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("RX_time", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, RX_time, 0); matvar = Mat_VarCreate("RX_time", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, RX_time.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("user_clk_offset", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, user_clk_offset, 0); matvar = Mat_VarCreate("user_clk_offset", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, user_clk_offset.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("pos_x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_x, 0); matvar = Mat_VarCreate("pos_x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_x.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("pos_y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_y, 0); matvar = Mat_VarCreate("pos_y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_y.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("pos_z", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_z, 0); matvar = Mat_VarCreate("pos_z", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pos_z.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("vel_x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_x, 0); matvar = Mat_VarCreate("vel_x", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_x.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("vel_y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_y, 0); matvar = Mat_VarCreate("vel_y", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_y.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("vel_z", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_z, 0); matvar = Mat_VarCreate("vel_z", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vel_z.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("cov_xx", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_xx, 0); matvar = Mat_VarCreate("cov_xx", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_xx.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("cov_yy", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_yy, 0); matvar = Mat_VarCreate("cov_yy", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_yy.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("cov_zz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_zz, 0); matvar = Mat_VarCreate("cov_zz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_zz.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("cov_xy", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_xy, 0); matvar = Mat_VarCreate("cov_xy", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_xy.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("cov_yz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_yz, 0); matvar = Mat_VarCreate("cov_yz", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_yz.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("cov_zx", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_zx, 0); matvar = Mat_VarCreate("cov_zx", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, cov_zx.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("latitude", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, latitude, 0); matvar = Mat_VarCreate("latitude", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, latitude.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("longitude", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, longitude, 0); matvar = Mat_VarCreate("longitude", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, longitude.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("height", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, height, 0); matvar = Mat_VarCreate("height", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, height.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("valid_sats", MAT_C_UINT8, MAT_T_UINT8, 2, dims, valid_sats, 0); matvar = Mat_VarCreate("valid_sats", MAT_C_UINT8, MAT_T_UINT8, 2, dims, valid_sats.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("solution_status", MAT_C_UINT8, MAT_T_UINT8, 2, dims, solution_status, 0); matvar = Mat_VarCreate("solution_status", MAT_C_UINT8, MAT_T_UINT8, 2, dims, solution_status.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("solution_type", MAT_C_UINT8, MAT_T_UINT8, 2, dims, solution_type, 0); matvar = Mat_VarCreate("solution_type", MAT_C_UINT8, MAT_T_UINT8, 2, dims, solution_type.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("AR_ratio_factor", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, AR_ratio_factor, 0); matvar = Mat_VarCreate("AR_ratio_factor", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, AR_ratio_factor.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("AR_ratio_threshold", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, AR_ratio_threshold, 0); matvar = Mat_VarCreate("AR_ratio_threshold", MAT_C_SINGLE, MAT_T_SINGLE, 2, dims, AR_ratio_threshold.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("gdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, gdop, 0); matvar = Mat_VarCreate("gdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, gdop.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("pdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pdop, 0); matvar = Mat_VarCreate("pdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, pdop.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("hdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, hdop, 0); matvar = Mat_VarCreate("hdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, hdop.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("vdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vdop, 0); matvar = Mat_VarCreate("vdop", MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, vdop.data(), 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
} }
Mat_Close(matfp); Mat_Close(matfp);
delete[] TOW_at_current_symbol_ms;
delete[] week;
delete[] RX_time;
delete[] user_clk_offset;
delete[] pos_x;
delete[] pos_y;
delete[] pos_z;
delete[] vel_x;
delete[] vel_y;
delete[] vel_z;
delete[] cov_xx;
delete[] cov_yy;
delete[] cov_zz;
delete[] cov_xy;
delete[] cov_yz;
delete[] cov_zx;
delete[] latitude;
delete[] longitude;
delete[] height;
delete[] valid_sats;
delete[] solution_status;
delete[] solution_type;
delete[] AR_ratio_factor;
delete[] AR_ratio_threshold;
delete[] gdop;
delete[] pdop;
delete[] hdop;
delete[] vdop;
return true; return true;
} }
@ -507,9 +412,9 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
int valid_obs = 0; // valid observations counter int valid_obs = 0; // valid observations counter
int glo_valid_obs = 0; // GLONASS L1/L2 valid observations counter int glo_valid_obs = 0; // GLONASS L1/L2 valid observations counter
obsd_t obs_data[MAXOBS]; std::array<obsd_t, MAXOBS> obs_data{};
eph_t eph_data[MAXOBS]; std::array<eph_t, MAXOBS> eph_data{};
geph_t geph_data[MAXOBS]; std::array<geph_t, MAXOBS> geph_data{};
// Workaround for NAV/CNAV clash problem // Workaround for NAV/CNAV clash problem
bool gps_dual_band = false; bool gps_dual_band = false;
@ -894,8 +799,8 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
int result = 0; int result = 0;
int sat = 0; int sat = 0;
nav_t nav_data; nav_t nav_data;
nav_data.eph = eph_data; nav_data.eph = eph_data.data();
nav_data.geph = geph_data; nav_data.geph = geph_data.data();
nav_data.n = valid_obs; nav_data.n = valid_obs;
nav_data.ng = glo_valid_obs; nav_data.ng = glo_valid_obs;
@ -915,7 +820,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
} }
} }
result = rtkpos(&rtk_, obs_data, valid_obs + glo_valid_obs, &nav_data); result = rtkpos(&rtk_, obs_data.data(), valid_obs + glo_valid_obs, &nav_data);
if (result == 0) if (result == 0)
{ {
@ -976,7 +881,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
} }
this->set_rx_pos(rx_position_and_time.rows(0, 2)); // save ECEF position for the next iteration this->set_rx_pos(rx_position_and_time.rows(0, 2)); // save ECEF position for the next iteration
//compute Ground speed and COG // compute Ground speed and COG
double ground_speed_ms = 0.0; double ground_speed_ms = 0.0;
double pos[3]; double pos[3];
double enuv[3]; double enuv[3];
@ -1015,9 +920,7 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
<< " [deg], Height= " << this->get_height() << " [m]" << " [deg], Height= " << this->get_height() << " [m]"
<< " RX time offset= " << this->get_time_offset_s() << " [s]"; << " RX time offset= " << this->get_time_offset_s() << " [s]";
// ######## PVT MONITOR #########
// PVT MONITOR
// TOW // TOW
monitor_pvt.TOW_at_current_symbol_ms = gnss_observables_map.begin()->second.TOW_at_current_symbol_ms; monitor_pvt.TOW_at_current_symbol_ms = gnss_observables_map.begin()->second.TOW_at_current_symbol_ms;
// WEEK // WEEK
@ -1067,7 +970,6 @@ bool Rtklib_Solver::get_PVT(const std::map<int, Gnss_Synchro> &gnss_observables_
monitor_pvt.hdop = dop_[2]; monitor_pvt.hdop = dop_[2];
monitor_pvt.vdop = dop_[3]; monitor_pvt.vdop = dop_[3];
// ######## LOG FILE ######### // ######## LOG FILE #########
if (d_flag_dump_enabled == true) if (d_flag_dump_enabled == true)
{ {

View File

@ -84,30 +84,18 @@
/*! /*!
* \brief This class implements a simple PVT Least Squares solution * \brief This class implements a PVT solution based on RTKLIB
*/ */
class Rtklib_Solver : public Pvt_Solution class Rtklib_Solver : public Pvt_Solution
{ {
private:
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;
public: public:
Rtklib_Solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, bool flag_dump_to_mat, const rtk_t& rtk); Rtklib_Solver(int nchannels, std::string dump_filename, bool flag_dump_to_file, bool flag_dump_to_mat, const rtk_t& rtk);
~Rtklib_Solver(); ~Rtklib_Solver();
bool get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_map, bool flag_averaging); bool get_PVT(const std::map<int, Gnss_Synchro>& gnss_observables_map, bool flag_averaging);
sol_t pvt_sol; sol_t pvt_sol{};
ssat_t pvt_ssat[MAXSAT]; std::array<ssat_t, MAXSAT> pvt_ssat{};
double get_hdop() const; double get_hdop() const;
double get_vdop() const; double get_vdop() const;
double get_pdop() const; double get_pdop() const;
@ -139,6 +127,17 @@ public:
std::map<int, Beidou_Dnav_Almanac> beidou_dnav_almanac_map; std::map<int, Beidou_Dnav_Almanac> beidou_dnav_almanac_map;
int count_valid_position; int count_valid_position;
private:
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{};
}; };
#endif #endif

View File

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

View File

@ -39,6 +39,8 @@
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
#include <memory>
BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition( BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
@ -49,48 +51,37 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
in_streams_(in_streams), in_streams_(in_streams),
out_streams_(out_streams) out_streams_(out_streams)
{ {
Acq_Conf acq_parameters = Acq_Conf();
configuration_ = configuration; configuration_ = configuration;
std::string default_item_type = "gr_complex"; std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./data/acquisition.dat"; std::string default_dump_filename = "./acquisition.mat";
DLOG(INFO) << "role " << role; LOG(INFO) << "role " << role;
item_type_ = configuration_->property(role + ".item_type", default_item_type); item_type_ = configuration_->property(role + ".item_type", default_item_type);
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_; acq_parameters_.fs_in = fs_in_;
dump_ = configuration_->property(role + ".dump", false); dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_; acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true); blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_; acq_parameters_.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000); doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) if (FLAGS_doppler_max != 0)
{ {
doppler_max_ = FLAGS_doppler_max; doppler_max_ = FLAGS_doppler_max;
} }
acq_parameters.doppler_max = doppler_max_; acq_parameters_.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false); bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
acq_parameters.bit_transition_flag = bit_transition_flag_; acq_parameters_.bit_transition_flag = bit_transition_flag_;
use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions use_CFAR_algorithm_flag_ = configuration_->property(role + ".use_CFAR_algorithm", true); //will be false in future versions
acq_parameters.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_; acq_parameters_.use_CFAR_algorithm_flag = use_CFAR_algorithm_flag_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1); max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters.max_dwells = max_dwells_; acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters.dump_filename = dump_filename_; acq_parameters_.dump_filename = dump_filename_;
//--- Find number of samples per spreading code ------------------------- acq_parameters_.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
code_length_ = static_cast<uint32_t>(std::round(static_cast<double>(fs_in_) / (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_;
if (bit_transition_flag_)
{
vector_length_ *= 2;
}
code_ = new gr_complex[vector_length_];
if (item_type_ == "cshort") if (item_type_ == "cshort")
{ {
@ -100,18 +91,28 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
{ {
item_size_ = sizeof(gr_complex); item_size_ = sizeof(gr_complex);
} }
acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = code_length_;
acq_parameters.samples_per_code = code_length_;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); acq_parameters_.ms_per_code = 1;
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; acq_parameters_.it_size = item_size_;
num_codes_ = acq_parameters_.sampled_ms;
acq_parameters_.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters_.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters_.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
acq_parameters_.resampled_fs = fs_in_;
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (BEIDOU_B1I_CODE_RATE_HZ / BEIDOU_B1I_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / BEIDOU_B1I_CODE_RATE_HZ) * static_cast<float>(acq_parameters_.fs_in)));
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(BEIDOU_B1I_CODE_PERIOD * 1000.0);
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
if (item_type_ == "cbyte") if (item_type_ == "cbyte")
{ {
@ -123,7 +124,7 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -135,10 +136,7 @@ BeidouB1iPcpsAcquisition::BeidouB1iPcpsAcquisition(
} }
BeidouB1iPcpsAcquisition::~BeidouB1iPcpsAcquisition() BeidouB1iPcpsAcquisition::~BeidouB1iPcpsAcquisition() = default;
{
delete[] code_;
}
void BeidouB1iPcpsAcquisition::stop_acquisition() void BeidouB1iPcpsAcquisition::stop_acquisition()
@ -204,18 +202,17 @@ void BeidouB1iPcpsAcquisition::init()
void BeidouB1iPcpsAcquisition::set_local_code() void BeidouB1iPcpsAcquisition::set_local_code()
{ {
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
beidou_b1i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0); beidou_b1i_code_gen_complex_sampled(gsl::span<std::complex<float>>(code, code_length_), gnss_synchro_->PRN, fs_in_, 0);
for (uint32_t i = 0; i < sampled_ms_; i++) gsl::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < num_codes_; i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_.data());
delete[] code;
} }
@ -235,15 +232,7 @@ float BeidouB1iPcpsAcquisition::calculate_threshold(float pfa)
{ {
//Calculate the threshold //Calculate the threshold
uint32_t frequency_bins = 0; uint32_t frequency_bins = 0;
/*
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
{
frequency_bins++;
}
*/
frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_; frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_;
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa; DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
uint32_t ncells = vector_length_ * frequency_bins; uint32_t ncells = vector_length_ * frequency_bins;
double exponent = 1 / static_cast<double>(ncells); double exponent = 1 / static_cast<double>(ncells);
@ -268,9 +257,11 @@ void BeidouB1iPcpsAcquisition::connect(gr::top_block_sptr top_block)
} }
else if (item_type_ == "cbyte") else if (item_type_ == "cbyte")
{ {
// Since a byte-based acq implementation is not available,
// we just convert cshorts to gr_complex
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); top_block->connect(float_to_complex_, 0, acquisition_, 0);
} }
else else
{ {
@ -291,11 +282,9 @@ void BeidouB1iPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
} }
else if (item_type_ == "cbyte") else if (item_type_ == "cbyte")
{ {
// Since a byte-based acq implementation is not available,
// we just convert cshorts to gr_complex
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); top_block->disconnect(float_to_complex_, 0, acquisition_, 0);
} }
else else
{ {
@ -331,6 +320,7 @@ gr::basic_block_sptr BeidouB1iPcpsAcquisition::get_right_block()
return acquisition_; return acquisition_;
} }
void BeidouB1iPcpsAcquisition::set_resampler_latency(uint32_t latency_samples) void BeidouB1iPcpsAcquisition::set_resampler_latency(uint32_t latency_samples)
{ {
acquisition_->set_resampler_latency(latency_samples); acquisition_->set_resampler_latency(latency_samples);

View File

@ -42,7 +42,9 @@
#include <gnuradio/blocks/stream_to_vector.h> #include <gnuradio/blocks/stream_to_vector.h>
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <cstdint> #include <cstdint>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -100,15 +102,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_->set_channel_fsm(channel_fsm); acquisition_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -159,36 +160,34 @@ public:
*/ */
void set_resampler_latency(uint32_t latency_samples) override; void set_resampler_latency(uint32_t latency_samples) override;
private: private:
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_; pcps_acquisition_sptr acquisition_;
gr::blocks::stream_to_vector::sptr stream_to_vector_; Acq_Conf acq_parameters_;
gr::blocks::float_to_complex::sptr float_to_complex_; gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
size_t item_size_; size_t item_size_;
std::string item_type_; std::string item_type_;
uint32_t vector_length_; unsigned int vector_length_;
uint32_t code_length_; unsigned int code_length_;
bool bit_transition_flag_; bool bit_transition_flag_;
bool use_CFAR_algorithm_flag_; bool use_CFAR_algorithm_flag_;
uint32_t channel_; unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_; std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_; float threshold_;
uint32_t doppler_max_; unsigned int doppler_max_;
uint32_t doppler_step_; unsigned int doppler_step_;
uint32_t sampled_ms_; unsigned int max_dwells_;
uint32_t max_dwells_;
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
bool blocking_; bool blocking_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
uint32_t in_streams_; unsigned int num_codes_;
uint32_t out_streams_; unsigned int in_streams_;
unsigned int out_streams_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -37,7 +37,7 @@
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
using google::LogMessage; using google::LogMessage;
@ -49,46 +49,37 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
in_streams_(in_streams), in_streams_(in_streams),
out_streams_(out_streams) out_streams_(out_streams)
{ {
Acq_Conf acq_parameters = Acq_Conf();
configuration_ = configuration; configuration_ = configuration;
std::string default_item_type = "gr_complex"; std::string default_item_type = "gr_complex";
std::string default_dump_filename = "./data/acquisition.dat"; std::string default_dump_filename = "./acquisition.mat";
DLOG(INFO) << "role " << role; LOG(INFO) << "role " << role;
item_type_ = configuration_->property(role + ".item_type", default_item_type); item_type_ = configuration_->property(role + ".item_type", default_item_type);
int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000); int64_t fs_in_deprecated = configuration_->property("GNSS-SDR.internal_fs_hz", 2048000);
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
acq_parameters.fs_in = fs_in_; acq_parameters_.fs_in = fs_in_;
dump_ = configuration_->property(role + ".dump", false); dump_ = configuration_->property(role + ".dump", false);
acq_parameters.dump = dump_; acq_parameters_.dump = dump_;
acq_parameters_.dump_channel = configuration_->property(role + ".dump_channel", 0);
blocking_ = configuration_->property(role + ".blocking", true); blocking_ = configuration_->property(role + ".blocking", true);
acq_parameters.blocking = blocking_; acq_parameters_.blocking = blocking_;
doppler_max_ = configuration_->property(role + ".doppler_max", 5000); doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; if (FLAGS_doppler_max != 0)
acq_parameters.doppler_max = doppler_max_;
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
acq_parameters.sampled_ms = sampled_ms_;
bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
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_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
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; doppler_max_ = FLAGS_doppler_max;
} }
acq_parameters_.doppler_max = doppler_max_;
code_ = new gr_complex[vector_length_]; bit_transition_flag_ = configuration_->property(role + ".bit_transition_flag", false);
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_;
max_dwells_ = configuration_->property(role + ".max_dwells", 1);
acq_parameters_.max_dwells = max_dwells_;
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
acq_parameters_.dump_filename = dump_filename_;
acq_parameters_.sampled_ms = configuration_->property(role + ".coherent_integration_time_ms", 1);
if (item_type_ == "cshort") if (item_type_ == "cshort")
{ {
@ -98,18 +89,28 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
{ {
item_size_ = sizeof(gr_complex); item_size_ = sizeof(gr_complex);
} }
acq_parameters.it_size = item_size_;
acq_parameters.sampled_ms = sampled_ms_;
acq_parameters.samples_per_ms = code_length_;
acq_parameters.samples_per_code = code_length_;
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acquisition_ = pcps_make_acquisition(acq_parameters);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
stream_to_vector_ = gr::blocks::stream_to_vector::make(item_size_, vector_length_); acq_parameters_.ms_per_code = 1;
DLOG(INFO) << "stream_to_vector(" << stream_to_vector_->unique_id() << ")"; acq_parameters_.it_size = item_size_;
num_codes_ = acq_parameters_.sampled_ms;
acq_parameters_.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4);
acq_parameters_.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
acq_parameters_.make_2_steps = configuration_->property(role + ".make_two_steps", false);
acq_parameters_.blocking_on_standby = configuration_->property(role + ".blocking_on_standby", false);
acq_parameters_.use_automatic_resampler = configuration_->property("GNSS-SDR.use_acquisition_resampler", false);
acq_parameters_.resampled_fs = fs_in_;
//--- Find number of samples per spreading code -------------------------
code_length_ = static_cast<unsigned int>(std::floor(static_cast<double>(fs_in_) / (BEIDOU_B3I_CODE_RATE_HZ / BEIDOU_B3I_CODE_LENGTH_CHIPS)));
acq_parameters_.samples_per_ms = static_cast<float>(fs_in_) * 0.001;
acq_parameters_.samples_per_chip = static_cast<unsigned int>(ceil((1.0 / BEIDOU_B3I_CODE_RATE_HZ) * static_cast<float>(acq_parameters_.fs_in)));
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(BEIDOU_B3I_CODE_PERIOD * 1000.0);
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = std::vector<std::complex<float>>(vector_length_);
acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
if (item_type_ == "cbyte") if (item_type_ == "cbyte")
{ {
@ -121,7 +122,7 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -133,20 +134,22 @@ BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
} }
BeidouB3iPcpsAcquisition::~BeidouB3iPcpsAcquisition() BeidouB3iPcpsAcquisition::~BeidouB3iPcpsAcquisition() = default;
{
delete[] code_;
}
void BeidouB3iPcpsAcquisition::stop_acquisition() void BeidouB3iPcpsAcquisition::stop_acquisition()
{ {
} }
void BeidouB3iPcpsAcquisition::set_threshold(float threshold) void BeidouB3iPcpsAcquisition::set_threshold(float threshold)
{ {
float pfa = configuration_->property(role_ + ".pfa", 0.0); float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0);
if (pfa == 0.0)
{
pfa = configuration_->property(role_ + ".pfa", 0.0);
}
if (pfa == 0.0) if (pfa == 0.0)
{ {
threshold_ = threshold; threshold_ = threshold;
@ -195,24 +198,22 @@ signed int BeidouB3iPcpsAcquisition::mag()
void BeidouB3iPcpsAcquisition::init() void BeidouB3iPcpsAcquisition::init()
{ {
acquisition_->init(); acquisition_->init();
set_local_code();
} }
void BeidouB3iPcpsAcquisition::set_local_code() void BeidouB3iPcpsAcquisition::set_local_code()
{ {
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
beidou_b3i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0); beidou_b3i_code_gen_complex_sampled(gsl::span<std::complex<float>>(code, code_length_), gnss_synchro_->PRN, fs_in_, 0);
for (unsigned int i = 0; i < sampled_ms_; i++) gsl::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < num_codes_; i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_.data());
delete[] code;
} }
@ -232,20 +233,12 @@ float BeidouB3iPcpsAcquisition::calculate_threshold(float pfa)
{ {
//Calculate the threshold //Calculate the threshold
unsigned int frequency_bins = 0; unsigned int frequency_bins = 0;
/*
for (int doppler = (int)(-doppler_max_); doppler <= (int)doppler_max_; doppler += doppler_step_)
{
frequency_bins++;
}
*/
frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_; frequency_bins = (2 * doppler_max_ + doppler_step_) / doppler_step_;
DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa; DLOG(INFO) << "Channel " << channel_ << " Pfa = " << pfa;
unsigned int ncells = vector_length_ * frequency_bins; unsigned int ncells = vector_length_ * frequency_bins;
double exponent = 1 / static_cast<double>(ncells); double exponent = 1.0 / static_cast<double>(ncells);
double val = pow(1.0 - pfa, exponent); double val = pow(1.0 - pfa, exponent);
auto lambda = static_cast<double>(vector_length_); auto lambda = double(vector_length_);
boost::math::exponential_distribution<double> mydist(lambda); boost::math::exponential_distribution<double> mydist(lambda);
auto threshold = static_cast<float>(quantile(mydist, val)); auto threshold = static_cast<float>(quantile(mydist, val));
@ -265,9 +258,11 @@ void BeidouB3iPcpsAcquisition::connect(gr::top_block_sptr top_block)
} }
else if (item_type_ == "cbyte") else if (item_type_ == "cbyte")
{ {
// Since a byte-based acq implementation is not available,
// we just convert cshorts to gr_complex
top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->connect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1); top_block->connect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
top_block->connect(float_to_complex_, 0, stream_to_vector_, 0); top_block->connect(float_to_complex_, 0, acquisition_, 0);
} }
else else
{ {
@ -288,11 +283,9 @@ void BeidouB3iPcpsAcquisition::disconnect(gr::top_block_sptr top_block)
} }
else if (item_type_ == "cbyte") else if (item_type_ == "cbyte")
{ {
// Since a byte-based acq implementation is not available,
// we just convert cshorts to gr_complex
top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0); top_block->disconnect(cbyte_to_float_x2_, 0, float_to_complex_, 0);
top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1); top_block->disconnect(cbyte_to_float_x2_, 1, float_to_complex_, 1);
top_block->disconnect(float_to_complex_, 0, stream_to_vector_, 0); top_block->disconnect(float_to_complex_, 0, acquisition_, 0);
} }
else else
{ {
@ -307,7 +300,7 @@ gr::basic_block_sptr BeidouB3iPcpsAcquisition::get_left_block()
{ {
return acquisition_; return acquisition_;
} }
else if (item_type_ == "cshort") if (item_type_ == "cshort")
{ {
return acquisition_; return acquisition_;
} }

View File

@ -41,7 +41,9 @@
#include <gnuradio/blocks/stream_to_vector.h> #include <gnuradio/blocks/stream_to_vector.h>
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <cstdint> #include <cstdint>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -99,15 +101,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_->set_channel_fsm(channel_fsm); acquisition_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -158,11 +159,10 @@ public:
*/ */
void set_resampler_latency(uint32_t latency_samples) override; void set_resampler_latency(uint32_t latency_samples) override;
private: private:
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_; pcps_acquisition_sptr acquisition_;
gr::blocks::stream_to_vector::sptr stream_to_vector_; Acq_Conf acq_parameters_;
gr::blocks::float_to_complex::sptr float_to_complex_; gr::blocks::float_to_complex::sptr float_to_complex_;
complex_byte_to_float_x2_sptr cbyte_to_float_x2_; complex_byte_to_float_x2_sptr cbyte_to_float_x2_;
size_t item_size_; size_t item_size_;
@ -176,18 +176,17 @@ private:
float threshold_; float threshold_;
unsigned int doppler_max_; unsigned int doppler_max_;
unsigned int doppler_step_; unsigned int doppler_step_;
unsigned int sampled_ms_;
unsigned int max_dwells_; unsigned int max_dwells_;
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
bool blocking_; bool blocking_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int num_codes_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -36,6 +36,7 @@
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GalileoE1Pcps8msAmbiguousAcquisition::GalileoE1Pcps8msAmbiguousAcquisition( GalileoE1Pcps8msAmbiguousAcquisition::GalileoE1Pcps8msAmbiguousAcquisition(
@ -86,7 +87,7 @@ GalileoE1Pcps8msAmbiguousAcquisition::GalileoE1Pcps8msAmbiguousAcquisition(
int samples_per_ms = code_length_ / 4; int samples_per_ms = code_length_ / 4;
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
@ -110,7 +111,7 @@ GalileoE1Pcps8msAmbiguousAcquisition::GalileoE1Pcps8msAmbiguousAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -122,10 +123,7 @@ GalileoE1Pcps8msAmbiguousAcquisition::GalileoE1Pcps8msAmbiguousAcquisition(
} }
GalileoE1Pcps8msAmbiguousAcquisition::~GalileoE1Pcps8msAmbiguousAcquisition() GalileoE1Pcps8msAmbiguousAcquisition::~GalileoE1Pcps8msAmbiguousAcquisition() = default;
{
delete[] code_;
}
void GalileoE1Pcps8msAmbiguousAcquisition::stop_acquisition() void GalileoE1Pcps8msAmbiguousAcquisition::stop_acquisition()
@ -216,20 +214,20 @@ void GalileoE1Pcps8msAmbiguousAcquisition::set_local_code()
bool cboc = configuration_->property( bool cboc = configuration_->property(
"Acquisition" + std::to_string(channel_) + ".cboc", false); "Acquisition" + std::to_string(channel_) + ".cboc", false);
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
std::array<char, 3> Signal_;
std::memcpy(Signal_.data(), gnss_synchro_->Signal, 3);
galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, galileo_e1_code_gen_complex_sampled(gsl::span<std::complex<float>>(code, code_length_), Signal_,
cboc, gnss_synchro_->PRN, fs_in_, 0, false); cboc, gnss_synchro_->PRN, fs_in_, 0, false);
gsl::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < sampled_ms_ / 4; i++) for (unsigned int i = 0; i < sampled_ms_ / 4; i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
acquisition_cc_->set_local_code(code_); acquisition_cc_->set_local_code(code_.data());
delete[] code;
} }
} }
@ -242,6 +240,7 @@ void GalileoE1Pcps8msAmbiguousAcquisition::reset()
} }
} }
float GalileoE1Pcps8msAmbiguousAcquisition::calculate_threshold(float pfa) float GalileoE1Pcps8msAmbiguousAcquisition::calculate_threshold(float pfa)
{ {
unsigned int frequency_bins = 0; unsigned int frequency_bins = 0;

View File

@ -36,7 +36,9 @@
#include "galileo_pcps_8ms_acquisition_cc.h" #include "galileo_pcps_8ms_acquisition_cc.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include <gnuradio/blocks/stream_to_vector.h> #include <gnuradio/blocks/stream_to_vector.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -165,7 +167,7 @@ private:
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;

View File

@ -37,6 +37,7 @@
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition( GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
@ -126,7 +127,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
vector_length_ *= 2; vector_length_ *= 2;
} }
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort") if (item_type_ == "cshort")
{ {
@ -154,7 +155,7 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -166,16 +167,14 @@ GalileoE1PcpsAmbiguousAcquisition::GalileoE1PcpsAmbiguousAcquisition(
} }
GalileoE1PcpsAmbiguousAcquisition::~GalileoE1PcpsAmbiguousAcquisition() GalileoE1PcpsAmbiguousAcquisition::~GalileoE1PcpsAmbiguousAcquisition() = default;
{
delete[] code_;
}
void GalileoE1PcpsAmbiguousAcquisition::stop_acquisition() void GalileoE1PcpsAmbiguousAcquisition::stop_acquisition()
{ {
} }
void GalileoE1PcpsAmbiguousAcquisition::set_threshold(float threshold) void GalileoE1PcpsAmbiguousAcquisition::set_threshold(float threshold)
{ {
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0); float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0);
@ -242,45 +241,47 @@ void GalileoE1PcpsAmbiguousAcquisition::set_local_code()
bool cboc = configuration_->property( bool cboc = configuration_->property(
"Acquisition" + std::to_string(channel_) + ".cboc", false); "Acquisition" + std::to_string(channel_) + ".cboc", false);
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
gsl::span<std::complex<float>> code_span(code.get(), code_length_);
if (acquire_pilot_ == true) if (acquire_pilot_ == true)
{ {
//set local signal generator to Galileo E1 pilot component (1C) //set local signal generator to Galileo E1 pilot component (1C)
char pilot_signal[3] = "1C"; std::array<char, 3> pilot_signal = {{'1', 'C', '\0'}};
if (acq_parameters_.use_automatic_resampler) if (acq_parameters_.use_automatic_resampler)
{ {
galileo_e1_code_gen_complex_sampled(code, pilot_signal, galileo_e1_code_gen_complex_sampled(code_span, pilot_signal,
cboc, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0, false); cboc, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0, false);
} }
else else
{ {
galileo_e1_code_gen_complex_sampled(code, pilot_signal, galileo_e1_code_gen_complex_sampled(code_span, pilot_signal,
cboc, gnss_synchro_->PRN, fs_in_, 0, false); cboc, gnss_synchro_->PRN, fs_in_, 0, false);
} }
} }
else else
{ {
std::array<char, 3> Signal_;
std::memcpy(Signal_.data(), gnss_synchro_->Signal, 3);
if (acq_parameters_.use_automatic_resampler) if (acq_parameters_.use_automatic_resampler)
{ {
galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, galileo_e1_code_gen_complex_sampled(code_span, Signal_,
cboc, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0, false); cboc, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0, false);
} }
else else
{ {
galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, galileo_e1_code_gen_complex_sampled(code_span, Signal_,
cboc, gnss_synchro_->PRN, fs_in_, 0, false); cboc, gnss_synchro_->PRN, fs_in_, 0, false);
} }
} }
gsl::span<gr_complex> code__span(code_.data(), vector_length_);
for (unsigned int i = 0; i < sampled_ms_ / 4; i++) for (unsigned int i = 0; i < sampled_ms_ / 4; i++)
{ {
memcpy(&(code_[i * code_length_]), code, sizeof(gr_complex) * code_length_); std::copy_n(code.get(), code_length_, code__span.subspan(i * code_length_, code_length_).data());
} }
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_.data());
delete[] code;
} }

View File

@ -39,7 +39,9 @@
#include "pcps_acquisition.h" #include "pcps_acquisition.h"
#include <gnuradio/blocks/float_to_complex.h> #include <gnuradio/blocks/float_to_complex.h>
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -98,13 +100,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_->set_channel_fsm(channel_fsm); acquisition_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -153,10 +156,8 @@ public:
/*! /*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation * \brief Sets the resampler latency to account it in the acquisition code delay estimation
*/ */
void set_resampler_latency(uint32_t latency_samples) override; void set_resampler_latency(uint32_t latency_samples) override;
private: private:
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
Acq_Conf acq_parameters_; Acq_Conf acq_parameters_;
@ -181,7 +182,7 @@ private:
bool dump_; bool dump_;
bool blocking_; bool blocking_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;

View File

@ -40,9 +40,9 @@
#include <gnuradio/gr_complex.h> // for gr_complex #include <gnuradio/gr_complex.h> // for gr_complex
#include <volk/volk.h> // for volk_32fc_conjugate_32fc #include <volk/volk.h> // for volk_32fc_conjugate_32fc
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <cmath> // for abs, pow, floor #include <algorithm> // for copy_n
#include <complex> // for complex #include <cmath> // for abs, pow, floor
#include <cstring> // for memcpy #include <complex> // for complex
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA // the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking. // expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
@ -108,11 +108,12 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
// compute all the GALILEO E1 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time // compute all the GALILEO E1 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time
// a channel is assigned) // a channel is assigned)
auto* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT auto fft_if = std::unique_ptr<gr::fft::fft_complex>(new gr::fft::fft_complex(nsamples_total, true)); // Direct FFT
auto* code = new std::complex<float>[nsamples_total]; // buffer for the local code std::vector<std::complex<float>> code(nsamples_total); // buffer for the local code
auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
d_all_fft_codes_ = new uint32_t[(nsamples_total * GALILEO_E1_NUMBER_OF_CODES)]; // memory containing all the possible fft codes for PRN 0 to 32 d_all_fft_codes_ = std::vector<uint32_t>(nsamples_total * GALILEO_E1_NUMBER_OF_CODES); // memory containing all the possible fft codes for PRN 0 to 32
float max; // temporary maxima search
float max; // temporary maxima search
int32_t tmp, tmp2, local_code, fft_data; int32_t tmp, tmp2, local_code, fft_data;
for (uint32_t PRN = 1; PRN <= GALILEO_E1_NUMBER_OF_CODES; PRN++) for (uint32_t PRN = 1; PRN <= GALILEO_E1_NUMBER_OF_CODES; PRN++)
@ -122,14 +123,14 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
if (acquire_pilot_ == true) if (acquire_pilot_ == true)
{ {
//set local signal generator to Galileo E1 pilot component (1C) //set local signal generator to Galileo E1 pilot component (1C)
char pilot_signal[3] = "1C"; std::array<char, 3> pilot_signal = {{'1', 'C', '\0'}};
galileo_e1_code_gen_complex_sampled(code, pilot_signal, galileo_e1_code_gen_complex_sampled(gsl::span<std::complex<float>>(code.data(), nsamples_total), pilot_signal,
cboc, PRN, fs_in, 0, false); cboc, PRN, fs_in, 0, false);
} }
else else
{ {
char data_signal[3] = "1B"; std::array<char, 3> data_signal = {{'1', 'B', '\0'}};
galileo_e1_code_gen_complex_sampled(code, data_signal, galileo_e1_code_gen_complex_sampled(gsl::span<std::complex<float>>(code.data(), nsamples_total), data_signal,
cboc, PRN, fs_in, 0, false); cboc, PRN, fs_in, 0, false);
} }
@ -144,7 +145,7 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
code[s] = std::complex<float>(0.0, 0.0); code[s] = std::complex<float>(0.0, 0.0);
} }
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer
fft_if->execute(); // Run the FFT of local code fft_if->execute(); // Run the FFT of local code
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
@ -173,7 +174,7 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
} }
} }
acq_parameters.all_fft_codes = d_all_fft_codes_; acq_parameters.all_fft_codes = d_all_fft_codes_.data();
acq_parameters.num_doppler_bins_step2 = configuration_->property(role + ".second_nbins", 4); 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.doppler_step2 = configuration_->property(role + ".second_doppler_step", 125.0);
@ -188,17 +189,12 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga(
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
// temporary buffers that we can delete // temporary buffers that we can release
delete[] code; volk_gnsssdr_free(fft_codes_padded);
delete fft_if;
delete[] fft_codes_padded;
} }
GalileoE1PcpsAmbiguousAcquisitionFpga::~GalileoE1PcpsAmbiguousAcquisitionFpga() GalileoE1PcpsAmbiguousAcquisitionFpga::~GalileoE1PcpsAmbiguousAcquisitionFpga() = default;
{
delete[] d_all_fft_codes_;
}
void GalileoE1PcpsAmbiguousAcquisitionFpga::stop_acquisition() void GalileoE1PcpsAmbiguousAcquisitionFpga::stop_acquisition()

View File

@ -37,7 +37,9 @@
#include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr #include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr
#include <volk/volk_complex.h> // for lv_16sc_t #include <volk/volk_complex.h> // for lv_16sc_t
#include <cstddef> // for size_t #include <cstddef> // for size_t
#include <memory>
#include <string> #include <string>
#include <vector>
class Gnss_Synchro; class Gnss_Synchro;
class ConfigurationInterface; class ConfigurationInterface;
@ -97,8 +99,8 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
@ -165,8 +167,7 @@ private:
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
std::vector<uint32_t> d_all_fft_codes_; // memory that contains all the code ffts
uint32_t* d_all_fft_codes_; // memory that contains all the code ffts
}; };
#endif /* GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ */ #endif /* GNSS_SDR_GALILEO_E1_PCPS_AMBIGUOUS_ACQUISITION_FPGA_H_ */

View File

@ -86,8 +86,8 @@ GalileoE1PcpsCccwsrAmbiguousAcquisition::GalileoE1PcpsCccwsrAmbiguousAcquisition
int samples_per_ms = code_length_ / 4; int samples_per_ms = code_length_ / 4;
code_data_ = new gr_complex[vector_length_]; code_data_ = std::vector<std::complex<float>>(vector_length_);
code_pilot_ = new gr_complex[vector_length_]; code_pilot_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
@ -111,7 +111,7 @@ GalileoE1PcpsCccwsrAmbiguousAcquisition::GalileoE1PcpsCccwsrAmbiguousAcquisition
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -123,11 +123,7 @@ GalileoE1PcpsCccwsrAmbiguousAcquisition::GalileoE1PcpsCccwsrAmbiguousAcquisition
} }
GalileoE1PcpsCccwsrAmbiguousAcquisition::~GalileoE1PcpsCccwsrAmbiguousAcquisition() GalileoE1PcpsCccwsrAmbiguousAcquisition::~GalileoE1PcpsCccwsrAmbiguousAcquisition() = default;
{
delete[] code_data_;
delete[] code_pilot_;
}
void GalileoE1PcpsCccwsrAmbiguousAcquisition::stop_acquisition() void GalileoE1PcpsCccwsrAmbiguousAcquisition::stop_acquisition()
@ -168,6 +164,7 @@ void GalileoE1PcpsCccwsrAmbiguousAcquisition::set_doppler_step(unsigned int dopp
} }
} }
void GalileoE1PcpsCccwsrAmbiguousAcquisition::set_gnss_synchro( void GalileoE1PcpsCccwsrAmbiguousAcquisition::set_gnss_synchro(
Gnss_Synchro* gnss_synchro) Gnss_Synchro* gnss_synchro)
{ {
@ -203,19 +200,17 @@ void GalileoE1PcpsCccwsrAmbiguousAcquisition::set_local_code()
bool cboc = configuration_->property( bool cboc = configuration_->property(
"Acquisition" + std::to_string(channel_) + ".cboc", false); "Acquisition" + std::to_string(channel_) + ".cboc", false);
char signal[3]; std::array<char, 3> signal = {{'1', 'B', '\0'}};
strcpy(signal, "1B"); galileo_e1_code_gen_complex_sampled(gsl::span<gr_complex>(code_data_.data(), vector_length_), signal,
galileo_e1_code_gen_complex_sampled(code_data_, signal,
cboc, gnss_synchro_->PRN, fs_in_, 0, false); cboc, gnss_synchro_->PRN, fs_in_, 0, false);
strcpy(signal, "1C"); std::array<char, 3> signal_C = {{'1', 'C', '\0'}};
galileo_e1_code_gen_complex_sampled(code_pilot_, signal, galileo_e1_code_gen_complex_sampled(gsl::span<gr_complex>(code_pilot_.data(), vector_length_), signal_C,
cboc, gnss_synchro_->PRN, fs_in_, 0, false); cboc, gnss_synchro_->PRN, fs_in_, 0, false);
acquisition_cc_->set_local_code(code_data_, code_pilot_); acquisition_cc_->set_local_code(code_data_.data(), code_pilot_.data());
} }
} }
@ -228,6 +223,7 @@ void GalileoE1PcpsCccwsrAmbiguousAcquisition::reset()
} }
} }
void GalileoE1PcpsCccwsrAmbiguousAcquisition::set_state(int state) void GalileoE1PcpsCccwsrAmbiguousAcquisition::set_state(int state)
{ {
acquisition_cc_->set_state(state); acquisition_cc_->set_state(state);

View File

@ -36,7 +36,9 @@
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "pcps_cccwsr_acquisition_cc.h" #include "pcps_cccwsr_acquisition_cc.h"
#include <gnuradio/blocks/stream_to_vector.h> #include <gnuradio/blocks/stream_to_vector.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -94,13 +96,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_cc_->set_channel_fsm(channel_fsm); acquisition_cc_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of CCCWSR algorithm * \brief Set statistics threshold of CCCWSR algorithm
*/ */
@ -153,7 +156,6 @@ private:
std::string item_type_; std::string item_type_;
unsigned int vector_length_; unsigned int vector_length_;
unsigned int code_length_; unsigned int code_length_;
//unsigned int satellite_;
unsigned int channel_; unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_; std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_; float threshold_;
@ -164,8 +166,8 @@ private:
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_data_; std::vector<std::complex<float>> code_data_;
std::complex<float>* code_pilot_; std::vector<std::complex<float>> code_pilot_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;

View File

@ -36,6 +36,7 @@
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcquisition( GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcquisition(
@ -114,7 +115,7 @@ GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcqui
dump_filename_ = configuration_->property(role + ".dump_filename", dump_filename_ = configuration_->property(role + ".dump_filename",
default_dump_filename); default_dump_filename);
code_ = new gr_complex[code_length_]; code_ = std::vector<std::complex<float>>(code_length_);
LOG(INFO) << "Vector Length: " << vector_length_ LOG(INFO) << "Vector Length: " << vector_length_
<< ", Samples per ms: " << samples_per_ms << ", Samples per ms: " << samples_per_ms
<< ", Folding factor: " << folding_factor_ << ", Folding factor: " << folding_factor_
@ -144,7 +145,7 @@ GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcqui
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -156,10 +157,7 @@ GalileoE1PcpsQuickSyncAmbiguousAcquisition::GalileoE1PcpsQuickSyncAmbiguousAcqui
} }
GalileoE1PcpsQuickSyncAmbiguousAcquisition::~GalileoE1PcpsQuickSyncAmbiguousAcquisition() GalileoE1PcpsQuickSyncAmbiguousAcquisition::~GalileoE1PcpsQuickSyncAmbiguousAcquisition() = default;
{
delete[] code_;
}
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::stop_acquisition() void GalileoE1PcpsQuickSyncAmbiguousAcquisition::stop_acquisition()
@ -250,23 +248,20 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_local_code()
bool cboc = configuration_->property( bool cboc = configuration_->property(
"Acquisition" + std::to_string(channel_) + ".cboc", false); "Acquisition" + std::to_string(channel_) + ".cboc", false);
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
std::array<char, 3> Signal_;
std::memcpy(Signal_.data(), gnss_synchro_->Signal, 3);
galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, galileo_e1_code_gen_complex_sampled(gsl::span<std::complex<float>>(code.get(), code_length_), Signal_,
cboc, gnss_synchro_->PRN, fs_in_, 0, false); cboc, gnss_synchro_->PRN, fs_in_, 0, false);
gsl::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < (sampled_ms_ / (folding_factor_ * 4)); i++) for (unsigned int i = 0; i < (sampled_ms_ / (folding_factor_ * 4)); i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
// memcpy(code_, code,sizeof(gr_complex)*code_length_); acquisition_cc_->set_local_code(code_.data());
acquisition_cc_->set_local_code(code_);
delete[] code;
code = nullptr;
} }
} }
@ -279,6 +274,7 @@ void GalileoE1PcpsQuickSyncAmbiguousAcquisition::reset()
} }
} }
void GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_state(int state) void GalileoE1PcpsQuickSyncAmbiguousAcquisition::set_state(int state)
{ {
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")

View File

@ -36,7 +36,9 @@
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "pcps_quicksync_acquisition_cc.h" #include "pcps_quicksync_acquisition_cc.h"
#include <gnuradio/blocks/stream_to_vector.h> #include <gnuradio/blocks/stream_to_vector.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -169,7 +171,7 @@ private:
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;

View File

@ -36,6 +36,7 @@
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GalileoE1PcpsTongAmbiguousAcquisition::GalileoE1PcpsTongAmbiguousAcquisition( GalileoE1PcpsTongAmbiguousAcquisition::GalileoE1PcpsTongAmbiguousAcquisition(
@ -89,7 +90,7 @@ GalileoE1PcpsTongAmbiguousAcquisition::GalileoE1PcpsTongAmbiguousAcquisition(
int samples_per_ms = code_length_ / 4; int samples_per_ms = code_length_ / 4;
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
@ -114,7 +115,7 @@ GalileoE1PcpsTongAmbiguousAcquisition::GalileoE1PcpsTongAmbiguousAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -126,10 +127,7 @@ GalileoE1PcpsTongAmbiguousAcquisition::GalileoE1PcpsTongAmbiguousAcquisition(
} }
GalileoE1PcpsTongAmbiguousAcquisition::~GalileoE1PcpsTongAmbiguousAcquisition() GalileoE1PcpsTongAmbiguousAcquisition::~GalileoE1PcpsTongAmbiguousAcquisition() = default;
{
delete[] code_;
}
void GalileoE1PcpsTongAmbiguousAcquisition::stop_acquisition() void GalileoE1PcpsTongAmbiguousAcquisition::stop_acquisition()
@ -220,20 +218,19 @@ void GalileoE1PcpsTongAmbiguousAcquisition::set_local_code()
bool cboc = configuration_->property( bool cboc = configuration_->property(
"Acquisition" + std::to_string(channel_) + ".cboc", false); "Acquisition" + std::to_string(channel_) + ".cboc", false);
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
std::array<char, 3> Signal_;
galileo_e1_code_gen_complex_sampled(code, gnss_synchro_->Signal, std::memcpy(Signal_.data(), gnss_synchro_->Signal, 3);
galileo_e1_code_gen_complex_sampled(gsl::span<std::complex<float>>(code.get(), code_length_), Signal_,
cboc, gnss_synchro_->PRN, fs_in_, 0, false); cboc, gnss_synchro_->PRN, fs_in_, 0, false);
gsl::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < sampled_ms_ / 4; i++) for (unsigned int i = 0; i < sampled_ms_ / 4; i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
acquisition_cc_->set_local_code(code_); acquisition_cc_->set_local_code(code_.data());
delete[] code;
} }
} }
@ -246,6 +243,7 @@ void GalileoE1PcpsTongAmbiguousAcquisition::reset()
} }
} }
void GalileoE1PcpsTongAmbiguousAcquisition::set_state(int state) void GalileoE1PcpsTongAmbiguousAcquisition::set_state(int state)
{ {
acquisition_cc_->set_state(state); acquisition_cc_->set_state(state);

View File

@ -36,7 +36,9 @@
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "pcps_tong_acquisition_cc.h" #include "pcps_tong_acquisition_cc.h"
#include <gnuradio/blocks/stream_to_vector.h> #include <gnuradio/blocks/stream_to_vector.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -168,7 +170,7 @@ private:
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;

View File

@ -42,6 +42,7 @@
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf( GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf(
@ -93,8 +94,8 @@ GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf(
vector_length_ = code_length_ * sampled_ms_; vector_length_ = code_length_ * sampled_ms_;
codeI_ = new gr_complex[vector_length_]; codeI_ = std::vector<std::complex<float>>(vector_length_);
codeQ_ = new gr_complex[vector_length_]; codeQ_ = std::vector<std::complex<float>>(vector_length_);
both_signal_components = false; both_signal_components = false;
std::string sig_ = configuration_->property("Channel.signal", std::string("5X")); std::string sig_ = configuration_->property("Channel.signal", std::string("5X"));
@ -119,7 +120,7 @@ GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -131,11 +132,7 @@ GalileoE5aNoncoherentIQAcquisitionCaf::GalileoE5aNoncoherentIQAcquisitionCaf(
} }
GalileoE5aNoncoherentIQAcquisitionCaf::~GalileoE5aNoncoherentIQAcquisitionCaf() GalileoE5aNoncoherentIQAcquisitionCaf::~GalileoE5aNoncoherentIQAcquisitionCaf() = default;
{
delete[] codeI_;
delete[] codeQ_;
}
void GalileoE5aNoncoherentIQAcquisitionCaf::stop_acquisition() void GalileoE5aNoncoherentIQAcquisitionCaf::stop_acquisition()
@ -223,55 +220,51 @@ void GalileoE5aNoncoherentIQAcquisitionCaf::set_local_code()
{ {
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
auto* codeI = new std::complex<float>[code_length_]; std::vector<std::complex<float>> codeI(code_length_);
auto* codeQ = new std::complex<float>[code_length_]; std::vector<std::complex<float>> codeQ(code_length_);
if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X') if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X')
{ {
char a[3]; std::array<char, 3> a = {{'5', 'I', '\0'}};
strcpy(a, "5I"); galileo_e5_a_code_gen_complex_sampled(gsl::span<std::complex<float>>(codeI.data(), code_length_), a,
galileo_e5_a_code_gen_complex_sampled(codeI, a,
gnss_synchro_->PRN, fs_in_, 0); gnss_synchro_->PRN, fs_in_, 0);
strcpy(a, "5Q"); std::array<char, 3> b = {{'5', 'Q', '\0'}};
galileo_e5_a_code_gen_complex_sampled(codeQ, a, galileo_e5_a_code_gen_complex_sampled(gsl::span<std::complex<float>>(codeQ.data(), code_length_), b,
gnss_synchro_->PRN, fs_in_, 0); gnss_synchro_->PRN, fs_in_, 0);
} }
else else
{ {
galileo_e5_a_code_gen_complex_sampled(codeI, gnss_synchro_->Signal, std::array<char, 3> signal_type_ = {{'5', 'X', '\0'}};
galileo_e5_a_code_gen_complex_sampled(gsl::span<std::complex<float>>(codeI.data(), code_length_), signal_type_,
gnss_synchro_->PRN, fs_in_, 0); gnss_synchro_->PRN, fs_in_, 0);
} }
// WARNING: 3ms are coherently integrated. Secondary sequence (1,1,1) // WARNING: 3ms are coherently integrated. Secondary sequence (1,1,1)
// is generated, and modulated in the 'block'. // is generated, and modulated in the 'block'.
gsl::span<gr_complex> codeQ_span(codeQ_.data(), vector_length_);
gsl::span<gr_complex> codeI_span(codeI_.data(), vector_length_);
if (Zero_padding == 0) // if no zero_padding if (Zero_padding == 0) // if no zero_padding
{ {
for (unsigned int i = 0; i < sampled_ms_; i++) for (unsigned int i = 0; i < sampled_ms_; i++)
{ {
memcpy(&(codeI_[i * code_length_]), codeI, std::copy_n(codeI.data(), code_length_, codeI_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X') if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X')
{ {
memcpy(&(codeQ_[i * code_length_]), codeQ, std::copy_n(codeQ.data(), code_length_, codeQ_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
} }
} }
else else
{ {
// 1ms code + 1ms zero padding // 1ms code + 1ms zero padding
memcpy(&(codeI_[0]), codeI, std::copy_n(codeI.data(), code_length_, codeI_.data());
sizeof(gr_complex) * code_length_);
if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X') if (gnss_synchro_->Signal[0] == '5' && gnss_synchro_->Signal[1] == 'X')
{ {
memcpy(&(codeQ_[0]), codeQ, std::copy_n(codeQ.data(), code_length_, codeQ_.data());
sizeof(gr_complex) * code_length_);
} }
} }
acquisition_cc_->set_local_code(codeI_, codeQ_); acquisition_cc_->set_local_code(codeI_.data(), codeQ_.data());
delete[] codeI;
delete[] codeQ;
} }
} }

View File

@ -41,7 +41,9 @@
#include "channel_fsm.h" #include "channel_fsm.h"
#include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h" #include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -95,13 +97,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_cc_->set_channel_fsm(channel_fsm); acquisition_cc_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -171,8 +174,8 @@ private:
std::string dump_filename_; std::string dump_filename_;
int Zero_padding; int Zero_padding;
int CAF_window_hz_; int CAF_window_hz_;
std::complex<float>* codeI_; std::vector<std::complex<float>> codeI_;
std::complex<float>* codeQ_; std::vector<std::complex<float>> codeQ_;
bool both_signal_components; bool both_signal_components;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;

View File

@ -37,6 +37,7 @@
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <volk_gnsssdr/volk_gnsssdr_complex.h> #include <volk_gnsssdr/volk_gnsssdr_complex.h>
#include <algorithm>
GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* configuration, GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* configuration,
@ -123,7 +124,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / GALILEO_E5A_CODE_CHIP_RATE_HZ * static_cast<double>(GALILEO_E5A_CODE_LENGTH_CHIPS))); code_length_ = static_cast<unsigned int>(std::round(static_cast<double>(fs_in_) / GALILEO_E5A_CODE_CHIP_RATE_HZ * static_cast<double>(GALILEO_E5A_CODE_LENGTH_CHIPS)));
vector_length_ = code_length_ * sampled_ms_; vector_length_ = code_length_ * sampled_ms_;
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
@ -152,7 +153,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -164,10 +165,7 @@ GalileoE5aPcpsAcquisition::GalileoE5aPcpsAcquisition(ConfigurationInterface* con
} }
GalileoE5aPcpsAcquisition::~GalileoE5aPcpsAcquisition() GalileoE5aPcpsAcquisition::~GalileoE5aPcpsAcquisition() = default;
{
delete[] code_;
}
void GalileoE5aPcpsAcquisition::stop_acquisition() void GalileoE5aPcpsAcquisition::stop_acquisition()
@ -235,38 +233,39 @@ void GalileoE5aPcpsAcquisition::init()
void GalileoE5aPcpsAcquisition::set_local_code() void GalileoE5aPcpsAcquisition::set_local_code()
{ {
auto* code = new gr_complex[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
char signal_[3]; std::array<char, 3> signal_;
signal_[0] = '5';
signal_[2] = '\0';
if (acq_iq_) if (acq_iq_)
{ {
strcpy(signal_, "5X"); signal_[1] = 'X';
} }
else if (acq_pilot_) else if (acq_pilot_)
{ {
strcpy(signal_, "5Q"); signal_[1] = 'Q';
} }
else else
{ {
strcpy(signal_, "5I"); signal_[1] = 'I';
} }
if (acq_parameters_.use_automatic_resampler) if (acq_parameters_.use_automatic_resampler)
{ {
galileo_e5_a_code_gen_complex_sampled(code, signal_, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0); galileo_e5_a_code_gen_complex_sampled(gsl::span<gr_complex>(code.get(), code_length_), signal_, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0);
} }
else else
{ {
galileo_e5_a_code_gen_complex_sampled(code, signal_, gnss_synchro_->PRN, fs_in_, 0); galileo_e5_a_code_gen_complex_sampled(gsl::span<gr_complex>(code.get(), code_length_), signal_, 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 < sampled_ms_; i++)
{ {
memcpy(code_ + (i * code_length_), code, sizeof(gr_complex) * code_length_); std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
} }
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_.data());
delete[] code;
} }

View File

@ -35,7 +35,9 @@
#include "channel_fsm.h" #include "channel_fsm.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "pcps_acquisition.h" #include "pcps_acquisition.h"
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -86,13 +88,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_->set_channel_fsm(channel_fsm); acquisition_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -143,29 +146,23 @@ public:
/*! /*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation * \brief Sets the resampler latency to account it in the acquisition code delay estimation
*/ */
void set_resampler_latency(uint32_t latency_samples) override; void set_resampler_latency(uint32_t latency_samples) override;
private: private:
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_; pcps_acquisition_sptr acquisition_;
Acq_Conf acq_parameters_; Acq_Conf acq_parameters_;
size_t item_size_; size_t item_size_;
std::string item_type_; std::string item_type_;
std::string dump_filename_; std::string dump_filename_;
std::string role_; std::string role_;
bool bit_transition_flag_; bool bit_transition_flag_;
bool dump_; bool dump_;
bool acq_pilot_; bool acq_pilot_;
bool use_CFAR_; bool use_CFAR_;
bool blocking_; bool blocking_;
bool acq_iq_; bool acq_iq_;
unsigned int vector_length_; unsigned int vector_length_;
unsigned int code_length_; unsigned int code_length_;
unsigned int channel_; unsigned int channel_;
@ -176,18 +173,10 @@ private:
unsigned int max_dwells_; unsigned int max_dwells_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
int64_t fs_in_; int64_t fs_in_;
float threshold_; float threshold_;
std::vector<std::complex<float>> code_;
/*
std::complex<float>* codeI_;
std::complex<float>* codeQ_;
*/
gr_complex* code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
}; };
#endif /* GALILEO_E5A_PCPS_ACQUISITION_H_ */ #endif /* GALILEO_E5A_PCPS_ACQUISITION_H_ */

View File

@ -40,9 +40,9 @@
#include <gnuradio/gr_complex.h> // for gr_complex #include <gnuradio/gr_complex.h> // for gr_complex
#include <volk/volk.h> // for volk_32fc_conjugate_32fc #include <volk/volk.h> // for volk_32fc_conjugate_32fc
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <cmath> // for abs, pow, floor #include <algorithm> // for copy_n
#include <complex> // for complex #include <cmath> // for abs, pow, floor
#include <cstring> // for strcpy, memcpy #include <complex> // for complex
// the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA // the following flags are FPGA-specific and they are using arrange the values of the fft of the local code in the way the FPGA
// expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking. // expects. This arrangement is done in the initialisation to avoid consuming unnecessary clock cycles during tracking.
@ -109,32 +109,34 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
// compute all the GALILEO E5 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time // compute all the GALILEO E5 PRN Codes (this is done only once in the class constructor in order to avoid re-computing the PRN codes every time
// a channel is assigned) // a channel is assigned)
auto* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT auto fft_if = std::unique_ptr<gr::fft::fft_complex>(new gr::fft::fft_complex(nsamples_total, true)); // Direct FFT
auto* code = new std::complex<float>[nsamples_total]; // buffer for the local code std::vector<std::complex<float>> code(nsamples_total); // buffer for the local code
auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
d_all_fft_codes_ = new uint32_t[(nsamples_total * GALILEO_E5A_NUMBER_OF_CODES)]; // memory containing all the possible fft codes for PRN 0 to 32 d_all_fft_codes_ = std::vector<uint32_t>(nsamples_total * GALILEO_E5A_NUMBER_OF_CODES); // memory containing all the possible fft codes for PRN 0 to 32
float max; // temporary maxima search float max; // temporary maxima search
int32_t tmp, tmp2, local_code, fft_data; int32_t tmp, tmp2, local_code, fft_data;
for (uint32_t PRN = 1; PRN <= GALILEO_E5A_NUMBER_OF_CODES; PRN++) for (uint32_t PRN = 1; PRN <= GALILEO_E5A_NUMBER_OF_CODES; PRN++)
{ {
char signal_[3]; std::array<char, 3> signal_;
signal_[0] = '5';
signal_[2] = '\0';
if (acq_iq_) if (acq_iq_)
{ {
strcpy(signal_, "5X"); signal_[1] = 'X';
} }
else if (acq_pilot_) else if (acq_pilot_)
{ {
strcpy(signal_, "5Q"); signal_[1] = 'Q';
} }
else else
{ {
strcpy(signal_, "5I"); signal_[1] = 'I';
} }
galileo_e5_a_code_gen_complex_sampled(code, signal_, PRN, fs_in, 0); galileo_e5_a_code_gen_complex_sampled(gsl::span<std::complex<float>>(code.data(), nsamples_total), signal_, PRN, fs_in, 0);
for (uint32_t s = code_length; s < 2 * code_length; s++) for (uint32_t s = code_length; s < 2 * code_length; s++)
{ {
@ -147,7 +149,7 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
code[s] = std::complex<float>(0.0, 0.0); code[s] = std::complex<float>(0.0, 0.0);
} }
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer
fft_if->execute(); // Run the FFT of local code fft_if->execute(); // Run the FFT of local code
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
@ -175,7 +177,7 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
} }
} }
acq_parameters.all_fft_codes = d_all_fft_codes_; acq_parameters.all_fft_codes = d_all_fft_codes_.data();
// reference for the FPGA FFT-IFFT attenuation factor // reference for the FPGA FFT-IFFT attenuation factor
acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 13); acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 13);
@ -190,17 +192,12 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga(ConfigurationInterf
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
// temporary buffers that we can delete // temporary buffers that we can release
delete[] code; volk_gnsssdr_free(fft_codes_padded);
delete fft_if;
delete[] fft_codes_padded;
} }
GalileoE5aPcpsAcquisitionFpga::~GalileoE5aPcpsAcquisitionFpga() GalileoE5aPcpsAcquisitionFpga::~GalileoE5aPcpsAcquisitionFpga() = default;
{
delete[] d_all_fft_codes_;
}
void GalileoE5aPcpsAcquisitionFpga::stop_acquisition() void GalileoE5aPcpsAcquisitionFpga::stop_acquisition()

View File

@ -39,7 +39,9 @@
#include <volk/volk_complex.h> // for lv_16sc_t #include <volk/volk_complex.h> // for lv_16sc_t
#include <cstddef> // for size_t #include <cstddef> // for size_t
#include <cstdint> #include <cstdint>
#include <memory>
#include <string> #include <string>
#include <vector>
class Gnss_Synchro; class Gnss_Synchro;
class ConfigurationInterface; class ConfigurationInterface;
@ -99,8 +101,8 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
@ -167,24 +169,19 @@ public:
private: private:
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
pcps_acquisition_fpga_sptr acquisition_fpga_; pcps_acquisition_fpga_sptr acquisition_fpga_;
std::string item_type_; std::string item_type_;
std::string dump_filename_; std::string dump_filename_;
std::string role_; std::string role_;
bool acq_pilot_; bool acq_pilot_;
bool acq_iq_; bool acq_iq_;
uint32_t channel_; uint32_t channel_;
std::weak_ptr<ChannelFsm> channel_fsm_; std::weak_ptr<ChannelFsm> channel_fsm_;
uint32_t doppler_max_; uint32_t doppler_max_;
uint32_t doppler_step_; uint32_t doppler_step_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::vector<uint32_t> d_all_fft_codes_; // memory that contains all the code ffts
uint32_t* d_all_fft_codes_; // memory that contains all the code ffts
}; };
#endif /* GNSS_SDR_GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ */ #endif /* GNSS_SDR_GALILEO_E5A_PCPS_ACQUISITION_FPGA_H_ */

View File

@ -39,6 +39,7 @@
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition( GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
@ -93,7 +94,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
vector_length_ *= 2; vector_length_ *= 2;
} }
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort") if (item_type_ == "cshort")
{ {
@ -125,7 +126,7 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -137,16 +138,14 @@ GlonassL1CaPcpsAcquisition::GlonassL1CaPcpsAcquisition(
} }
GlonassL1CaPcpsAcquisition::~GlonassL1CaPcpsAcquisition() GlonassL1CaPcpsAcquisition::~GlonassL1CaPcpsAcquisition() = default;
{
delete[] code_;
}
void GlonassL1CaPcpsAcquisition::stop_acquisition() void GlonassL1CaPcpsAcquisition::stop_acquisition()
{ {
} }
void GlonassL1CaPcpsAcquisition::set_threshold(float threshold) void GlonassL1CaPcpsAcquisition::set_threshold(float threshold)
{ {
float pfa = configuration_->property(role_ + ".pfa", 0.0); float pfa = configuration_->property(role_ + ".pfa", 0.0);
@ -206,18 +205,17 @@ void GlonassL1CaPcpsAcquisition::init()
void GlonassL1CaPcpsAcquisition::set_local_code() void GlonassL1CaPcpsAcquisition::set_local_code()
{ {
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
glonass_l1_ca_code_gen_complex_sampled(code, /* gnss_synchro_->PRN,*/ fs_in_, 0); glonass_l1_ca_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 < sampled_ms_; i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_.data());
delete[] code;
} }

View File

@ -39,7 +39,9 @@
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "pcps_acquisition.h" #include "pcps_acquisition.h"
#include <gnuradio/blocks/float_to_complex.h> #include <gnuradio/blocks/float_to_complex.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -86,6 +88,7 @@ public:
* tracking blocks * tracking blocks
*/ */
void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override; void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro) override;
/*! /*!
* \brief Set acquisition channel unique ID * \brief Set acquisition channel unique ID
*/ */
@ -96,13 +99,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_->set_channel_fsm(channel_fsm); acquisition_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -172,12 +176,11 @@ private:
bool dump_; bool dump_;
bool blocking_; bool blocking_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -38,6 +38,7 @@
#include "gnss_sdr_flags.h" #include "gnss_sdr_flags.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition( GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
@ -92,7 +93,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
vector_length_ *= 2; vector_length_ *= 2;
} }
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort") if (item_type_ == "cshort")
{ {
@ -124,7 +125,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -136,10 +137,7 @@ GlonassL2CaPcpsAcquisition::GlonassL2CaPcpsAcquisition(
} }
GlonassL2CaPcpsAcquisition::~GlonassL2CaPcpsAcquisition() GlonassL2CaPcpsAcquisition::~GlonassL2CaPcpsAcquisition() = default;
{
delete[] code_;
}
void GlonassL2CaPcpsAcquisition::stop_acquisition() void GlonassL2CaPcpsAcquisition::stop_acquisition()
@ -206,18 +204,17 @@ void GlonassL2CaPcpsAcquisition::init()
void GlonassL2CaPcpsAcquisition::set_local_code() void GlonassL2CaPcpsAcquisition::set_local_code()
{ {
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
glonass_l2_ca_code_gen_complex_sampled(code, /* gnss_synchro_->PRN,*/ fs_in_, 0); glonass_l2_ca_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 < sampled_ms_; i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_.data());
delete[] code;
} }

View File

@ -38,7 +38,9 @@
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "pcps_acquisition.h" #include "pcps_acquisition.h"
#include <gnuradio/blocks/float_to_complex.h> #include <gnuradio/blocks/float_to_complex.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -96,13 +98,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_->set_channel_fsm(channel_fsm); acquisition_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -172,12 +175,11 @@ private:
bool dump_; bool dump_;
bool blocking_; bool blocking_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -41,6 +41,8 @@
#include "gps_sdr_signal_processing.h" #include "gps_sdr_signal_processing.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
#include <gsl/gsl>
GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition( GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
@ -121,7 +123,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD * 1000.0); acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L1_CA_CODE_PERIOD * 1000.0);
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort") if (item_type_ == "cshort")
{ {
@ -147,7 +149,7 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -159,16 +161,14 @@ GpsL1CaPcpsAcquisition::GpsL1CaPcpsAcquisition(
} }
GpsL1CaPcpsAcquisition::~GpsL1CaPcpsAcquisition() GpsL1CaPcpsAcquisition::~GpsL1CaPcpsAcquisition() = default;
{
delete[] code_;
}
void GpsL1CaPcpsAcquisition::stop_acquisition() void GpsL1CaPcpsAcquisition::stop_acquisition()
{ {
} }
void GpsL1CaPcpsAcquisition::set_threshold(float threshold) void GpsL1CaPcpsAcquisition::set_threshold(float threshold)
{ {
float pfa = configuration_->property(role_ + ".pfa", 0.0); float pfa = configuration_->property(role_ + ".pfa", 0.0);
@ -226,24 +226,23 @@ void GpsL1CaPcpsAcquisition::init()
void GpsL1CaPcpsAcquisition::set_local_code() void GpsL1CaPcpsAcquisition::set_local_code()
{ {
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
if (acq_parameters_.use_automatic_resampler) if (acq_parameters_.use_automatic_resampler)
{ {
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0); gps_l1_ca_code_gen_complex_sampled(gsl::span<std::complex<float>>(code, code_length_), gnss_synchro_->PRN, acq_parameters_.resampled_fs, 0);
} }
else else
{ {
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0); gps_l1_ca_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 < sampled_ms_; i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_.data());
delete[] code;
} }

View File

@ -43,7 +43,9 @@
#include "pcps_acquisition.h" #include "pcps_acquisition.h"
#include <gnuradio/blocks/float_to_complex.h> #include <gnuradio/blocks/float_to_complex.h>
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -102,13 +104,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_->set_channel_fsm(channel_fsm); acquisition_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -157,10 +160,8 @@ public:
/*! /*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation * \brief Sets the resampler latency to account it in the acquisition code delay estimation
*/ */
void set_resampler_latency(uint32_t latency_samples) override; void set_resampler_latency(uint32_t latency_samples) override;
private: private:
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_; pcps_acquisition_sptr acquisition_;
@ -184,12 +185,11 @@ private:
bool dump_; bool dump_;
bool blocking_; bool blocking_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -80,7 +80,7 @@ GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler(
//--- Find number of samples per spreading code ------------------------- //--- Find number of samples per spreading code -------------------------
vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
acq_parameters.samples_per_ms = vector_length_; acq_parameters.samples_per_ms = vector_length_;
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
@ -97,7 +97,7 @@ GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -109,10 +109,7 @@ GpsL1CaPcpsAcquisitionFineDoppler::GpsL1CaPcpsAcquisitionFineDoppler(
} }
GpsL1CaPcpsAcquisitionFineDoppler::~GpsL1CaPcpsAcquisitionFineDoppler() GpsL1CaPcpsAcquisitionFineDoppler::~GpsL1CaPcpsAcquisitionFineDoppler() = default;
{
delete[] code_;
}
void GpsL1CaPcpsAcquisitionFineDoppler::stop_acquisition() void GpsL1CaPcpsAcquisitionFineDoppler::stop_acquisition()
@ -163,8 +160,8 @@ void GpsL1CaPcpsAcquisitionFineDoppler::init()
void GpsL1CaPcpsAcquisitionFineDoppler::set_local_code() void GpsL1CaPcpsAcquisitionFineDoppler::set_local_code()
{ {
gps_l1_ca_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_, 0); gps_l1_ca_code_gen_complex_sampled(gsl::span<std::complex<float>>(code_.data(), vector_length_), gnss_synchro_->PRN, fs_in_, 0);
acquisition_cc_->set_local_code(code_); acquisition_cc_->set_local_code(code_.data());
} }

View File

@ -37,7 +37,9 @@
#include "channel_fsm.h" #include "channel_fsm.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "pcps_acquisition_fine_doppler_cc.h" #include "pcps_acquisition_fine_doppler_cc.h"
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -95,13 +97,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_cc_->set_channel_fsm(channel_fsm); acquisition_cc_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -161,7 +164,7 @@ private:
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;

View File

@ -43,9 +43,9 @@
#include <gnuradio/gr_complex.h> // for gr_complex #include <gnuradio/gr_complex.h> // for gr_complex
#include <volk/volk.h> // for volk_32fc_conjugate_32fc #include <volk/volk.h> // for volk_32fc_conjugate_32fc
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <cmath> // for abs, pow, floor #include <algorithm> // for copy_n
#include <complex> // for complex #include <cmath> // for abs, pow, floor
#include <cstring> // for memcpy #include <complex> // for complex
#define NUM_PRNs 32 #define NUM_PRNs 32
@ -103,17 +103,17 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
// compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time // compute all the GPS L1 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
// a channel is assigned) // a channel is assigned)
auto* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT auto fft_if = std::unique_ptr<gr::fft::fft_complex>(new gr::fft::fft_complex(nsamples_total, true));
// allocate memory to compute all the PRNs and compute all the possible codes // allocate memory to compute all the PRNs and compute all the possible codes
auto* code = new std::complex<float>[nsamples_total]; // buffer for the local code std::vector<std::complex<float>> code(nsamples_total); // buffer for the local code
auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
d_all_fft_codes_ = new uint32_t[(nsamples_total * NUM_PRNs)]; // memory containing all the possible fft codes for PRN 0 to 32 d_all_fft_codes_ = std::vector<uint32_t>(nsamples_total * NUM_PRNs); // memory containing all the possible fft codes for PRN 0 to 32
float max; float max;
int32_t tmp, tmp2, local_code, fft_data; int32_t tmp, tmp2, local_code, fft_data;
// temporary maxima search // temporary maxima search
for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++) for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++)
{ {
gps_l1_ca_code_gen_complex_sampled(code, PRN, fs_in, 0); // generate PRN code gps_l1_ca_code_gen_complex_sampled(gsl::span<std::complex<float>>(code.data(), nsamples_total), PRN, fs_in, 0); // generate PRN code
for (uint32_t s = code_length; s < 2 * code_length; s++) for (uint32_t s = code_length; s < 2 * code_length; s++)
{ {
@ -126,7 +126,7 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
code[s] = std::complex<float>(0.0, 0.0); code[s] = std::complex<float>(0.0, 0.0);
} }
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer
fft_if->execute(); // Run the FFT of local code fft_if->execute(); // Run the FFT of local code
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
@ -154,8 +154,8 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
} }
} }
//acq_parameters // acq_parameters
acq_parameters.all_fft_codes = d_all_fft_codes_; acq_parameters.all_fft_codes = d_all_fft_codes_.data();
// reference for the FPGA FFT-IFFT attenuation factor // reference for the FPGA FFT-IFFT attenuation factor
acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 10); acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 10);
@ -169,18 +169,13 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga(
channel_ = 0; channel_ = 0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
// temporary buffers that we can delete // temporary buffers that we can release
delete[] code; volk_gnsssdr_free(fft_codes_padded);
delete fft_if;
delete[] fft_codes_padded;
} }
GpsL1CaPcpsAcquisitionFpga::~GpsL1CaPcpsAcquisitionFpga() GpsL1CaPcpsAcquisitionFpga::~GpsL1CaPcpsAcquisitionFpga() = default;
{
delete[] d_all_fft_codes_;
}
void GpsL1CaPcpsAcquisitionFpga::stop_acquisition() void GpsL1CaPcpsAcquisitionFpga::stop_acquisition()

View File

@ -41,7 +41,9 @@
#include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr #include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr
#include <volk/volk_complex.h> // for lv_16sc_t #include <volk/volk_complex.h> // for lv_16sc_t
#include <cstddef> // for size_t #include <cstddef> // for size_t
#include <string> // for string #include <memory>
#include <string>
#include <vector>
class Gnss_Synchro; class Gnss_Synchro;
class ConfigurationInterface; class ConfigurationInterface;
@ -167,7 +169,7 @@ private:
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
uint32_t* d_all_fft_codes_; // memory that contains all the code ffts std::vector<uint32_t> d_all_fft_codes_; // memory that contains all the code ffts
}; };
#endif /* GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FPGA_H_ */ #endif /* GNSS_SDR_GPS_L1_CA_PCPS_ACQUISITION_FPGA_H_ */

View File

@ -70,7 +70,7 @@ GpsL1CaPcpsAssistedAcquisition::GpsL1CaPcpsAssistedAcquisition(
//--- Find number of samples per spreading code ------------------------- //--- Find number of samples per spreading code -------------------------
vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS)); vector_length_ = round(fs_in_ / (GPS_L1_CA_CODE_RATE_HZ / GPS_L1_CA_CODE_LENGTH_CHIPS));
code_ = new gr_complex[vector_length_]; code_ = std::make_shared<std::complex<float>>(vector_length_);
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
@ -89,7 +89,7 @@ GpsL1CaPcpsAssistedAcquisition::GpsL1CaPcpsAssistedAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -101,10 +101,7 @@ GpsL1CaPcpsAssistedAcquisition::GpsL1CaPcpsAssistedAcquisition(
} }
GpsL1CaPcpsAssistedAcquisition::~GpsL1CaPcpsAssistedAcquisition() GpsL1CaPcpsAssistedAcquisition::~GpsL1CaPcpsAssistedAcquisition() = default;
{
delete[] code_;
}
void GpsL1CaPcpsAssistedAcquisition::stop_acquisition() void GpsL1CaPcpsAssistedAcquisition::stop_acquisition()
@ -154,8 +151,8 @@ void GpsL1CaPcpsAssistedAcquisition::init()
void GpsL1CaPcpsAssistedAcquisition::set_local_code() void GpsL1CaPcpsAssistedAcquisition::set_local_code()
{ {
gps_l1_ca_code_gen_complex_sampled(code_, gnss_synchro_->PRN, fs_in_, 0); gps_l1_ca_code_gen_complex_sampled(gsl::span<gr_complex>(code_.get(), vector_length_), gnss_synchro_->PRN, fs_in_, 0);
acquisition_cc_->set_local_code(code_); acquisition_cc_->set_local_code(code_.get());
} }
void GpsL1CaPcpsAssistedAcquisition::reset() void GpsL1CaPcpsAssistedAcquisition::reset()

View File

@ -37,7 +37,9 @@
#include "channel_fsm.h" #include "channel_fsm.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "pcps_assisted_acquisition_cc.h" #include "pcps_assisted_acquisition_cc.h"
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -95,13 +97,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_cc_->set_channel_fsm(channel_fsm); acquisition_cc_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -147,7 +150,6 @@ private:
size_t item_size_; size_t item_size_;
std::string item_type_; std::string item_type_;
unsigned int vector_length_; unsigned int vector_length_;
//unsigned int satellite_;
unsigned int channel_; unsigned int channel_;
std::weak_ptr<ChannelFsm> channel_fsm_; std::weak_ptr<ChannelFsm> channel_fsm_;
float threshold_; float threshold_;
@ -159,7 +161,7 @@ private:
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::shared_ptr<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;

View File

@ -36,6 +36,7 @@
#include "gps_sdr_signal_processing.h" #include "gps_sdr_signal_processing.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GpsL1CaPcpsOpenClAcquisition::GpsL1CaPcpsOpenClAcquisition( GpsL1CaPcpsOpenClAcquisition::GpsL1CaPcpsOpenClAcquisition(
@ -59,7 +60,10 @@ GpsL1CaPcpsOpenClAcquisition::GpsL1CaPcpsOpenClAcquisition(
fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated); fs_in_ = configuration_->property("GNSS-SDR.internal_fs_sps", fs_in_deprecated);
dump_ = configuration_->property(role + ".dump", false); dump_ = configuration_->property(role + ".dump", false);
doppler_max_ = configuration->property(role + ".doppler_max", 5000); doppler_max_ = configuration->property(role + ".doppler_max", 5000);
if (FLAGS_doppler_max != 0) doppler_max_ = FLAGS_doppler_max; if (FLAGS_doppler_max != 0)
{
doppler_max_ = FLAGS_doppler_max;
}
sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1); sampled_ms_ = configuration_->property(role + ".coherent_integration_time_ms", 1);
bit_transition_flag_ = configuration_->property("Acquisition.bit_transition_flag", false); bit_transition_flag_ = configuration_->property("Acquisition.bit_transition_flag", false);
@ -81,7 +85,7 @@ GpsL1CaPcpsOpenClAcquisition::GpsL1CaPcpsOpenClAcquisition(
vector_length_ = code_length_ * sampled_ms_; vector_length_ = code_length_ * sampled_ms_;
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
@ -105,7 +109,7 @@ GpsL1CaPcpsOpenClAcquisition::GpsL1CaPcpsOpenClAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -117,16 +121,14 @@ GpsL1CaPcpsOpenClAcquisition::GpsL1CaPcpsOpenClAcquisition(
} }
GpsL1CaPcpsOpenClAcquisition::~GpsL1CaPcpsOpenClAcquisition() GpsL1CaPcpsOpenClAcquisition::~GpsL1CaPcpsOpenClAcquisition() = default;
{
delete[] code_;
}
void GpsL1CaPcpsOpenClAcquisition::stop_acquisition() void GpsL1CaPcpsOpenClAcquisition::stop_acquisition()
{ {
} }
void GpsL1CaPcpsOpenClAcquisition::set_threshold(float threshold) void GpsL1CaPcpsOpenClAcquisition::set_threshold(float threshold)
{ {
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0); float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0);
@ -207,19 +209,17 @@ void GpsL1CaPcpsOpenClAcquisition::set_local_code()
{ {
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0); gps_l1_ca_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 < sampled_ms_; i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
acquisition_cc_->set_local_code(code_); acquisition_cc_->set_local_code(code_.data());
delete[] code;
} }
} }

View File

@ -36,7 +36,9 @@
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "pcps_opencl_acquisition_cc.h" #include "pcps_opencl_acquisition_cc.h"
#include <gnuradio/blocks/stream_to_vector.h> #include <gnuradio/blocks/stream_to_vector.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -94,13 +96,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_cc_->set_channel_fsm(channel_fsm); acquisition_cc_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -169,12 +172,11 @@ private:
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -37,6 +37,7 @@
#include "gps_sdr_signal_processing.h" #include "gps_sdr_signal_processing.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition( GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition(
@ -104,7 +105,7 @@ GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition(
dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename); dump_filename_ = configuration_->property(role + ".dump_filename", default_dump_filename);
int samples_per_ms = round(code_length_); int samples_per_ms = round(code_length_);
code_ = new gr_complex[code_length_](); code_ = std::vector<std::complex<float>>(code_length_);
/*Object relevant information for debugging*/ /*Object relevant information for debugging*/
LOG(INFO) << "Implementation: " << this->implementation() LOG(INFO) << "Implementation: " << this->implementation()
<< ", Vector Length: " << vector_length_ << ", Vector Length: " << vector_length_
@ -137,7 +138,7 @@ GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -149,16 +150,14 @@ GpsL1CaPcpsQuickSyncAcquisition::GpsL1CaPcpsQuickSyncAcquisition(
} }
GpsL1CaPcpsQuickSyncAcquisition::~GpsL1CaPcpsQuickSyncAcquisition() GpsL1CaPcpsQuickSyncAcquisition::~GpsL1CaPcpsQuickSyncAcquisition() = default;
{
delete[] code_;
}
void GpsL1CaPcpsQuickSyncAcquisition::stop_acquisition() void GpsL1CaPcpsQuickSyncAcquisition::stop_acquisition()
{ {
} }
void GpsL1CaPcpsQuickSyncAcquisition::set_threshold(float threshold) void GpsL1CaPcpsQuickSyncAcquisition::set_threshold(float threshold)
{ {
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0); float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0);
@ -236,20 +235,17 @@ void GpsL1CaPcpsQuickSyncAcquisition::set_local_code()
{ {
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
auto* code = new std::complex<float>[code_length_](); std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0); gps_l1_ca_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_ / folding_factor_); i++) for (unsigned int i = 0; i < (sampled_ms_ / folding_factor_); i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
//memcpy(code_, code,sizeof(gr_complex)*code_length_); acquisition_cc_->set_local_code(code_.data());
acquisition_cc_->set_local_code(code_);
delete[] code;
} }
} }

View File

@ -38,7 +38,9 @@
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "pcps_quicksync_acquisition_cc.h" #include "pcps_quicksync_acquisition_cc.h"
#include <gnuradio/blocks/stream_to_vector.h> #include <gnuradio/blocks/stream_to_vector.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -96,13 +98,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_cc_->set_channel_fsm(channel_fsm); acquisition_cc_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -170,12 +173,11 @@ private:
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -36,6 +36,7 @@
#include "gps_sdr_signal_processing.h" #include "gps_sdr_signal_processing.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GpsL1CaPcpsTongAcquisition::GpsL1CaPcpsTongAcquisition( GpsL1CaPcpsTongAcquisition::GpsL1CaPcpsTongAcquisition(
@ -75,7 +76,7 @@ GpsL1CaPcpsTongAcquisition::GpsL1CaPcpsTongAcquisition(
vector_length_ = code_length_ * sampled_ms_; vector_length_ = code_length_ * sampled_ms_;
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
@ -99,7 +100,7 @@ GpsL1CaPcpsTongAcquisition::GpsL1CaPcpsTongAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -111,16 +112,14 @@ GpsL1CaPcpsTongAcquisition::GpsL1CaPcpsTongAcquisition(
} }
GpsL1CaPcpsTongAcquisition::~GpsL1CaPcpsTongAcquisition() GpsL1CaPcpsTongAcquisition::~GpsL1CaPcpsTongAcquisition() = default;
{
delete[] code_;
}
void GpsL1CaPcpsTongAcquisition::stop_acquisition() void GpsL1CaPcpsTongAcquisition::stop_acquisition()
{ {
} }
void GpsL1CaPcpsTongAcquisition::set_threshold(float threshold) void GpsL1CaPcpsTongAcquisition::set_threshold(float threshold)
{ {
float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0); float pfa = configuration_->property(role_ + std::to_string(channel_) + ".pfa", 0.0);
@ -193,23 +192,22 @@ void GpsL1CaPcpsTongAcquisition::init()
//set_local_code(); //set_local_code();
} }
void GpsL1CaPcpsTongAcquisition::set_local_code() void GpsL1CaPcpsTongAcquisition::set_local_code()
{ {
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
gps_l1_ca_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_, 0); gps_l1_ca_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 < sampled_ms_; i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
acquisition_cc_->set_local_code(code_); acquisition_cc_->set_local_code(code_.data());
delete[] code;
} }
} }

View File

@ -37,7 +37,9 @@
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "pcps_tong_acquisition_cc.h" #include "pcps_tong_acquisition_cc.h"
#include <gnuradio/blocks/stream_to_vector.h> #include <gnuradio/blocks/stream_to_vector.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -95,13 +97,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_cc_->set_channel_fsm(channel_fsm); acquisition_cc_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of TONG algorithm * \brief Set statistics threshold of TONG algorithm
*/ */
@ -169,12 +172,11 @@ private:
int64_t fs_in_; int64_t fs_in_;
bool dump_; bool dump_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -39,6 +39,7 @@
#include "gps_l2c_signal.h" #include "gps_l2c_signal.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition( GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
@ -126,7 +127,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L2_M_PERIOD * 1000.0); acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L2_M_PERIOD * 1000.0);
vector_length_ = acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms * (acq_parameters_.bit_transition_flag ? 2 : 1); vector_length_ = acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
if (item_type_ == "cshort") if (item_type_ == "cshort")
{ {
@ -151,7 +152,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
num_codes_ = acq_parameters_.sampled_ms / acq_parameters_.ms_per_code; num_codes_ = acq_parameters_.sampled_ms / acq_parameters_.ms_per_code;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
@ -164,10 +165,7 @@ GpsL2MPcpsAcquisition::GpsL2MPcpsAcquisition(
} }
GpsL2MPcpsAcquisition::~GpsL2MPcpsAcquisition() GpsL2MPcpsAcquisition::~GpsL2MPcpsAcquisition() = default;
{
delete[] code_;
}
void GpsL2MPcpsAcquisition::stop_acquisition() void GpsL2MPcpsAcquisition::stop_acquisition()
@ -239,27 +237,24 @@ void GpsL2MPcpsAcquisition::init()
void GpsL2MPcpsAcquisition::set_local_code() void GpsL2MPcpsAcquisition::set_local_code()
{ {
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
if (acq_parameters_.use_automatic_resampler) if (acq_parameters_.use_automatic_resampler)
{ {
gps_l2c_m_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.resampled_fs); gps_l2c_m_code_gen_complex_sampled(gsl::span<std::complex<float>>(code.get(), code_length_), gnss_synchro_->PRN, acq_parameters_.resampled_fs);
} }
else else
{ {
gps_l2c_m_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_); gps_l2c_m_code_gen_complex_sampled(gsl::span<std::complex<float>>(code.get(), code_length_), gnss_synchro_->PRN, fs_in_);
} }
gsl::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < num_codes_; i++) for (unsigned int i = 0; i < num_codes_; i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_.data());
delete[] code;
} }
@ -268,6 +263,7 @@ void GpsL2MPcpsAcquisition::reset()
acquisition_->set_active(true); acquisition_->set_active(true);
} }
void GpsL2MPcpsAcquisition::set_state(int state) void GpsL2MPcpsAcquisition::set_state(int state)
{ {
acquisition_->set_state(state); acquisition_->set_state(state);

View File

@ -40,7 +40,9 @@
#include "pcps_acquisition.h" #include "pcps_acquisition.h"
#include <gnuradio/blocks/float_to_complex.h> #include <gnuradio/blocks/float_to_complex.h>
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -99,13 +101,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_->set_channel_fsm(channel_fsm); acquisition_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -154,10 +157,8 @@ public:
/*! /*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation * \brief Sets the resampler latency to account it in the acquisition code delay estimation
*/ */
void set_resampler_latency(uint32_t latency_samples) override; void set_resampler_latency(uint32_t latency_samples) override;
private: private:
ConfigurationInterface* configuration_; ConfigurationInterface* configuration_;
pcps_acquisition_sptr acquisition_; pcps_acquisition_sptr acquisition_;
@ -180,13 +181,12 @@ private:
bool dump_; bool dump_;
bool blocking_; bool blocking_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
unsigned int num_codes_; unsigned int num_codes_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -42,9 +42,9 @@
#include <gnuradio/gr_complex.h> // for gr_complex #include <gnuradio/gr_complex.h> // for gr_complex
#include <volk/volk.h> // for volk_32fc_conjugate_32fc #include <volk/volk.h> // for volk_32fc_conjugate_32fc
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <cmath> // for abs, pow, floor #include <algorithm> // for copy_n
#include <complex> // for complex #include <cmath> // for abs, pow, floor
#include <cstring> // for memcpy #include <complex> // for complex
#define NUM_PRNs 32 #define NUM_PRNs 32
#define QUANT_BITS_LOCAL_CODE 16 #define QUANT_BITS_LOCAL_CODE 16
@ -102,24 +102,24 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga(
// compute all the GPS L2C PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time // compute all the GPS L2C PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
// a channel is assigned) // a channel is assigned)
auto* fft_if = new gr::fft::fft_complex(vector_length, true); // Direct FFT auto fft_if = std::unique_ptr<gr::fft::fft_complex>(new gr::fft::fft_complex(nsamples_total, true)); // Direct FFT
// allocate memory to compute all the PRNs and compute all the possible codes // allocate memory to compute all the PRNs and compute all the possible codes
auto* code = new std::complex<float>[nsamples_total]; // buffer for the local code std::vector<std::complex<float>> code(nsamples_total); // buffer for the local code
auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
//d_all_fft_codes_ = new lv_16sc_t[nsamples_total * NUM_PRNs]; // memory containing all the possible fft codes for PRN 0 to 32 d_all_fft_codes_ = std::vector<uint32_t>(nsamples_total * NUM_PRNs); // memory containing all the possible fft codes for PRN 0 to 32
d_all_fft_codes_ = new uint32_t[(nsamples_total * NUM_PRNs)]; // memory containing all the possible fft codes for PRN 0 to 32
float max; // temporary maxima search float max; // temporary maxima search
int32_t tmp, tmp2, local_code, fft_data; int32_t tmp, tmp2, local_code, fft_data;
for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++) for (unsigned int PRN = 1; PRN <= NUM_PRNs; PRN++)
{ {
gps_l2c_m_code_gen_complex_sampled(code, PRN, fs_in_); gps_l2c_m_code_gen_complex_sampled(gsl::span<std::complex<float>>(code.data(), nsamples_total), PRN, fs_in_);
// fill in zero padding // fill in zero padding
for (unsigned int s = code_length; s < nsamples_total; s++) for (unsigned int s = code_length; s < nsamples_total; s++)
{ {
code[s] = std::complex<float>(0.0, 0.0); code[s] = std::complex<float>(0.0, 0.0);
} }
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer
fft_if->execute(); // Run the FFT of local code fft_if->execute(); // Run the FFT of local code
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
max = 0; // initialize maximum value max = 0; // initialize maximum value
@ -149,28 +149,22 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga(
} }
} }
acq_parameters.all_fft_codes = d_all_fft_codes_; acq_parameters.all_fft_codes = d_all_fft_codes_.data();
// temporary buffers that we can delete
delete[] code;
delete fft_if;
delete[] fft_codes_padded;
acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters); acquisition_fpga_ = pcps_make_acquisition_fpga(acq_parameters);
channel_ = 0; channel_ = 0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
threshold_ = 0.0; threshold_ = 0.0;
// temporary buffers that we can release
volk_gnsssdr_free(fft_codes_padded);
} }
GpsL2MPcpsAcquisitionFpga::~GpsL2MPcpsAcquisitionFpga() GpsL2MPcpsAcquisitionFpga::~GpsL2MPcpsAcquisitionFpga() = default;
{
delete[] d_all_fft_codes_;
}
void GpsL2MPcpsAcquisitionFpga::stop_acquisition() void GpsL2MPcpsAcquisitionFpga::stop_acquisition()

View File

@ -39,7 +39,9 @@
#include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr #include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr
#include <volk/volk_complex.h> // for lv_16sc_t #include <volk/volk_complex.h> // for lv_16sc_t
#include <cstddef> // for size_t #include <cstddef> // for size_t
#include <memory> // for weak_ptr
#include <string> // for string #include <string> // for string
#include <vector>
class Gnss_Synchro; class Gnss_Synchro;
class ConfigurationInterface; class ConfigurationInterface;
@ -98,8 +100,8 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
@ -168,10 +170,7 @@ private:
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
std::vector<uint32_t> d_all_fft_codes_; // memory that contains all the code ffts
uint32_t* d_all_fft_codes_; // memory that contains all the code ffts
//float calculate_threshold(float pfa);
}; };
#endif /* GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H_ */ #endif /* GNSS_SDR_GPS_L2_M_PCPS_ACQUISITION_FPGA_H_ */

View File

@ -39,6 +39,7 @@
#include "gps_l5_signal.h" #include "gps_l5_signal.h"
#include <boost/math/distributions/exponential.hpp> #include <boost/math/distributions/exponential.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <algorithm>
GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition( GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
@ -133,7 +134,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L5I_PERIOD * 1000.0); acq_parameters_.samples_per_code = acq_parameters_.samples_per_ms * static_cast<float>(GPS_L5I_PERIOD * 1000.0);
vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1); vector_length_ = std::floor(acq_parameters_.sampled_ms * acq_parameters_.samples_per_ms) * (acq_parameters_.bit_transition_flag ? 2 : 1);
code_ = new gr_complex[vector_length_]; code_ = std::vector<std::complex<float>>(vector_length_);
acquisition_ = pcps_make_acquisition(acq_parameters_); acquisition_ = pcps_make_acquisition(acq_parameters_);
DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")"; DLOG(INFO) << "acquisition(" << acquisition_->unique_id() << ")";
@ -147,7 +148,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
threshold_ = 0.0; threshold_ = 0.0;
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
if (in_streams_ > 1) if (in_streams_ > 1)
{ {
LOG(ERROR) << "This implementation only supports one input stream"; LOG(ERROR) << "This implementation only supports one input stream";
@ -159,10 +160,7 @@ GpsL5iPcpsAcquisition::GpsL5iPcpsAcquisition(
} }
GpsL5iPcpsAcquisition::~GpsL5iPcpsAcquisition() GpsL5iPcpsAcquisition::~GpsL5iPcpsAcquisition() = default;
{
delete[] code_;
}
void GpsL5iPcpsAcquisition::stop_acquisition() void GpsL5iPcpsAcquisition::stop_acquisition()
@ -230,28 +228,27 @@ void GpsL5iPcpsAcquisition::init()
acquisition_->init(); acquisition_->init();
} }
void GpsL5iPcpsAcquisition::set_local_code() void GpsL5iPcpsAcquisition::set_local_code()
{ {
auto* code = new std::complex<float>[code_length_]; std::unique_ptr<std::complex<float>> code{new std::complex<float>[code_length_]};
if (acq_parameters_.use_automatic_resampler) if (acq_parameters_.use_automatic_resampler)
{ {
gps_l5i_code_gen_complex_sampled(code, gnss_synchro_->PRN, acq_parameters_.resampled_fs); gps_l5i_code_gen_complex_sampled(gsl::span<std::complex<float>>(code.get(), code_length_), gnss_synchro_->PRN, acq_parameters_.resampled_fs);
} }
else else
{ {
gps_l5i_code_gen_complex_sampled(code, gnss_synchro_->PRN, fs_in_); gps_l5i_code_gen_complex_sampled(gsl::span<std::complex<float>>(code.get(), code_length_), gnss_synchro_->PRN, fs_in_);
} }
gsl::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < num_codes_; i++) for (unsigned int i = 0; i < num_codes_; i++)
{ {
memcpy(&(code_[i * code_length_]), code, std::copy_n(code.get(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
sizeof(gr_complex) * code_length_);
} }
acquisition_->set_local_code(code_); acquisition_->set_local_code(code_.data());
delete[] code;
} }
@ -260,6 +257,7 @@ void GpsL5iPcpsAcquisition::reset()
acquisition_->set_active(true); acquisition_->set_active(true);
} }
void GpsL5iPcpsAcquisition::set_state(int state) void GpsL5iPcpsAcquisition::set_state(int state)
{ {
acquisition_->set_state(state); acquisition_->set_state(state);
@ -359,6 +357,7 @@ gr::basic_block_sptr GpsL5iPcpsAcquisition::get_right_block()
return acquisition_; return acquisition_;
} }
void GpsL5iPcpsAcquisition::set_resampler_latency(uint32_t latency_samples) void GpsL5iPcpsAcquisition::set_resampler_latency(uint32_t latency_samples)
{ {
acquisition_->set_resampler_latency(latency_samples); acquisition_->set_resampler_latency(latency_samples);

View File

@ -31,8 +31,8 @@
* ------------------------------------------------------------------------- * -------------------------------------------------------------------------
*/ */
#ifndef GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_H_ #ifndef GNSS_SDR_GPS_L5I_PCPS_ACQUISITION_H_
#define GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_H_ #define GNSS_SDR_GPS_L5I_PCPS_ACQUISITION_H_
#include "channel_fsm.h" #include "channel_fsm.h"
#include "complex_byte_to_float_x2.h" #include "complex_byte_to_float_x2.h"
@ -40,7 +40,9 @@
#include "pcps_acquisition.h" #include "pcps_acquisition.h"
#include <gnuradio/blocks/float_to_complex.h> #include <gnuradio/blocks/float_to_complex.h>
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <memory>
#include <string> #include <string>
#include <vector>
class ConfigurationInterface; class ConfigurationInterface;
@ -99,13 +101,14 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
acquisition_->set_channel_fsm(channel_fsm); acquisition_->set_channel_fsm(channel_fsm);
} }
/*! /*!
* \brief Set statistics threshold of PCPS algorithm * \brief Set statistics threshold of PCPS algorithm
*/ */
@ -154,7 +157,6 @@ public:
/*! /*!
* \brief Sets the resampler latency to account it in the acquisition code delay estimation * \brief Sets the resampler latency to account it in the acquisition code delay estimation
*/ */
void set_resampler_latency(uint32_t latency_samples) override; void set_resampler_latency(uint32_t latency_samples) override;
private: private:
@ -179,14 +181,13 @@ private:
bool dump_; bool dump_;
bool blocking_; bool blocking_;
std::string dump_filename_; std::string dump_filename_;
std::complex<float>* code_; std::vector<std::complex<float>> code_;
Gnss_Synchro* gnss_synchro_; Gnss_Synchro* gnss_synchro_;
std::string role_; std::string role_;
unsigned int num_codes_; unsigned int num_codes_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };
#endif /* GNSS_SDR_GPS_L5i_PCPS_ACQUISITION_H_ */ #endif /* GNSS_SDR_GPS_L5I_PCPS_ACQUISITION_H_ */

View File

@ -43,9 +43,9 @@
#include <gnuradio/gr_complex.h> // for gr_complex #include <gnuradio/gr_complex.h> // for gr_complex
#include <volk/volk.h> // for volk_32fc_conjugate_32fc #include <volk/volk.h> // for volk_32fc_conjugate_32fc
#include <volk_gnsssdr/volk_gnsssdr.h> #include <volk_gnsssdr/volk_gnsssdr.h>
#include <cmath> // for abs, pow, floor #include <algorithm> // for copy_n
#include <complex> // for complex #include <cmath> // for abs, pow, floor
#include <cstring> // for memcpy #include <complex> // for complex
#define NUM_PRNs 32 #define NUM_PRNs 32
@ -108,17 +108,17 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga(
// compute all the GPS L5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time // compute all the GPS L5 PRN Codes (this is done only once upon the class constructor in order to avoid re-computing the PRN codes every time
// a channel is assigned) // a channel is assigned)
auto* fft_if = new gr::fft::fft_complex(nsamples_total, true); // Direct FFT auto fft_if = std::unique_ptr<gr::fft::fft_complex>(new gr::fft::fft_complex(nsamples_total, true)); // Direct FFT
auto* code = new gr_complex[nsamples_total]; std::vector<std::complex<float>> code(nsamples_total);
auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment())); auto* fft_codes_padded = static_cast<gr_complex*>(volk_gnsssdr_malloc(nsamples_total * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
d_all_fft_codes_ = new uint32_t[(nsamples_total * NUM_PRNs)]; // memory containing all the possible fft codes for PRN 0 to 32 d_all_fft_codes_ = std::vector<uint32_t>(nsamples_total * NUM_PRNs); // memory containing all the possible fft codes for PRN 0 to 32
float max; // temporary maxima search float max; // temporary maxima search
int32_t tmp, tmp2, local_code, fft_data; int32_t tmp, tmp2, local_code, fft_data;
for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++) for (uint32_t PRN = 1; PRN <= NUM_PRNs; PRN++)
{ {
gps_l5i_code_gen_complex_sampled(code, PRN, fs_in); gps_l5i_code_gen_complex_sampled(gsl::span<gr_complex>(code.data(), nsamples_total), PRN, fs_in);
for (uint32_t s = code_length; s < 2 * code_length; s++) for (uint32_t s = code_length; s < 2 * code_length; s++)
{ {
@ -130,7 +130,7 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga(
// fill in zero padding // fill in zero padding
code[s] = std::complex<float>(0.0, 0.0); code[s] = std::complex<float>(0.0, 0.0);
} }
memcpy(fft_if->get_inbuf(), code, sizeof(gr_complex) * nsamples_total); // copy to FFT buffer std::copy_n(code.data(), nsamples_total, fft_if->get_inbuf()); // copy to FFT buffer
fft_if->execute(); // Run the FFT of local code fft_if->execute(); // Run the FFT of local code
volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values volk_32fc_conjugate_32fc(fft_codes_padded, fft_if->get_outbuf(), nsamples_total); // conjugate values
@ -158,7 +158,7 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga(
} }
} }
acq_parameters.all_fft_codes = d_all_fft_codes_; acq_parameters.all_fft_codes = d_all_fft_codes_.data();
// reference for the FPGA FFT-IFFT attenuation factor // reference for the FPGA FFT-IFFT attenuation factor
acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 13); acq_parameters.total_block_exp = configuration_->property(role + ".total_block_exp", 13);
@ -173,18 +173,12 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga(
doppler_step_ = 0; doppler_step_ = 0;
gnss_synchro_ = nullptr; gnss_synchro_ = nullptr;
// temporary buffers that we can delete // temporary buffers that we can release
delete[] code; volk_gnsssdr_free(fft_codes_padded);
delete fft_if;
delete[] fft_codes_padded;
} }
GpsL5iPcpsAcquisitionFpga::~GpsL5iPcpsAcquisitionFpga() GpsL5iPcpsAcquisitionFpga::~GpsL5iPcpsAcquisitionFpga() = default;
{
//delete[] code_;
delete[] d_all_fft_codes_;
}
void GpsL5iPcpsAcquisitionFpga::stop_acquisition() void GpsL5iPcpsAcquisitionFpga::stop_acquisition()

View File

@ -40,7 +40,9 @@
#include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr #include <gnuradio/runtime_types.h> // for basic_block_sptr, top_block_sptr
#include <volk/volk_complex.h> // for lv_16sc_t #include <volk/volk_complex.h> // for lv_16sc_t
#include <cstddef> // for size_t #include <cstddef> // for size_t
#include <memory>
#include <string> #include <string>
#include <vector>
class Gnss_Synchro; class Gnss_Synchro;
class ConfigurationInterface; class ConfigurationInterface;
@ -99,8 +101,8 @@ public:
} }
/*! /*!
* \brief Set channel fsm associated to this acquisition instance * \brief Set channel fsm associated to this acquisition instance
*/ */
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) override
{ {
channel_fsm_ = channel_fsm; channel_fsm_ = channel_fsm;
@ -167,9 +169,7 @@ private:
std::string role_; std::string role_;
unsigned int in_streams_; unsigned int in_streams_;
unsigned int out_streams_; unsigned int out_streams_;
std::vector<uint32_t> d_all_fft_codes_; // memory that contains all the code ffts
uint32_t* d_all_fft_codes_; // memory that contains all the code ffts
float calculate_threshold(float pfa); float calculate_threshold(float pfa);
}; };

View File

@ -145,10 +145,10 @@ galileo_e5a_noncoherentIQ_acquisition_caf_cc::galileo_e5a_noncoherentIQ_acquisit
} }
// Direct FFT // Direct FFT
d_fft_if = new gr::fft::fft_complex(d_fft_size, true); d_fft_if = std::make_shared<gr::fft::fft_complex>(d_fft_size, true);
// Inverse FFT // Inverse FFT
d_ifft = new gr::fft::fft_complex(d_fft_size, false); d_ifft = std::make_shared<gr::fft::fft_complex>(d_fft_size, false);
// For dumping samples into a file // For dumping samples into a file
d_dump = dump; d_dump = dump;
@ -210,9 +210,6 @@ galileo_e5a_noncoherentIQ_acquisition_caf_cc::~galileo_e5a_noncoherentIQ_acquisi
} }
} }
delete d_fft_if;
delete d_ifft;
try try
{ {
if (d_dump) if (d_dump)

View File

@ -44,6 +44,7 @@
#include <gnuradio/fft/fft.h> #include <gnuradio/fft/fft.h>
#include <gnuradio/gr_complex.h> #include <gnuradio/gr_complex.h>
#include <fstream> #include <fstream>
#include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
@ -51,8 +52,8 @@ class galileo_e5a_noncoherentIQ_acquisition_caf_cc;
using galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr = boost::shared_ptr<galileo_e5a_noncoherentIQ_acquisition_caf_cc>; using galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr = boost::shared_ptr<galileo_e5a_noncoherentIQ_acquisition_caf_cc>;
galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(
galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(unsigned int sampled_ms, unsigned int sampled_ms,
unsigned int max_dwells, unsigned int max_dwells,
unsigned int doppler_max, int64_t fs_in, unsigned int doppler_max, int64_t fs_in,
int samples_per_ms, int samples_per_code, int samples_per_ms, int samples_per_code,
@ -71,88 +72,6 @@ galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(unsigned int sampled_ms,
*/ */
class galileo_e5a_noncoherentIQ_acquisition_caf_cc : public gr::block class galileo_e5a_noncoherentIQ_acquisition_caf_cc : public gr::block
{ {
private:
friend galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr
galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(
unsigned int sampled_ms,
unsigned int max_dwells,
unsigned int doppler_max, int64_t fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag,
bool dump,
std::string dump_filename,
bool both_signal_components_,
int CAF_window_hz_,
int Zero_padding_);
galileo_e5a_noncoherentIQ_acquisition_caf_cc(
unsigned int sampled_ms,
unsigned int max_dwells,
unsigned int doppler_max, int64_t fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag,
bool dump,
std::string dump_filename,
bool both_signal_components_,
int CAF_window_hz_,
int Zero_padding_);
void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift,
int doppler_offset);
float estimate_input_power(gr_complex* in);
std::weak_ptr<ChannelFsm> d_channel_fsm;
int64_t d_fs_in;
int d_samples_per_ms;
int d_sampled_ms;
int d_samples_per_code;
unsigned int d_doppler_resolution;
float d_threshold;
std::string d_satellite_str;
unsigned int d_doppler_max;
unsigned int d_doppler_step;
unsigned int d_max_dwells;
unsigned int d_well_count;
unsigned int d_fft_size;
uint64_t d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
unsigned int d_num_doppler_bins;
gr_complex* d_fft_code_I_A;
gr_complex* d_fft_code_I_B;
gr_complex* d_fft_code_Q_A;
gr_complex* d_fft_code_Q_B;
gr_complex* d_inbuffer;
gr::fft::fft_complex* d_fft_if;
gr::fft::fft_complex* d_ifft;
Gnss_Synchro* d_gnss_synchro;
unsigned int d_code_phase;
float d_doppler_freq;
float d_mag;
float* d_magnitudeIA;
float* d_magnitudeIB;
float* d_magnitudeQA;
float* d_magnitudeQB;
float d_input_power;
float d_test_statistics;
bool d_bit_transition_flag;
std::ofstream d_dump_file;
bool d_active;
int d_state;
bool d_dump;
bool d_both_signal_components;
// bool d_CAF_filter;
int d_CAF_window_hz;
float* d_CAF_vector;
float* d_CAF_vector_I;
float* d_CAF_vector_Q;
// double* d_CAF_vector;
// double* d_CAF_vector_I;
// double* d_CAF_vector_Q;
unsigned int d_channel;
std::string d_dump_filename;
unsigned int d_buffer_count;
unsigned int d_gr_stream_buffer;
public: public:
/*! /*!
* \brief Default destructor. * \brief Default destructor.
@ -256,5 +175,85 @@ public:
int general_work(int noutput_items, gr_vector_int& ninput_items, int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items); gr_vector_void_star& output_items);
private:
friend galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr
galileo_e5a_noncoherentIQ_make_acquisition_caf_cc(
unsigned int sampled_ms,
unsigned int max_dwells,
unsigned int doppler_max, int64_t fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag,
bool dump,
std::string dump_filename,
bool both_signal_components_,
int CAF_window_hz_,
int Zero_padding_);
galileo_e5a_noncoherentIQ_acquisition_caf_cc(
unsigned int sampled_ms,
unsigned int max_dwells,
unsigned int doppler_max, int64_t fs_in,
int samples_per_ms, int samples_per_code,
bool bit_transition_flag,
bool dump,
std::string dump_filename,
bool both_signal_components_,
int CAF_window_hz_,
int Zero_padding_);
void calculate_magnitudes(gr_complex* fft_begin, int doppler_shift,
int doppler_offset);
float estimate_input_power(gr_complex* in);
std::weak_ptr<ChannelFsm> d_channel_fsm;
int64_t d_fs_in;
int d_samples_per_ms;
int d_sampled_ms;
int d_samples_per_code;
unsigned int d_doppler_resolution;
float d_threshold;
std::string d_satellite_str;
unsigned int d_doppler_max;
unsigned int d_doppler_step;
unsigned int d_max_dwells;
unsigned int d_well_count;
unsigned int d_fft_size;
uint64_t d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
unsigned int d_num_doppler_bins;
gr_complex* d_fft_code_I_A;
gr_complex* d_fft_code_I_B;
gr_complex* d_fft_code_Q_A;
gr_complex* d_fft_code_Q_B;
gr_complex* d_inbuffer;
std::shared_ptr<gr::fft::fft_complex> d_fft_if;
std::shared_ptr<gr::fft::fft_complex> d_ifft;
Gnss_Synchro* d_gnss_synchro;
unsigned int d_code_phase;
float d_doppler_freq;
float d_mag;
float* d_magnitudeIA;
float* d_magnitudeIB;
float* d_magnitudeQA;
float* d_magnitudeQB;
float d_input_power;
float d_test_statistics;
bool d_bit_transition_flag;
std::ofstream d_dump_file;
bool d_active;
int d_state;
bool d_dump;
bool d_both_signal_components;
int d_CAF_window_hz;
float* d_CAF_vector;
float* d_CAF_vector_I;
float* d_CAF_vector_Q;
unsigned int d_channel;
std::string d_dump_filename;
unsigned int d_buffer_count;
unsigned int d_gr_stream_buffer;
}; };
#endif /* GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_CC_H_ */ #endif /* GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_CC_H_ */

View File

@ -87,10 +87,10 @@ galileo_pcps_8ms_acquisition_cc::galileo_pcps_8ms_acquisition_cc(
d_magnitude = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); d_magnitude = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
// Direct FFT // Direct FFT
d_fft_if = new gr::fft::fft_complex(d_fft_size, true); d_fft_if = std::make_shared<gr::fft::fft_complex>(d_fft_size, true);
// Inverse FFT // Inverse FFT
d_ifft = new gr::fft::fft_complex(d_fft_size, false); d_ifft = std::make_shared<gr::fft::fft_complex>(d_fft_size, false);
// For dumping samples into a file // For dumping samples into a file
d_dump = dump; d_dump = dump;
@ -123,9 +123,6 @@ galileo_pcps_8ms_acquisition_cc::~galileo_pcps_8ms_acquisition_cc()
volk_gnsssdr_free(d_fft_code_B); volk_gnsssdr_free(d_fft_code_B);
volk_gnsssdr_free(d_magnitude); volk_gnsssdr_free(d_magnitude);
delete d_ifft;
delete d_fft_if;
try try
{ {
if (d_dump) if (d_dump)

View File

@ -38,6 +38,7 @@
#include <gnuradio/fft/fft.h> #include <gnuradio/fft/fft.h>
#include <gnuradio/gr_complex.h> #include <gnuradio/gr_complex.h>
#include <fstream> #include <fstream>
#include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
@ -61,67 +62,6 @@ galileo_pcps_8ms_make_acquisition_cc(uint32_t sampled_ms,
*/ */
class galileo_pcps_8ms_acquisition_cc : public gr::block class galileo_pcps_8ms_acquisition_cc : public gr::block
{ {
private:
friend galileo_pcps_8ms_acquisition_cc_sptr
galileo_pcps_8ms_make_acquisition_cc(
uint32_t sampled_ms,
uint32_t max_dwells,
uint32_t doppler_max,
int64_t fs_in,
int32_t samples_per_ms,
int32_t samples_per_code,
bool dump,
std::string dump_filename);
galileo_pcps_8ms_acquisition_cc(
uint32_t sampled_ms,
uint32_t max_dwells,
uint32_t doppler_max,
int64_t fs_in,
int32_t samples_per_ms,
int32_t samples_per_code,
bool dump,
std::string dump_filename);
void calculate_magnitudes(
gr_complex* fft_begin,
int32_t doppler_shift,
int32_t doppler_offset);
int64_t d_fs_in;
int32_t d_samples_per_ms;
int32_t d_samples_per_code;
uint32_t d_doppler_resolution;
float d_threshold;
std::string d_satellite_str;
uint32_t d_doppler_max;
uint32_t d_doppler_step;
uint32_t d_sampled_ms;
uint32_t d_max_dwells;
uint32_t d_well_count;
uint32_t d_fft_size;
uint64_t d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
uint32_t d_num_doppler_bins;
gr_complex* d_fft_code_A;
gr_complex* d_fft_code_B;
gr::fft::fft_complex* d_fft_if;
gr::fft::fft_complex* d_ifft;
Gnss_Synchro* d_gnss_synchro;
uint32_t d_code_phase;
float d_doppler_freq;
float d_mag;
float* d_magnitude;
float d_input_power;
float d_test_statistics;
std::ofstream d_dump_file;
bool d_active;
int32_t d_state;
bool d_dump;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
public: public:
/*! /*!
* \brief Default destructor. * \brief Default destructor.
@ -225,6 +165,67 @@ public:
int general_work(int noutput_items, gr_vector_int& ninput_items, int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items); gr_vector_void_star& output_items);
private:
friend galileo_pcps_8ms_acquisition_cc_sptr
galileo_pcps_8ms_make_acquisition_cc(
uint32_t sampled_ms,
uint32_t max_dwells,
uint32_t doppler_max,
int64_t fs_in,
int32_t samples_per_ms,
int32_t samples_per_code,
bool dump,
std::string dump_filename);
galileo_pcps_8ms_acquisition_cc(
uint32_t sampled_ms,
uint32_t max_dwells,
uint32_t doppler_max,
int64_t fs_in,
int32_t samples_per_ms,
int32_t samples_per_code,
bool dump,
std::string dump_filename);
void calculate_magnitudes(
gr_complex* fft_begin,
int32_t doppler_shift,
int32_t doppler_offset);
int64_t d_fs_in;
int32_t d_samples_per_ms;
int32_t d_samples_per_code;
uint32_t d_doppler_resolution;
float d_threshold;
std::string d_satellite_str;
uint32_t d_doppler_max;
uint32_t d_doppler_step;
uint32_t d_sampled_ms;
uint32_t d_max_dwells;
uint32_t d_well_count;
uint32_t d_fft_size;
uint64_t d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
uint32_t d_num_doppler_bins;
gr_complex* d_fft_code_A;
gr_complex* d_fft_code_B;
std::shared_ptr<gr::fft::fft_complex> d_fft_if;
std::shared_ptr<gr::fft::fft_complex> d_ifft;
Gnss_Synchro* d_gnss_synchro;
uint32_t d_code_phase;
float d_doppler_freq;
float d_mag;
float* d_magnitude;
float d_input_power;
float d_test_statistics;
std::ofstream d_dump_file;
bool d_active;
int32_t d_state;
bool d_dump;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
}; };
#endif /* GNSS_SDR_PCPS_8MS_ACQUISITION_CC_H_*/ #endif /* GNSS_SDR_PCPS_8MS_ACQUISITION_CC_H_*/

View File

@ -134,30 +134,22 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
acq_parameters.max_dwells = 1; // Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells acq_parameters.max_dwells = 1; // Activation of acq_parameters.bit_transition_flag invalidates the value of acq_parameters.max_dwells
} }
d_tmp_buffer = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); d_tmp_buffer = std::vector<float>(d_fft_size);
d_fft_codes = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_fft_codes = std::vector<std::complex<float>>(d_fft_size);
d_magnitude = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); d_input_signal = std::vector<std::complex<float>>(d_fft_size);
d_input_signal = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
// Direct FFT // Direct FFT
d_fft_if = new gr::fft::fft_complex(d_fft_size, true); d_fft_if = std::make_shared<gr::fft::fft_complex>(d_fft_size, true);
// Inverse FFT // Inverse FFT
d_ifft = new gr::fft::fft_complex(d_fft_size, false); d_ifft = std::make_shared<gr::fft::fft_complex>(d_fft_size, false);
d_gnss_synchro = nullptr; d_gnss_synchro = nullptr;
d_grid_doppler_wipeoffs = nullptr;
d_grid_doppler_wipeoffs_step_two = nullptr;
d_magnitude_grid = nullptr;
d_worker_active = false; d_worker_active = false;
d_data_buffer = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_consumed_samples * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_data_buffer = std::vector<std::complex<float>>(d_consumed_samples);
if (d_cshort) if (d_cshort)
{ {
d_data_buffer_sc = static_cast<lv_16sc_t*>(volk_gnsssdr_malloc(d_consumed_samples * sizeof(lv_16sc_t), volk_gnsssdr_get_alignment())); d_data_buffer_sc = std::vector<lv_16sc_t>(d_consumed_samples);
}
else
{
d_data_buffer_sc = nullptr;
} }
grid_ = arma::fmat(); grid_ = arma::fmat();
narrow_grid_ = arma::fmat(); narrow_grid_ = arma::fmat();
@ -213,38 +205,7 @@ pcps_acquisition::pcps_acquisition(const Acq_Conf& conf_) : gr::block("pcps_acqu
} }
pcps_acquisition::~pcps_acquisition() pcps_acquisition::~pcps_acquisition() = default;
{
if (d_num_doppler_bins > 0)
{
for (uint32_t i = 0; i < d_num_doppler_bins; i++)
{
volk_gnsssdr_free(d_grid_doppler_wipeoffs[i]);
volk_gnsssdr_free(d_magnitude_grid[i]);
}
delete[] d_grid_doppler_wipeoffs;
delete[] d_magnitude_grid;
}
if (acq_parameters.make_2_steps)
{
for (uint32_t i = 0; i < d_num_doppler_bins_step2; i++)
{
volk_gnsssdr_free(d_grid_doppler_wipeoffs_step_two[i]);
}
delete[] d_grid_doppler_wipeoffs_step_two;
}
volk_gnsssdr_free(d_fft_codes);
volk_gnsssdr_free(d_magnitude);
volk_gnsssdr_free(d_tmp_buffer);
volk_gnsssdr_free(d_input_signal);
delete d_ifft;
delete d_fft_if;
volk_gnsssdr_free(d_data_buffer);
if (d_cshort)
{
volk_gnsssdr_free(d_data_buffer_sc);
}
}
void pcps_acquisition::set_resampler_latency(uint32_t latency_samples) void pcps_acquisition::set_resampler_latency(uint32_t latency_samples)
@ -288,7 +249,7 @@ void pcps_acquisition::set_local_code(std::complex<float>* code)
} }
d_fft_if->execute(); // We need the FFT of local code d_fft_if->execute(); // We need the FFT of local code
volk_32fc_conjugate_32fc(d_fft_codes, d_fft_if->get_outbuf(), d_fft_size); volk_32fc_conjugate_32fc(d_fft_codes.data(), d_fft_if->get_outbuf(), d_fft_size);
} }
@ -311,7 +272,7 @@ bool pcps_acquisition::is_fdma()
} }
void pcps_acquisition::update_local_carrier(gr_complex* carrier_vector, int32_t correlator_length_samples, float freq) void pcps_acquisition::update_local_carrier(gsl::span<gr_complex> carrier_vector, float freq)
{ {
float phase_step_rad; float phase_step_rad;
if (acq_parameters.use_automatic_resampler) if (acq_parameters.use_automatic_resampler)
@ -324,7 +285,7 @@ void pcps_acquisition::update_local_carrier(gr_complex* carrier_vector, int32_t
} }
float _phase[1]; float _phase[1];
_phase[0] = 0.0; _phase[0] = 0.0;
volk_gnsssdr_s32f_sincos_32fc(carrier_vector, -phase_step_rad, _phase, correlator_length_samples); volk_gnsssdr_s32f_sincos_32fc(carrier_vector.data(), -phase_step_rad, _phase, carrier_vector.length());
} }
@ -344,27 +305,18 @@ void pcps_acquisition::init()
d_num_doppler_bins = static_cast<uint32_t>(std::ceil(static_cast<double>(static_cast<int32_t>(acq_parameters.doppler_max) - static_cast<int32_t>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step))); d_num_doppler_bins = static_cast<uint32_t>(std::ceil(static_cast<double>(static_cast<int32_t>(acq_parameters.doppler_max) - static_cast<int32_t>(-acq_parameters.doppler_max)) / static_cast<double>(d_doppler_step)));
// Create the carrier Doppler wipeoff signals // Create the carrier Doppler wipeoff signals
if (d_grid_doppler_wipeoffs == nullptr) if (d_grid_doppler_wipeoffs.empty())
{ {
d_grid_doppler_wipeoffs = new gr_complex*[d_num_doppler_bins]; d_grid_doppler_wipeoffs = std::vector<std::vector<std::complex<float>>>(d_num_doppler_bins, std::vector<std::complex<float>>(d_fft_size));
} }
if (acq_parameters.make_2_steps && (d_grid_doppler_wipeoffs_step_two == nullptr)) if (acq_parameters.make_2_steps && (d_grid_doppler_wipeoffs_step_two.empty()))
{ {
d_grid_doppler_wipeoffs_step_two = new gr_complex*[d_num_doppler_bins_step2]; d_grid_doppler_wipeoffs_step_two = std::vector<std::vector<std::complex<float>>>(d_num_doppler_bins_step2, std::vector<std::complex<float>>(d_fft_size));
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++)
{
d_grid_doppler_wipeoffs_step_two[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
}
} }
if (d_magnitude_grid == nullptr) if (d_magnitude_grid.empty())
{ {
d_magnitude_grid = new float*[d_num_doppler_bins]; d_magnitude_grid = std::vector<std::vector<float>>(d_num_doppler_bins, std::vector<float>(d_fft_size));
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
{
d_grid_doppler_wipeoffs[doppler_index] = static_cast<gr_complex*>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
d_magnitude_grid[doppler_index] = static_cast<float*>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
}
} }
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
@ -374,7 +326,7 @@ void pcps_acquisition::init()
d_magnitude_grid[doppler_index][k] = 0.0; d_magnitude_grid[doppler_index][k] = 0.0;
} }
int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * doppler_index; int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler); update_local_carrier(gsl::span<gr_complex>(d_grid_doppler_wipeoffs[doppler_index].data(), d_fft_size), d_old_freq + doppler);
} }
d_worker_active = false; d_worker_active = false;
@ -393,7 +345,7 @@ void pcps_acquisition::update_grid_doppler_wipeoffs()
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
{ {
int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * doppler_index; int32_t doppler = -static_cast<int32_t>(acq_parameters.doppler_max) + d_doppler_step * doppler_index;
update_local_carrier(d_grid_doppler_wipeoffs[doppler_index], d_fft_size, d_old_freq + doppler); update_local_carrier(gsl::span<gr_complex>(d_grid_doppler_wipeoffs[doppler_index].data(), d_fft_size), d_old_freq + doppler);
} }
} }
@ -403,7 +355,7 @@ void pcps_acquisition::update_grid_doppler_wipeoffs_step2()
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++) for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++)
{ {
float doppler = (static_cast<float>(doppler_index) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * acq_parameters.doppler_step2; float doppler = (static_cast<float>(doppler_index) - static_cast<float>(floor(d_num_doppler_bins_step2 / 2.0))) * acq_parameters.doppler_step2;
update_local_carrier(d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size, d_doppler_center_step_two + doppler); update_local_carrier(gsl::span<gr_complex>(d_grid_doppler_wipeoffs_step_two[doppler_index].data(), d_fft_size), d_doppler_center_step_two + doppler);
} }
} }
@ -450,7 +402,7 @@ void pcps_acquisition::send_positive_acquisition()
if (!d_channel_fsm.expired()) if (!d_channel_fsm.expired())
{ {
//the channel FSM is set, so, notify it directly the positive acquisition to minimize delays // the channel FSM is set, so, notify it directly the positive acquisition to minimize delays
d_channel_fsm.lock()->Event_valid_acquisition(); d_channel_fsm.lock()->Event_valid_acquisition();
} }
else else
@ -510,11 +462,11 @@ void pcps_acquisition::dump_results(int32_t effective_fft_size)
dims[0] = static_cast<size_t>(1); dims[0] = static_cast<size_t>(1);
dims[1] = static_cast<size_t>(1); dims[1] = static_cast<size_t>(1);
matvar = Mat_VarCreate("doppler_max", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &acq_parameters.doppler_max, 0); matvar = Mat_VarCreate("doppler_max", MAT_C_INT32, MAT_T_INT32, 1, dims, &acq_parameters.doppler_max, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("doppler_step", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_doppler_step, 0); matvar = Mat_VarCreate("doppler_step", MAT_C_INT32, MAT_T_INT32, 1, dims, &d_doppler_step, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
@ -552,7 +504,7 @@ void pcps_acquisition::dump_results(int32_t effective_fft_size)
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("num_dwells", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_num_noncoherent_integrations_counter, 0); matvar = Mat_VarCreate("num_dwells", MAT_C_INT32, MAT_T_INT32, 1, dims, &d_num_noncoherent_integrations_counter, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
@ -592,7 +544,7 @@ float pcps_acquisition::max_to_input_power_statistic(uint32_t& indext, int32_t&
// Find the correlation peak and the carrier frequency // Find the correlation peak and the carrier frequency
for (uint32_t i = 0; i < num_doppler_bins; i++) for (uint32_t i = 0; i < num_doppler_bins; i++)
{ {
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i].data(), d_fft_size);
if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum) if (d_magnitude_grid[i][tmp_intex_t] > grid_maximum)
{ {
grid_maximum = d_magnitude_grid[i][tmp_intex_t]; grid_maximum = d_magnitude_grid[i][tmp_intex_t];
@ -629,7 +581,7 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int32_t
// Find the correlation peak and the carrier frequency // Find the correlation peak and the carrier frequency
for (uint32_t i = 0; i < num_doppler_bins; i++) for (uint32_t i = 0; i < num_doppler_bins; i++)
{ {
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i], d_fft_size); volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_magnitude_grid[i].data(), d_fft_size);
if (d_magnitude_grid[i][tmp_intex_t] > firstPeak) if (d_magnitude_grid[i][tmp_intex_t] > firstPeak)
{ {
firstPeak = d_magnitude_grid[i][tmp_intex_t]; firstPeak = d_magnitude_grid[i][tmp_intex_t];
@ -663,7 +615,7 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int32_t
} }
int32_t idx = excludeRangeIndex1; int32_t idx = excludeRangeIndex1;
memcpy(d_tmp_buffer, d_magnitude_grid[index_doppler], d_fft_size); memcpy(d_tmp_buffer.data(), d_magnitude_grid[index_doppler].data(), d_fft_size);
do do
{ {
d_tmp_buffer[idx] = 0.0; d_tmp_buffer[idx] = 0.0;
@ -676,7 +628,7 @@ float pcps_acquisition::first_vs_second_peak_statistic(uint32_t& indext, int32_t
while (idx != excludeRangeIndex2); while (idx != excludeRangeIndex2);
// Find the second highest correlation peak in the same freq. bin --- // Find the second highest correlation peak in the same freq. bin ---
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_tmp_buffer, d_fft_size); volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_tmp_buffer.data(), d_fft_size);
float secondPeak = d_tmp_buffer[tmp_intex_t]; float secondPeak = d_tmp_buffer[tmp_intex_t];
// Compute the test statistics and compare to the threshold // Compute the test statistics and compare to the threshold
@ -694,9 +646,9 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
int32_t effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size); int32_t effective_fft_size = (acq_parameters.bit_transition_flag ? d_fft_size / 2 : d_fft_size);
if (d_cshort) if (d_cshort)
{ {
volk_gnsssdr_16ic_convert_32fc(d_data_buffer, d_data_buffer_sc, d_consumed_samples); volk_gnsssdr_16ic_convert_32fc(d_data_buffer.data(), d_data_buffer_sc.data(), d_consumed_samples);
} }
memcpy(d_input_signal, d_data_buffer, d_consumed_samples * sizeof(gr_complex)); memcpy(d_input_signal.data(), d_data_buffer.data(), d_consumed_samples * sizeof(gr_complex));
if (d_fft_size > d_consumed_samples) if (d_fft_size > d_consumed_samples)
{ {
for (uint32_t i = d_consumed_samples; i < d_fft_size; i++) for (uint32_t i = d_consumed_samples; i < d_fft_size; i++)
@ -704,7 +656,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
d_input_signal[i] = gr_complex(0.0, 0.0); d_input_signal[i] = gr_complex(0.0, 0.0);
} }
} }
const gr_complex* in = d_input_signal; // Get the input samples pointer const gr_complex* in = d_input_signal.data(); // Get the input samples pointer
d_input_power = 0.0; d_input_power = 0.0;
d_mag = 0.0; d_mag = 0.0;
@ -722,8 +674,8 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
if (d_use_CFAR_algorithm_flag or acq_parameters.bit_transition_flag) if (d_use_CFAR_algorithm_flag or acq_parameters.bit_transition_flag)
{ {
// Compute the input signal power estimation // Compute the input signal power estimation
volk_32fc_magnitude_squared_32f(d_tmp_buffer, in, d_fft_size); volk_32fc_magnitude_squared_32f(d_tmp_buffer.data(), in, d_fft_size);
volk_32f_accumulator_s32f(&d_input_power, d_tmp_buffer, d_fft_size); volk_32f_accumulator_s32f(&d_input_power, d_tmp_buffer.data(), d_fft_size);
d_input_power /= static_cast<float>(d_fft_size); d_input_power /= static_cast<float>(d_fft_size);
} }
@ -733,14 +685,14 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++) for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins; doppler_index++)
{ {
// Remove Doppler // Remove Doppler
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size); volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index].data(), d_fft_size);
// Perform the FFT-based convolution (parallel time search) // Perform the FFT-based convolution (parallel time search)
// Compute the FFT of the carrier wiped--off incoming signal // Compute the FFT of the carrier wiped--off incoming signal
d_fft_if->execute(); d_fft_if->execute();
// Multiply carrier wiped--off, Fourier transformed incoming signal with the local FFT'd code reference // Multiply carrier wiped--off, Fourier transformed incoming signal with the local FFT'd code reference
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size); volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes.data(), d_fft_size);
// Compute the inverse FFT // Compute the inverse FFT
d_ifft->execute(); d_ifft->execute();
@ -749,17 +701,17 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0); size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0);
if (d_num_noncoherent_integrations_counter == 1) if (d_num_noncoherent_integrations_counter == 1)
{ {
volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index], d_ifft->get_outbuf() + offset, effective_fft_size); volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index].data(), d_ifft->get_outbuf() + offset, effective_fft_size);
} }
else else
{ {
volk_32fc_magnitude_squared_32f(d_tmp_buffer, d_ifft->get_outbuf() + offset, effective_fft_size); volk_32fc_magnitude_squared_32f(d_tmp_buffer.data(), d_ifft->get_outbuf() + offset, effective_fft_size);
volk_32f_x2_add_32f(d_magnitude_grid[doppler_index], d_magnitude_grid[doppler_index], d_tmp_buffer, effective_fft_size); volk_32f_x2_add_32f(d_magnitude_grid[doppler_index].data(), d_magnitude_grid[doppler_index].data(), d_tmp_buffer.data(), effective_fft_size);
} }
// Record results to file if required // Record results to file if required
if (d_dump and d_channel == d_dump_channel) if (d_dump and d_channel == d_dump_channel)
{ {
memcpy(grid_.colptr(doppler_index), d_magnitude_grid[doppler_index], sizeof(float) * effective_fft_size); memcpy(grid_.colptr(doppler_index), d_magnitude_grid[doppler_index].data(), sizeof(float) * effective_fft_size);
} }
} }
@ -774,7 +726,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
} }
if (acq_parameters.use_automatic_resampler) if (acq_parameters.use_automatic_resampler)
{ {
//take into account the acquisition resampler ratio // take into account the acquisition resampler ratio
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)) * acq_parameters.resampler_ratio; d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)) * acq_parameters.resampler_ratio;
d_gnss_synchro->Acq_delay_samples -= static_cast<double>(acq_parameters.resampler_latency_samples); //account the resampler filter latency d_gnss_synchro->Acq_delay_samples -= static_cast<double>(acq_parameters.resampler_latency_samples); //account the resampler filter latency
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
@ -791,7 +743,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
{ {
for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++) for (uint32_t doppler_index = 0; doppler_index < d_num_doppler_bins_step2; doppler_index++)
{ {
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs_step_two[doppler_index], d_fft_size); volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs_step_two[doppler_index].data(), d_fft_size);
// Perform the FFT-based convolution (parallel time search) // Perform the FFT-based convolution (parallel time search)
// Compute the FFT of the carrier wiped--off incoming signal // Compute the FFT of the carrier wiped--off incoming signal
@ -799,7 +751,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
// Multiply carrier wiped--off, Fourier transformed incoming signal // Multiply carrier wiped--off, Fourier transformed incoming signal
// with the local FFT'd code reference using SIMD operations with VOLK library // with the local FFT'd code reference using SIMD operations with VOLK library
volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes, d_fft_size); volk_32fc_x2_multiply_32fc(d_ifft->get_inbuf(), d_fft_if->get_outbuf(), d_fft_codes.data(), d_fft_size);
// compute the inverse FFT // compute the inverse FFT
d_ifft->execute(); d_ifft->execute();
@ -807,17 +759,17 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0); size_t offset = (acq_parameters.bit_transition_flag ? effective_fft_size : 0);
if (d_num_noncoherent_integrations_counter == 1) if (d_num_noncoherent_integrations_counter == 1)
{ {
volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index], d_ifft->get_outbuf() + offset, effective_fft_size); volk_32fc_magnitude_squared_32f(d_magnitude_grid[doppler_index].data(), d_ifft->get_outbuf() + offset, effective_fft_size);
} }
else else
{ {
volk_32fc_magnitude_squared_32f(d_tmp_buffer, d_ifft->get_outbuf() + offset, effective_fft_size); volk_32fc_magnitude_squared_32f(d_tmp_buffer.data(), d_ifft->get_outbuf() + offset, effective_fft_size);
volk_32f_x2_add_32f(d_magnitude_grid[doppler_index], d_magnitude_grid[doppler_index], d_tmp_buffer, effective_fft_size); volk_32f_x2_add_32f(d_magnitude_grid[doppler_index].data(), d_magnitude_grid[doppler_index].data(), d_tmp_buffer.data(), effective_fft_size);
} }
// Record results to file if required // Record results to file if required
if (d_dump and d_channel == d_dump_channel) if (d_dump and d_channel == d_dump_channel)
{ {
memcpy(narrow_grid_.colptr(doppler_index), d_magnitude_grid[doppler_index], sizeof(float) * effective_fft_size); memcpy(narrow_grid_.colptr(doppler_index), d_magnitude_grid[doppler_index].data(), sizeof(float) * effective_fft_size);
} }
} }
// Compute the test statistic // Compute the test statistic
@ -832,7 +784,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
if (acq_parameters.use_automatic_resampler) if (acq_parameters.use_automatic_resampler)
{ {
//take into account the acquisition resampler ratio // take into account the acquisition resampler ratio
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)) * acq_parameters.resampler_ratio; d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), acq_parameters.samples_per_code)) * acq_parameters.resampler_ratio;
d_gnss_synchro->Acq_delay_samples -= static_cast<double>(acq_parameters.resampler_latency_samples); //account the resampler filter latency d_gnss_synchro->Acq_delay_samples -= static_cast<double>(acq_parameters.resampler_latency_samples); //account the resampler filter latency
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler); d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);

View File

@ -61,17 +61,25 @@
#include <gnuradio/thread/thread.h> // for scoped_lock #include <gnuradio/thread/thread.h> // for scoped_lock
#include <gnuradio/types.h> // for gr_vector_const_void_star #include <gnuradio/types.h> // for gr_vector_const_void_star
#include <volk/volk_complex.h> // for lv_16sc_t #include <volk/volk_complex.h> // for lv_16sc_t
#include <complex>
#include <cstdint> #include <cstdint>
#include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector>
#if HAS_SPAN
#include <span>
namespace gsl = std;
#else
#include <gsl/gsl>
#endif
class Gnss_Synchro; class Gnss_Synchro;
class pcps_acquisition; class pcps_acquisition;
using pcps_acquisition_sptr = boost::shared_ptr<pcps_acquisition>; using pcps_acquisition_sptr = boost::shared_ptr<pcps_acquisition>;
pcps_acquisition_sptr pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_);
pcps_make_acquisition(const Acq_Conf& conf_);
/*! /*!
* \brief This class implements a Parallel Code Phase Search Acquisition. * \brief This class implements a Parallel Code Phase Search Acquisition.
@ -81,75 +89,6 @@ pcps_make_acquisition(const Acq_Conf& conf_);
*/ */
class pcps_acquisition : public gr::block class pcps_acquisition : public gr::block
{ {
private:
friend pcps_acquisition_sptr
pcps_make_acquisition(const Acq_Conf& conf_);
pcps_acquisition(const Acq_Conf& conf_);
void update_local_carrier(gr_complex* carrier_vector, int32_t correlator_length_samples, float freq);
void update_grid_doppler_wipeoffs();
void update_grid_doppler_wipeoffs_step2();
bool is_fdma();
void acquisition_core(uint64_t samp_count);
void send_negative_acquisition();
void send_positive_acquisition();
void dump_results(int32_t effective_fft_size);
float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
float max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, float input_power, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
bool start();
Acq_Conf acq_parameters;
bool d_active;
bool d_worker_active;
bool d_cshort;
bool d_step_two;
bool d_use_CFAR_algorithm_flag;
int32_t d_positive_acq;
float d_threshold;
float d_mag;
float d_input_power;
float d_test_statistics;
float* d_magnitude;
float** d_magnitude_grid;
float* d_tmp_buffer;
gr_complex* d_input_signal;
uint32_t d_samplesPerChip;
int64_t d_old_freq;
int32_t d_state;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
uint32_t d_doppler_step;
float d_doppler_center_step_two;
uint32_t d_num_noncoherent_integrations_counter;
uint32_t d_fft_size;
uint32_t d_consumed_samples;
uint32_t d_num_doppler_bins;
uint64_t d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
gr_complex** d_grid_doppler_wipeoffs_step_two;
gr_complex* d_fft_codes;
gr_complex* d_data_buffer;
lv_16sc_t* d_data_buffer_sc;
gr::fft::fft_complex* d_fft_if;
gr::fft::fft_complex* d_ifft;
Gnss_Synchro* d_gnss_synchro;
arma::fmat grid_;
arma::fmat narrow_grid_;
uint32_t d_num_doppler_bins_step2;
int64_t d_dump_number;
uint32_t d_dump_channel;
uint32_t d_buffer_count;
bool d_dump;
std::string d_dump_filename;
public: public:
~pcps_acquisition(); ~pcps_acquisition();
@ -249,7 +188,6 @@ public:
d_doppler_step = doppler_step; d_doppler_step = doppler_step;
} }
void set_resampler_latency(uint32_t latency_samples); void set_resampler_latency(uint32_t latency_samples);
/*! /*!
@ -258,6 +196,63 @@ public:
int general_work(int noutput_items, gr_vector_int& ninput_items, int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items); gr_vector_void_star& output_items);
private:
friend pcps_acquisition_sptr pcps_make_acquisition(const Acq_Conf& conf_);
pcps_acquisition(const Acq_Conf& conf_);
bool d_active;
bool d_worker_active;
bool d_cshort;
bool d_step_two;
bool d_use_CFAR_algorithm_flag;
bool d_dump;
int32_t d_state;
int32_t d_positive_acq;
uint32_t d_channel;
uint32_t d_samplesPerChip;
uint32_t d_doppler_step;
uint32_t d_num_noncoherent_integrations_counter;
uint32_t d_fft_size;
uint32_t d_consumed_samples;
uint32_t d_num_doppler_bins;
uint32_t d_num_doppler_bins_step2;
uint32_t d_dump_channel;
uint32_t d_buffer_count;
uint64_t d_sample_counter;
int64_t d_dump_number;
int64_t d_old_freq;
float d_threshold;
float d_mag;
float d_input_power;
float d_test_statistics;
float d_doppler_center_step_two;
std::string d_dump_filename;
std::vector<std::vector<float>> d_magnitude_grid;
std::vector<float> d_tmp_buffer;
std::vector<std::complex<float>> d_input_signal;
std::vector<std::vector<std::complex<float>>> d_grid_doppler_wipeoffs;
std::vector<std::vector<std::complex<float>>> d_grid_doppler_wipeoffs_step_two;
std::vector<std::complex<float>> d_fft_codes;
std::vector<std::complex<float>> d_data_buffer;
std::vector<lv_16sc_t> d_data_buffer_sc;
std::shared_ptr<gr::fft::fft_complex> d_fft_if;
std::shared_ptr<gr::fft::fft_complex> d_ifft;
std::weak_ptr<ChannelFsm> d_channel_fsm;
Acq_Conf acq_parameters;
Gnss_Synchro* d_gnss_synchro;
arma::fmat grid_;
arma::fmat narrow_grid_;
void update_local_carrier(gsl::span<gr_complex> carrier_vector, float freq);
void update_grid_doppler_wipeoffs();
void update_grid_doppler_wipeoffs_step2();
void acquisition_core(uint64_t samp_count);
void send_negative_acquisition();
void send_positive_acquisition();
void dump_results(int32_t effective_fft_size);
bool is_fdma();
bool start();
float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
float max_to_input_power_statistic(uint32_t& indext, int32_t& doppler, float input_power, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
}; };
#endif /* GNSS_SDR_PCPS_ACQUISITION_H_*/ #endif /* GNSS_SDR_PCPS_ACQUISITION_H_*/

View File

@ -93,10 +93,10 @@ pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(const Acq_Con
d_10_ms_buffer = static_cast<gr_complex *>(volk_gnsssdr_malloc(50 * d_samples_per_ms * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_10_ms_buffer = static_cast<gr_complex *>(volk_gnsssdr_malloc(50 * d_samples_per_ms * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
// Direct FFT // Direct FFT
d_fft_if = new gr::fft::fft_complex(d_fft_size, true); d_fft_if = std::make_shared<gr::fft::fft_complex>(d_fft_size, true);
// Inverse FFT // Inverse FFT
d_ifft = new gr::fft::fft_complex(d_fft_size, false); d_ifft = std::make_shared<gr::fft::fft_complex>(d_fft_size, false);
// For dumping samples into a file // For dumping samples into a file
d_dump = conf_.dump; d_dump = conf_.dump;
@ -138,8 +138,6 @@ pcps_acquisition_fine_doppler_cc::pcps_acquisition_fine_doppler_cc(const Acq_Con
d_threshold = 0; d_threshold = 0;
d_num_doppler_points = 0; d_num_doppler_points = 0;
d_doppler_step = 0; d_doppler_step = 0;
d_grid_data = nullptr;
d_grid_doppler_wipeoffs = nullptr;
d_gnss_synchro = nullptr; d_gnss_synchro = nullptr;
d_code_phase = 0; d_code_phase = 0;
d_doppler_freq = 0; d_doppler_freq = 0;
@ -168,6 +166,7 @@ unsigned int pcps_acquisition_fine_doppler_cc::nextPowerOf2(unsigned int n)
return n; return n;
} }
void pcps_acquisition_fine_doppler_cc::set_doppler_step(unsigned int doppler_step) void pcps_acquisition_fine_doppler_cc::set_doppler_step(unsigned int doppler_step)
{ {
d_doppler_step = doppler_step; d_doppler_step = doppler_step;
@ -175,11 +174,7 @@ void pcps_acquisition_fine_doppler_cc::set_doppler_step(unsigned int doppler_ste
d_num_doppler_points = floor(std::abs(2 * d_config_doppler_max) / d_doppler_step); d_num_doppler_points = floor(std::abs(2 * d_config_doppler_max) / d_doppler_step);
d_grid_data = new float *[d_num_doppler_points]; d_grid_data = std::vector<std::vector<float>>(d_num_doppler_points, std::vector<float>(d_fft_size));
for (int i = 0; i < d_num_doppler_points; i++)
{
d_grid_data[i] = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
}
if (d_dump) if (d_dump)
{ {
@ -190,27 +185,12 @@ void pcps_acquisition_fine_doppler_cc::set_doppler_step(unsigned int doppler_ste
} }
void pcps_acquisition_fine_doppler_cc::free_grid_memory()
{
for (int i = 0; i < d_num_doppler_points; i++)
{
volk_gnsssdr_free(d_grid_data[i]);
delete[] d_grid_doppler_wipeoffs[i];
}
delete d_grid_data;
delete d_grid_doppler_wipeoffs;
}
pcps_acquisition_fine_doppler_cc::~pcps_acquisition_fine_doppler_cc() pcps_acquisition_fine_doppler_cc::~pcps_acquisition_fine_doppler_cc()
{ {
volk_gnsssdr_free(d_carrier); volk_gnsssdr_free(d_carrier);
volk_gnsssdr_free(d_fft_codes); volk_gnsssdr_free(d_fft_codes);
volk_gnsssdr_free(d_magnitude); volk_gnsssdr_free(d_magnitude);
volk_gnsssdr_free(d_10_ms_buffer); volk_gnsssdr_free(d_10_ms_buffer);
delete d_ifft;
delete d_fft_if;
free_grid_memory();
} }
@ -266,17 +246,16 @@ void pcps_acquisition_fine_doppler_cc::update_carrier_wipeoff()
// create the carrier Doppler wipeoff signals // create the carrier Doppler wipeoff signals
int doppler_hz; int doppler_hz;
float phase_step_rad; float phase_step_rad;
d_grid_doppler_wipeoffs = new gr_complex *[d_num_doppler_points]; d_grid_doppler_wipeoffs = std::vector<std::vector<std::complex<float>>>(d_num_doppler_points, std::vector<std::complex<float>>(d_fft_size));
for (int doppler_index = 0; doppler_index < d_num_doppler_points; doppler_index++) for (int doppler_index = 0; doppler_index < d_num_doppler_points; doppler_index++)
{ {
doppler_hz = d_doppler_step * doppler_index - d_config_doppler_max; doppler_hz = d_doppler_step * doppler_index - d_config_doppler_max;
// doppler search steps // doppler search steps
// compute the carrier doppler wipe-off signal and store it // compute the carrier doppler wipe-off signal and store it
phase_step_rad = static_cast<float>(GPS_TWO_PI) * doppler_hz / static_cast<float>(d_fs_in); phase_step_rad = static_cast<float>(GPS_TWO_PI) * doppler_hz / static_cast<float>(d_fs_in);
d_grid_doppler_wipeoffs[doppler_index] = new gr_complex[d_fft_size];
float _phase[1]; float _phase[1];
_phase[0] = 0; _phase[0] = 0;
volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index], -phase_step_rad, _phase, d_fft_size); volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index].data(), -phase_step_rad, _phase, d_fft_size);
} }
} }
@ -294,7 +273,7 @@ double pcps_acquisition_fine_doppler_cc::compute_CAF()
//--- Find the correlation peak and the carrier frequency -------------- //--- Find the correlation peak and the carrier frequency --------------
for (int i = 0; i < d_num_doppler_points; i++) for (int i = 0; i < d_num_doppler_points; i++)
{ {
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_grid_data[i], d_fft_size); volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_grid_data[i].data(), d_fft_size);
if (d_grid_data[i][tmp_intex_t] > firstPeak) if (d_grid_data[i][tmp_intex_t] > firstPeak)
{ {
firstPeak = d_grid_data[i][tmp_intex_t]; firstPeak = d_grid_data[i][tmp_intex_t];
@ -305,7 +284,7 @@ double pcps_acquisition_fine_doppler_cc::compute_CAF()
// Record results to file if required // Record results to file if required
if (d_dump and d_channel == d_dump_channel) if (d_dump and d_channel == d_dump_channel)
{ {
memcpy(grid_.colptr(i), d_grid_data[i], sizeof(float) * d_fft_size); memcpy(grid_.colptr(i), d_grid_data[i].data(), sizeof(float) * d_fft_size);
} }
} }
@ -337,7 +316,7 @@ double pcps_acquisition_fine_doppler_cc::compute_CAF()
while (idx != excludeRangeIndex2); while (idx != excludeRangeIndex2);
//--- Find the second highest correlation peak in the same freq. bin --- //--- Find the second highest correlation peak in the same freq. bin ---
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_grid_data[index_doppler], d_fft_size); volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_grid_data[index_doppler].data(), d_fft_size);
float secondPeak = d_grid_data[index_doppler][tmp_intex_t]; float secondPeak = d_grid_data[index_doppler][tmp_intex_t];
// 5- Compute the test statistics and compare to the threshold // 5- Compute the test statistics and compare to the threshold
@ -383,7 +362,7 @@ int pcps_acquisition_fine_doppler_cc::compute_and_accumulate_grid(gr_vector_cons
{ {
// doppler search steps // doppler search steps
// Perform the carrier wipe-off // Perform the carrier wipe-off
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size); volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index].data(), d_fft_size);
// 3- Perform the FFT-based convolution (parallel time search) // 3- Perform the FFT-based convolution (parallel time search)
// Compute the FFT of the carrier wiped--off incoming signal // Compute the FFT of the carrier wiped--off incoming signal
@ -399,7 +378,7 @@ int pcps_acquisition_fine_doppler_cc::compute_and_accumulate_grid(gr_vector_cons
// save the grid matrix delay file // save the grid matrix delay file
volk_32fc_magnitude_squared_32f(p_tmp_vector, d_ifft->get_outbuf(), d_fft_size); volk_32fc_magnitude_squared_32f(p_tmp_vector, d_ifft->get_outbuf(), d_fft_size);
//accumulate grid values //accumulate grid values
volk_32f_x2_add_32f(d_grid_data[doppler_index], d_grid_data[doppler_index], p_tmp_vector, d_fft_size); volk_32f_x2_add_32f(d_grid_data[doppler_index].data(), d_grid_data[doppler_index].data(), p_tmp_vector, d_fft_size);
} }
volk_gnsssdr_free(p_tmp_vector); volk_gnsssdr_free(p_tmp_vector);
@ -423,14 +402,14 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler()
int signal_samples = prn_replicas * d_fft_size; int signal_samples = prn_replicas * d_fft_size;
//int fft_size_extended = nextPowerOf2(signal_samples * zero_padding_factor); //int fft_size_extended = nextPowerOf2(signal_samples * zero_padding_factor);
int fft_size_extended = signal_samples * zero_padding_factor; int fft_size_extended = signal_samples * zero_padding_factor;
auto *fft_operator = new gr::fft::fft_complex(fft_size_extended, true); auto fft_operator = std::make_shared<gr::fft::fft_complex>(fft_size_extended, true);
//zero padding the entire vector //zero padding the entire vector
std::fill_n(fft_operator->get_inbuf(), fft_size_extended, gr_complex(0.0, 0.0)); std::fill_n(fft_operator->get_inbuf(), fft_size_extended, gr_complex(0.0, 0.0));
//1. generate local code aligned with the acquisition code phase estimation //1. generate local code aligned with the acquisition code phase estimation
auto *code_replica = static_cast<gr_complex *>(volk_gnsssdr_malloc(signal_samples * sizeof(gr_complex), volk_gnsssdr_get_alignment())); auto *code_replica = static_cast<gr_complex *>(volk_gnsssdr_malloc(signal_samples * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
gps_l1_ca_code_gen_complex_sampled(code_replica, d_gnss_synchro->PRN, d_fs_in, 0); gps_l1_ca_code_gen_complex_sampled(gsl::span<gr_complex>(code_replica, signal_samples * sizeof(gr_complex)), d_gnss_synchro->PRN, d_fs_in, 0);
int shift_index = static_cast<int>(d_gnss_synchro->Acq_delay_samples); int shift_index = static_cast<int>(d_gnss_synchro->Acq_delay_samples);
@ -460,9 +439,7 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler()
//case even //case even
int counter = 0; int counter = 0;
auto *fftFreqBins = new float[fft_size_extended]; auto fftFreqBins = std::vector<float>(fft_size_extended);
std::fill_n(fftFreqBins, fft_size_extended, 0.0);
for (int k = 0; k < (fft_size_extended / 2); k++) for (int k = 0; k < (fft_size_extended / 2); k++)
{ {
@ -489,10 +466,8 @@ int pcps_acquisition_fine_doppler_cc::estimate_Doppler()
} }
// free memory!! // free memory!!
delete fft_operator;
volk_gnsssdr_free(code_replica); volk_gnsssdr_free(code_replica);
volk_gnsssdr_free(p_tmp_vector); volk_gnsssdr_free(p_tmp_vector);
delete[] fftFreqBins;
return d_fft_size; return d_fft_size;
} }
@ -705,11 +680,11 @@ void pcps_acquisition_fine_doppler_cc::dump_results(int effective_fft_size)
dims[0] = static_cast<size_t>(1); dims[0] = static_cast<size_t>(1);
dims[1] = static_cast<size_t>(1); dims[1] = static_cast<size_t>(1);
matvar = Mat_VarCreate("doppler_max", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_config_doppler_max, 0); matvar = Mat_VarCreate("doppler_max", MAT_C_INT32, MAT_T_INT32, 1, dims, &d_config_doppler_max, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);
matvar = Mat_VarCreate("doppler_step", MAT_C_UINT32, MAT_T_UINT32, 1, dims, &d_doppler_step, 0); matvar = Mat_VarCreate("doppler_step", MAT_C_INT32, MAT_T_INT32, 1, dims, &d_doppler_step, 0);
Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE Mat_VarWrite(matfp, matvar, MAT_COMPRESSION_ZLIB); // or MAT_COMPRESSION_NONE
Mat_VarFree(matvar); Mat_VarFree(matvar);

View File

@ -58,15 +58,16 @@
#include <gnuradio/gr_complex.h> #include <gnuradio/gr_complex.h>
#include <cstdint> #include <cstdint>
#include <fstream> #include <fstream>
#include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector>
class pcps_acquisition_fine_doppler_cc; class pcps_acquisition_fine_doppler_cc;
using pcps_acquisition_fine_doppler_cc_sptr = boost::shared_ptr<pcps_acquisition_fine_doppler_cc>; using pcps_acquisition_fine_doppler_cc_sptr = boost::shared_ptr<pcps_acquisition_fine_doppler_cc>;
pcps_acquisition_fine_doppler_cc_sptr pcps_acquisition_fine_doppler_cc_sptr pcps_make_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
pcps_make_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
/*! /*!
* \brief This class implements a Parallel Code Phase Search Acquisition. * \brief This class implements a Parallel Code Phase Search Acquisition.
@ -74,63 +75,6 @@ pcps_make_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
*/ */
class pcps_acquisition_fine_doppler_cc : public gr::block class pcps_acquisition_fine_doppler_cc : public gr::block
{ {
private:
friend pcps_acquisition_fine_doppler_cc_sptr
pcps_make_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
pcps_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
int compute_and_accumulate_grid(gr_vector_const_void_star& input_items);
int estimate_Doppler();
float estimate_input_power(gr_vector_const_void_star& input_items);
double compute_CAF();
void reset_grid();
void update_carrier_wipeoff();
void free_grid_memory();
bool start();
Acq_Conf acq_parameters;
int64_t d_fs_in;
int d_samples_per_ms;
int d_max_dwells;
int d_gnuradio_forecast_samples;
float d_threshold;
std::string d_satellite_str;
int d_config_doppler_max;
int d_num_doppler_points;
int d_doppler_step;
unsigned int d_fft_size;
uint64_t d_sample_counter;
gr_complex* d_carrier;
gr_complex* d_fft_codes;
gr_complex* d_10_ms_buffer;
float* d_magnitude;
float** d_grid_data;
gr_complex** d_grid_doppler_wipeoffs;
gr::fft::fft_complex* d_fft_if;
gr::fft::fft_complex* d_ifft;
Gnss_Synchro* d_gnss_synchro;
unsigned int d_code_phase;
float d_doppler_freq;
float d_test_statistics;
int d_positive_acq;
int d_state;
bool d_active;
int d_well_count;
int d_n_samples_in_buffer;
bool d_dump;
unsigned int d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
arma::fmat grid_;
int64_t d_dump_number;
unsigned int d_dump_channel;
public: public:
/*! /*!
* \brief Default destructor. * \brief Default destructor.
@ -220,20 +164,11 @@ public:
void set_doppler_step(unsigned int doppler_step); void set_doppler_step(unsigned int doppler_step);
/*! /*!
* \brief If set to 1, ensures that acquisition starts at the * \brief If set to 1, ensures that acquisition starts at the
* first available sample. * first available sample.
* \param state - int=1 forces start of acquisition * \param state - int=1 forces start of acquisition
*/
void set_state(int state);
/*!
* \brief Parallel Code Phase Search Acquisition signal processing.
*/ */
int general_work(int noutput_items, gr_vector_int& ninput_items, void set_state(int state);
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items);
void forecast(int noutput_items, gr_vector_int& ninput_items_required);
/*! /*!
* \brief Obtains the next power of 2 greater or equal to the input parameter * \brief Obtains the next power of 2 greater or equal to the input parameter
@ -242,6 +177,64 @@ public:
unsigned int nextPowerOf2(unsigned int n); unsigned int nextPowerOf2(unsigned int n);
void dump_results(int effective_fft_size); void dump_results(int effective_fft_size);
void forecast(int noutput_items, gr_vector_int& ninput_items_required);
/*!
* \brief Parallel Code Phase Search Acquisition signal processing.
*/
int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items);
private:
friend pcps_acquisition_fine_doppler_cc_sptr
pcps_make_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
pcps_acquisition_fine_doppler_cc(const Acq_Conf& conf_);
int compute_and_accumulate_grid(gr_vector_const_void_star& input_items);
int estimate_Doppler();
float estimate_input_power(gr_vector_const_void_star& input_items);
double compute_CAF();
void reset_grid();
void update_carrier_wipeoff();
bool start();
Acq_Conf acq_parameters;
int64_t d_fs_in;
int d_samples_per_ms;
int d_max_dwells;
int d_gnuradio_forecast_samples;
float d_threshold;
std::string d_satellite_str;
int d_config_doppler_max;
int d_num_doppler_points;
int d_doppler_step;
unsigned int d_fft_size;
uint64_t d_sample_counter;
gr_complex* d_carrier;
gr_complex* d_fft_codes;
gr_complex* d_10_ms_buffer;
float* d_magnitude;
std::vector<std::vector<float>> d_grid_data;
std::vector<std::vector<std::complex<float>>> d_grid_doppler_wipeoffs;
std::shared_ptr<gr::fft::fft_complex> d_fft_if;
std::shared_ptr<gr::fft::fft_complex> d_ifft;
Gnss_Synchro* d_gnss_synchro;
unsigned int d_code_phase;
float d_doppler_freq;
float d_test_statistics;
int d_positive_acq;
int d_state;
bool d_active;
int d_well_count;
int d_n_samples_in_buffer;
bool d_dump;
unsigned int d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
arma::fmat grid_;
int64_t d_dump_number;
unsigned int d_dump_channel;
}; };
#endif /* pcps_acquisition_fine_doppler_cc*/ #endif /* pcps_acquisition_fine_doppler_cc*/

View File

@ -34,7 +34,6 @@
#include "pcps_acquisition_fpga.h" #include "pcps_acquisition_fpga.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
//#include <boost/chrono.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <cmath> // for ceil #include <cmath> // for ceil
#include <iostream> // for operator<< #include <iostream> // for operator<<
@ -87,6 +86,7 @@ pcps_acquisition_fpga::pcps_acquisition_fpga(pcpsconf_fpga_t conf_)
pcps_acquisition_fpga::~pcps_acquisition_fpga() = default; pcps_acquisition_fpga::~pcps_acquisition_fpga() = default;
void pcps_acquisition_fpga::set_local_code() void pcps_acquisition_fpga::set_local_code()
{ {
acquisition_fpga->set_local_code(d_gnss_synchro->PRN); acquisition_fpga->set_local_code(d_gnss_synchro->PRN);
@ -174,6 +174,7 @@ void pcps_acquisition_fpga::send_negative_acquisition()
} }
} }
void pcps_acquisition_fpga::acquisition_core(uint32_t num_doppler_bins, uint32_t doppler_step, int32_t doppler_min) void pcps_acquisition_fpga::acquisition_core(uint32_t num_doppler_bins, uint32_t doppler_step, int32_t doppler_min)
{ {
uint32_t indext = 0U; uint32_t indext = 0U;

View File

@ -62,7 +62,7 @@ typedef struct
int32_t code_length; int32_t code_length;
uint32_t select_queue_Fpga; uint32_t select_queue_Fpga;
std::string device_name; std::string device_name;
uint32_t* all_fft_codes; // pointer to memory that contains all the code ffts uint32_t* all_fft_codes; // pointer to memory that contains all the code ffts
//float downsampling_factor; //float downsampling_factor;
uint32_t downsampling_factor; uint32_t downsampling_factor;
uint32_t total_block_exp; uint32_t total_block_exp;
@ -78,8 +78,7 @@ class pcps_acquisition_fpga;
using pcps_acquisition_fpga_sptr = boost::shared_ptr<pcps_acquisition_fpga>; using pcps_acquisition_fpga_sptr = boost::shared_ptr<pcps_acquisition_fpga>;
pcps_acquisition_fpga_sptr pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_);
pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_);
/*! /*!
* \brief This class implements a Parallel Code Phase Search Acquisition that uses the FPGA. * \brief This class implements a Parallel Code Phase Search Acquisition that uses the FPGA.
@ -89,49 +88,6 @@ pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_);
*/ */
class pcps_acquisition_fpga class pcps_acquisition_fpga
{ {
private:
friend pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_);
pcps_acquisition_fpga(pcpsconf_fpga_t conf_);
void send_negative_acquisition();
void send_positive_acquisition();
float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
void acquisition_core(uint32_t num_doppler_bins, uint32_t doppler_step, int32_t doppler_max);
pcpsconf_fpga_t acq_parameters;
bool d_active;
float d_threshold;
float d_mag;
float d_input_power;
uint32_t d_doppler_index;
float d_test_statistics;
int32_t d_state;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
uint32_t d_doppler_step;
uint32_t d_doppler_max;
uint32_t d_fft_size;
uint32_t d_num_doppler_bins;
uint64_t d_sample_counter;
Gnss_Synchro* d_gnss_synchro;
std::shared_ptr<Fpga_Acquisition> acquisition_fpga;
//float d_downsampling_factor;
uint32_t d_downsampling_factor;
uint32_t d_select_queue_Fpga;
uint32_t d_total_block_exp;
bool d_make_2_steps;
uint32_t d_num_doppler_bins_step2;
float d_doppler_step2;
float d_doppler_center_step_two;
uint32_t d_max_num_acqs;
public: public:
~pcps_acquisition_fpga(); ~pcps_acquisition_fpga();
@ -229,6 +185,39 @@ public:
* \brief This funciton triggers a HW reset of the FPGA PL. * \brief This funciton triggers a HW reset of the FPGA PL.
*/ */
void reset_acquisition(void); void reset_acquisition(void);
private:
friend pcps_acquisition_fpga_sptr pcps_make_acquisition_fpga(pcpsconf_fpga_t conf_);
pcps_acquisition_fpga(pcpsconf_fpga_t conf_);
bool d_active;
bool d_make_2_steps;
uint32_t d_doppler_index;
uint32_t d_channel;
uint32_t d_doppler_step;
uint32_t d_doppler_max;
uint32_t d_fft_size;
uint32_t d_num_doppler_bins;
uint32_t d_downsampling_factor;
uint32_t d_select_queue_Fpga;
uint32_t d_total_block_exp;
uint32_t d_num_doppler_bins_step2;
uint32_t d_max_num_acqs;
int32_t d_state;
uint64_t d_sample_counter;
float d_threshold;
float d_mag;
float d_input_power;
float d_test_statistics;
float d_doppler_step2;
float d_doppler_center_step_two;
pcpsconf_fpga_t acq_parameters;
Gnss_Synchro* d_gnss_synchro;
std::shared_ptr<Fpga_Acquisition> acquisition_fpga;
std::weak_ptr<ChannelFsm> d_channel_fsm;
void send_negative_acquisition();
void send_positive_acquisition();
void acquisition_core(uint32_t num_doppler_bins, uint32_t doppler_step, int32_t doppler_max);
float first_vs_second_peak_statistic(uint32_t& indext, int32_t& doppler, uint32_t num_doppler_bins, int32_t doppler_max, int32_t doppler_step);
}; };
#endif /* GNSS_SDR_PCPS_ACQUISITION_FPGA_H_*/ #endif /* GNSS_SDR_PCPS_ACQUISITION_FPGA_H_*/

View File

@ -82,10 +82,10 @@ pcps_assisted_acquisition_cc::pcps_assisted_acquisition_cc(
d_carrier = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment())); d_carrier = static_cast<gr_complex *>(volk_gnsssdr_malloc(d_fft_size * sizeof(gr_complex), volk_gnsssdr_get_alignment()));
// Direct FFT // Direct FFT
d_fft_if = new gr::fft::fft_complex(d_fft_size, true); d_fft_if = std::make_shared<gr::fft::fft_complex>(d_fft_size, true);
// Inverse FFT // Inverse FFT
d_ifft = new gr::fft::fft_complex(d_fft_size, false); d_ifft = std::make_shared<gr::fft::fft_complex>(d_fft_size, false);
// For dumping samples into a file // For dumping samples into a file
d_dump = dump; d_dump = dump;
@ -97,8 +97,6 @@ pcps_assisted_acquisition_cc::pcps_assisted_acquisition_cc(
d_doppler_min = 0; d_doppler_min = 0;
d_num_doppler_points = 0; d_num_doppler_points = 0;
d_doppler_step = 0; d_doppler_step = 0;
d_grid_data = nullptr;
d_grid_doppler_wipeoffs = nullptr;
d_gnss_synchro = nullptr; d_gnss_synchro = nullptr;
d_code_phase = 0; d_code_phase = 0;
d_doppler_freq = 0; d_doppler_freq = 0;
@ -114,23 +112,10 @@ void pcps_assisted_acquisition_cc::set_doppler_step(uint32_t doppler_step)
} }
void pcps_assisted_acquisition_cc::free_grid_memory()
{
for (int32_t i = 0; i < d_num_doppler_points; i++)
{
delete[] d_grid_data[i];
delete[] d_grid_doppler_wipeoffs[i];
}
delete d_grid_data;
}
pcps_assisted_acquisition_cc::~pcps_assisted_acquisition_cc() pcps_assisted_acquisition_cc::~pcps_assisted_acquisition_cc()
{ {
volk_gnsssdr_free(d_carrier); volk_gnsssdr_free(d_carrier);
volk_gnsssdr_free(d_fft_codes); volk_gnsssdr_free(d_fft_codes);
delete d_ifft;
delete d_fft_if;
try try
{ {
if (d_dump) if (d_dump)
@ -236,26 +221,21 @@ void pcps_assisted_acquisition_cc::redefine_grid()
// Create the search grid array // Create the search grid array
d_num_doppler_points = floor(std::abs(d_doppler_max - d_doppler_min) / d_doppler_step); d_num_doppler_points = floor(std::abs(d_doppler_max - d_doppler_min) / d_doppler_step);
d_grid_data = new float *[d_num_doppler_points]; d_grid_data = std::vector<std::vector<float>>(d_num_doppler_points, std::vector<float>(d_fft_size));
for (int32_t i = 0; i < d_num_doppler_points; i++)
{
d_grid_data[i] = new float[d_fft_size];
}
// create the carrier Doppler wipeoff signals // create the carrier Doppler wipeoff signals
int32_t doppler_hz; int32_t doppler_hz;
float phase_step_rad; float phase_step_rad;
d_grid_doppler_wipeoffs = new gr_complex *[d_num_doppler_points]; d_grid_doppler_wipeoffs = std::vector<std::vector<std::complex<float>>>(d_num_doppler_points, std::vector<std::complex<float>>(d_fft_size));
for (int32_t doppler_index = 0; doppler_index < d_num_doppler_points; doppler_index++) for (int32_t doppler_index = 0; doppler_index < d_num_doppler_points; doppler_index++)
{ {
doppler_hz = d_doppler_min + d_doppler_step * doppler_index; doppler_hz = d_doppler_min + d_doppler_step * doppler_index;
// doppler search steps // doppler search steps
// compute the carrier doppler wipe-off signal and store it // compute the carrier doppler wipe-off signal and store it
phase_step_rad = static_cast<float>(GPS_TWO_PI) * doppler_hz / static_cast<float>(d_fs_in); phase_step_rad = static_cast<float>(GPS_TWO_PI) * doppler_hz / static_cast<float>(d_fs_in);
d_grid_doppler_wipeoffs[doppler_index] = new gr_complex[d_fft_size];
float _phase[1]; float _phase[1];
_phase[0] = 0; _phase[0] = 0;
volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index], -phase_step_rad, _phase, d_fft_size); volk_gnsssdr_s32f_sincos_32fc(d_grid_doppler_wipeoffs[doppler_index].data(), -phase_step_rad, _phase, d_fft_size);
} }
} }
@ -270,7 +250,7 @@ double pcps_assisted_acquisition_cc::search_maximum()
for (int32_t i = 0; i < d_num_doppler_points; i++) for (int32_t i = 0; i < d_num_doppler_points; i++)
{ {
volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_grid_data[i], d_fft_size); volk_gnsssdr_32f_index_max_32u(&tmp_intex_t, d_grid_data[i].data(), d_fft_size);
if (d_grid_data[i][tmp_intex_t] > magt) if (d_grid_data[i][tmp_intex_t] > magt)
{ {
magt = d_grid_data[i][index_time]; magt = d_grid_data[i][index_time];
@ -302,7 +282,7 @@ double pcps_assisted_acquisition_cc::search_maximum()
<< "_" << d_gnss_synchro->Signal << "_sat_" << "_" << d_gnss_synchro->Signal << "_sat_"
<< d_gnss_synchro->PRN << "_doppler_" << d_gnss_synchro->Acq_doppler_hz << ".dat"; << d_gnss_synchro->PRN << "_doppler_" << d_gnss_synchro->Acq_doppler_hz << ".dat";
d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary); d_dump_file.open(filename.str().c_str(), std::ios::out | std::ios::binary);
d_dump_file.write(reinterpret_cast<char *>(d_grid_data[index_doppler]), n); //write directly |abs(x)|^2 in this Doppler bin? d_dump_file.write(reinterpret_cast<char *>(d_grid_data[index_doppler].data()), n); //write directly |abs(x)|^2 in this Doppler bin?
d_dump_file.close(); d_dump_file.close();
} }
@ -345,7 +325,7 @@ int32_t pcps_assisted_acquisition_cc::compute_and_accumulate_grid(gr_vector_cons
{ {
// doppler search steps // doppler search steps
// Perform the carrier wipe-off // Perform the carrier wipe-off
volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index], d_fft_size); volk_32fc_x2_multiply_32fc(d_fft_if->get_inbuf(), in, d_grid_doppler_wipeoffs[doppler_index].data(), d_fft_size);
// 3- Perform the FFT-based convolution (parallel time search) // 3- Perform the FFT-based convolution (parallel time search)
// Compute the FFT of the carrier wiped--off incoming signal // Compute the FFT of the carrier wiped--off incoming signal
d_fft_if->execute(); d_fft_if->execute();
@ -359,8 +339,8 @@ int32_t pcps_assisted_acquisition_cc::compute_and_accumulate_grid(gr_vector_cons
// save the grid matrix delay file // save the grid matrix delay file
volk_32fc_magnitude_squared_32f(p_tmp_vector, d_ifft->get_outbuf(), d_fft_size); volk_32fc_magnitude_squared_32f(p_tmp_vector, d_ifft->get_outbuf(), d_fft_size);
const float *old_vector = d_grid_data[doppler_index]; const float *old_vector = d_grid_data[doppler_index].data();
volk_32f_x2_add_32f(d_grid_data[doppler_index], old_vector, p_tmp_vector, d_fft_size); volk_32f_x2_add_32f(d_grid_data[doppler_index].data(), old_vector, p_tmp_vector, d_fft_size);
} }
volk_gnsssdr_free(p_tmp_vector); volk_gnsssdr_free(p_tmp_vector);
return d_fft_size; return d_fft_size;
@ -441,7 +421,6 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items,
consume_each(ninput_items[0]); consume_each(ninput_items[0]);
break; break;
case 4: // RedefineGrid case 4: // RedefineGrid
free_grid_memory();
redefine_grid(); redefine_grid();
reset_grid(); reset_grid();
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
@ -460,7 +439,6 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items,
d_active = false; d_active = false;
// Send message to channel port //0=STOP_CHANNEL 1=ACQ_SUCCESS 2=ACQ_FAIL // Send message to channel port //0=STOP_CHANNEL 1=ACQ_SUCCESS 2=ACQ_FAIL
this->message_port_pub(pmt::mp("events"), pmt::from_long(1)); this->message_port_pub(pmt::mp("events"), pmt::from_long(1));
free_grid_memory();
// consume samples to not block the GNU Radio flowgraph // consume samples to not block the GNU Radio flowgraph
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
consume_each(ninput_items[0]); consume_each(ninput_items[0]);
@ -478,7 +456,6 @@ int pcps_assisted_acquisition_cc::general_work(int noutput_items,
d_active = false; d_active = false;
// Send message to channel port //0=STOP_CHANNEL 1=ACQ_SUCCESS 2=ACQ_FAIL // Send message to channel port //0=STOP_CHANNEL 1=ACQ_SUCCESS 2=ACQ_FAIL
this->message_port_pub(pmt::mp("events"), pmt::from_long(2)); this->message_port_pub(pmt::mp("events"), pmt::from_long(2));
free_grid_memory();
// consume samples to not block the GNU Radio flowgraph // consume samples to not block the GNU Radio flowgraph
d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter d_sample_counter += static_cast<uint64_t>(ninput_items[0]); // sample counter
consume_each(ninput_items[0]); consume_each(ninput_items[0]);

View File

@ -54,15 +54,16 @@
#include <gnuradio/fft/fft.h> #include <gnuradio/fft/fft.h>
#include <gnuradio/gr_complex.h> #include <gnuradio/gr_complex.h>
#include <fstream> #include <fstream>
#include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector>
class pcps_assisted_acquisition_cc; class pcps_assisted_acquisition_cc;
using pcps_assisted_acquisition_cc_sptr = boost::shared_ptr<pcps_assisted_acquisition_cc>; using pcps_assisted_acquisition_cc_sptr = boost::shared_ptr<pcps_assisted_acquisition_cc>;
pcps_assisted_acquisition_cc_sptr pcps_assisted_acquisition_cc_sptr pcps_make_assisted_acquisition_cc(
pcps_make_assisted_acquisition_cc(
int32_t max_dwells, int32_t max_dwells,
uint32_t sampled_ms, uint32_t sampled_ms,
int32_t doppler_max, int32_t doppler_max,
@ -79,69 +80,6 @@ pcps_make_assisted_acquisition_cc(
*/ */
class pcps_assisted_acquisition_cc : public gr::block class pcps_assisted_acquisition_cc : public gr::block
{ {
private:
friend pcps_assisted_acquisition_cc_sptr
pcps_make_assisted_acquisition_cc(int32_t max_dwells, uint32_t sampled_ms,
int32_t doppler_max, int32_t doppler_min, int64_t fs_in,
int32_t samples_per_ms, bool dump,
std::string dump_filename);
pcps_assisted_acquisition_cc(int32_t max_dwells, uint32_t sampled_ms,
int32_t doppler_max, int32_t doppler_min, int64_t fs_in,
int32_t samples_per_ms, bool dump,
std::string dump_filename);
void calculate_magnitudes(gr_complex* fft_begin, int32_t doppler_shift,
int32_t doppler_offset);
int32_t compute_and_accumulate_grid(gr_vector_const_void_star& input_items);
float estimate_input_power(gr_vector_const_void_star& input_items);
double search_maximum();
void get_assistance();
void reset_grid();
void redefine_grid();
void free_grid_memory();
int64_t d_fs_in;
int32_t d_samples_per_ms;
int32_t d_max_dwells;
uint32_t d_doppler_resolution;
int32_t d_gnuradio_forecast_samples;
float d_threshold;
std::string d_satellite_str;
int32_t d_doppler_max;
int32_t d_doppler_min;
int32_t d_config_doppler_max;
int32_t d_config_doppler_min;
int32_t d_num_doppler_points;
int32_t d_doppler_step;
uint32_t d_sampled_ms;
uint32_t d_fft_size;
uint64_t d_sample_counter;
gr_complex* d_carrier;
gr_complex* d_fft_codes;
float** d_grid_data;
gr_complex** d_grid_doppler_wipeoffs;
gr::fft::fft_complex* d_fft_if;
gr::fft::fft_complex* d_ifft;
Gnss_Synchro* d_gnss_synchro;
uint32_t d_code_phase;
float d_doppler_freq;
float d_input_power;
float d_test_statistics;
std::ofstream d_dump_file;
int32_t d_state;
bool d_active;
bool d_disable_assist;
int32_t d_well_count;
bool d_dump;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
public: public:
/*! /*!
* \brief Default destructor. * \brief Default destructor.
@ -237,6 +175,68 @@ public:
gr_vector_void_star& output_items); gr_vector_void_star& output_items);
void forecast(int noutput_items, gr_vector_int& ninput_items_required); void forecast(int noutput_items, gr_vector_int& ninput_items_required);
private:
friend pcps_assisted_acquisition_cc_sptr
pcps_make_assisted_acquisition_cc(int32_t max_dwells, uint32_t sampled_ms,
int32_t doppler_max, int32_t doppler_min, int64_t fs_in,
int32_t samples_per_ms, bool dump,
std::string dump_filename);
pcps_assisted_acquisition_cc(int32_t max_dwells, uint32_t sampled_ms,
int32_t doppler_max, int32_t doppler_min, int64_t fs_in,
int32_t samples_per_ms, bool dump,
std::string dump_filename);
void calculate_magnitudes(gr_complex* fft_begin, int32_t doppler_shift,
int32_t doppler_offset);
int32_t compute_and_accumulate_grid(gr_vector_const_void_star& input_items);
float estimate_input_power(gr_vector_const_void_star& input_items);
double search_maximum();
void get_assistance();
void reset_grid();
void redefine_grid();
int64_t d_fs_in;
int32_t d_samples_per_ms;
int32_t d_max_dwells;
uint32_t d_doppler_resolution;
int32_t d_gnuradio_forecast_samples;
float d_threshold;
std::string d_satellite_str;
int32_t d_doppler_max;
int32_t d_doppler_min;
int32_t d_config_doppler_max;
int32_t d_config_doppler_min;
int32_t d_num_doppler_points;
int32_t d_doppler_step;
uint32_t d_sampled_ms;
uint32_t d_fft_size;
uint64_t d_sample_counter;
gr_complex* d_carrier;
gr_complex* d_fft_codes;
std::vector<std::vector<float>> d_grid_data;
std::vector<std::vector<std::complex<float>>> d_grid_doppler_wipeoffs;
std::shared_ptr<gr::fft::fft_complex> d_fft_if;
std::shared_ptr<gr::fft::fft_complex> d_ifft;
Gnss_Synchro* d_gnss_synchro;
uint32_t d_code_phase;
float d_doppler_freq;
float d_input_power;
float d_test_statistics;
std::ofstream d_dump_file;
int32_t d_state;
bool d_active;
bool d_disable_assist;
int32_t d_well_count;
bool d_dump;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
}; };
#endif /* GNSS_SDR_PCPS_assisted_acquisition_cc_H_*/ #endif /* GNSS_SDR_PCPS_assisted_acquisition_cc_H_*/

View File

@ -97,10 +97,10 @@ pcps_cccwsr_acquisition_cc::pcps_cccwsr_acquisition_cc(
d_magnitude = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); d_magnitude = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
// Direct FFT // Direct FFT
d_fft_if = new gr::fft::fft_complex(d_fft_size, true); d_fft_if = std::make_shared<gr::fft::fft_complex>(d_fft_size, true);
// Inverse FFT // Inverse FFT
d_ifft = new gr::fft::fft_complex(d_fft_size, false); d_ifft = std::make_shared<gr::fft::fft_complex>(d_fft_size, false);
// For dumping samples into a file // For dumping samples into a file
d_dump = dump; d_dump = dump;
@ -137,9 +137,6 @@ pcps_cccwsr_acquisition_cc::~pcps_cccwsr_acquisition_cc()
volk_gnsssdr_free(d_correlation_minus); volk_gnsssdr_free(d_correlation_minus);
volk_gnsssdr_free(d_magnitude); volk_gnsssdr_free(d_magnitude);
delete d_ifft;
delete d_fft_if;
try try
{ {
if (d_dump) if (d_dump)

View File

@ -43,6 +43,7 @@
#include <gnuradio/fft/fft.h> #include <gnuradio/fft/fft.h>
#include <gnuradio/gr_complex.h> #include <gnuradio/gr_complex.h>
#include <fstream> #include <fstream>
#include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
@ -51,8 +52,7 @@ class pcps_cccwsr_acquisition_cc;
using pcps_cccwsr_acquisition_cc_sptr = boost::shared_ptr<pcps_cccwsr_acquisition_cc>; using pcps_cccwsr_acquisition_cc_sptr = boost::shared_ptr<pcps_cccwsr_acquisition_cc>;
pcps_cccwsr_acquisition_cc_sptr pcps_cccwsr_acquisition_cc_sptr pcps_cccwsr_make_acquisition_cc(
pcps_cccwsr_make_acquisition_cc(
uint32_t sampled_ms, uint32_t sampled_ms,
uint32_t max_dwells, uint32_t max_dwells,
uint32_t doppler_max, uint32_t doppler_max,
@ -68,59 +68,6 @@ pcps_cccwsr_make_acquisition_cc(
*/ */
class pcps_cccwsr_acquisition_cc : public gr::block class pcps_cccwsr_acquisition_cc : public gr::block
{ {
private:
friend pcps_cccwsr_acquisition_cc_sptr
pcps_cccwsr_make_acquisition_cc(uint32_t sampled_ms, uint32_t max_dwells,
uint32_t doppler_max, int64_t fs_in,
int32_t samples_per_ms, int32_t samples_per_code,
bool dump, std::string dump_filename);
pcps_cccwsr_acquisition_cc(uint32_t sampled_ms, uint32_t max_dwells,
uint32_t doppler_max, int64_t fs_in,
int32_t samples_per_ms, int32_t samples_per_code,
bool dump, std::string dump_filename);
void calculate_magnitudes(gr_complex* fft_begin, int32_t doppler_shift,
int32_t doppler_offset);
int64_t d_fs_in;
int32_t d_samples_per_ms;
int32_t d_samples_per_code;
uint32_t d_doppler_resolution;
float d_threshold;
std::string d_satellite_str;
uint32_t d_doppler_max;
uint32_t d_doppler_step;
uint32_t d_sampled_ms;
uint32_t d_max_dwells;
uint32_t d_well_count;
uint32_t d_fft_size;
uint64_t d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
uint32_t d_num_doppler_bins;
gr_complex* d_fft_code_data;
gr_complex* d_fft_code_pilot;
gr::fft::fft_complex* d_fft_if;
gr::fft::fft_complex* d_ifft;
Gnss_Synchro* d_gnss_synchro;
uint32_t d_code_phase;
float d_doppler_freq;
float d_mag;
float* d_magnitude;
gr_complex* d_data_correlation;
gr_complex* d_pilot_correlation;
gr_complex* d_correlation_plus;
gr_complex* d_correlation_minus;
float d_input_power;
float d_test_statistics;
std::ofstream d_dump_file;
bool d_active;
int32_t d_state;
bool d_dump;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
public: public:
/*! /*!
* \brief Default destructor. * \brief Default destructor.
@ -225,6 +172,59 @@ public:
int general_work(int noutput_items, gr_vector_int& ninput_items, int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items); gr_vector_void_star& output_items);
private:
friend pcps_cccwsr_acquisition_cc_sptr
pcps_cccwsr_make_acquisition_cc(uint32_t sampled_ms, uint32_t max_dwells,
uint32_t doppler_max, int64_t fs_in,
int32_t samples_per_ms, int32_t samples_per_code,
bool dump, std::string dump_filename);
pcps_cccwsr_acquisition_cc(uint32_t sampled_ms, uint32_t max_dwells,
uint32_t doppler_max, int64_t fs_in,
int32_t samples_per_ms, int32_t samples_per_code,
bool dump, std::string dump_filename);
void calculate_magnitudes(gr_complex* fft_begin, int32_t doppler_shift,
int32_t doppler_offset);
int64_t d_fs_in;
int32_t d_samples_per_ms;
int32_t d_samples_per_code;
uint32_t d_doppler_resolution;
float d_threshold;
std::string d_satellite_str;
uint32_t d_doppler_max;
uint32_t d_doppler_step;
uint32_t d_sampled_ms;
uint32_t d_max_dwells;
uint32_t d_well_count;
uint32_t d_fft_size;
uint64_t d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
uint32_t d_num_doppler_bins;
gr_complex* d_fft_code_data;
gr_complex* d_fft_code_pilot;
std::shared_ptr<gr::fft::fft_complex> d_fft_if;
std::shared_ptr<gr::fft::fft_complex> d_ifft;
Gnss_Synchro* d_gnss_synchro;
uint32_t d_code_phase;
float d_doppler_freq;
float d_mag;
float* d_magnitude;
gr_complex* d_data_correlation;
gr_complex* d_pilot_correlation;
gr_complex* d_correlation_plus;
gr_complex* d_correlation_minus;
float d_input_power;
float d_test_statistics;
std::ofstream d_dump_file;
bool d_active;
int32_t d_state;
bool d_dump;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
}; };
#endif /* GNSS_SDR_PCPS_CCCWSR_ACQUISITION_CC_H_*/ #endif /* GNSS_SDR_PCPS_CCCWSR_ACQUISITION_CC_H_*/

View File

@ -131,10 +131,10 @@ pcps_opencl_acquisition_cc::pcps_opencl_acquisition_cc(
if (d_opencl != 0) if (d_opencl != 0)
{ {
// Direct FFT // Direct FFT
d_fft_if = new gr::fft::fft_complex(d_fft_size, true); d_fft_if = std::make_shared<gr::fft::fft_complex>(d_fft_size, true);
// Inverse FFT // Inverse FFT
d_ifft = new gr::fft::fft_complex(d_fft_size, false); d_ifft = std::make_shared<gr::fft::fft_complex>(d_fft_size, false);
} }
// For dumping samples into a file // For dumping samples into a file
@ -179,11 +179,6 @@ pcps_opencl_acquisition_cc::~pcps_opencl_acquisition_cc()
clFFT_DestroyPlan(d_cl_fft_plan); clFFT_DestroyPlan(d_cl_fft_plan);
} }
else
{
delete d_ifft;
delete d_fft_if;
}
try try
{ {

View File

@ -54,11 +54,11 @@
#define CL_SILENCE_DEPRECATION #define CL_SILENCE_DEPRECATION
#include "channel_fsm.h" #include "channel_fsm.h"
#include "gnss_synchro.h" #include "gnss_synchro.h"
#include "opencl/cl.hpp"
#include "opencl/fft_internal.h" #include "opencl/fft_internal.h"
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <gnuradio/fft/fft.h> #include <gnuradio/fft/fft.h>
#include <gnuradio/gr_complex.h> #include <gnuradio/gr_complex.h>
#include "opencl/cl.hpp"
#include <cstdint> #include <cstdint>
#include <fstream> #include <fstream>
#include <string> #include <string>
@ -68,10 +68,13 @@ class pcps_opencl_acquisition_cc;
typedef boost::shared_ptr<pcps_opencl_acquisition_cc> pcps_opencl_acquisition_cc_sptr; typedef boost::shared_ptr<pcps_opencl_acquisition_cc> pcps_opencl_acquisition_cc_sptr;
pcps_opencl_acquisition_cc_sptr pcps_opencl_acquisition_cc_sptr pcps_make_opencl_acquisition_cc(
pcps_make_opencl_acquisition_cc(uint32_t sampled_ms, uint32_t max_dwells, uint32_t sampled_ms,
uint32_t doppler_max, int64_t fs_in, uint32_t max_dwells,
int samples_per_ms, int samples_per_code, uint32_t doppler_max,
int64_t fs_in,
int samples_per_ms,
int samples_per_code,
bool bit_transition_flag, bool bit_transition_flag,
bool dump, bool dump,
std::string dump_filename); std::string dump_filename);
@ -84,6 +87,124 @@ pcps_make_opencl_acquisition_cc(uint32_t sampled_ms, uint32_t max_dwells,
*/ */
class pcps_opencl_acquisition_cc : public gr::block class pcps_opencl_acquisition_cc : public gr::block
{ {
public:
/*!
* \brief Default destructor.
*/
~pcps_opencl_acquisition_cc();
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to exchange synchronization data between acquisition and tracking blocks.
* \param p_gnss_synchro Satellite information shared by the processing blocks.
*/
inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
{
d_gnss_synchro = p_gnss_synchro;
}
/*!
* \brief Returns the maximum peak of grid search.
*/
inline uint32_t mag() const
{
return d_mag;
}
/*!
* \brief Initializes acquisition algorithm.
*/
void init();
/*!
* \brief Sets local code for PCPS acquisition algorithm.
* \param code - Pointer to the PRN code.
*/
void set_local_code(std::complex<float>* code);
/*!
* \brief Starts acquisition algorithm, turning from standby mode to
* active mode
* \param active - bool that activates/deactivates the block.
*/
inline void set_active(bool active)
{
d_active = active;
}
/*!
* \brief If set to 1, ensures that acquisition starts at the
* first available sample.
* \param state - int=1 forces start of acquisition
*/
void set_state(int state);
/*!
* \brief Set acquisition channel unique ID
* \param channel - receiver channel.
*/
inline void set_channel(uint32_t channel)
{
d_channel = channel;
}
/*!
* \brief Set channel fsm associated to this acquisition instance
*/
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm)
{
d_channel_fsm = channel_fsm;
}
/*!
* \brief Set statistics threshold of PCPS algorithm.
* \param threshold - Threshold for signal detection (check \ref Navitec2012,
* Algorithm 1, for a definition of this threshold).
*/
inline void set_threshold(float threshold)
{
d_threshold = threshold;
}
/*!
* \brief Set maximum Doppler grid search
* \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
*/
inline void set_doppler_max(uint32_t doppler_max)
{
d_doppler_max = doppler_max;
}
/*!
* \brief Set Doppler steps for the grid search
* \param doppler_step - Frequency bin of the search grid [Hz].
*/
inline void set_doppler_step(uint32_t doppler_step)
{
d_doppler_step = doppler_step;
}
inline bool opencl_ready() const
{
bool ready = false;
if (d_opencl == 0)
{
ready = true;
}
return ready;
}
void acquisition_core_volk();
void acquisition_core_opencl();
/*!
* \brief Parallel Code Phase Search Acquisition signal processing.
*/
int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items);
private: private:
friend pcps_opencl_acquisition_cc_sptr friend pcps_opencl_acquisition_cc_sptr
pcps_make_opencl_acquisition_cc(uint32_t sampled_ms, uint32_t max_dwells, pcps_make_opencl_acquisition_cc(uint32_t sampled_ms, uint32_t max_dwells,
@ -123,8 +244,8 @@ private:
gr_complex** d_grid_doppler_wipeoffs; gr_complex** d_grid_doppler_wipeoffs;
uint32_t d_num_doppler_bins; uint32_t d_num_doppler_bins;
gr_complex* d_fft_codes; gr_complex* d_fft_codes;
gr::fft::fft_complex* d_fft_if; std::shared_ptr<gr::fft::fft_complex> d_fft_if;
gr::fft::fft_complex* d_ifft; std::shared_ptr<gr::fft::fft_complex> d_ifft;
Gnss_Synchro* d_gnss_synchro; Gnss_Synchro* d_gnss_synchro;
uint32_t d_code_phase; uint32_t d_code_phase;
float d_doppler_freq; float d_doppler_freq;
@ -144,6 +265,8 @@ private:
gr_complex** d_in_buffer; gr_complex** d_in_buffer;
std::vector<uint64_t> d_sample_counter_buffer; std::vector<uint64_t> d_sample_counter_buffer;
uint32_t d_in_dwell_count; uint32_t d_in_dwell_count;
std::weak_ptr<ChannelFsm> d_channel_fsm;
int d_opencl;
cl::Platform d_cl_platform; cl::Platform d_cl_platform;
cl::Device d_cl_device; cl::Device d_cl_device;
@ -158,125 +281,6 @@ private:
cl::CommandQueue* d_cl_queue; cl::CommandQueue* d_cl_queue;
clFFT_Plan d_cl_fft_plan; clFFT_Plan d_cl_fft_plan;
cl_int d_cl_fft_batch_size; cl_int d_cl_fft_batch_size;
std::weak_ptr<ChannelFsm> d_channel_fsm;
int d_opencl;
public:
/*!
* \brief Default destructor.
*/
~pcps_opencl_acquisition_cc();
/*!
* \brief Set acquisition/tracking common Gnss_Synchro object pointer
* to exchange synchronization data between acquisition and tracking blocks.
* \param p_gnss_synchro Satellite information shared by the processing blocks.
*/
inline void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro)
{
d_gnss_synchro = p_gnss_synchro;
}
/*!
* \brief Returns the maximum peak of grid search.
*/
inline uint32_t mag() const
{
return d_mag;
}
/*!
* \brief Initializes acquisition algorithm.
*/
void init();
/*!
* \brief Sets local code for PCPS acquisition algorithm.
* \param code - Pointer to the PRN code.
*/
void set_local_code(std::complex<float>* code);
/*!
* \brief Starts acquisition algorithm, turning from standby mode to
* active mode
* \param active - bool that activates/deactivates the block.
*/
inline void set_active(bool active)
{
d_active = active;
}
/*!
* \brief If set to 1, ensures that acquisition starts at the
* first available sample.
* \param state - int=1 forces start of acquisition
*/
void set_state(int state);
/*!
* \brief Set acquisition channel unique ID
* \param channel - receiver channel.
*/
inline void set_channel(uint32_t channel)
{
d_channel = channel;
}
/*!
* \brief Set channel fsm associated to this acquisition instance
*/
inline void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm)
{
d_channel_fsm = channel_fsm;
}
/*!
* \brief Set statistics threshold of PCPS algorithm.
* \param threshold - Threshold for signal detection (check \ref Navitec2012,
* Algorithm 1, for a definition of this threshold).
*/
inline void set_threshold(float threshold)
{
d_threshold = threshold;
}
/*!
* \brief Set maximum Doppler grid search
* \param doppler_max - Maximum Doppler shift considered in the grid search [Hz].
*/
inline void set_doppler_max(uint32_t doppler_max)
{
d_doppler_max = doppler_max;
}
/*!
* \brief Set Doppler steps for the grid search
* \param doppler_step - Frequency bin of the search grid [Hz].
*/
inline void set_doppler_step(uint32_t doppler_step)
{
d_doppler_step = doppler_step;
}
inline bool opencl_ready() const
{
bool ready = false;
if (d_opencl == 0)
{
ready = true;
}
return ready;
}
/*!
* \brief Parallel Code Phase Search Acquisition signal processing.
*/
int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items);
void acquisition_core_volk();
void acquisition_core_opencl();
}; };
#endif #endif

View File

@ -106,9 +106,9 @@ pcps_quicksync_acquisition_cc::pcps_quicksync_acquisition_cc(
d_code = new gr_complex[d_samples_per_code](); d_code = new gr_complex[d_samples_per_code]();
// Direct FFT // Direct FFT
d_fft_if = new gr::fft::fft_complex(d_fft_size, true); d_fft_if = std::make_shared<gr::fft::fft_complex>(d_fft_size, true);
// Inverse FFT // Inverse FFT
d_ifft = new gr::fft::fft_complex(d_fft_size, false); d_ifft = std::make_shared<gr::fft::fft_complex>(d_fft_size, false);
// For dumping samples into a file // For dumping samples into a file
d_dump = dump; d_dump = dump;
@ -122,7 +122,6 @@ pcps_quicksync_acquisition_cc::pcps_quicksync_acquisition_cc(
d_threshold = 0; d_threshold = 0;
d_doppler_step = 0; d_doppler_step = 0;
d_grid_doppler_wipeoffs = nullptr; d_grid_doppler_wipeoffs = nullptr;
d_fft_if2 = nullptr;
d_gnss_synchro = nullptr; d_gnss_synchro = nullptr;
d_code_phase = 0; d_code_phase = 0;
d_doppler_freq = 0; d_doppler_freq = 0;
@ -150,8 +149,6 @@ pcps_quicksync_acquisition_cc::~pcps_quicksync_acquisition_cc()
volk_gnsssdr_free(d_magnitude); volk_gnsssdr_free(d_magnitude);
volk_gnsssdr_free(d_magnitude_folded); volk_gnsssdr_free(d_magnitude_folded);
delete d_ifft;
delete d_fft_if;
delete d_code; delete d_code;
delete d_possible_delay; delete d_possible_delay;
delete d_corr_output_f; delete d_corr_output_f;

View File

@ -67,8 +67,7 @@ class pcps_quicksync_acquisition_cc;
using pcps_quicksync_acquisition_cc_sptr = boost::shared_ptr<pcps_quicksync_acquisition_cc>; using pcps_quicksync_acquisition_cc_sptr = boost::shared_ptr<pcps_quicksync_acquisition_cc>;
pcps_quicksync_acquisition_cc_sptr pcps_quicksync_acquisition_cc_sptr pcps_quicksync_make_acquisition_cc(
pcps_quicksync_make_acquisition_cc(
uint32_t folding_factor, uint32_t folding_factor,
uint32_t sampled_ms, uint32_t sampled_ms,
uint32_t max_dwells, uint32_t max_dwells,
@ -89,72 +88,6 @@ pcps_quicksync_make_acquisition_cc(
*/ */
class pcps_quicksync_acquisition_cc : public gr::block class pcps_quicksync_acquisition_cc : public gr::block
{ {
private:
friend pcps_quicksync_acquisition_cc_sptr
pcps_quicksync_make_acquisition_cc(uint32_t folding_factor,
uint32_t sampled_ms, uint32_t max_dwells,
uint32_t doppler_max, int64_t fs_in,
int32_t samples_per_ms, int32_t samples_per_code,
bool bit_transition_flag,
bool dump,
std::string dump_filename);
pcps_quicksync_acquisition_cc(uint32_t folding_factor,
uint32_t sampled_ms, uint32_t max_dwells,
uint32_t doppler_max, int64_t fs_in,
int32_t samples_per_ms, int32_t samples_per_code,
bool bit_transition_flag,
bool dump,
std::string dump_filename);
void calculate_magnitudes(gr_complex* fft_begin, int32_t doppler_shift,
int32_t doppler_offset);
gr_complex* d_code;
uint32_t d_folding_factor; // also referred in the paper as 'p'
float* d_corr_acumulator;
uint32_t* d_possible_delay;
float* d_corr_output_f;
float* d_magnitude_folded;
gr_complex* d_signal_folded;
gr_complex* d_code_folded;
float d_noise_floor_power;
int64_t d_fs_in;
int32_t d_samples_per_ms;
int32_t d_samples_per_code;
uint32_t d_doppler_resolution;
float d_threshold;
std::string d_satellite_str;
uint32_t d_doppler_max;
uint32_t d_doppler_step;
uint32_t d_sampled_ms;
uint32_t d_max_dwells;
uint32_t d_well_count;
uint32_t d_fft_size;
uint64_t d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
uint32_t d_num_doppler_bins;
gr_complex* d_fft_codes;
gr::fft::fft_complex* d_fft_if;
gr::fft::fft_complex* d_fft_if2;
gr::fft::fft_complex* d_ifft;
Gnss_Synchro* d_gnss_synchro;
uint32_t d_code_phase;
float d_doppler_freq;
float d_mag;
float* d_magnitude;
float d_input_power;
float d_test_statistics;
bool d_bit_transition_flag;
std::ofstream d_dump_file;
bool d_active;
int32_t d_state;
bool d_dump;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
public: public:
/*! /*!
* \brief Default destructor. * \brief Default destructor.
@ -258,6 +191,70 @@ public:
int general_work(int noutput_items, gr_vector_int& ninput_items, int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items); gr_vector_void_star& output_items);
private:
friend pcps_quicksync_acquisition_cc_sptr
pcps_quicksync_make_acquisition_cc(uint32_t folding_factor,
uint32_t sampled_ms, uint32_t max_dwells,
uint32_t doppler_max, int64_t fs_in,
int32_t samples_per_ms, int32_t samples_per_code,
bool bit_transition_flag,
bool dump,
std::string dump_filename);
pcps_quicksync_acquisition_cc(uint32_t folding_factor,
uint32_t sampled_ms, uint32_t max_dwells,
uint32_t doppler_max, int64_t fs_in,
int32_t samples_per_ms, int32_t samples_per_code,
bool bit_transition_flag,
bool dump,
std::string dump_filename);
void calculate_magnitudes(gr_complex* fft_begin, int32_t doppler_shift,
int32_t doppler_offset);
gr_complex* d_code;
uint32_t d_folding_factor; // also referred in the paper as 'p'
float* d_corr_acumulator;
uint32_t* d_possible_delay;
float* d_corr_output_f;
float* d_magnitude_folded;
gr_complex* d_signal_folded;
gr_complex* d_code_folded;
float d_noise_floor_power;
int64_t d_fs_in;
int32_t d_samples_per_ms;
int32_t d_samples_per_code;
uint32_t d_doppler_resolution;
float d_threshold;
std::string d_satellite_str;
uint32_t d_doppler_max;
uint32_t d_doppler_step;
uint32_t d_sampled_ms;
uint32_t d_max_dwells;
uint32_t d_well_count;
uint32_t d_fft_size;
uint64_t d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
uint32_t d_num_doppler_bins;
gr_complex* d_fft_codes;
std::shared_ptr<gr::fft::fft_complex> d_fft_if;
std::shared_ptr<gr::fft::fft_complex> d_ifft;
Gnss_Synchro* d_gnss_synchro;
uint32_t d_code_phase;
float d_doppler_freq;
float d_mag;
float* d_magnitude;
float d_input_power;
float d_test_statistics;
bool d_bit_transition_flag;
std::ofstream d_dump_file;
bool d_active;
int32_t d_state;
bool d_dump;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
}; };
#endif /* GNSS_SDR_PCPS_ACQUISITION_CC_H_*/ #endif /* GNSS_SDR_PCPS_QUICKSYNC_ACQUISITION_CC_H_ */

View File

@ -113,10 +113,10 @@ pcps_tong_acquisition_cc::pcps_tong_acquisition_cc(
d_magnitude = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment())); d_magnitude = static_cast<float *>(volk_gnsssdr_malloc(d_fft_size * sizeof(float), volk_gnsssdr_get_alignment()));
// Direct FFT // Direct FFT
d_fft_if = new gr::fft::fft_complex(d_fft_size, true); d_fft_if = std::make_shared<gr::fft::fft_complex>(d_fft_size, true);
// Inverse FFT // Inverse FFT
d_ifft = new gr::fft::fft_complex(d_fft_size, false); d_ifft = std::make_shared<gr::fft::fft_complex>(d_fft_size, false);
// For dumping samples into a file // For dumping samples into a file
d_dump = dump; d_dump = dump;
@ -134,6 +134,7 @@ pcps_tong_acquisition_cc::pcps_tong_acquisition_cc(
d_channel = 0; d_channel = 0;
} }
pcps_tong_acquisition_cc::~pcps_tong_acquisition_cc() pcps_tong_acquisition_cc::~pcps_tong_acquisition_cc()
{ {
if (d_num_doppler_bins > 0) if (d_num_doppler_bins > 0)
@ -150,9 +151,6 @@ pcps_tong_acquisition_cc::~pcps_tong_acquisition_cc()
volk_gnsssdr_free(d_fft_codes); volk_gnsssdr_free(d_fft_codes);
volk_gnsssdr_free(d_magnitude); volk_gnsssdr_free(d_magnitude);
delete d_ifft;
delete d_fft_if;
try try
{ {
if (d_dump) if (d_dump)

View File

@ -65,8 +65,7 @@ class pcps_tong_acquisition_cc;
using pcps_tong_acquisition_cc_sptr = boost::shared_ptr<pcps_tong_acquisition_cc>; using pcps_tong_acquisition_cc_sptr = boost::shared_ptr<pcps_tong_acquisition_cc>;
pcps_tong_acquisition_cc_sptr pcps_tong_acquisition_cc_sptr pcps_tong_make_acquisition_cc(
pcps_tong_make_acquisition_cc(
uint32_t sampled_ms, uint32_t sampled_ms,
uint32_t doppler_max, uint32_t doppler_max,
int64_t fs_in, int64_t fs_in,
@ -84,60 +83,6 @@ pcps_tong_make_acquisition_cc(
*/ */
class pcps_tong_acquisition_cc : public gr::block class pcps_tong_acquisition_cc : public gr::block
{ {
private:
friend pcps_tong_acquisition_cc_sptr
pcps_tong_make_acquisition_cc(uint32_t sampled_ms, uint32_t doppler_max,
int64_t fs_in, int32_t samples_per_ms,
int32_t samples_per_code, uint32_t tong_init_val,
uint32_t tong_max_val, uint32_t tong_max_dwells,
bool dump, std::string dump_filename);
pcps_tong_acquisition_cc(uint32_t sampled_ms, uint32_t doppler_max,
int64_t fs_in, int32_t samples_per_ms,
int32_t samples_per_code, uint32_t tong_init_val,
uint32_t tong_max_val, uint32_t tong_max_dwells,
bool dump, std::string dump_filename);
void calculate_magnitudes(gr_complex* fft_begin, int32_t doppler_shift,
int32_t doppler_offset);
int64_t d_fs_in;
int32_t d_samples_per_ms;
int32_t d_samples_per_code;
uint32_t d_doppler_resolution;
float d_threshold;
std::string d_satellite_str;
uint32_t d_doppler_max;
uint32_t d_doppler_step;
uint32_t d_sampled_ms;
uint32_t d_dwell_count;
uint32_t d_tong_count;
uint32_t d_tong_init_val;
uint32_t d_tong_max_val;
uint32_t d_tong_max_dwells;
uint32_t d_fft_size;
uint64_t d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
uint32_t d_num_doppler_bins;
gr_complex* d_fft_codes;
float** d_grid_data;
gr::fft::fft_complex* d_fft_if;
gr::fft::fft_complex* d_ifft;
Gnss_Synchro* d_gnss_synchro;
uint32_t d_code_phase;
float d_doppler_freq;
float d_mag;
float* d_magnitude;
float d_input_power;
float d_test_statistics;
std::ofstream d_dump_file;
bool d_active;
int32_t d_state;
bool d_dump;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
public: public:
/*! /*!
* \brief Default destructor. * \brief Default destructor.
@ -241,6 +186,60 @@ public:
int general_work(int noutput_items, gr_vector_int& ninput_items, int general_work(int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items); gr_vector_void_star& output_items);
private:
friend pcps_tong_acquisition_cc_sptr
pcps_tong_make_acquisition_cc(uint32_t sampled_ms, uint32_t doppler_max,
int64_t fs_in, int32_t samples_per_ms,
int32_t samples_per_code, uint32_t tong_init_val,
uint32_t tong_max_val, uint32_t tong_max_dwells,
bool dump, std::string dump_filename);
pcps_tong_acquisition_cc(uint32_t sampled_ms, uint32_t doppler_max,
int64_t fs_in, int32_t samples_per_ms,
int32_t samples_per_code, uint32_t tong_init_val,
uint32_t tong_max_val, uint32_t tong_max_dwells,
bool dump, std::string dump_filename);
void calculate_magnitudes(gr_complex* fft_begin, int32_t doppler_shift,
int32_t doppler_offset);
int64_t d_fs_in;
int32_t d_samples_per_ms;
int32_t d_samples_per_code;
uint32_t d_doppler_resolution;
float d_threshold;
std::string d_satellite_str;
uint32_t d_doppler_max;
uint32_t d_doppler_step;
uint32_t d_sampled_ms;
uint32_t d_dwell_count;
uint32_t d_tong_count;
uint32_t d_tong_init_val;
uint32_t d_tong_max_val;
uint32_t d_tong_max_dwells;
uint32_t d_fft_size;
uint64_t d_sample_counter;
gr_complex** d_grid_doppler_wipeoffs;
uint32_t d_num_doppler_bins;
gr_complex* d_fft_codes;
float** d_grid_data;
std::shared_ptr<gr::fft::fft_complex> d_fft_if;
std::shared_ptr<gr::fft::fft_complex> d_ifft;
Gnss_Synchro* d_gnss_synchro;
uint32_t d_code_phase;
float d_doppler_freq;
float d_mag;
float* d_magnitude;
float d_input_power;
float d_test_statistics;
std::ofstream d_dump_file;
bool d_active;
int32_t d_state;
bool d_dump;
uint32_t d_channel;
std::weak_ptr<ChannelFsm> d_channel_fsm;
std::string d_dump_filename;
}; };
#endif /* GNSS_SDR_PCPS_TONG_ACQUISITION_CC_H_ */ #endif /* GNSS_SDR_PCPS_TONG_ACQUISITION_CC_H_ */

View File

@ -81,7 +81,6 @@ Fpga_Acquisition::Fpga_Acquisition(std::string device_name,
int64_t fs_in, int64_t fs_in,
uint32_t sampled_ms __attribute__((unused)), uint32_t sampled_ms __attribute__((unused)),
uint32_t select_queue, uint32_t select_queue,
//lv_16sc_t *all_fft_codes,
uint32_t *all_fft_codes, uint32_t *all_fft_codes,
uint32_t excludelimit) uint32_t excludelimit)
{ {
@ -209,6 +208,7 @@ void Fpga_Acquisition::set_block_exp(uint32_t total_block_exp)
d_map_base[11] = total_block_exp; d_map_base[11] = total_block_exp;
} }
void Fpga_Acquisition::set_doppler_sweep(uint32_t num_sweeps, uint32_t doppler_step, int32_t doppler_min) void Fpga_Acquisition::set_doppler_sweep(uint32_t num_sweeps, uint32_t doppler_step, int32_t doppler_min)
{ {
float phase_step_rad_real; float phase_step_rad_real;
@ -233,7 +233,6 @@ void Fpga_Acquisition::set_doppler_sweep(uint32_t num_sweeps, uint32_t doppler_s
void Fpga_Acquisition::configure_acquisition() void Fpga_Acquisition::configure_acquisition()
{ {
//Fpga_Acquisition::open_device(); //Fpga_Acquisition::open_device();
d_map_base[0] = d_select_queue; d_map_base[0] = d_select_queue;
d_map_base[1] = d_vector_length; d_map_base[1] = d_vector_length;
d_map_base[2] = d_nsamples; d_map_base[2] = d_nsamples;
@ -318,6 +317,7 @@ void Fpga_Acquisition::read_fpga_total_scale_factor(uint32_t *total_scale_factor
*fw_scale_factor = 0; *fw_scale_factor = 0;
} }
void Fpga_Acquisition::read_result_valid(uint32_t *result_valid) void Fpga_Acquisition::read_result_valid(uint32_t *result_valid)
{ {
uint32_t readval = 0; uint32_t readval = 0;

View File

@ -36,7 +36,6 @@
#ifndef GNSS_SDR_FPGA_ACQUISITION_H_ #ifndef GNSS_SDR_FPGA_ACQUISITION_H_
#define GNSS_SDR_FPGA_ACQUISITION_H_ #define GNSS_SDR_FPGA_ACQUISITION_H_
#include <volk/volk_complex.h> // for lv_16sc_t
#include <cstdint> #include <cstdint>
#include <string> #include <string>
@ -46,7 +45,8 @@
class Fpga_Acquisition class Fpga_Acquisition
{ {
public: public:
Fpga_Acquisition(std::string device_name, Fpga_Acquisition(
std::string device_name,
uint32_t nsamples, uint32_t nsamples,
uint32_t doppler_max, uint32_t doppler_max,
uint32_t nsamples_total, uint32_t nsamples_total,
@ -57,13 +57,24 @@ public:
uint32_t excludelimit); uint32_t excludelimit);
~Fpga_Acquisition(); ~Fpga_Acquisition();
bool set_local_code(uint32_t PRN); bool set_local_code(uint32_t PRN);
void set_doppler_sweep(uint32_t num_sweeps, uint32_t doppler_step, int32_t doppler_min); void set_doppler_sweep(uint32_t num_sweeps, uint32_t doppler_step, int32_t doppler_min);
void run_acquisition(void); void run_acquisition(void);
void read_acquisition_results(uint32_t *max_index, float *firstpeak, float *secondpeak, uint64_t *initial_sample, float *power_sum, uint32_t *doppler_index, uint32_t *total_blk_exp); void read_acquisition_results(
uint32_t *max_index,
float *firstpeak,
float *secondpeak,
uint64_t *initial_sample,
float *power_sum,
uint32_t *doppler_index,
uint32_t *total_blk_exp);
void block_samples(); void block_samples();
void unblock_samples(); void unblock_samples();
/*! /*!
@ -100,9 +111,10 @@ public:
void configure_acquisition(void); void configure_acquisition(void);
void close_device();
void open_device(); void open_device();
void close_device();
private: private:
int64_t d_fs_in; int64_t d_fs_in;
// data related to the hardware module and the driver // data related to the hardware module and the driver

View File

@ -87,6 +87,7 @@ bool ChannelFsm::Event_start_acquisition_fpga()
return true; return true;
} }
bool ChannelFsm::Event_start_acquisition() bool ChannelFsm::Event_start_acquisition()
{ {
std::lock_guard<std::mutex> lk(mx); std::lock_guard<std::mutex> lk(mx);
@ -170,11 +171,14 @@ void ChannelFsm::set_tracking(std::shared_ptr<TrackingInterface> tracking)
trk_ = std::move(tracking); trk_ = std::move(tracking);
} }
void ChannelFsm::set_telemetry(std::shared_ptr<TelemetryDecoderInterface> telemetry) void ChannelFsm::set_telemetry(std::shared_ptr<TelemetryDecoderInterface> telemetry)
{ {
std::lock_guard<std::mutex> lk(mx); std::lock_guard<std::mutex> lk(mx);
nav_ = std::move(telemetry); nav_ = std::move(telemetry);
} }
void ChannelFsm::set_queue(gr::msg_queue::sptr queue) void ChannelFsm::set_queue(gr::msg_queue::sptr queue)
{ {
std::lock_guard<std::mutex> lk(mx); std::lock_guard<std::mutex> lk(mx);
@ -194,6 +198,7 @@ void ChannelFsm::stop_acquisition()
acq_->stop_acquisition(); acq_->stop_acquisition();
} }
void ChannelFsm::stop_tracking() void ChannelFsm::stop_tracking()
{ {
trk_->stop_tracking(); trk_->stop_tracking();

View File

@ -47,15 +47,15 @@ channel_msg_receiver_cc_sptr channel_msg_receiver_make_cc(std::shared_ptr<Channe
*/ */
class channel_msg_receiver_cc : public gr::block class channel_msg_receiver_cc : public gr::block
{ {
private:
std::shared_ptr<ChannelFsm> d_channel_fsm;
bool d_repeat; // todo: change FSM to include repeat value
friend channel_msg_receiver_cc_sptr channel_msg_receiver_make_cc(std::shared_ptr<ChannelFsm> channel_fsm, bool repeat);
void msg_handler_events(pmt::pmt_t msg);
channel_msg_receiver_cc(std::shared_ptr<ChannelFsm> channel_fsm, bool repeat);
public: public:
~channel_msg_receiver_cc(); //!< Default destructor ~channel_msg_receiver_cc(); //!< Default destructor
private:
friend channel_msg_receiver_cc_sptr channel_msg_receiver_make_cc(std::shared_ptr<ChannelFsm> channel_fsm, bool repeat);
channel_msg_receiver_cc(std::shared_ptr<ChannelFsm> channel_fsm, bool repeat);
std::shared_ptr<ChannelFsm> d_channel_fsm;
bool d_repeat; // todo: change FSM to include repeat value
void msg_handler_events(pmt::pmt_t msg);
}; };
#endif #endif

View File

@ -47,15 +47,14 @@ interleaved_byte_to_complex_byte_sptr make_interleaved_byte_to_complex_byte();
*/ */
class interleaved_byte_to_complex_byte : public gr::sync_decimator class interleaved_byte_to_complex_byte : public gr::sync_decimator
{ {
private:
friend interleaved_byte_to_complex_byte_sptr make_interleaved_byte_to_complex_byte();
public: public:
interleaved_byte_to_complex_byte();
int work(int noutput_items, int work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
private:
friend interleaved_byte_to_complex_byte_sptr make_interleaved_byte_to_complex_byte();
interleaved_byte_to_complex_byte();
}; };
#endif #endif

View File

@ -46,15 +46,14 @@ interleaved_byte_to_complex_short_sptr make_interleaved_byte_to_complex_short();
*/ */
class interleaved_byte_to_complex_short : public gr::sync_decimator class interleaved_byte_to_complex_short : public gr::sync_decimator
{ {
private:
friend interleaved_byte_to_complex_short_sptr make_interleaved_byte_to_complex_short();
public: public:
interleaved_byte_to_complex_short();
int work(int noutput_items, int work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
private:
friend interleaved_byte_to_complex_short_sptr make_interleaved_byte_to_complex_short();
interleaved_byte_to_complex_short();
}; };
#endif #endif // GNSS_SDR_INTERLEAVED_BYTE_TO_COMPLEX_SHORT_H_

View File

@ -46,15 +46,14 @@ interleaved_short_to_complex_short_sptr make_interleaved_short_to_complex_short(
*/ */
class interleaved_short_to_complex_short : public gr::sync_decimator class interleaved_short_to_complex_short : public gr::sync_decimator
{ {
private:
friend interleaved_short_to_complex_short_sptr make_interleaved_short_to_complex_short();
public: public:
interleaved_short_to_complex_short();
int work(int noutput_items, int work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
private:
friend interleaved_short_to_complex_short_sptr make_interleaved_short_to_complex_short();
interleaved_short_to_complex_short();
}; };
#endif #endif // GNSS_SDR_INTERLEAVED_SHORT_TO_COMPLEX_SHORT_H_

View File

@ -49,7 +49,7 @@ BeamformerFilter::BeamformerFilter(
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
item_size_ = sizeof(gr_complex); item_size_ = sizeof(gr_complex);
beamformer_ = make_beamformer(); beamformer_ = make_beamformer_sptr();
DLOG(INFO) << "Item size " << item_size_; DLOG(INFO) << "Item size " << item_size_;
DLOG(INFO) << "resampler(" << beamformer_->unique_id() << ")"; DLOG(INFO) << "resampler(" << beamformer_->unique_id() << ")";
} }

View File

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

View File

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

View File

@ -41,16 +41,30 @@ class Notch;
using notch_sptr = boost::shared_ptr<Notch>; using notch_sptr = boost::shared_ptr<Notch>;
notch_sptr make_notch_filter(float pfa, float p_c_factor, notch_sptr make_notch_filter(
int32_t length_, int32_t n_segments_est, int32_t n_segments_reset); float pfa,
float p_c_factor,
int32_t length_,
int32_t n_segments_est,
int32_t n_segments_reset);
/*! /*!
* \brief This class implements a real-time software-defined multi state notch filter * \brief This class implements a real-time software-defined multi state notch filter
*/ */
class Notch : public gr::block class Notch : public gr::block
{ {
public:
~Notch();
void forecast(int noutput_items, gr_vector_int &ninput_items_required);
int general_work(int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
private: private:
friend notch_sptr make_notch_filter(float pfa, float p_c_factor, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset);
Notch(float pfa, float p_c_factor, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset);
float pfa; float pfa;
float noise_pow_est; float noise_pow_est;
float thres_; float thres_;
@ -67,17 +81,6 @@ private:
float *angle_; float *angle_;
float *power_spect; float *power_spect;
std::unique_ptr<gr::fft::fft_complex> d_fft; std::unique_ptr<gr::fft::fft_complex> d_fft;
public:
Notch(float pfa, float p_c_factor, int32_t length_, int32_t n_segments_est, int32_t n_segments_reset);
~Notch();
void forecast(int noutput_items, gr_vector_int &ninput_items_required);
int general_work(int noutput_items, gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
}; };
#endif //GNSS_SDR_NOTCH_H_ #endif // GNSS_SDR_NOTCH_H_

Some files were not shown because too many files have changed in this diff Show More