diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5206c6d31..bb0bd3724 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -52,6 +52,7 @@ jobs: rm /usr/local/bin/idle3.1* || true rm /usr/local/bin/pydoc3.1* || true rm /usr/local/bin/python3.1* || true + export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install ninja hdf5 automake armadillo lapack \ gflags glog gnuradio log4cpp openssl pugixml protobuf pip3 install mako @@ -80,6 +81,7 @@ jobs: rm /usr/local/bin/idle3.1* || true rm /usr/local/bin/pydoc3.1* || true rm /usr/local/bin/python3.1* || true + export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install ninja pkg-config hdf5 automake armadillo lapack gflags glog \ gnuradio log4cpp openssl pugixml protobuf pip3 install mako @@ -127,6 +129,7 @@ jobs: rm /usr/local/bin/idle3.1* || true rm /usr/local/bin/pydoc3.1* || true rm /usr/local/bin/python3.1* || true + export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install llvm pkg-config hdf5 armadillo lapack gflags glog gnuradio libmatio \ log4cpp openssl pugixml protobuf pip3 install mako diff --git a/CMakeLists.txt b/CMakeLists.txt index ab0c1bc3e..348c2f2a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2010-2023 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2010-2024 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause ################################################################################ @@ -911,6 +911,11 @@ if((Boost_VERSION_STRING VERSION_GREATER 1.71) AND (Boost_VERSION_STRING VERSION endif() endif() +# Workaround for macOS Sonoma +if((CMAKE_CXX_STANDARD EQUAL 17) AND ((${CMAKE_SYSTEM_NAME} MATCHES "Darwin") AND ("${DARWIN_VERSION}" VERSION_GREATER "22.99"))) + add_definitions(-D_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION=1) +endif() + # Fix for Boost Asio < 1.70 when using Clang in macOS if(Boost_VERSION_STRING VERSION_LESS 1.70.0) # Check if we have std::string_view @@ -1823,7 +1828,7 @@ endif() # Check that BLAS (Basic Linear Algebra Subprograms) is found in the system # See https://www.netlib.org/blas/ ################################################################################ -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") +if((${CMAKE_SYSTEM_NAME} MATCHES "Darwin") AND ("${DARWIN_VERSION}" VERSION_LESS "23")) # Avoid using the implementation that comes with the Accelerate framework include(AvoidAccelerate) else() @@ -1870,7 +1875,7 @@ endif() # Check that LAPACK (Linear Algebra PACKage) is found in the system # See https://www.netlib.org/lapack/ ################################################################################ -if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")) +if(NOT((${CMAKE_SYSTEM_NAME} MATCHES "Darwin") AND ("${DARWIN_VERSION}" VERSION_LESS "23"))) find_package(LAPACK) set_package_properties(LAPACK PROPERTIES URL "https://www.netlib.org/lapack/" @@ -1881,13 +1886,15 @@ if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")) endif() if(NOT LAPACK_FOUND) message(" The LAPACK library has not been found.") - message(" You can try to install it by typing:") - if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") - message(" sudo yum install lapack-devel") - elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") - message(" sudo zypper install lapack-devel") - else() - message(" sudo apt-get install liblapack-dev") + if(LINUX_DISTRIBUTION) + message(" You can try to install it by typing:") + if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat") + message(" sudo yum install lapack-devel") + elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE") + message(" sudo zypper install lapack-devel") + else() + message(" sudo apt-get install liblapack-dev") + endif() endif() message(FATAL_ERROR "LAPACK is required to build gnss-sdr") endif() @@ -2054,7 +2061,7 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO) IMPORTED_LOCATION_RELWITHDEBINFO ${ARMADILLO_STATIC_LIBRARY} IMPORTED_LOCATION_MINSIZEREL ${ARMADILLO_STATIC_LIBRARY} INTERFACE_INCLUDE_DIRECTORIES ${GNSSSDR_BINARY_DIR}/thirdparty/armadillo/armadillo-${armadillo_RELEASE}/include - INTERFACE_LINK_LIBRARIES ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES} ${GFORTRAN} ${ARMADILLO_STATIC_LIBRARY} + INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}" "${LAPACK_LIBRARIES}" ${GFORTRAN} ${ARMADILLO_STATIC_LIBRARY} ) if((CMAKE_GENERATOR STREQUAL Xcode) OR MSVC) set_target_properties(Armadillo::armadillo PROPERTIES @@ -2062,7 +2069,7 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO) IMPORTED_LOCATION_RELEASE ${binary_dir}/Release/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo${CMAKE_STATIC_LIBRARY_SUFFIX} IMPORTED_LOCATION_RELWITHDEBINFO ${binary_dir}/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo${CMAKE_STATIC_LIBRARY_SUFFIX} IMPORTED_LOCATION_MINSIZEREL ${binary_dir}/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo${CMAKE_STATIC_LIBRARY_SUFFIX} - INTERFACE_LINK_LIBRARIES ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES} ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo${CMAKE_STATIC_LIBRARY_SUFFIX}/$<$:Debug/>$<$:Release/>$<$:RelWithDebInfo/>$<$:MinSizeRel/>${CMAKE_FIND_LIBRARY_PREFIXES}armadillo${CMAKE_STATIC_LIBRARY_SUFFIX} + INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}" "${LAPACK_LIBRARIES}" ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo${CMAKE_STATIC_LIBRARY_SUFFIX}/$<$:Debug/>$<$:Release/>$<$:RelWithDebInfo/>$<$:MinSizeRel/>${CMAKE_FIND_LIBRARY_PREFIXES}armadillo${CMAKE_STATIC_LIBRARY_SUFFIX} ) endif() set_package_properties(Armadillo PROPERTIES diff --git a/README.md b/README.md index 7dfb672cd..7e9fd62d9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ SPDX-License-Identifier: GPL-3.0-or-later ) [comment]: # ( -SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades +SPDX-FileCopyrightText: 2011-2024 Carles Fernandez-Prades ) @@ -799,7 +799,7 @@ Of course, you will also need a GPU that ## macOS GNSS-SDR can be built on macOS (or the former Mac OS X), starting from 10.9 -(Mavericks) and including 11 (Big Sur). If you still have not installed +(Mavericks) and including 14 (Sonoma). If you still have not installed [Xcode](https://developer.apple.com/xcode/ "Xcode"), do it now from the App Store (it's free). You will also need the Xcode Command Line Tools, which do not come by default in macOS versions older than Big Sur. If you are using an older @@ -830,12 +830,19 @@ In a terminal, type: ``` $ sudo port selfupdate $ sudo port upgrade outdated -$ sudo port install armadillo boost cmake gnuradio gnutls lapack libad9361-iio libiio \ - matio pkgconfig protobuf3-cpp pugixml google-glog +gflags +$ sudo port install armadillo cmake pkgconfig protobuf3-cpp pugixml gnutls +$ sudo port install gnuradio +uhd +grc +zeromq +$ sudo port install boost matio libad9361-iio libiio google-glog +gflags $ sudo port install py311-mako $ sudo port install doxygen +docs ``` +For macOS versions older than Sonoma, you will also need LAPACK: + +``` +$ sudo port install lapack +``` + You also might need to activate a Python installation. The list of installed versions can be retrieved with: @@ -846,7 +853,7 @@ $ port select --list python and you can activate a certain version by typing: ``` -$ sudo port select --set python python37 +$ sudo port select --set python python311 ``` ### Homebrew @@ -871,13 +878,19 @@ Install the required dependencies: ``` $ brew update && brew upgrade -$ brew install armadillo cmake hdf5 gflags glog gnuradio lapack libmatio log4cpp \ +$ brew install armadillo cmake hdf5 gflags glog gnuradio libmatio log4cpp \ openssl pkg-config protobuf pugixml $ pip3 install mako $ brew install --cask mactex # when completed, restart Terminal $ brew install graphviz doxygen ``` +For macOS versions older than Sonoma, you will also need LAPACK: + +``` +$ brew install lapack +``` + ### Other package managers GNU Radio and other dependencies can also be installed using other package diff --git a/cmake/Modules/RemoveDuplicates.cmake b/cmake/Modules/RemoveDuplicates.cmake new file mode 100644 index 000000000..446dedbae --- /dev/null +++ b/cmake/Modules/RemoveDuplicates.cmake @@ -0,0 +1,22 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# SPDX-FileCopyrightText: 2024 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-License-Identifier: BSD-3-Clause + +# Usage: +# include(RemoveDuplicates) +# remove_duplicate_linked_libraries(my_target) + +if(DEFINED __INCLUDED_REMOVE_DUPLICATE_LINKED_LIBRARIES_MODULE) + return() +endif() +set(__INCLUDED_REMOVE_DUPLICATE_LINKED_LIBRARIES_MODULE TRUE) + +function(remove_duplicate_linked_libraries target_name) + if(CMAKE_VERSION VERSION_GREATER 3.5) + get_target_property(LINK_LIBRARIES ${target_name} LINK_LIBRARIES) + list(REMOVE_DUPLICATES LINK_LIBRARIES) + set_target_properties(${target_name} PROPERTIES LINK_LIBRARIES "${LINK_LIBRARIES}") + endif() +endfunction() \ No newline at end of file diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index ca209027e..6f5ca432b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,7 +4,7 @@ SPDX-License-Identifier: GPL-3.0-or-later ) [comment]: # ( -SPDX-FileCopyrightText: 2011-2023 Carles Fernandez-Prades +SPDX-FileCopyrightText: 2011-2024 Carles Fernandez-Prades ) @@ -45,11 +45,12 @@ All notable changes to GNSS-SDR will be documented in this file. - Updated local `cpu_features` library to v0.9.0. - `volk_gnsssdr`: fix syntax for Python 3.12 without breaking backward compatibility with Python 2.7. -- Fixed linking against latest GNU Radio version. +- Fixed linking against GNU Radio v3.10.9.1. - Make use of new API if linking against VOLK >= 3.1. - Fixed undefined behaviour in `volk_gnsssdr` arising from incompatibility between complex numbers in C and C++. - Now build system paths are not leaked when cross-compiling. +- Enabled building using macOS Sonoma and `arm64` processor architecture. ### Improvements in Repeatability: diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 92098517f..6c2d322d5 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -5651,7 +5651,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::mapsecond.E1B_DVS); - std::string SVhealth_str = std::move(E5B_HS) + std::to_string(galileo_ephemeris_iter->second.E5b_DVS) + "11" + "1" + std::string(E1B_DVS) + std::string(E1B_HS) + std::to_string(galileo_ephemeris_iter->second.E1B_DVS); + std::string SVhealth_str = std::move(E5B_HS) + std::to_string(galileo_ephemeris_iter->second.E5b_DVS) + "11" + "1" + std::move(E1B_DVS) + std::move(E1B_HS) + std::to_string(galileo_ephemeris_iter->second.E1B_DVS); int32_t SVhealth = Rinex_Printer::toInt(SVhealth_str, 9); line += Rinex_Printer::doub2for(static_cast(SVhealth), 18, 2); line += std::string(1, ' '); diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc index 20efd8ae3..87e4c2d06 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.cc @@ -44,7 +44,7 @@ GalileoE1PcpsAmbiguousAcquisitionFpga::GalileoE1PcpsAmbiguousAcquisitionFpga( out_streams_(out_streams), acquire_pilot_(configuration->property(role + ".acquire_pilot", false)) { - acq_parameters_.SetFromConfiguration(configuration, role_, fpga_buff_num, fpga_blk_exp, GALILEO_E1_CODE_CHIP_RATE_CPS, GALILEO_E1_B_CODE_LENGTH_CHIPS); + acq_parameters_.SetFromConfiguration(configuration, role_, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GALILEO_E1_CODE_CHIP_RATE_CPS, GALILEO_E1_B_CODE_LENGTH_CHIPS); if (FLAGS_doppler_max != 0) { diff --git a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h index db9f10bf1..09829267c 100644 --- a/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e1_pcps_ambiguous_acquisition_fpga.h @@ -182,6 +182,7 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: + static const uint32_t downsampling_factor_default = 4; static const uint32_t fpga_buff_num = 0; // L1/E1 band static const uint32_t fpga_blk_exp = 13; // default block exponent diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc index d049ccd37..f3c041952 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.cc @@ -43,7 +43,7 @@ GalileoE5aPcpsAcquisitionFpga::GalileoE5aPcpsAcquisitionFpga( acq_pilot_(configuration->property(role + ".acquire_pilot", false)), acq_iq_(configuration->property(role + ".acquire_iq", false)) { - acq_parameters_.SetFromConfiguration(configuration, role_, fpga_buff_num, fpga_blk_exp, GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_CODE_LENGTH_CHIPS); + acq_parameters_.SetFromConfiguration(configuration, role_, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GALILEO_E5A_CODE_CHIP_RATE_CPS, GALILEO_E5A_CODE_LENGTH_CHIPS); if (FLAGS_doppler_max != 0) { diff --git a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h index 8cebfc042..12d38bf34 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h @@ -189,6 +189,7 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: + static const uint32_t downsampling_factor_default = 1; static const uint32_t fpga_buff_num = 1; // L5/E5a band static const uint32_t fpga_blk_exp = 13; // default block exponent diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc index 4ec2c5341..83996b5c8 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.cc @@ -43,7 +43,7 @@ GalileoE5bPcpsAcquisitionFpga::GalileoE5bPcpsAcquisitionFpga(const Configuration acq_pilot_(configuration->property(role + ".acquire_pilot", false)), acq_iq_(configuration->property(role + ".acquire_iq", false)) { - acq_parameters_.SetFromConfiguration(configuration, role_, fpga_buff_num, fpga_blk_exp, GALILEO_E5B_CODE_CHIP_RATE_CPS, GALILEO_E5B_CODE_LENGTH_CHIPS); + acq_parameters_.SetFromConfiguration(configuration, role_, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GALILEO_E5B_CODE_CHIP_RATE_CPS, GALILEO_E5B_CODE_LENGTH_CHIPS); if (FLAGS_doppler_max != 0) { acq_parameters_.doppler_max = FLAGS_doppler_max; diff --git a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h index f42720a92..8ae54e46a 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h @@ -188,6 +188,7 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: + static const uint32_t downsampling_factor_default = 1; static const uint32_t fpga_buff_num = 1; // E5b band static const uint32_t fpga_blk_exp = 13; // default block exponent diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc index 0b9ae0b9a..cc2713d24 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.cc @@ -43,7 +43,7 @@ GpsL1CaPcpsAcquisitionFpga::GpsL1CaPcpsAcquisitionFpga( in_streams_(in_streams), out_streams_(out_streams) { - acq_parameters_.SetFromConfiguration(configuration, role, fpga_buff_num, fpga_blk_exp, GPS_L1_CA_CODE_RATE_CPS, GPS_L1_CA_CODE_LENGTH_CHIPS); + acq_parameters_.SetFromConfiguration(configuration, role, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GPS_L1_CA_CODE_RATE_CPS, GPS_L1_CA_CODE_LENGTH_CHIPS); DLOG(INFO) << "role " << role; diff --git a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h index c3f38a8b7..cfc483cda 100644 --- a/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l1_ca_pcps_acquisition_fpga.h @@ -186,7 +186,7 @@ public: private: static const uint32_t NUM_PRNs = 32; - + static const uint32_t downsampling_factor_default = 4; static const uint32_t fpga_buff_num = 0; // L1/E1 band static const uint32_t fpga_blk_exp = 10; // default block exponent diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc index c74f1275b..ecce4df4c 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.cc @@ -43,7 +43,7 @@ GpsL2MPcpsAcquisitionFpga::GpsL2MPcpsAcquisitionFpga( in_streams_(in_streams), out_streams_(out_streams) { - acq_parameters_.SetFromConfiguration(configuration, role, fpga_buff_num, fpga_blk_exp, GPS_L2_M_CODE_RATE_CPS, GPS_L2_M_CODE_LENGTH_CHIPS); + acq_parameters_.SetFromConfiguration(configuration, role, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GPS_L2_M_CODE_RATE_CPS, GPS_L2_M_CODE_LENGTH_CHIPS); LOG(INFO) << "role " << role; diff --git a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h index c72328be6..19acec8cb 100644 --- a/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l2_m_pcps_acquisition_fpga.h @@ -150,6 +150,7 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: + static const uint32_t downsampling_factor_default = 1; static const uint32_t fpga_buff_num = 0; // L2 band static const uint32_t fpga_blk_exp = 13; // default block exponent diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc index ebd701840..a96bf531d 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.cc @@ -44,7 +44,7 @@ GpsL5iPcpsAcquisitionFpga::GpsL5iPcpsAcquisitionFpga( in_streams_(in_streams), out_streams_(out_streams) { - acq_parameters_.SetFromConfiguration(configuration, role, fpga_buff_num, fpga_blk_exp, GPS_L5I_CODE_RATE_CPS, GPS_L5I_CODE_LENGTH_CHIPS); + acq_parameters_.SetFromConfiguration(configuration, role, fpga_buff_num, fpga_blk_exp, downsampling_factor_default, GPS_L5I_CODE_RATE_CPS, GPS_L5I_CODE_LENGTH_CHIPS); LOG(INFO) << "role " << role; diff --git a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h index ee4d193a2..497ab9b90 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h @@ -186,7 +186,7 @@ public: private: static const uint32_t NUM_PRNs = 32; - + static const uint32_t downsampling_factor_default = 1; static const uint32_t fpga_buff_num = 1; // L5/E5a band static const uint32_t fpga_blk_exp = 13; // default block exponent diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h index d0c0c3849..92ec51781 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition_fpga.h @@ -33,6 +33,7 @@ #include // for uint32_t #include // for shared_ptr #include // for string +#include // for move /** \addtogroup Acquisition * \{ */ @@ -118,7 +119,7 @@ public: */ inline void set_channel_fsm(std::weak_ptr channel_fsm) { - d_channel_fsm = channel_fsm; + d_channel_fsm = std::move(channel_fsm); } /*! diff --git a/src/algorithms/acquisition/libs/acq_conf_fpga.cc b/src/algorithms/acquisition/libs/acq_conf_fpga.cc index ac68a92ad..838ab3ae6 100644 --- a/src/algorithms/acquisition/libs/acq_conf_fpga.cc +++ b/src/algorithms/acquisition/libs/acq_conf_fpga.cc @@ -21,9 +21,10 @@ #include #include #include +#include void Acq_Conf_Fpga::SetFromConfiguration(const ConfigurationInterface *configuration, - const std::string &role, uint32_t sel_queue_fpga, uint32_t blk_exp, double chip_rate, double code_length_chips) + const std::string &role, uint32_t sel_queue_fpga, uint32_t blk_exp, uint32_t downsampling_factor_default, double chip_rate, double code_length_chips) { // sampling frequency const int64_t fs_in_deprecated = configuration->property("GNSS-SDR.internal_fs_hz", fs_in); @@ -33,7 +34,7 @@ void Acq_Conf_Fpga::SetFromConfiguration(const ConfigurationInterface *configura doppler_max = configuration->property(role + ".doppler_max", doppler_max); // downsampling factor - downsampling_factor = configuration->property(role + ".downsampling_factor", downsampling_factor); + downsampling_factor = configuration->property(role + ".downsampling_factor", downsampling_factor_default); fs_in = fs_in / downsampling_factor; @@ -58,7 +59,7 @@ void Acq_Conf_Fpga::SetFromConfiguration(const ConfigurationInterface *configura std::cout << "Cannot find the FPGA uio device file corresponding to device name " << acquisition_device_name << std::endl; throw std::exception(); } - device_name = device_io_name; + device_name = std::move(device_io_name); // exclusion limit excludelimit = static_cast(1 + ceil((1.0 / chip_rate) * static_cast(fs_in))); diff --git a/src/algorithms/acquisition/libs/acq_conf_fpga.h b/src/algorithms/acquisition/libs/acq_conf_fpga.h index c24cbb031..11a2c7856 100644 --- a/src/algorithms/acquisition/libs/acq_conf_fpga.h +++ b/src/algorithms/acquisition/libs/acq_conf_fpga.h @@ -35,7 +35,7 @@ class Acq_Conf_Fpga public: Acq_Conf_Fpga() = default; - void SetFromConfiguration(const ConfigurationInterface *configuration, const std::string &role, uint32_t sel_queue_fpga, uint32_t blk_exp, double chip_rate, double code_length_chips); + void SetFromConfiguration(const ConfigurationInterface *configuration, const std::string &role, uint32_t sel_queue_fpga, uint32_t blk_exp, uint32_t downsampling_factor_default, double chip_rate, double code_length_chips); /* PCPS Acquisition configuration */ std::string device_name = "uio0"; diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt index 8bfd62614..2562bd90c 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt @@ -224,9 +224,9 @@ check_c_source_compiles("#include \nint main(){ uint8_t *dest; uint8 if(neon_compile_result) set(CMAKE_REQUIRED_INCLUDES ${PROJECT_SOURCE_DIR}/include) - check_c_source_compiles("#include \n int main(){__VOLK_ASM __VOLK_VOLATILE(\"vrev32.8 q0, q0\");}" + check_c_source_compiles("#include \n int main(){__VOLK_ASM(\"vrev32.8 q0, q0\");}" have_neonv7_result) - check_c_source_compiles("#include \n int main(){__VOLK_ASM __VOLK_VOLATILE(\"sub v1.4s,v1.4s,v1.4s\");}" + check_c_source_compiles("#include \n int main(){__VOLK_ASM(\"sub v1.4s,v1.4s,v1.4s\");}" have_neonv8_result) if(NOT have_neonv7_result) diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc index 0caa240f0..488c80ead 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc @@ -73,7 +73,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast(500000))), Fpass_(configuration->property(role + ".Fpass", static_cast(0.0))), Fstop_(configuration->property(role + ".Fstop", static_cast(0.0))), - num_freq_bands_(2), + num_input_files_(1), dma_buff_offset_pos_(0), in_stream_(in_stream), out_stream_(out_stream), @@ -95,16 +95,14 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con { const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", 0.0); const size_t header_size = configuration->property(role + ".header_size", 0); - const int num_ch_rx1 = configuration->property("Channels_1C.count", 0) + - configuration->property("Channels_1B.count", 0); - const int num_ch_rx2 = (configuration->property("Channels_L2.count", 0) > 0) ? configuration->property("Channels_L2.count", 0) : configuration->property("Channels_L5.count", 0) + configuration->property("Channels_5X.count", 0); - // number of frequency bands - if (num_ch_rx2 == 0) - { - num_freq_bands_ = 1; - } + const bool enable_rx1_band((configuration->property("Channels_1C.count", 0) > 0) || + (configuration->property("Channels_1B.count", 0) > 0)); + const bool enable_rx2_band((configuration->property("Channels_L2.count", 0) > 0) || + (configuration->property("Channels_L5.count", 0) > 0) || + (configuration->property("Channels_5X.count", 0) > 0)); + const uint32_t num_freq_bands = ((enable_rx1_band == true) and (enable_rx2_band == true)) ? 2 : 1; if (freq0_ == 0) { // use ".freq0" @@ -132,6 +130,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con if (filename0_.empty()) { + num_input_files_ = 2; filename0_ = configuration->property(role + ".filename0", empty_string); filename1_ = configuration->property(role + ".filename1", empty_string); } @@ -141,7 +140,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con // if more than one input file are specified then the DMA transfer the samples to both the L1 and the L2/L5 frequency channels. if (filename1_.empty()) { - if (num_ch_rx1 != 0) + if (enable_rx1_band) { dma_buff_offset_pos_ = 2; } @@ -427,14 +426,14 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con return; } - buffer_monitor_fpga = std::make_shared(device_io_name_buffer_monitor, num_freq_bands_, dump_, dump_filename); + buffer_monitor_fpga = std::make_shared(device_io_name_buffer_monitor, num_freq_bands, dump_, dump_filename); thread_buffer_monitor = std::thread([&] { run_buffer_monitor_process(); }); } // dynamic bits selection if (enable_dynamic_bit_selection_) { - dynamic_bit_selection_fpga = std::make_shared(num_freq_bands_); + dynamic_bit_selection_fpga = std::make_shared(enable_rx1_band, enable_rx2_band); thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); } @@ -607,7 +606,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, cons // if only one frequency band is used then clear the samples corresponding to the unused frequency band uint32_t dma_index = 0; - if (num_freq_bands_ == 1) + if (num_input_files_ == 1) { // if only one file is enabled then clear the samples corresponding to the frequency band that is not used. for (int index0 = 0; index0 < (nread_elements); index0 += 2) @@ -660,7 +659,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, cons } // read filename 1 (if enabled) - if (num_freq_bands_ > 1) + if (num_input_files_ > 1) { dma_index = 0; try @@ -781,7 +780,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, cons std::cerr << "Exception closing file " << filename0_ << '\n'; } - if (num_freq_bands_ > 1) + if (num_input_files_ > 1) { try { diff --git a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h index a78b1aa00..bedd25ad5 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h @@ -23,11 +23,7 @@ #include "concurrent_queue.h" #include "fpga_buffer_monitor.h" -#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture #include "fpga_dma-proxy.h" -#else -#include "fpga_ezdma.h" -#endif #include "fpga_dynamic_bit_selection.h" #include "fpga_switch.h" #include "gnss_block_interface.h" @@ -145,7 +141,7 @@ private: float Fpass_; float Fstop_; - uint32_t num_freq_bands_; + uint32_t num_input_files_; uint32_t dma_buff_offset_pos_; uint32_t in_stream_; uint32_t out_stream_; diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index 92da88664..a5d582116 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -19,13 +19,8 @@ if(ENABLE_FPGA OR ENABLE_AD9361) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dynamic_bit_selection.h) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h) - if(ARCH_64BITS) - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dma-proxy.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dma-proxy.h) - else() - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_ezdma.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_ezdma.h) - endif() + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dma-proxy.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dma-proxy.h) endif() diff --git a/src/algorithms/signal_source/libs/ad9361_manager.cc b/src/algorithms/signal_source/libs/ad9361_manager.cc index ccf02220f..7e7e3fa74 100644 --- a/src/algorithms/signal_source/libs/ad9361_manager.cc +++ b/src/algorithms/signal_source/libs/ad9361_manager.cc @@ -157,7 +157,7 @@ void cfg_ad9361_streaming_ch(struct stream_cfg *cfg, iio_channel *chn) int setup_filter(const std::string &filter_source_, uint64_t bandwidth_, uint64_t sample_rate_, uint64_t freq_, const std::string &rf_port_select_, - struct iio_device *ad9361_phy_dev, struct iio_channel *rx_chan, struct iio_channel *chn, int chid, std::string filter_filename_, float Fpass_, float Fstop_) + struct iio_device *ad9361_phy_dev, struct iio_channel *rx_chan, struct iio_channel *chn, int chid, std::string filter_filename_, [[maybe_unused]] float Fpass_, [[maybe_unused]] float Fstop_) { int ret; if (filter_source_ == "Off") @@ -337,6 +337,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, struct iio_channel *rx_chan0; // stream channel 0 struct iio_channel *rx_chan1; // stream channel 1 struct iio_channel *chn; // phy channel + struct iio_channel *lo_chn; // phy channel int ret; @@ -419,12 +420,12 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, } // Configure LO channel std::cout << "* Acquiring " << RX_DEV_A << " LO RX channel 0\n"; - if (!get_lo_chan(ad9361_phy, RX, 0, &chn)) + if (!get_lo_chan(ad9361_phy, RX, 0, &lo_chn)) { std::cout << "RX LO channel 0not found\n"; throw std::runtime_error("RX LO channel 0not found"); } - wr_ch_lli(chn, "frequency", freq0_); + wr_ch_lli(lo_chn, "frequency", freq0_); if (enable_ad9361_b) { @@ -449,7 +450,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, { return false; } - if (setup_filter(filter_source_, bandwidth_, sample_rate_, freq1_, rf_port_select_, ad9361_phy_B, rx_chan1, chn, 0, filter_filename_, Fpass_, Fstop_) == -1) + if (setup_filter(filter_source_, bandwidth_, sample_rate_, freq1_, rf_port_select_, ad9361_phy_B, rx_chan1, chn, 0, std::move(filter_filename_), Fpass_, Fstop_) == -1) { return false; } @@ -471,7 +472,7 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, std::cout << rx_stream_dev_a << " channel 1 not found\n"; throw std::runtime_error(rx_stream_dev_a + "RX channel 1 not found"); } - if (setup_filter(filter_source_, bandwidth_, sample_rate_, freq0_, rf_port_select_, ad9361_phy, rx_chan1, chn, 1, filter_filename_, Fpass_, Fstop_) == -1) + if (setup_filter(filter_source_, bandwidth_, sample_rate_, freq0_, rf_port_select_, ad9361_phy, rx_chan1, chn, 1, std::move(filter_filename_), Fpass_, Fstop_) == -1) { return false; } @@ -485,7 +486,10 @@ bool config_ad9361_rx_local(uint64_t bandwidth_, if (rx2_enable_) { iio_channel_enable(rx_chan1); - ad9361_fmcomms5_multichip_sync(ctx, FIXUP_INTERFACE_TIMING | CHECK_SAMPLE_RATES); + if (enable_ad9361_b) + { + ad9361_fmcomms5_multichip_sync(ctx, FIXUP_INTERFACE_TIMING | CHECK_SAMPLE_RATES); + } } if (!rx1_enable_ and !rx2_enable_) { diff --git a/src/algorithms/signal_source/libs/ad936x_iio_custom.cc b/src/algorithms/signal_source/libs/ad936x_iio_custom.cc index e487d29b5..23474891c 100644 --- a/src/algorithms/signal_source/libs/ad936x_iio_custom.cc +++ b/src/algorithms/signal_source/libs/ad936x_iio_custom.cc @@ -805,7 +805,7 @@ double ad936x_iio_custom::get_rx_gain(int ch_num) } -bool ad936x_iio_custom::calibrate(int ch, double bw_hz) +bool ad936x_iio_custom::calibrate([[maybe_unused]] int ch, [[maybe_unused]] double bw_hz) { if (check_device() == false) return false; // todo diff --git a/src/algorithms/signal_source/libs/fpga_dma-proxy.cc b/src/algorithms/signal_source/libs/fpga_dma-proxy.cc index 1e8881300..8ee7b411d 100644 --- a/src/algorithms/signal_source/libs/fpga_dma-proxy.cc +++ b/src/algorithms/signal_source/libs/fpga_dma-proxy.cc @@ -42,11 +42,13 @@ int Fpga_DMA::DMA_open() return 0; } + int8_t *Fpga_DMA::get_buffer_address() // NOLINT(readability-make-member-function-const) { return tx_channel.buf_ptr[0].buffer; } + int Fpga_DMA::DMA_write(int nbytes) const { int buffer_id = 0; diff --git a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc index c897e40f5..933d8b77f 100644 --- a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc @@ -26,38 +26,31 @@ #include // for cout #include // for mmap -Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(uint32_t num_freq_bands) - : d_num_freq_bands(num_freq_bands) +Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(bool enable_rx1_band, bool enable_rx2_band) + : d_map_base_freq_band_1(nullptr), + d_map_base_freq_band_2(nullptr), + d_dev_descr_freq_band_1(0), + d_dev_descr_freq_band_2(0), + d_shift_out_bits_freq_band_1(0), + d_shift_out_bits_freq_band_2(0), + d_enable_rx1_band(enable_rx1_band), + d_enable_rx2_band(enable_rx2_band) { - d_map_base = std::vector(d_num_freq_bands); - d_device_descriptors = std::vector(d_num_freq_bands); - d_shift_out_bits = std::vector(d_num_freq_bands); - for (uint32_t k = 0; k < d_num_freq_bands; k++) + if (d_enable_rx1_band) { - // find the uio device file corresponding to the dynamic bit selector 0 module. - std::string device_name; - if (find_uio_dev_file_name(device_name, dyn_bit_sel_device_name, 0) < 0) - { - std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n'; - return; - } - // dynamic bits selection corresponding to frequency band 1 - if ((d_device_descriptors[k] = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1) - { - LOG(WARNING) << "Cannot open deviceio" << device_name; - } - d_map_base[k] = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE, - PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptors[k], 0)); + open_device(&d_map_base_freq_band_1, d_dev_descr_freq_band_1, 0); - if (d_map_base[k] == reinterpret_cast(-1)) - { - LOG(WARNING) << "Cannot map the FPGA dynamic bit selection module in frequency band 1 into tracking memory"; - std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 1.\n"; - } + // init bit selection corresponding to frequency band 1 + d_shift_out_bits_freq_band_1 = shift_out_bits_default; + d_map_base_freq_band_1[0] = d_shift_out_bits_freq_band_1; + } + if (d_enable_rx2_band) + { + open_device(&d_map_base_freq_band_2, d_dev_descr_freq_band_2, 1); - // init bit selection corresopnding to frequency band 1 - d_shift_out_bits[k] = shift_out_bits_default; - d_map_base[k][0] = d_shift_out_bits[k]; + // init bit selection corresponding to frequency band 2 + d_shift_out_bits_freq_band_2 = shift_out_bits_default; + d_map_base_freq_band_2[0] = d_shift_out_bits_freq_band_2; } DLOG(INFO) << "Dynamic bit selection FPGA class created"; } @@ -65,48 +58,90 @@ Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(uint32_t num_freq_bands) Fpga_dynamic_bit_selection::~Fpga_dynamic_bit_selection() { - close_devices(); + if (d_enable_rx1_band) + { + close_device(d_map_base_freq_band_1, d_dev_descr_freq_band_1); + } + if (d_enable_rx2_band) + { + close_device(d_map_base_freq_band_2, d_dev_descr_freq_band_2); + } } void Fpga_dynamic_bit_selection::bit_selection() { - for (uint32_t k = 0; k < d_num_freq_bands; k++) + if (d_enable_rx1_band) { - // estimated signal power - uint32_t rx_signal_power = d_map_base[k][1]; + bit_selection_per_rf_band(d_map_base_freq_band_1, d_shift_out_bits_freq_band_1); + } - // dynamic bit selection - if (rx_signal_power > Power_Threshold_High) - { - if (d_shift_out_bits[k] < shift_out_bit_max) - { - d_shift_out_bits[k] = d_shift_out_bits[k] + 1; - } - } - else if (rx_signal_power < Power_Threshold_Low) - { - if (d_shift_out_bits[k] > shift_out_bits_min) - { - d_shift_out_bits[k] = d_shift_out_bits[k] - 1; - } - } - - // update bit selection corresopnding to frequency band 1 - d_map_base[k][0] = d_shift_out_bits[k]; + if (d_enable_rx2_band) + { + bit_selection_per_rf_band(d_map_base_freq_band_2, d_shift_out_bits_freq_band_2); } } -void Fpga_dynamic_bit_selection::close_devices() +void Fpga_dynamic_bit_selection::open_device(volatile unsigned **d_map_base, int &d_dev_descr, int freq_band) { - for (uint32_t k = 0; k < d_num_freq_bands; k++) + // find the uio device file corresponding to the dynamic bit selector 0 module. + std::string device_name; + if (find_uio_dev_file_name(device_name, dyn_bit_sel_device_name, freq_band) < 0) { - auto *aux = const_cast(d_map_base[k]); - if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1) - { - std::cout << "Failed to unmap memory uio\n"; - } - close(d_device_descriptors[k]); + std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n'; + std::cout << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n'; + return; + } + // dynamic bits selection corresponding to frequency band 1 + if ((d_dev_descr = open(device_name.c_str(), O_RDWR | O_SYNC)) == -1) + { + LOG(WARNING) << "Cannot open deviceio" << device_name; + std::cout << "Cannot open deviceio" << device_name << std::endl; + } + *d_map_base = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE, + PROT_READ | PROT_WRITE, MAP_SHARED, d_dev_descr, 0)); + + if (*d_map_base == reinterpret_cast(-1)) + { + LOG(WARNING) << "Cannot map the FPGA dynamic bit selection module in frequency band 1 into tracking memory"; + std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 1.\n"; } } + + +void Fpga_dynamic_bit_selection::bit_selection_per_rf_band(volatile unsigned *d_map_base, uint32_t shift_out_bits) +{ + // estimated signal power + uint32_t rx_signal_power = d_map_base[1]; + + // dynamic bit selection + if (rx_signal_power > Power_Threshold_High) + { + if (shift_out_bits < shift_out_bit_max) + { + shift_out_bits = shift_out_bits + 1; + } + } + else if (rx_signal_power < Power_Threshold_Low) + { + if (shift_out_bits > shift_out_bits_min) + { + shift_out_bits = shift_out_bits - 1; + } + } + + // update bit selection corresopnding to frequency band 1 + d_map_base[0] = shift_out_bits; +} + + +void Fpga_dynamic_bit_selection::close_device(volatile unsigned *d_map_base, int &d_dev_descr) +{ + auto *aux = const_cast(d_map_base); + if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1) + { + std::cout << "Failed to unmap memory uio\n"; + } + close(d_dev_descr); +} diff --git a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h index f5454e299..3f4b73a5a 100644 --- a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h @@ -43,7 +43,7 @@ public: /*! * \brief Constructor */ - explicit Fpga_dynamic_bit_selection(uint32_t num_freq_bands); + explicit Fpga_dynamic_bit_selection(bool enable_rx1_band, bool enable_rx2_band); /*! * \brief Destructor @@ -69,13 +69,18 @@ private: static const uint32_t Power_Threshold_High = 9000; static const uint32_t Power_Threshold_Low = 3000; - void close_devices(void); + void open_device(volatile unsigned **d_map_base, int &d_dev_descr, int freq_band); + void bit_selection_per_rf_band(volatile unsigned *d_map_base, uint32_t shift_out_bits); + void close_device(volatile unsigned *d_map_base, int &d_dev_descr); - std::vector d_map_base; - std::vector d_device_descriptors; - std::vector d_shift_out_bits; - - uint32_t d_num_freq_bands; // number of frequency bands + volatile unsigned *d_map_base_freq_band_1; + volatile unsigned *d_map_base_freq_band_2; + int d_dev_descr_freq_band_1; + int d_dev_descr_freq_band_2; + uint32_t d_shift_out_bits_freq_band_1; + uint32_t d_shift_out_bits_freq_band_2; + bool d_enable_rx1_band; + bool d_enable_rx2_band; }; diff --git a/src/algorithms/signal_source/libs/fpga_ezdma.cc b/src/algorithms/signal_source/libs/fpga_ezdma.cc deleted file mode 100644 index cb8f5497e..000000000 --- a/src/algorithms/signal_source/libs/fpga_ezdma.cc +++ /dev/null @@ -1,68 +0,0 @@ -/*! - * \file fpga_edma.cc - * \brief FPGA DMA control using the ezdma (See https://github.com/jeremytrimble/ezdma). - * \author Marc Majoral, mmajoral(at)cttc.es - * - * ----------------------------------------------------------------------------- - * - * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. - * This file is part of GNSS-SDR. - * - * Copyright (C) 2010-2022 (see AUTHORS file for a list of contributors) - * SPDX-License-Identifier: GPL-3.0-or-later - * - * ----------------------------------------------------------------------------- - */ -#include "fpga_ezdma.h" -#include -#include // for std::cerr -#include - -int Fpga_DMA::DMA_open() -{ - tx_fd = open("/dev/loop_tx", O_WRONLY); - if (tx_fd < 1) - { - return tx_fd; - } - // note: a problem was identified with the DMA: when switching from tx to rx or rx to tx mode - // the DMA transmission may hang. This problem will be fixed soon. - // for the moment this problem can be avoided by closing and opening the DMA a second time - if (close(tx_fd) < 0) - { - std::cerr << "Error closing loop device " << '\n'; - return -1; - } - // open the DMA a second time - tx_fd = open("/dev/loop_tx", O_WRONLY); - if (tx_fd < 1) - { - std::cerr << "Cannot open loop device\n"; - // stop the receiver - return tx_fd; - } - return 0; -} - - -int8_t *Fpga_DMA::get_buffer_address() -{ - return buffer; -} - - -int Fpga_DMA::DMA_write(int nbytes) const -{ - const int num_bytes_sent = write(tx_fd, buffer, nbytes); - if (num_bytes_sent != nbytes) - { - return -1; - } - return 0; -} - - -int Fpga_DMA::DMA_close() const -{ - return close(tx_fd); -} diff --git a/src/algorithms/signal_source/libs/fpga_ezdma.h b/src/algorithms/signal_source/libs/fpga_ezdma.h deleted file mode 100644 index 801d2a6b7..000000000 --- a/src/algorithms/signal_source/libs/fpga_ezdma.h +++ /dev/null @@ -1,64 +0,0 @@ -/*! - * \file fpga_ezdma.h - * \brief FPGA DMA control using the ezdma (See https://github.com/jeremytrimble/ezdma). - * \author Marc Majoral, mmajoral(at)cttc.es - * - * ----------------------------------------------------------------------------- - * - * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. - * This file is part of GNSS-SDR. - * - * Copyright (C) 2010-2022 (see AUTHORS file for a list of contributors) - * SPDX-License-Identifier: GPL-3.0-or-later - * - * ----------------------------------------------------------------------------- - */ - - -#ifndef GNSS_SDR_FPGA_EDMA_H -#define GNSS_SDR_FPGA_EDMA_H - -#include // for std::int8_t - -/*! - * \brief Class that controls the switch DMA in the FPGA - */ -class Fpga_DMA -{ -public: - /*! - * \brief Default constructor. - */ - Fpga_DMA() = default; - - /*! - * \brief Default destructor. - */ - ~Fpga_DMA() = default; - - /*! - * \brief Open the DMA device driver. - */ - int DMA_open(void); - - /*! - * \brief Obtain DMA buffer address. - */ - int8_t *get_buffer_address(void); // NOLINT(readability-make-member-function-const) - - /*! - * \brief Transfer DMA data - */ - int DMA_write(int nbytes) const; - - /*! - * \brief Close the DMA device driver - */ - int DMA_close(void) const; - -private: - static const uint32_t DMA_MAX_BUFFER_SIZE = 4 * 16384; // 4-channel 16384-sample buffers - int8_t buffer[DMA_MAX_BUFFER_SIZE]; - int tx_fd; -}; -#endif // GNSS_SDR_FPGA_EDMA_H diff --git a/src/algorithms/signal_source/libs/ppstcprx.cc b/src/algorithms/signal_source/libs/ppstcprx.cc index 0855ad0b6..c23261aff 100644 --- a/src/algorithms/signal_source/libs/ppstcprx.cc +++ b/src/algorithms/signal_source/libs/ppstcprx.cc @@ -27,16 +27,19 @@ pps_tcp_rx::pps_tcp_rx() clientSd = -1; } + pps_tcp_rx::~pps_tcp_rx() { // TODO Auto-generated destructor stub } + void pps_tcp_rx::set_pps_samplestamp_queue(std::shared_ptr> queue) { Pps_queue = std::move(queue); } + bool pps_tcp_rx::send_cmd(std::string cmd) { if (is_connected == true) @@ -59,6 +62,8 @@ bool pps_tcp_rx::send_cmd(std::string cmd) } return true; } + + void pps_tcp_rx::receive_pps(std::string ip_address, int port) { // create a message buffer diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc index 68df0ec82..070f0d46f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc @@ -446,7 +446,7 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & { std::string dump_filename_ = d_dump_filename.substr(d_dump_filename.find_last_of('/') + 1); dump_path = d_dump_filename.substr(0, d_dump_filename.find_last_of('/')); - d_dump_filename = dump_filename_; + d_dump_filename = std::move(dump_filename_); } else { @@ -1383,6 +1383,7 @@ void dll_pll_veml_tracking_fpga::set_gnss_synchro(Gnss_Synchro *p_gnss_synchro) d_acquisition_gnss_synchro = p_gnss_synchro; if (p_gnss_synchro->PRN > 0) { + gr::thread::scoped_lock lock(d_setlock); // A set_gnss_synchro command with a valid PRN is received when the system is going to run acquisition with that PRN. // We can use this command to pre-initialize tracking parameters and variables before the actual acquisition process takes place. // In this way we minimize the latency between acquisition and tracking once the acquisition has been made. @@ -1527,8 +1528,8 @@ int dll_pll_veml_tracking_fpga::general_work(int noutput_items __attribute__((un { case 1: // Pull-in { - d_worker_is_done = false; boost::mutex::scoped_lock lock(d_mutex); + d_worker_is_done = false; while (!d_worker_is_done) { d_m_condition.wait(lock); diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_gaussian_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_gaussian_tracking_cc.cc index df97429eb..0b8c3bb84 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_gaussian_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_gaussian_tracking_cc.cc @@ -235,6 +235,7 @@ Gps_L1_Ca_Gaussian_Tracking_cc::Gps_L1_Ca_Gaussian_Tracking_cc( void Gps_L1_Ca_Gaussian_Tracking_cc::start_tracking() { + gr::thread::scoped_lock l(d_setlock); /* * correct the code phase according to the delay between acq and trk */ @@ -308,10 +309,6 @@ void Gps_L1_Ca_Gaussian_Tracking_cc::start_tracking() sys = std::string(1, d_acquisition_gnss_synchro->System); - // DEBUG OUTPUT - std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n'; - LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; - // enable tracking d_pull_in = true; d_enable_tracking = true; @@ -319,6 +316,9 @@ void Gps_L1_Ca_Gaussian_Tracking_cc::start_tracking() LOG(INFO) << "PULL-IN Doppler [Hz]=" << d_carrier_doppler_hz << " Code Phase correction [samples]=" << delay_correction_samples << " PULL-IN Code Phase [samples]=" << d_acq_code_phase_samples; + + std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n'; + LOG(INFO) << "Starting tracking of satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << " on channel " << d_channel; } @@ -609,7 +609,7 @@ int Gps_L1_Ca_Gaussian_Tracking_cc::general_work(int noutput_items __attribute__ // GNSS_SYNCHRO OBJECT to interchange data between tracking->telemetry_decoder Gnss_Synchro current_synchro_data = Gnss_Synchro(); - + gr::thread::scoped_lock l(d_setlock); if (d_enable_tracking == true) { // Fill the acquisition data diff --git a/src/algorithms/tracking/libs/fpga_multicorrelator.cc b/src/algorithms/tracking/libs/fpga_multicorrelator.cc index 0269ed25d..99f5f778c 100644 --- a/src/algorithms/tracking/libs/fpga_multicorrelator.cc +++ b/src/algorithms/tracking/libs/fpga_multicorrelator.cc @@ -57,20 +57,26 @@ Fpga_Multicorrelator_8sc::Fpga_Multicorrelator_8sc(int32_t n_correlators, d_Prompt_Data(nullptr), d_shifts_chips(nullptr), d_prompt_data_shift(nullptr), - d_rem_code_phase_chips(0), - d_code_phase_step_chips(0), - d_rem_carrier_phase_in_rad(0), - d_phase_step_rad(0), + d_rem_code_phase_chips(0.0), + d_code_phase_step_chips(0.0), + d_code_phase_rate_step_chips(0.0), + d_rem_carrier_phase_in_rad(0.0), + d_phase_step_rad(0.0), + d_carrier_phase_rate_step_rad(0.0), d_code_length_samples(code_length_chips * code_samples_per_chip), d_n_correlators(n_correlators), d_device_descriptor(0), d_map_base(nullptr), d_correlator_length_samples(0), d_code_phase_step_chips_num(0), + d_code_phase_rate_step_chips_num(0), d_rem_carr_phase_rad_int(0), d_phase_step_rad_int(0), + d_carrier_phase_rate_step_rad_int(0), d_ca_codes(ca_codes), d_data_codes(data_codes), + d_secondary_code_0_length(0), + d_secondary_code_1_length(0), d_track_pilot(track_pilot), d_secondary_code_enabled(false) { diff --git a/src/core/libs/gnss_sdr_fpga_sample_counter.cc b/src/core/libs/gnss_sdr_fpga_sample_counter.cc index 6aa5c44a8..d67ea3b37 100644 --- a/src/core/libs/gnss_sdr_fpga_sample_counter.cc +++ b/src/core/libs/gnss_sdr_fpga_sample_counter.cc @@ -206,7 +206,7 @@ int gnss_sdr_fpga_sample_counter::general_work(int noutput_items __attribute__(( out[0].Channel_ID = -1; out[0].fs = fs; - if ((sample_counter - last_sample_counter) > samples_per_report) + if ((sample_counter - last_sample_counter) >= samples_per_report) { last_sample_counter = sample_counter; diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index 5bbd9ad98..c21622a96 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -2163,6 +2163,7 @@ void GNSSFlowgraph::set_configuration(const std::shared_ptr lock(signal_list_mutex_); for (int i = 0; i < channels_count_; i++) { if (channels_state_[i] == 1) diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt index 2895d5973..05b96fd5f 100644 --- a/src/main/CMakeLists.txt +++ b/src/main/CMakeLists.txt @@ -60,6 +60,8 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") target_link_libraries(gnss-sdr PRIVATE "-lc++") endif() endif() +include(RemoveDuplicates) +remove_duplicate_linked_libraries(gnss-sdr) if(ENABLE_STRIP) set_target_properties(gnss-sdr PROPERTIES LINK_FLAGS "-s") diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 53cc054d9..94ae13246 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,12 +1,13 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2010-2020 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2010-2024 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause add_subdirectory(unit-tests/signal-processing-blocks/libs) add_subdirectory(system-tests/libs) +include(RemoveDuplicates) ################################################################################ # Google Test - https://github.com/google/googletest @@ -408,6 +409,10 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) set(GNSSTK_FLAGS "-DCMAKE_CXX_FLAGS:STRING=-w") # Fix for clang in aarch64 endif() if(CMAKE_VERSION VERSION_GREATER 3.17.0) + set(GNSSTK_CXX_STANDARD 17) + if((${CMAKE_SYSTEM_NAME} MATCHES "Darwin") AND ("${DARWIN_VERSION}" VERSION_GREATER_EQUAL "14")) + set(GNSSTK_CXX_STANDARD 14) + endif() ExternalProject_Add(gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION} GIT_REPOSITORY https://github.com/SGL-UT/gnsstk GIT_TAG v${GNSSSDR_GNSSTK_LOCAL_VERSION} @@ -420,7 +425,7 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/gnsstk-${GNSSSDR_GNSSTK_LOCAL_VERSION}/install -DBUILD_EXT=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_CXX_STANDARD=17 + -DCMAKE_CXX_STANDARD=${GNSSTK_CXX_STANDARD} -DCMAKE_CXX_EXTENSIONS=ON -DCMAKE_C_STANDARD=11 -DCMAKE_C_EXTENSIONS=ON @@ -641,6 +646,7 @@ if(ENABLE_UNIT_TESTING) target_compile_definitions(run_tests PRIVATE -DGNSSTK_OLDER_THAN_9=1) endif() endif() + remove_duplicate_linked_libraries(run_tests) if(ENABLE_STRIP) set_target_properties(run_tests PROPERTIES LINK_FLAGS "-s") endif() @@ -763,6 +769,7 @@ if(ENABLE_FPGA) target_include_directories(gps_l1_ca_dll_pll_tracking_test_fpga INTERFACE ${GNSSSDR_SOURCE_DIR}/src/tests/common-files ) + remove_duplicate_linked_libraries(gps_l1_ca_dll_pll_tracking_test_fpga) install(TARGETS gps_l1_ca_dll_pll_tracking_test_fpga RUNTIME DESTINATION bin COMPONENT "fpga-test" @@ -852,6 +859,7 @@ if(ENABLE_SYSTEM_TESTING) ) if(NOT ENABLE_PACKAGING) add_system_test(ttff) + remove_duplicate_linked_libraries(ttff) endif() if(ENABLE_SYSTEM_TESTING_EXTRA) @@ -873,6 +881,7 @@ if(ENABLE_SYSTEM_TESTING) ) endif() endif() + remove_duplicate_linked_libraries(position_test) if(NOT GNSSSIMULATOR_FOUND OR ENABLE_GNSS_SIM_INSTALL) if(NOT CMAKE_CROSSCOMPILING) add_dependencies(position_test gnss-sim) @@ -933,7 +942,7 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) PRIVATE ${GNSSSDR_SOURCE_DIR}/src/algorithms/libs ) - + remove_duplicate_linked_libraries(flowgraph_test) add_test(flowgraph_test flowgraph_test) set_property(TEST flowgraph_test PROPERTY TIMEOUT 30) @@ -988,7 +997,7 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) if(ENABLE_FPGA) target_compile_definitions(gnss_block_test PRIVATE -DENABLE_FPGA=1) endif() - + remove_duplicate_linked_libraries(gnss_block_test) add_test(gnss_block_test gnss_block_test) set_property(TEST gnss_block_test PROPERTY TIMEOUT 60) @@ -1025,7 +1034,7 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) core_receiver algorithms_libs ) - + remove_duplicate_linked_libraries(gnuradio_block_test) add_test(gnuradio_block_test gnuradio_block_test) set_property(TEST gnuradio_block_test PROPERTY TIMEOUT 30) @@ -1059,7 +1068,7 @@ target_include_directories(matio_test INTERFACE ${GNSSSDR_SOURCE_DIR}/src/tests/common-files ) - +remove_duplicate_linked_libraries(matio_test) add_test(matio_test matio_test) set_property(TEST matio_test PROPERTY TIMEOUT 30) @@ -1108,6 +1117,7 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) -DPMT_USES_BOOST_ANY=1 ) endif() + remove_duplicate_linked_libraries(acq_test) add_test(acq_test acq_test) if(USE_GENERIC_LAMBDAS) @@ -1203,7 +1213,7 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) -DPMT_USES_BOOST_ANY=1 ) endif() - + remove_duplicate_linked_libraries(trk_test) add_test(trk_test trk_test) set_property(TEST trk_test PROPERTY TIMEOUT 30) @@ -1234,7 +1244,7 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) algorithms_libs core_receiver ) - + remove_duplicate_linked_libraries(control_thread_test) add_test(control_thread_test control_thread_test) set_property(TEST control_thread_test PROPERTY TIMEOUT 30) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc index 3206fdc67..714810fd7 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_test_fpga.cc @@ -91,6 +91,7 @@ GalileoE1PcpsAmbiguousAcquisitionTestFpga::GalileoE1PcpsAmbiguousAcquisitionTest doppler_max = 5000; doppler_step = 100; + nsamples_to_transfer = 0; } @@ -280,7 +281,7 @@ public: } private: - bool acquisition_successful; + bool acquisition_successful{}; }; @@ -310,7 +311,7 @@ bool GalileoE1PcpsAmbiguousAcquisitionTestFpga::acquire_signal() args.scaling_factor = DMA_SIGNAL_SCALING_FACTOR; std::string file = "data/Galileo_E1_ID_1_Fs_4Msps_8ms.dat"; - args.file = file; // DMA file configuration + args.file = std::move(file); // DMA file configuration // instantiate the FPGA switch and set the // switch position to DMA. @@ -348,7 +349,7 @@ bool GalileoE1PcpsAmbiguousAcquisitionTestFpga::acquire_signal() args.nsamples_tx = nsamples_to_transfer; // run the acquisition. The acquisition must run in a separate thread because it is a blocking function - args_acq.acquisition = acquisition; + args_acq.acquisition = std::move(acquisition); if (pthread_create(&thread_acquisition, nullptr, handler_acquisition_galileo_e1_pcps_ambiguous_acq_test, reinterpret_cast(&args_acq)) < 0) { diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc index eb5d8fe2a..60db2ec9b 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/gps_l1_ca_pcps_acquisition_test_fpga.cc @@ -90,6 +90,7 @@ GpsL1CaPcpsAcquisitionTestFpga::GpsL1CaPcpsAcquisitionTestFpga() doppler_max = 5000; doppler_step = 100; + nsamples_to_transfer = 0; } @@ -279,7 +280,7 @@ public: } private: - bool acquisition_successful; + bool acquisition_successful{}; }; @@ -309,7 +310,7 @@ bool GpsL1CaPcpsAcquisitionTestFpga::acquire_signal() args.scaling_factor = DMA_SIGNAL_SCALING_FACTOR; std::string file = "data/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; - args.file = file; // DMA file configuration + args.file = std::move(file); // DMA file configuration // instantiate the FPGA switch and set the // switch position to DMA. @@ -347,7 +348,7 @@ bool GpsL1CaPcpsAcquisitionTestFpga::acquire_signal() args.nsamples_tx = nsamples_to_transfer; // run the acquisition. The acquisition must run in a separate thread because it is a blocking function - args_acq.acquisition = acquisition; + args_acq.acquisition = std::move(acquisition); if (pthread_create(&thread_acquisition, nullptr, handler_acquisition_gps_l1_acq_test, reinterpret_cast(&args_acq)) < 0) { diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc index ec1b783ef..97b27f51c 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/filter/fir_filter_test.cc @@ -224,7 +224,7 @@ TEST_F(FirFilterTest, ConnectAndRunGrcomplex) config2->set_property("Test_Source.sampling_frequency", "4000000"); std::string path = std::string(TEST_PATH); std::string filename = path + "signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; - config2->set_property("Test_Source.filename", filename); + config2->set_property("Test_Source.filename", std::move(filename)); config2->set_property("Test_Source.item_type", "gr_complex"); config2->set_property("Test_Source.repeat", "true"); diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc index 36c7346a2..cf4cde035 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/filter/notch_filter_test.cc @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef GR_GREATER_38 #include #else @@ -177,7 +178,7 @@ TEST_F(NotchFilterTest, ConnectAndRunGrcomplex) config2->set_property("Test_Source.sampling_frequency", "4000000"); std::string path = std::string(TEST_PATH); std::string filename = path + "signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; - config2->set_property("Test_Source.filename", filename); + config2->set_property("Test_Source.filename", std::move(filename)); config2->set_property("Test_Source.item_type", "gr_complex"); config2->set_property("Test_Source.repeat", "true"); diff --git a/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc b/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc index 63038b5f1..4cb3c5c43 100644 --- a/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/filter/pulse_blanking_filter_test.cc @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef GR_GREATER_38 #include #else @@ -176,7 +177,7 @@ TEST_F(PulseBlankingFilterTest, ConnectAndRunGrcomplex) config2->set_property("Test_Source.sampling_frequency", "4000000"); std::string path = std::string(TEST_PATH); std::string filename = path + "signal_samples/GPS_L1_CA_ID_1_Fs_4Msps_2ms.dat"; - config2->set_property("Test_Source.filename", filename); + config2->set_property("Test_Source.filename", std::move(filename)); config2->set_property("Test_Source.item_type", "gr_complex"); config2->set_property("Test_Source.repeat", "true"); diff --git a/src/utils/front-end-cal/main.cc b/src/utils/front-end-cal/main.cc index 4915b35b5..972e4a21e 100644 --- a/src/utils/front-end-cal/main.cc +++ b/src/utils/front-end-cal/main.cc @@ -269,18 +269,26 @@ static time_t utc_time(int week, int64_t tow) int main(int argc, char** argv) { - const std::string intro_help( - std::string("\n RTL-SDR E4000 RF front-end center frequency and sampling rate calibration tool that uses GPS signals\n") + - "Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)\n" + - "This program comes with ABSOLUTELY NO WARRANTY;\n" + - "See COPYING file to see a copy of the General Public License\n \n"); + try + { + const std::string intro_help( + std::string("\n RTL-SDR E4000 RF front-end center frequency and sampling rate calibration tool that uses GPS signals\n") + + "Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)\n" + + "This program comes with ABSOLUTELY NO WARRANTY;\n" + + "See COPYING file to see a copy of the General Public License\n \n"); - gflags::SetUsageMessage(intro_help); - google::SetVersionString(FRONT_END_CAL_VERSION); - gflags::ParseCommandLineFlags(&argc, &argv, true); - - std::cout << "Initializing... Please wait.\n"; + gflags::SetUsageMessage(intro_help); + google::SetVersionString(FRONT_END_CAL_VERSION); + gflags::ParseCommandLineFlags(&argc, &argv, true); + std::cout << "Initializing... Please wait.\n"; + } + catch (const std::exception& e) + { + std::cerr << e.what() << '\n'; + std::cout << "front-end-cal program ended.\n"; + return 1; + } google::InitGoogleLogging(argv[0]); if (FLAGS_log_dir.empty()) { @@ -292,358 +300,390 @@ int main(int argc, char** argv) } else { - const fs::path p(FLAGS_log_dir); - if (!fs::exists(p)) + try { - std::cout << "The path " - << FLAGS_log_dir - << " does not exist, attempting to create it" - << '\n'; - fs::create_directory(p); + const fs::path p(FLAGS_log_dir); + if (!fs::exists(p)) + { + std::cout << "The path " + << FLAGS_log_dir + << " does not exist, attempting to create it" + << '\n'; + errorlib::error_code ec; + if (!fs::create_directory(p, ec)) + { + std::cerr << "Could not create the " << FLAGS_log_dir << " folder. Front-end-cal program ended.\n"; + gflags::ShutDownCommandLineFlags(); + return 1; + } + } + std::cout << "Logging with be done at " + << FLAGS_log_dir << '\n'; + } + catch (const std::exception& e) + { + std::cerr << e.what() << '\n'; + std::cerr << "Could not create the " << FLAGS_log_dir << " folder. Front-end-cal program ended.\n"; + gflags::ShutDownCommandLineFlags(); + return 1; } - std::cout << "Logging with be done at " - << FLAGS_log_dir << '\n'; } // 0. Instantiate the FrontEnd Calibration class - FrontEndCal front_end_cal; - - // 1. Load configuration parameters from config file - std::shared_ptr configuration = std::make_shared(FLAGS_config_file); - front_end_cal.set_configuration(configuration); - - // 2. Get SUPL information from server: Ephemeris record, assistance info and TOW try { - if (front_end_cal.get_ephemeris() == true) - { - std::cout << "SUPL data received OK!\n"; - } - else - { - std::cout << "Failure connecting to SUPL server\n"; - } - } - catch (const boost::exception& e) - { - std::cout << "Failure connecting to SUPL server\n"; - } + FrontEndCal front_end_cal; - // 3. Capture some front-end samples to hard disk - try - { - if (front_end_capture(configuration)) - { - std::cout << "Front-end RAW samples captured\n"; - } - else - { - std::cout << "Failure capturing front-end samples\n"; - } - } - catch (const boost::bad_lexical_cast& e) - { - std::cout << "Exception caught while capturing samples (bad lexical cast)\n"; - } - catch (const std::exception& e) - { - std::cout << "Exception caught while capturing samples: " << e.what() << '\n'; - } - catch (...) - { - std::cout << "Unexpected exception\n"; - } + // 1. Load configuration parameters from config file + std::shared_ptr configuration = std::make_shared(FLAGS_config_file); + front_end_cal.set_configuration(configuration); - // 4. Setup GNU Radio flowgraph (file_source -> Acquisition_10m) - gr::top_block_sptr top_block; - top_block = gr::make_top_block("Acquisition test"); - - // Satellite signal definition - gnss_synchro = Gnss_Synchro(); - gnss_synchro.Channel_ID = 0; - gnss_synchro.System = 'G'; - std::string signal = "1C"; - signal.copy(gnss_synchro.Signal, 2, 0); - gnss_synchro.PRN = 1; - - int64_t fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", 2048000); - configuration->set_property("Acquisition.max_dwells", "10"); - - auto acquisition = std::make_shared(configuration.get(), "Acquisition", 1, 1); - - acquisition->set_channel(1); - acquisition->set_gnss_synchro(&gnss_synchro); - acquisition->set_threshold(configuration->property("Acquisition.threshold", 2.0)); - acquisition->set_doppler_max(configuration->property("Acquisition.doppler_max", 10000)); - acquisition->set_doppler_step(configuration->property("Acquisition.doppler_step", 250)); - - gr::block_sptr source; - source = gr::blocks::file_source::make(sizeof(gr_complex), "tmp_capture.dat"); -#if GNURADIO_USES_STD_POINTERS - std::shared_ptr msg_rx; -#else - boost::shared_ptr msg_rx; -#endif - try - { - msg_rx = FrontEndCal_msg_rx_make(); - } - catch (const std::exception& e) - { - std::cout << "Failure connecting the message port system: " << e.what() << '\n'; - exit(0); - } - - try - { - acquisition->connect(top_block); - top_block->connect(source, 0, acquisition->get_left_block(), 0); - top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); - } - catch (const std::exception& e) - { - std::cout << "Failure connecting the GNU Radio blocks: " << e.what() << '\n'; - } - - // 5. Run the flowgraph - // Get visible GPS satellites (positive acquisitions with Doppler measurements) - // Compute Doppler estimations - - // todo: Fix the front-end cal to support new channel internal message system (no more external queues) - std::map doppler_measurements_map; - std::map cn0_measurements_map; - - std::thread ch_thread; - - // record startup time - std::chrono::time_point start; - std::chrono::time_point end; - std::chrono::duration elapsed_seconds{}; - start = std::chrono::system_clock::now(); - - bool start_msg = true; - - for (unsigned int PRN = 1; PRN < 33; PRN++) - { - gnss_synchro.PRN = PRN; - acquisition->set_gnss_synchro(&gnss_synchro); - acquisition->init(); - acquisition->set_local_code(); - acquisition->reset(); - stop = false; + // 2. Get SUPL information from server: Ephemeris record, assistance info and TOW try { - ch_thread = std::thread(wait_message); - } - catch (const std::exception& e) - { - LOG(INFO) << "Exception caught (thread resource error)"; - } - top_block->run(); - if (start_msg == true) - { - std::cout << "Searching for GPS Satellites in L1 band...\n"; - std::cout << "["; - start_msg = false; - } - if (!gnss_sync_vector.empty()) - { - std::cout << " " << PRN << " "; - double doppler_measurement_hz = 0; - for (auto& it : gnss_sync_vector) + if (front_end_cal.get_ephemeris() == true) { - doppler_measurement_hz += it.Acq_doppler_hz; + std::cout << "SUPL data received OK!\n"; + } + else + { + std::cout << "Failure connecting to SUPL server\n"; } - doppler_measurement_hz = doppler_measurement_hz / gnss_sync_vector.size(); - doppler_measurements_map.insert(std::pair(PRN, doppler_measurement_hz)); - } - else - { - std::cout << " . "; - } - try - { - channel_internal_queue.push(3); } catch (const boost::exception& e) { - LOG(INFO) << "Exception caught while pushing to the internal queue."; + std::cout << "Failure connecting to SUPL server\n"; } + + // 3. Capture some front-end samples to hard disk try { - ch_thread.join(); + if (front_end_capture(configuration)) + { + std::cout << "Front-end RAW samples captured\n"; + } + else + { + std::cout << "Failure capturing front-end samples\n"; + } + } + catch (const boost::bad_lexical_cast& e) + { + std::cout << "Exception caught while capturing samples (bad lexical cast)\n"; } catch (const std::exception& e) { - LOG(INFO) << "Exception caught while joining threads."; + std::cout << "Exception caught while capturing samples: " << e.what() << '\n'; } - gnss_sync_vector.clear(); + catch (...) + { + std::cout << "Unexpected exception\n"; + } + + // 4. Setup GNU Radio flowgraph (file_source -> Acquisition_10m) + gr::top_block_sptr top_block; + top_block = gr::make_top_block("Acquisition test"); + + // Satellite signal definition + gnss_synchro = Gnss_Synchro(); + gnss_synchro.Channel_ID = 0; + gnss_synchro.System = 'G'; + std::string signal = "1C"; + signal.copy(gnss_synchro.Signal, 2, 0); + gnss_synchro.PRN = 1; + + int64_t fs_in_ = configuration->property("GNSS-SDR.internal_fs_sps", 2048000); + configuration->set_property("Acquisition.max_dwells", "10"); + + auto acquisition = std::make_shared(configuration.get(), "Acquisition", 1, 1); + + acquisition->set_channel(1); + acquisition->set_gnss_synchro(&gnss_synchro); + acquisition->set_threshold(configuration->property("Acquisition.threshold", 2.0)); + acquisition->set_doppler_max(configuration->property("Acquisition.doppler_max", 10000)); + acquisition->set_doppler_step(configuration->property("Acquisition.doppler_step", 250)); + + gr::block_sptr source; + source = gr::blocks::file_source::make(sizeof(gr_complex), "tmp_capture.dat"); #if GNURADIO_USES_STD_POINTERS - std::dynamic_pointer_cast(source)->seek(0, 0); + std::shared_ptr msg_rx; #else - boost::dynamic_pointer_cast(source)->seek(0, 0); + boost::shared_ptr msg_rx; #endif - std::cout.flush(); - } - std::cout << "]\n"; - - // report the elapsed time - end = std::chrono::system_clock::now(); - elapsed_seconds = end - start; - std::cout << "Total signal acquisition run time " - << elapsed_seconds.count() - << " [seconds]\n"; - - // 6. find TOW from SUPL assistance - double current_TOW = 0; - try - { - if (global_gps_ephemeris_map.size() > 0) + try { - std::map Eph_map; - Eph_map = global_gps_ephemeris_map.get_map_copy(); - current_TOW = Eph_map.begin()->second.tow; - - time_t t = utc_time(Eph_map.begin()->second.WN, static_cast(current_TOW)); - - std::cout << "Reference Time:\n"; - std::cout << " GPS Week: " << Eph_map.begin()->second.WN << '\n'; - std::cout << " GPS TOW: " << static_cast(current_TOW) << " " << static_cast(current_TOW) * 0.08 << '\n'; - std::cout << " ~ UTC: " << ctime(&t) << '\n'; - std::cout << "Current TOW obtained from SUPL assistance = " << current_TOW << '\n'; + msg_rx = FrontEndCal_msg_rx_make(); } - else + catch (const std::exception& e) { - std::cout << "Unable to get Ephemeris SUPL assistance. TOW is unknown!\n"; + std::cout << "Failure connecting the message port system: " << e.what() << '\n'; + exit(0); + } + + try + { + acquisition->connect(top_block); + top_block->connect(source, 0, acquisition->get_left_block(), 0); + top_block->msg_connect(acquisition->get_right_block(), pmt::mp("events"), msg_rx, pmt::mp("events")); + } + catch (const std::exception& e) + { + std::cout << "Failure connecting the GNU Radio blocks: " << e.what() << '\n'; + } + + // 5. Run the flowgraph + // Get visible GPS satellites (positive acquisitions with Doppler measurements) + // Compute Doppler estimations + + // todo: Fix the front-end cal to support new channel internal message system (no more external queues) + std::map doppler_measurements_map; + std::map cn0_measurements_map; + + std::thread ch_thread; + + // record startup time + std::chrono::time_point start; + std::chrono::time_point end; + std::chrono::duration elapsed_seconds{}; + start = std::chrono::system_clock::now(); + + bool start_msg = true; + + for (unsigned int PRN = 1; PRN < 33; PRN++) + { + gnss_synchro.PRN = PRN; + acquisition->set_gnss_synchro(&gnss_synchro); + acquisition->init(); + acquisition->set_local_code(); + acquisition->reset(); + stop = false; + try + { + ch_thread = std::thread(wait_message); + } + catch (const std::exception& e) + { + LOG(INFO) << "Exception caught (thread resource error)"; + } + top_block->run(); + if (start_msg == true) + { + std::cout << "Searching for GPS Satellites in L1 band...\n"; + std::cout << "["; + start_msg = false; + } + if (!gnss_sync_vector.empty()) + { + std::cout << " " << PRN << " "; + double doppler_measurement_hz = 0; + for (auto& it : gnss_sync_vector) + { + doppler_measurement_hz += it.Acq_doppler_hz; + } + doppler_measurement_hz = doppler_measurement_hz / gnss_sync_vector.size(); + doppler_measurements_map.insert(std::pair(PRN, doppler_measurement_hz)); + } + else + { + std::cout << " . "; + } + try + { + channel_internal_queue.push(3); + } + catch (const boost::exception& e) + { + LOG(INFO) << "Exception caught while pushing to the internal queue."; + } + try + { + ch_thread.join(); + } + catch (const std::exception& e) + { + LOG(INFO) << "Exception caught while joining threads."; + } + gnss_sync_vector.clear(); +#if GNURADIO_USES_STD_POINTERS + std::dynamic_pointer_cast(source)->seek(0, 0); +#else + boost::dynamic_pointer_cast(source)->seek(0, 0); +#endif + std::cout.flush(); + } + std::cout << "]\n"; + + // report the elapsed time + end = std::chrono::system_clock::now(); + elapsed_seconds = end - start; + std::cout << "Total signal acquisition run time " + << elapsed_seconds.count() + << " [seconds]\n"; + + // 6. find TOW from SUPL assistance + double current_TOW = 0; + try + { + if (global_gps_ephemeris_map.size() > 0) + { + std::map Eph_map; + Eph_map = global_gps_ephemeris_map.get_map_copy(); + current_TOW = Eph_map.begin()->second.tow; + + time_t t = utc_time(Eph_map.begin()->second.WN, static_cast(current_TOW)); + + std::cout << "Reference Time:\n"; + std::cout << " GPS Week: " << Eph_map.begin()->second.WN << '\n'; + std::cout << " GPS TOW: " << static_cast(current_TOW) << " " << static_cast(current_TOW) * 0.08 << '\n'; + std::cout << " ~ UTC: " << ctime(&t) << '\n'; + std::cout << "Current TOW obtained from SUPL assistance = " << current_TOW << '\n'; + } + else + { + std::cout << "Unable to get Ephemeris SUPL assistance. TOW is unknown!\n"; + gflags::ShutDownCommandLineFlags(); + std::cout << "GNSS-SDR Front-end calibration program ended.\n"; + return 0; + } + } + catch (const boost::exception& e) + { + std::cout << "Exception in getting Global ephemeris map\n"; gflags::ShutDownCommandLineFlags(); std::cout << "GNSS-SDR Front-end calibration program ended.\n"; return 0; } + + // Get user position from config file (or from SUPL using GSM Cell ID) + double lat_deg = configuration->property("GNSS-SDR.init_latitude_deg", 41.0); + double lon_deg = configuration->property("GNSS-SDR.init_longitude_deg", 2.0); + double altitude_m = configuration->property("GNSS-SDR.init_altitude_m", 100); + + std::cout << "Reference location (defined in config file):\n"; + + std::cout << "Latitude=" << lat_deg << " [º]\n"; + std::cout << "Longitude=" << lon_deg << " [º]\n"; + std::cout << "Altitude=" << altitude_m << " [m]\n"; + + if (doppler_measurements_map.empty()) + { + std::cout << "Sorry, no GPS satellites detected in the front-end capture, please check the antenna setup...\n"; + gflags::ShutDownCommandLineFlags(); + std::cout << "GNSS-SDR Front-end calibration program ended.\n"; + return 0; + } + + std::map f_if_estimation_Hz_map; + std::map f_fs_estimation_Hz_map; + std::map f_ppm_estimation_Hz_map; + + std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(2) << "Doppler analysis results:\n"; + + std::cout << "SV ID Measured [Hz] Predicted [Hz]\n"; + + for (auto& it : doppler_measurements_map) + { + try + { + double doppler_estimated_hz; + doppler_estimated_hz = front_end_cal.estimate_doppler_from_eph(it.first, current_TOW, lat_deg, lon_deg, altitude_m); + std::cout << " " << it.first << " " << it.second << " " << doppler_estimated_hz << '\n'; + // 7. Compute front-end IF and sampling frequency estimation + // Compare with the measurements and compute clock drift using FE model + double estimated_fs_Hz; + double estimated_f_if_Hz; + double f_osc_err_ppm; + front_end_cal.GPS_L1_front_end_model_E4000(doppler_estimated_hz, it.second, fs_in_, &estimated_fs_Hz, &estimated_f_if_Hz, &f_osc_err_ppm); + + f_if_estimation_Hz_map.insert(std::pair(it.first, estimated_f_if_Hz)); + f_fs_estimation_Hz_map.insert(std::pair(it.first, estimated_fs_Hz)); + f_ppm_estimation_Hz_map.insert(std::pair(it.first, f_osc_err_ppm)); + } + catch (const std::logic_error& e) + { + std::cout << "Logic error caught: " << e.what() << '\n'; + } + catch (const boost::lock_error& e) + { + std::cout << "Exception caught while reading ephemeris\n"; + } + catch (const std::exception& ex) + { + std::cout << " " << it.first << " " << it.second << " (Eph not found)\n"; + } + } + + // FINAL FE estimations + double mean_f_if_Hz = 0; + double mean_fs_Hz = 0; + double mean_osc_err_ppm = 0; + int n_elements = f_if_estimation_Hz_map.size(); + + for (auto& it : f_if_estimation_Hz_map) + { + mean_f_if_Hz += it.second; + const auto est_fs = f_fs_estimation_Hz_map.find(it.first); + if (est_fs != f_fs_estimation_Hz_map.cend()) + { + mean_fs_Hz += est_fs->second; + } + const auto est_ppm = f_ppm_estimation_Hz_map.find(it.first); + if (est_ppm != f_ppm_estimation_Hz_map.cend()) + { + mean_osc_err_ppm += est_ppm->second; + } + } + + mean_f_if_Hz /= n_elements; + mean_fs_Hz /= n_elements; + mean_osc_err_ppm /= n_elements; + + std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(2) << "Parameters estimation for Elonics E4000 Front-End:\n"; + + std::cout << "Sampling frequency =" << mean_fs_Hz << " [Hz]\n"; + std::cout << "IF bias present in baseband=" << mean_f_if_Hz << " [Hz]\n"; + std::cout << "Reference oscillator error =" << mean_osc_err_ppm << " [ppm]\n"; + + std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(2) + << "Corrected Doppler vs. Predicted\n"; + std::cout << "SV ID Corrected [Hz] Predicted [Hz]\n"; + + for (auto& it : doppler_measurements_map) + { + try + { + double doppler_estimated_hz; + doppler_estimated_hz = front_end_cal.estimate_doppler_from_eph(it.first, current_TOW, lat_deg, lon_deg, altitude_m); + std::cout << " " << it.first << " " << it.second - mean_f_if_Hz << " " << doppler_estimated_hz << '\n'; + } + catch (const std::logic_error& e) + { + std::cout << "Logic error caught: " << e.what() << '\n'; + } + catch (const boost::lock_error& e) + { + std::cout << "Exception caught while reading ephemeris\n"; + } + catch (const std::exception& ex) + { + std::cout << " " << it.first << " " << it.second - mean_f_if_Hz << " (Eph not found)\n"; + } + } } - catch (const boost::exception& e) + catch (const std::exception& e) { - std::cout << "Exception in getting Global ephemeris map\n"; + std::cerr << "Exception: " << e.what(); gflags::ShutDownCommandLineFlags(); - std::cout << "GNSS-SDR Front-end calibration program ended.\n"; - return 0; + return 1; } - - // Get user position from config file (or from SUPL using GSM Cell ID) - double lat_deg = configuration->property("GNSS-SDR.init_latitude_deg", 41.0); - double lon_deg = configuration->property("GNSS-SDR.init_longitude_deg", 2.0); - double altitude_m = configuration->property("GNSS-SDR.init_altitude_m", 100); - - std::cout << "Reference location (defined in config file):\n"; - - std::cout << "Latitude=" << lat_deg << " [º]\n"; - std::cout << "Longitude=" << lon_deg << " [º]\n"; - std::cout << "Altitude=" << altitude_m << " [m]\n"; - - if (doppler_measurements_map.empty()) + catch (...) { - std::cout << "Sorry, no GPS satellites detected in the front-end capture, please check the antenna setup...\n"; + std::cerr << "Unknown error\n"; gflags::ShutDownCommandLineFlags(); - std::cout << "GNSS-SDR Front-end calibration program ended.\n"; - return 0; - } - - std::map f_if_estimation_Hz_map; - std::map f_fs_estimation_Hz_map; - std::map f_ppm_estimation_Hz_map; - - std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(2) << "Doppler analysis results:\n"; - - std::cout << "SV ID Measured [Hz] Predicted [Hz]\n"; - - for (auto& it : doppler_measurements_map) - { - try - { - double doppler_estimated_hz; - doppler_estimated_hz = front_end_cal.estimate_doppler_from_eph(it.first, current_TOW, lat_deg, lon_deg, altitude_m); - std::cout << " " << it.first << " " << it.second << " " << doppler_estimated_hz << '\n'; - // 7. Compute front-end IF and sampling frequency estimation - // Compare with the measurements and compute clock drift using FE model - double estimated_fs_Hz; - double estimated_f_if_Hz; - double f_osc_err_ppm; - front_end_cal.GPS_L1_front_end_model_E4000(doppler_estimated_hz, it.second, fs_in_, &estimated_fs_Hz, &estimated_f_if_Hz, &f_osc_err_ppm); - - f_if_estimation_Hz_map.insert(std::pair(it.first, estimated_f_if_Hz)); - f_fs_estimation_Hz_map.insert(std::pair(it.first, estimated_fs_Hz)); - f_ppm_estimation_Hz_map.insert(std::pair(it.first, f_osc_err_ppm)); - } - catch (const std::logic_error& e) - { - std::cout << "Logic error caught: " << e.what() << '\n'; - } - catch (const boost::lock_error& e) - { - std::cout << "Exception caught while reading ephemeris\n"; - } - catch (const std::exception& ex) - { - std::cout << " " << it.first << " " << it.second << " (Eph not found)\n"; - } - } - - // FINAL FE estimations - double mean_f_if_Hz = 0; - double mean_fs_Hz = 0; - double mean_osc_err_ppm = 0; - int n_elements = f_if_estimation_Hz_map.size(); - - for (auto& it : f_if_estimation_Hz_map) - { - mean_f_if_Hz += it.second; - const auto est_fs = f_fs_estimation_Hz_map.find(it.first); - if (est_fs != f_fs_estimation_Hz_map.cend()) - { - mean_fs_Hz += est_fs->second; - } - const auto est_ppm = f_ppm_estimation_Hz_map.find(it.first); - if (est_ppm != f_ppm_estimation_Hz_map.cend()) - { - mean_osc_err_ppm += est_ppm->second; - } - } - - mean_f_if_Hz /= n_elements; - mean_fs_Hz /= n_elements; - mean_osc_err_ppm /= n_elements; - - std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(2) << "Parameters estimation for Elonics E4000 Front-End:\n"; - - std::cout << "Sampling frequency =" << mean_fs_Hz << " [Hz]\n"; - std::cout << "IF bias present in baseband=" << mean_f_if_Hz << " [Hz]\n"; - std::cout << "Reference oscillator error =" << mean_osc_err_ppm << " [ppm]\n"; - - std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(2) - << "Corrected Doppler vs. Predicted\n"; - std::cout << "SV ID Corrected [Hz] Predicted [Hz]\n"; - - for (auto& it : doppler_measurements_map) - { - try - { - double doppler_estimated_hz; - doppler_estimated_hz = front_end_cal.estimate_doppler_from_eph(it.first, current_TOW, lat_deg, lon_deg, altitude_m); - std::cout << " " << it.first << " " << it.second - mean_f_if_Hz << " " << doppler_estimated_hz << '\n'; - } - catch (const std::logic_error& e) - { - std::cout << "Logic error caught: " << e.what() << '\n'; - } - catch (const boost::lock_error& e) - { - std::cout << "Exception caught while reading ephemeris\n"; - } - catch (const std::exception& ex) - { - std::cout << " " << it.first << " " << it.second - mean_f_if_Hz << " (Eph not found)\n"; - } + return 1; } gflags::ShutDownCommandLineFlags(); std::cout << "GNSS-SDR Front-end calibration program ended.\n"; + return 0; } diff --git a/src/utils/rinex-tools/obsdiff.cc b/src/utils/rinex-tools/obsdiff.cc index 60c74fe9f..0b156bb86 100644 --- a/src/utils/rinex-tools/obsdiff.cc +++ b/src/utils/rinex-tools/obsdiff.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include #if GNSSTK_USES_GPSTK_NAMESPACE @@ -673,7 +674,7 @@ void carrier_doppler_single_diff( { // 2. RMSE arma::vec err; - err = delta_measured_carrier_doppler_cycles; + err = std::move(delta_measured_carrier_doppler_cycles); arma::vec err2 = arma::square(err); double rmse = sqrt(arma::mean(err2)); @@ -865,7 +866,7 @@ void code_pseudorange_single_diff( // 2. RMSE arma::vec err; - err = delta_measured_obs; + err = std::move(delta_measured_obs); arma::vec err2 = arma::square(err); double rmse = sqrt(arma::mean(err2)); @@ -1014,7 +1015,7 @@ void coderate_phaserate_consistence( // 2. RMSE arma::vec err; - err = ratediff; + err = std::move(ratediff); arma::vec err2 = arma::square(err); double rmse = sqrt(arma::mean(err2)); @@ -1098,7 +1099,7 @@ void code_phase_diff( { // 2. RMSE arma::vec err; - err = code_minus_phase; + err = std::move(code_minus_phase); arma::vec err2 = arma::square(err); double rmse = sqrt(arma::mean(err2)); @@ -1727,22 +1728,42 @@ int main(int argc, char** argv) { std::cout << "Running RINEX observables difference tool...\n"; gflags::ParseCommandLineFlags(&argc, &argv, true); - if (FLAGS_single_diff) + try { - if (FLAGS_dupli_sat) + if (FLAGS_single_diff) { - RINEX_doublediff_dupli_sat(); + if (FLAGS_dupli_sat) + { + RINEX_doublediff_dupli_sat(); + } + else + { + RINEX_singlediff(); + } } else { - RINEX_singlediff(); + RINEX_doublediff(FLAGS_remove_rx_clock_error); } } - else + catch (const gnsstk::Exception& e) { - RINEX_doublediff(FLAGS_remove_rx_clock_error); + std::cerr << e; + gflags::ShutDownCommandLineFlags(); + return 1; + } + catch (const std::exception& e) + { + std::cerr << "Exception: " << e.what(); + gflags::ShutDownCommandLineFlags(); + return 1; + } + catch (...) + { + std::cerr << "Unknown error\n"; + gflags::ShutDownCommandLineFlags(); + return 1; } - gflags::ShutDownCommandLineFlags(); return 0; }