diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 26108abcf..ac057c239 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ jobs: build-ubuntu: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install dependencies run: | sudo apt-get update -y @@ -39,14 +39,23 @@ jobs: build-macos: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install dependencies run: | brew update - brew install --overwrite python@3.10 python@3.11 - python3.11 -m pip install mako - brew install ninja pkg-config hdf5 automake armadillo lapack \ + rm /usr/local/bin/2to3 || true + rm /usr/local/bin/idle3 || true + rm /usr/local/bin/pydoc3 || true + rm /usr/local/bin/python3 || true + rm /usr/local/bin/python3-config || true + rm /usr/local/bin/2to3-3.11 || true + rm /usr/local/bin/idle3.11 || true + rm /usr/local/bin/pydoc3.11 || true + rm /usr/local/bin/python3.11 || true + rm /usr/local/bin/python3.11-config || true + brew install ninja hdf5 automake armadillo lapack \ gflags glog gnuradio log4cpp openssl pugixml protobuf + pip3 install mako - name: configure run: cd build && cmake -GNinja .. - name: build @@ -59,14 +68,23 @@ jobs: build-macos-xcode: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install dependencies run: | brew update - brew install --overwrite python@3.10 python@3.11 - python3.11 -m pip install mako + rm /usr/local/bin/2to3 || true + rm /usr/local/bin/idle3 || true + rm /usr/local/bin/pydoc3 || true + rm /usr/local/bin/python3 || true + rm /usr/local/bin/python3-config || true + rm /usr/local/bin/2to3-3.11 || true + rm /usr/local/bin/idle3.11 || true + rm /usr/local/bin/pydoc3.11 || true + rm /usr/local/bin/python3.11 || true + rm /usr/local/bin/python3.11-config || true brew install ninja pkg-config hdf5 automake armadillo lapack gflags glog \ gnuradio log4cpp openssl pugixml protobuf + pip3 install mako - name: configure run: cd build && cmake -GXcode .. - name: build @@ -87,7 +105,7 @@ jobs: clang-format: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: run clang-format uses: jidicula/clang-format-action@v4.11.0 with: @@ -98,14 +116,23 @@ jobs: clang-tidy: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install dependencies run: | brew update - brew install --overwrite python@3.10 python@3.11 - python3.11 -m pip install mako + rm /usr/local/bin/2to3 || true + rm /usr/local/bin/idle3 || true + rm /usr/local/bin/pydoc3 || true + rm /usr/local/bin/python3 || true + rm /usr/local/bin/python3-config || true + rm /usr/local/bin/2to3-3.11 || true + rm /usr/local/bin/idle3.11 || true + rm /usr/local/bin/pydoc3.11 || true + rm /usr/local/bin/python3.11 || true + rm /usr/local/bin/python3.11-config || true brew install llvm pkg-config hdf5 armadillo lapack gflags glog gnuradio libmatio \ log4cpp openssl pugixml protobuf + pip3 install mako ln -s $(brew --prefix llvm)/bin/clang-tidy /usr/local/bin ln -s $(brew --prefix llvm)/bin/clang-apply-replacements /usr/local/bin ln -s $(brew --prefix llvm)/bin/run-clang-tidy /usr/local/bin @@ -123,7 +150,7 @@ jobs: cpplint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install dependencies run: sudo apt-get install python3-pip && sudo pip3 install cpplint - name: run checks @@ -144,7 +171,7 @@ jobs: prettier-markdown: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install dependencies run: sudo npm install --global prettier - name: check markdown @@ -153,7 +180,7 @@ jobs: cmakelint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install dependencies run: | sudo python -m pip install --upgrade pip @@ -164,7 +191,7 @@ jobs: volk-gnsssdr-windows: runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 - name: Install dependencies run: | @@ -186,7 +213,7 @@ jobs: volk-gnsssdr-ubuntu: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install dependencies run: sudo apt install python3-mako liborc-dev - name: configure @@ -201,7 +228,7 @@ jobs: volk-gnsssdr-macos: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install dependencies run: pip3 install mako - name: configure @@ -214,7 +241,7 @@ jobs: volk-gnsssdr-macos-xcode: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install dependencies run: pip3 install mako - name: configure @@ -229,7 +256,7 @@ jobs: shellcheck: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install dependencies run: sudo apt install shellcheck - name: check scripts @@ -238,7 +265,7 @@ jobs: REUSE-compliance: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Check REUSE compliance uses: docker://fsfe/reuse with: diff --git a/CMakeLists.txt b/CMakeLists.txt index f2a91527b..56aeda777 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ endif() # Build type can still be overridden by setting -DCMAKE_BUILD_TYPE= set(CMAKE_BUILD_TYPE "Release" CACHE STRING "") -cmake_minimum_required(VERSION 2.8.12...3.26) +cmake_minimum_required(VERSION 2.8.12...3.27) project(gnss-sdr CXX C) set(GNSSSDR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) # Allows to be a sub-project @@ -335,12 +335,12 @@ set(GNSSSDR_PYTHON3_MIN_VERSION "3.4") ################################################################################ # Versions to download and build (but not to install system-wide) if not found ################################################################################ -set(GNSSSDR_ARMADILLO_LOCAL_VERSION "12.2.x") +set(GNSSSDR_ARMADILLO_LOCAL_VERSION "12.6.x") set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2") set(GNSSSDR_GLOG_LOCAL_VERSION "0.6.0") set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.23") set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "22.4") -set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.13") +set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.14") set(GNSSSDR_GTEST_LOCAL_VERSION "1.13.0") set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master") set(GNSSSDR_GNSSTK_LOCAL_VERSION "14.0.0") @@ -361,6 +361,13 @@ if(CMAKE_VERSION VERSION_LESS "3.0.2") set(GNSSSDR_GLOG_LOCAL_VERSION "0.3.4") # Fix for Ubuntu 14.04 endif() +if(CMAKE_VERSION VERSION_LESS "3.5") + set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.13") +endif() +if(CMAKE_VERSION VERSION_LESS "3.4") + set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.10") +endif() + if(CMAKE_CROSSCOMPILING OR CMAKE_VERSION VERSION_LESS "3.13") set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "21.12") endif() @@ -1109,7 +1116,7 @@ if(NOT VOLKGNSSSDR_FOUND) endif() endif() - if(PYTHONINTERP_FOUND) + if(CMAKE_VERSION VERSION_LESS 3.27 AND PYTHONINTERP_FOUND) set_package_properties(PythonInterp PROPERTIES URL "https://www.python.org/" DESCRIPTION "An interpreted, high-level, general-purpose programming language (found: v${PYTHON_VERSION_STRING})" diff --git a/cmake/Modules/SetupPython.cmake b/cmake/Modules/SetupPython.cmake index 2260357ce..2dc93b955 100644 --- a/cmake/Modules/SetupPython.cmake +++ b/cmake/Modules/SetupPython.cmake @@ -48,9 +48,25 @@ if(CMAKE_VERSION VERSION_LESS 3.12 OR CMAKE_CROSSCOMPILING) message(STATUS "User set python executable ${PYTHON_EXECUTABLE}") string(FIND "${PYTHON_EXECUTABLE}" "python3" IS_PYTHON3) if(IS_PYTHON3 EQUAL -1) - find_package(PythonInterp ${GNSSSDR_PYTHON_MIN_VERSION} REQUIRED) + if(CMAKE_VERSION VERSION_LESS "3.24") + find_package(PythonInterp ${GNSSSDR_PYTHON_MIN_VERSION} REQUIRED) + else() + set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) + find_package(Python2 COMPONENTS Interpreter) + set(PYTHONINTERP_FOUND Python2_Interpreter_FOUND) + set(PYTHON_VERSION_MAJOR "${Python2_VERSION_MAJOR}") + set(PYTHON_VERSION_STRING "${Python2_VERSION_MAJOR}.${Python2_VERSION_MINOR}") + endif() else() - find_package(PythonInterp ${GNSSSDR_PYTHON3_MIN_VERSION} REQUIRED) + if(CMAKE_VERSION VERSION_LESS "3.24") + find_package(PythonInterp ${GNSSSDR_PYTHON3_MIN_VERSION} REQUIRED) + else() + set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) + find_package(Python3 COMPONENTS Interpreter) + set(PYTHONINTERP_FOUND Python3_Interpreter_FOUND) + set(PYTHON_VERSION_MAJOR "${Python3_VERSION_MAJOR}") + set(PYTHON_VERSION_STRING "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}") + endif() endif() gnsssdr_python_check_module("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND) gnsssdr_python_check_module("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND) @@ -59,11 +75,28 @@ if(CMAKE_VERSION VERSION_LESS 3.12 OR CMAKE_CROSSCOMPILING) endif() else() message(STATUS "PYTHON_EXECUTABLE not set - trying by default python3") - set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7 3.8 3.9) - find_package(PythonInterp ${GNSSSDR_PYTHON_MIN3_VERSION}) + if(CMAKE_VERSION VERSION_LESS "3.24") + set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11) + find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION}) + else() + find_package(Python COMPONENTS Interpreter) + set(PYTHONINTERP_FOUND Python_Interpreter_FOUND) + set(PYTHON_EXECUTABLE "${Python_EXECUTABLE}") + set(PYTHON_VERSION_MAJOR "${Python_VERSION_MAJOR}") + set(PYTHON_VERSION_STRING "${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}") + endif() if(NOT PYTHONINTERP_FOUND) message(STATUS "python3 not found - trying with python2.7") - find_package(PythonInterp ${GNSSSDR_PYTHON_MIN_VERSION} REQUIRED) + if(CMAKE_VERSION VERSION_LESS "3.24") + set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11) + find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION}) + else() + find_package(Python2 COMPONENTS Interpreter) + set(PYTHONINTERP_FOUND Python2_Interpreter_FOUND) + set(PYTHON_EXECUTABLE "${Python2_EXECUTABLE}") + set(PYTHON_VERSION_MAJOR "${Python2_VERSION_MAJOR}") + set(PYTHON_VERSION_STRING "${Python2_VERSION_MAJOR}.${Python2_VERSION_MINOR}") + endif() endif() gnsssdr_python_check_module("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND) gnsssdr_python_check_module("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND) @@ -76,13 +109,17 @@ else() set(_previous ${CMAKE_FIND_FRAMEWORK}) set(CMAKE_FIND_FRAMEWORK LAST) endif() + if(PYTHON_EXECUTABLE) + set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) + endif() find_package(Python3 COMPONENTS Interpreter) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(CMAKE_FIND_FRAMEWORK ${_previous}) endif() if(Python3_FOUND) set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) - set(PYTHON_VERSION_MAJOR ${Python3_VERSION_MAJOR}) + set(PYTHON_VERSION_MAJOR "${Python3_VERSION_MAJOR}") + set(PYTHON_VERSION_STRING "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}") gnsssdr_python_check_module("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND) gnsssdr_python_check_module("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND) endif() @@ -91,16 +128,44 @@ else() if(Python2_FOUND) set(PYTHON_EXECUTABLE ${Python2_EXECUTABLE}) set(PYTHON_VERSION_MAJOR ${Python2_VERSION_MAJOR}) + set(PYTHON_VERSION_STRING "${Python2_VERSION_MAJOR}.${Python2_VERSION_MINOR}") gnsssdr_python_check_module("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND) gnsssdr_python_check_module("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND) gnsssdr_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) endif() if(NOT MAKO_FOUND OR NOT SIX_FOUND) unset(PYTHON_EXECUTABLE) - find_package(PythonInterp ${GNSSSDR_PYTHON_MIN_VERSION}) + if(CMAKE_VERSION VERSION_LESS "3.24") + find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION}) + else() + find_package(Python COMPONENTS Interpreter) + set(PYTHONINTERP_FOUND Python_Interpreter_FOUND) + set(PYTHON_EXECUTABLE "${Python_EXECUTABLE}") + set(PYTHON_VERSION_STRING "${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}") + set(PYTHON_VERSION_MAJOR "${Python_VERSION_MAJOR}") + endif() gnsssdr_python_check_module("python >= ${GNSSSDR_PYTHON_MIN_VERSION}" sys "sys.version.split()[0] >= '${GNSSSDR_PYTHON_MIN_VERSION}'" PYTHON_MIN_VER_FOUND) gnsssdr_python_check_module("mako >= ${GNSSSDR_MAKO_MIN_VERSION}" mako "mako.__version__ >= '${GNSSSDR_MAKO_MIN_VERSION}'" MAKO_FOUND) - if(PYTHON_VERSION_STRING VERSION_LESS "3.0") + if(NOT MAKO_FOUND) + unset(PYTHON_EXECUTABLE) + unset(PYTHON_VERSION_STRING) + unset(PYTHON_VERSION_MAJOR) + find_program(PYTHON_EXECUTABLE NAMES python3 python) + if(PYTHON_EXECUTABLE) + set(PYTHONINTERP_FOUND TRUE) + execute_process(COMMAND "${PYTHON_EXECUTABLE} --version" OUTPUT_VARIABLE PYTHON_VERSION_STRING_AUX) + string(FIND "${PYTHON_VERSION_STRING_AUX}" " " blank_char_index) + if(blank_char_index GREATER -1) + math(EXPR start_index "${blank_char_index} + 1") + string(SUBSTRING "${PYTHON_VERSION_STRING_AUX}" ${start_index} -1 PYTHON_VERSION_STRING) + string(STRIP ${PYTHON_VERSION_STRING} PYTHON_VERSION_STRING) + string(SUBSTRING "${PYTHON_VERSION_STRING_AUX}" ${start_index} 1 PYTHON_VERSION_MAJOR) + message(STATUS "Found Python: ${PYTHON_EXECUTABLE} (found version: ${PYTHON_VERSION_STRING})") + endif() + endif() + volk_python_check_module("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND) + endif() + if(MAKO_FOUND AND PYTHON_VERSION_STRING VERSION_LESS "3.0") gnsssdr_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) endif() endif() diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 422237dd3..160083a7a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -14,7 +14,24 @@ All notable changes to GNSS-SDR will be documented in this file. ## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next) -### Improvements in Repeatability +### Improvements in Interoperability: + +- Added a new PVT configuration boolean flag (`flag_geohash_log_out`) that + enables or disables the Position Geohash tag output in INFO log files. Set to + `false` by default. +- New fields have been added to the custom output stream defined by + `monitor_pvt.proto`: + - `utc_time` (a [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) datetime + string), + - velocity in the local ENU frame (`vel_e`, `vel_n`, and `vel_u`), in m/s, + - the course over ground, `cog`, in degrees, + - the status of the Galileo's High Accuracy Service, `galhas_status`: + - 0: HAS data not available + - 1: HAS Corrections applied + - `geohash`, an + [encoded geographic location](https://en.wikipedia.org/wiki/Geohash). + +### Improvements in Repeatability: - A Kalman filter is now available in the PVT block, smoothing the outputs of a simple Least Squares solution and improving the precision of delivered fixes. @@ -26,6 +43,21 @@ All notable changes to GNSS-SDR will be documented in this file. `PVT.kf_system_ecef_pos_sd_m=0.01`, in [m]; and `PVT.kf_system_ecef_vel_sd_ms=0.001`, in [m/s]. +### Improvements in Usability: + +- The Galileo E1B Reduced CED parameters usage has been set to `false` by + default. You can activate its usage with `Galileo_E1B_Telemetry_Decoder=true` + in your configuration file. +- The generation of Galileo E6B observables has been disabled if the user sets + `PVT.use_e6_for_pvt=false`, fixing the PVT computation in some multi-band + configurations. +- Fix bug in the custom binary output (`PVT.enable_monitor=true`) output rate. + Before this fix, it was outputting data every 20 ms, instead of observing the + `PVT.output_rate_ms` setting. +- Now the program exits properly if a SIGINT signal is received (_e.g._, the + user pressing Ctrl+C, or another user application sending an interruption + signal). + ## [GNSS-SDR v0.0.18](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.18) - 2023-04-06 [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7805514.svg)](https://doi.org/10.5281/zenodo.7805514) diff --git a/docs/protobuf/monitor_pvt.proto b/docs/protobuf/monitor_pvt.proto index d8b9d7f54..9b297bae7 100644 --- a/docs/protobuf/monitor_pvt.proto +++ b/docs/protobuf/monitor_pvt.proto @@ -7,39 +7,49 @@ package gnss_sdr; /* MonitorPvt represents a search query, with pagination options to * indicate which results to include in the response. */ message MonitorPvt { -uint32 tow_at_current_symbol_ms = 1; // Time of week of the current symbol, in ms -uint32 week = 2; // PVT GPS week -double rx_time = 3; // PVT GPS time -double user_clk_offset = 4; // User clock offset, in s + uint32 tow_at_current_symbol_ms = 1; // Time of week of the current symbol, in ms + uint32 week = 2; // PVT GPS week + double rx_time = 3; // PVT GPS time + double user_clk_offset = 4; // User clock offset, in s -double pos_x = 5; // Position X component in ECEF, expressed in m -double pos_y = 6; // Position Y component in ECEF, expressed in m -double pos_z = 7; // Position Z component in ECEF, expressed in m -double vel_x = 8; // Velocity X component in ECEF, in m/s -double vel_y = 9; // Velocity Y component in ECEF, in m/s -double vel_z = 10; // Velocity Z component in ECEF, in m/s + double pos_x = 5; // Position X component in ECEF, expressed in m + double pos_y = 6; // Position Y component in ECEF, expressed in m + double pos_z = 7; // Position Z component in ECEF, expressed in m + double vel_x = 8; // Velocity X component in ECEF, in m/s + double vel_y = 9; // Velocity Y component in ECEF, in m/s + double vel_z = 10; // Velocity Z component in ECEF, in m/s -double cov_xx = 11; // Position variance in the Y component, in m2 -double cov_yy = 12; // Position variance in the Y component, in m2 -double cov_zz = 13; // Position variance in the Z component, in m2 -double cov_xy = 14; // Position XY covariance, in m2 -double cov_yz = 15; // Position YZ covariance, in m2 -double cov_zx = 16; // Position ZX covariance, in m2 + double cov_xx = 11; // Position variance in the Y component, in m2 + double cov_yy = 12; // Position variance in the Y component, in m2 + double cov_zz = 13; // Position variance in the Z component, in m2 + double cov_xy = 14; // Position XY covariance, in m2 + double cov_yz = 15; // Position YZ covariance, in m2 + double cov_zx = 16; // Position ZX covariance, in m2 -double latitude = 17; // Latitude, in deg. Positive: North -double longitude = 18; // Longitude, in deg. Positive: East -double height = 19; // Height, in m + double latitude = 17; // Latitude, in deg. Positive: North + double longitude = 18; // Longitude, in deg. Positive: East + double height = 19; // Height, in m -uint32 valid_sats = 20; // Number of valid satellites -uint32 solution_status = 21; // RTKLIB solution status -uint32 solution_type = 22; // RTKLIB solution type (0: xyz-ecef, 1: enu-baseline) -float ar_ratio_factor = 23; // Ambiguity resolution ratio factor for validation -float ar_ratio_threshold = 24; // Ambiguity resolution ratio threshold for validation + uint32 valid_sats = 20; // Number of valid satellites + uint32 solution_status = 21; // RTKLIB solution status + uint32 solution_type = 22; // RTKLIB solution type (0: xyz-ecef, 1: enu-baseline) + float ar_ratio_factor = 23; // Ambiguity resolution ratio factor for validation + float ar_ratio_threshold = 24; // Ambiguity resolution ratio threshold for validation -double gdop = 25; // Geometric Dilution of Precision -double pdop = 26; // Position (3D) Dilution of Precision -double hdop = 27; // Horizontal Dilution of Precision -double vdop = 28; // Vertical Dilution of Precision + double gdop = 25; // Geometric Dilution of Precision + double pdop = 26; // Position (3D) Dilution of Precision + double hdop = 27; // Horizontal Dilution of Precision + double vdop = 28; // Vertical Dilution of Precision -double user_clk_drift_ppm = 29; // User clock drift [ppm] + double user_clk_drift_ppm = 29; // User clock drift [ppm] + string utc_time = 30; // PVT UTC time (rfc 3339 datetime string) + + double vel_e = 31; // Velocity East component in the local frame, in m/s + double vel_n = 32; // Velocity North component in the local frame, in m/s + double vel_u = 33; // Velocity Up component in the local frame, in m/s + + double cog = 34; // Course Over Ground, in deg + + uint32 galhas_status = 35; // Galileo HAS status: 1- HAS messages decoded and applied, 0 - HAS not available + string geohash = 36; // Encoded geographic location. See https://en.wikipedia.org/wiki/Geohash } diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc index 9388354ec..ca234a7a9 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc @@ -2458,21 +2458,22 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item // p_time += boost::posix_time::microseconds(round(rtklib_utc_time.sec * 1e6)); // std::cout << TEXT_MAGENTA << "Observable RX time (GPST) " << boost::posix_time::to_simple_string(p_time) << TEXT_RESET << '\n'; - LOG(INFO) << "Position at " << boost::posix_time::to_simple_string(d_user_pvt_solver->get_position_UTC_time()) - << " UTC using " << d_user_pvt_solver->get_num_valid_observations() << " observations is Lat = " << d_user_pvt_solver->get_latitude() << " [deg], Long = " << d_user_pvt_solver->get_longitude() - << " [deg], Height = " << d_user_pvt_solver->get_height() << " [m]"; - LOG(INFO) << "geohash=" << d_geohash->encode(d_user_pvt_solver->get_latitude(), d_user_pvt_solver->get_longitude()); + DLOG(INFO) << "Position at " << boost::posix_time::to_simple_string(d_user_pvt_solver->get_position_UTC_time()) + << " UTC using " << d_user_pvt_solver->get_num_valid_observations() << " observations is Lat = " << d_user_pvt_solver->get_latitude() << " [deg], Long = " << d_user_pvt_solver->get_longitude() + << " [deg], Height = " << d_user_pvt_solver->get_height() << " [m]"; + /* std::cout << "Dilution of Precision at " << boost::posix_time::to_simple_string(d_user_pvt_solver->get_position_UTC_time()) - << " UTC using "<< d_user_pvt_solver->get_num_valid_observations() <<" observations is HDOP = " << d_user_pvt_solver->get_hdop() << " VDOP = " - << d_user_pvt_solver->get_vdop() - << " GDOP = " << d_user_pvt_solver->get_gdop() << '\n'; */ + << " UTC using "<< d_user_pvt_solver->get_num_valid_observations() <<" observations is HDOP = " << d_user_pvt_solver->get_hdop() << " VDOP = " + << d_user_pvt_solver->get_vdop() + << " GDOP = " << d_user_pvt_solver->get_gdop() << '\n'; */ } // PVT MONITOR - if (d_user_pvt_solver->is_valid_position()) + if (d_user_pvt_solver->is_valid_position() && flag_compute_pvt_output == true) { const std::shared_ptr monitor_pvt = std::make_shared(d_user_pvt_solver->get_monitor_pvt()); - + monitor_pvt->geohash = d_geohash->encode(d_user_pvt_solver->get_latitude(), d_user_pvt_solver->get_longitude()); + DLOG(INFO) << "geohash=" << monitor_pvt->geohash; // publish new position to the gnss_flowgraph channel status monitor if (current_RX_time_ms % d_report_rate_ms == 0) { diff --git a/src/algorithms/PVT/libs/monitor_pvt.h b/src/algorithms/PVT/libs/monitor_pvt.h index 18c43229b..e70f681de 100644 --- a/src/algorithms/PVT/libs/monitor_pvt.h +++ b/src/algorithms/PVT/libs/monitor_pvt.h @@ -19,6 +19,7 @@ #include #include +#include /** \addtogroup PVT * \{ */ @@ -63,6 +64,16 @@ public: double longitude; // GEO user position Height [m] double height; + // East, Nord, Up (ENU) Velocity [m/s] + double vel_e; + double vel_n; + double vel_u; + + // Course Over Ground (COG) [deg] + double cog; + + // Galileo HAS status: 1- HAS messages decoded and applied, 0 - HAS not avaliable + uint32_t galhas_status; // NUMBER OF VALID SATS uint8_t valid_sats; @@ -84,6 +95,11 @@ public: // User clock drift [ppm] double user_clk_drift_ppm; + // PVT UTC Time (rfc 3339 datetime string) + std::string utc_time; + + std::string geohash; // See https://en.wikipedia.org/wiki/Geohash + /*! * \brief This member function serializes and restores * Monitor_Pvt objects from a byte stream. @@ -131,6 +147,14 @@ public: ar& BOOST_SERIALIZATION_NVP(vdop); ar& BOOST_SERIALIZATION_NVP(user_clk_drift_ppm); + ar& BOOST_SERIALIZATION_NVP(utc_time); + + ar& BOOST_SERIALIZATION_NVP(vel_e); + ar& BOOST_SERIALIZATION_NVP(vel_n); + ar& BOOST_SERIALIZATION_NVP(vel_u); + + ar& BOOST_SERIALIZATION_NVP(cog); + ar& BOOST_SERIALIZATION_NVP(geohash); } }; diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index 8b9d5b8ee..faf8af5f0 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -1598,7 +1598,7 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ ecef2pos(pvt_sol.rr, pos.data()); ecef2enu(pos.data(), &pvt_sol.rr[3], enuv.data()); this->set_speed_over_ground(norm_rtk(enuv.data(), 2)); - double new_cog; + double new_cog = -9999.0; // COG not estimated due to insuficient velocity if (ground_speed_ms >= 1.0) { new_cog = atan2(enuv[0], enuv[1]) * R2D; @@ -1680,12 +1680,41 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ this->set_rx_vel({enuv[0], enuv[1], enuv[2]}); + // ENU vel [m/s] + d_monitor_pvt.vel_e = enuv[0]; + d_monitor_pvt.vel_n = enuv[1]; + d_monitor_pvt.vel_u = enuv[2]; + + // Course Over Ground (cog) [deg] + d_monitor_pvt.cog = new_cog; + + // Galileo HAS status: 1- HAS messages decoded and applied, 0 - HAS not avaliable + if (d_has_obs_corr_map.empty()) + { + d_monitor_pvt.galhas_status = 0; + } + else + { + d_monitor_pvt.galhas_status = 1; + } + const double clock_drift_ppm = pvt_sol.dtr[5] / SPEED_OF_LIGHT_M_S * 1e6; this->set_clock_drift_ppm(clock_drift_ppm); // User clock drift [ppm] d_monitor_pvt.user_clk_drift_ppm = clock_drift_ppm; + // write UTC time string + + // Use a facet to display time in a custom format (only hour and minutes). + auto *facet = new boost::posix_time::time_facet(); + facet->format("%Y-%m-%dT%H:%M:%S%F"); + std::stringstream stream; + stream.imbue(std::locale(std::locale::classic(), facet)); + stream << p_time; + stream << 'Z'; + d_monitor_pvt.utc_time = stream.str(); + // ######## LOG FILE ######### if (d_flag_dump_enabled == true) { diff --git a/src/algorithms/PVT/libs/serdes_monitor_pvt.h b/src/algorithms/PVT/libs/serdes_monitor_pvt.h index a792e18d6..f7ac8e72e 100644 --- a/src/algorithms/PVT/libs/serdes_monitor_pvt.h +++ b/src/algorithms/PVT/libs/serdes_monitor_pvt.h @@ -112,6 +112,13 @@ public: monitor_.set_hdop(monitor->hdop); monitor_.set_vdop(monitor->vdop); monitor_.set_user_clk_drift_ppm(monitor->user_clk_drift_ppm); + monitor_.set_utc_time(monitor->utc_time); + monitor_.set_vel_e(monitor->vel_e); + monitor_.set_vel_n(monitor->vel_n); + monitor_.set_vel_u(monitor->vel_u); + monitor_.set_cog(monitor->cog); + monitor_.set_galhas_status(monitor->galhas_status); + monitor_.set_geohash(monitor->geohash); monitor_.SerializeToString(&data); return data; @@ -150,6 +157,13 @@ public: monitor.hdop = mon.hdop(); monitor.vdop = mon.vdop(); monitor.user_clk_drift_ppm = mon.user_clk_drift_ppm(); + monitor.utc_time = mon.utc_time(); + monitor.vel_e = mon.vel_e(); + monitor.vel_n = mon.vel_n(); + monitor.vel_u = mon.vel_u(); + monitor.cog = mon.cog(); + monitor.galhas_status = mon.galhas_status(); + monitor.geohash = mon.geohash(); return monitor; } 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 926b680e4..20efd8ae3 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_downsampling_factor, 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, 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 209ba88d7..597d9975a 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 @@ -181,9 +181,8 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: - static const uint32_t fpga_downsampling_factor = 4; // downampling factor in the FPGA - static const uint32_t fpga_buff_num = 0; // L1/E1 band - static const uint32_t fpga_blk_exp = 13; // default block exponent + static const uint32_t fpga_buff_num = 0; // L1/E1 band + static const uint32_t fpga_blk_exp = 13; // default block exponent // 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. 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 497da79e9..d049ccd37 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_downsampling_factor, 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, 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 9f9170c40..a33f6738e 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5a_pcps_acquisition_fpga.h @@ -188,9 +188,8 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: - static const uint32_t fpga_downsampling_factor = 1; // downampling factor in the FPGA - static const uint32_t fpga_buff_num = 1; // L5/E5a band - static const uint32_t fpga_blk_exp = 13; // default block exponent + static const uint32_t fpga_buff_num = 1; // L5/E5a band + static const uint32_t fpga_blk_exp = 13; // default block exponent // 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. 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 f75d29db4..4ec2c5341 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_downsampling_factor, 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, 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 e3c43aeea..33545bd2b 100644 --- a/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/galileo_e5b_pcps_acquisition_fpga.h @@ -187,9 +187,8 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: - static const uint32_t fpga_downsampling_factor = 1; // downampling factor in the FPGA - static const uint32_t fpga_buff_num = 1; // E5b band - static const uint32_t fpga_blk_exp = 13; // default block exponent + static const uint32_t fpga_buff_num = 1; // E5b band + static const uint32_t fpga_blk_exp = 13; // default block exponent // 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. 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 5b01d13f4..0b9ae0b9a 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_downsampling_factor, 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, 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 addbdd5ec..f187d77c0 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,9 +186,8 @@ public: private: static const uint32_t NUM_PRNs = 32; - static const uint32_t fpga_downsampling_factor = 4; // downampling factor in the FPGA - static const uint32_t fpga_buff_num = 0; // L1/E1 band - static const uint32_t fpga_blk_exp = 10; // default block exponent + static const uint32_t fpga_buff_num = 0; // L1/E1 band + static const uint32_t fpga_blk_exp = 10; // default block exponent // 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. 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 30680e011..c74f1275b 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_downsampling_factor, 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, 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 67f8f621a..d105ea7e2 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 @@ -149,9 +149,8 @@ public: void set_resampler_latency(uint32_t latency_samples __attribute__((unused))) override{}; private: - static const uint32_t fpga_downsampling_factor = 4; // downampling factor in the FPGA - static const uint32_t fpga_buff_num = 0; // L2 band - static const uint32_t fpga_blk_exp = 13; // default block exponent + static const uint32_t fpga_buff_num = 0; // L2 band + static const uint32_t fpga_blk_exp = 13; // default block exponent static const uint32_t NUM_PRNs = 32; static const uint32_t QUANT_BITS_LOCAL_CODE = 16; 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 269672f65..ebd701840 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_downsampling_factor, 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, 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 a2e69c3df..c68cd7bda 100644 --- a/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h +++ b/src/algorithms/acquisition/adapters/gps_l5i_pcps_acquisition_fpga.h @@ -186,9 +186,8 @@ public: private: static const uint32_t NUM_PRNs = 32; - static const uint32_t fpga_downsampling_factor = 1; // downampling factor in the FPGA - static const uint32_t fpga_buff_num = 1; // L5/E5a band - static const uint32_t fpga_blk_exp = 13; // default block exponent + static const uint32_t fpga_buff_num = 1; // L5/E5a band + static const uint32_t fpga_blk_exp = 13; // default block exponent // 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. diff --git a/src/algorithms/acquisition/libs/acq_conf_fpga.cc b/src/algorithms/acquisition/libs/acq_conf_fpga.cc index 94d9a321f..ac68a92ad 100644 --- a/src/algorithms/acquisition/libs/acq_conf_fpga.cc +++ b/src/algorithms/acquisition/libs/acq_conf_fpga.cc @@ -23,7 +23,7 @@ #include void Acq_Conf_Fpga::SetFromConfiguration(const ConfigurationInterface *configuration, - const std::string &role, uint32_t downs_factor, 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, 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 +33,8 @@ void Acq_Conf_Fpga::SetFromConfiguration(const ConfigurationInterface *configura doppler_max = configuration->property(role + ".doppler_max", doppler_max); // downsampling factor - uint32_t downsampling_factor = configuration->property(role + ".downsampling_factor", downs_factor); + downsampling_factor = configuration->property(role + ".downsampling_factor", downsampling_factor); + fs_in = fs_in / downsampling_factor; // code length in samples diff --git a/src/algorithms/acquisition/libs/acq_conf_fpga.h b/src/algorithms/acquisition/libs/acq_conf_fpga.h index 5bac585f4..c24cbb031 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 downs_factor, 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, 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/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt index 0a668f741..4235cb586 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt @@ -8,7 +8,7 @@ ######################################################################## # Project setup ######################################################################## -cmake_minimum_required(VERSION 2.8.12...3.26) +cmake_minimum_required(VERSION 2.8.12...3.27) set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Choose build type: None Debug Release RelWithDebInfo MinSizeRel") project(volk_gnsssdr) enable_language(CXX) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkPython.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkPython.cmake index 2fc0819b7..697fe8c3b 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkPython.cmake +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/VolkPython.cmake @@ -52,18 +52,42 @@ set(VOLK_PYTHON3_MIN_VERSION "3.4") if(CMAKE_VERSION VERSION_LESS 3.12 OR CMAKE_CROSSCOMPILING) if(PYTHON_EXECUTABLE) message(STATUS "User set python executable ${PYTHON_EXECUTABLE}") - find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION} REQUIRED) + if(CMAKE_VERSION VERSION_LESS "3.24") # For cross-compiling + find_package(PythonInterp ${VOLK_PYTHON_MIN3_VERSION} REQUIRED) + else() + set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) + find_package(Python COMPONENTS Interpreter) + set(PYTHONINTERP_FOUND Python_Interpreter_FOUND) + set(PYTHON_VERSION_MAJOR "${Python_VERSION_MAJOR}") + set(PYTHON_VERSION_STRING "${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}") + endif() if(PYTHON_VERSION_STRING VERSION_LESS "3.0") volk_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) endif() else() message(STATUS "PYTHON_EXECUTABLE not set - trying by default python3") message(STATUS "Use -DPYTHON_EXECUTABLE=/path/to/python to build for python 2.7") - set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7 3.8 3.9) - find_package(PythonInterp ${VOLK_PYTHON_MIN3_VERSION}) + if(CMAKE_VERSION VERSION_LESS "3.24") # For cross-compiling + set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11) + find_package(PythonInterp ${VOLK_PYTHON_MIN3_VERSION} REQUIRED) + else() + find_package(Python COMPONENTS Interpreter) + set(PYTHONINTERP_FOUND Python_Interpreter_FOUND) + set(PYTHON_EXECUTABLE "${Python_EXECUTABLE}") + set(PYTHON_VERSION_MAJOR "${Python_VERSION_MAJOR}") + set(PYTHON_VERSION_STRING "${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}") + endif() if(NOT PYTHONINTERP_FOUND) message(STATUS "python3 not found - trying with python2.7") - find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION} REQUIRED) + if(CMAKE_VERSION VERSION_LESS "3.24") + find_package(PythonInterp ${VOLK_PYTHON_MIN3_VERSION} REQUIRED) + else() + find_package(Python2 COMPONENTS Interpreter) + set(PYTHONINTERP_FOUND Python2_Interpreter_FOUND) + set(PYTHON_VERSION_MAJOR "${Python2_VERSION_MAJOR}") + set(PYTHON_EXECUTABLE "${Python2_EXECUTABLE}") + set(PYTHON_VERSION_STRING "${Python2_VERSION_MAJOR}.${Python2_VERSION_MINOR}") + endif() volk_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) endif() endif() @@ -71,7 +95,15 @@ if(CMAKE_VERSION VERSION_LESS 3.12 OR CMAKE_CROSSCOMPILING) else() if(PYTHON_EXECUTABLE) message(STATUS "User set python executable ${PYTHON_EXECUTABLE}") - find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION} REQUIRED) + if(CMAKE_VERSION VERSION_LESS "3.24") + find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION} REQUIRED) + else() + set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) + find_package(Python COMPONENTS Interpreter) + set(PYTHONINTERP_FOUND Python_Interpreter_FOUND) + set(PYTHON_VERSION_MAJOR "${Python_VERSION_MAJOR}") + set(PYTHON_VERSION_STRING "${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}") + endif() volk_python_check_module("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND) if(PYTHON_VERSION_STRING VERSION_LESS "3.0") volk_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) @@ -102,8 +134,37 @@ else() endif() if(NOT MAKO_FOUND OR NOT SIX_FOUND) unset(PYTHON_EXECUTABLE) - find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION}) + if(CMAKE_VERSION VERSION_LESS "3.24") + find_package(PythonInterp ${VOLK_PYTHON_MIN_VERSION}) + else() + find_package(Python COMPONENTS Interpreter) + set(PYTHONINTERP_FOUND Python_Interpreter_FOUND) + set(PYTHON_EXECUTABLE "${Python_EXECUTABLE}") + set(PYTHON_VERSION_MAJOR "${Python_VERSION_MAJOR}") + set(PYTHON_VERSION_STRING "${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}") + endif() volk_python_check_module("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND) + if(NOT MAKO_FOUND) + unset(PYTHON_EXECUTABLE) + unset(PYTHON_VERSION_STRING) + find_program(PYTHON_EXECUTABLE NAMES python3 python) + if(PYTHON_EXECUTABLE) + set(PYTHONINTERP_FOUND TRUE) + execute_process(COMMAND ${PYTHON_EXECUTABLE} --version OUTPUT_VARIABLE PYTHON_VERSION_STRING_AUX) + string(FIND "${PYTHON_VERSION_STRING_AUX}" " " blank_char_index) + if(blank_char_index GREATER -1) + math(EXPR start_index "${blank_char_index} + 1") + string(SUBSTRING "${PYTHON_VERSION_STRING_AUX}" ${start_index} -1 PYTHON_VERSION_STRING) + string(STRIP ${PYTHON_VERSION_STRING} PYTHON_VERSION_STRING) + string(SUBSTRING "${PYTHON_VERSION_STRING_AUX}" ${start_index} 1 PYTHON_VERSION_MAJOR) + message(STATUS "Found Python: ${PYTHON_EXECUTABLE} (found version: ${PYTHON_VERSION_STRING})") + endif() + volk_python_check_module("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND) + if(MAKO_FOUND AND PYTHON_VERSION_STRING VERSION_LESS "3.0") + gnsssdr_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND) + endif() + endif() + endif() endif() endif() endif() @@ -114,6 +175,7 @@ if(${PYTHON_VERSION_MAJOR} VERSION_EQUAL 3) endif() + ######################################################################## # Sets the python installation directory VOLK_PYTHON_DIR ######################################################################## diff --git a/src/algorithms/observables/adapters/hybrid_observables.cc b/src/algorithms/observables/adapters/hybrid_observables.cc index 6413d48a7..fbb6ba2a3 100644 --- a/src/algorithms/observables/adapters/hybrid_observables.cc +++ b/src/algorithms/observables/adapters/hybrid_observables.cc @@ -43,6 +43,7 @@ HybridObservables::HybridObservables(const ConfigurationInterface* configuration conf.observable_interval_ms = configuration->property("GNSS-SDR.observable_interval_ms", conf.observable_interval_ms); conf.enable_carrier_smoothing = configuration->property(role + ".enable_carrier_smoothing", conf.enable_carrier_smoothing); conf.always_output_gs = configuration->property("PVT.an_output_enabled", conf.always_output_gs) || configuration->property(role + ".always_output_gs", conf.always_output_gs); + conf.enable_E6 = configuration->property("PVT.use_e6_for_pvt", conf.enable_E6); if (FLAGS_carrier_smoothing_factor == DEFAULT_CARRIER_SMOOTHING_FACTOR) { diff --git a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc index 6fb36d92c..d32f0ba68 100644 --- a/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc +++ b/src/algorithms/observables/gnuradio_blocks/hybrid_observables_gs.cc @@ -93,7 +93,7 @@ hybrid_observables_gs::hybrid_observables_gs(const Obs_Conf &conf_) d_gnss_synchro_history = std::make_unique>(1000, d_nchannels_out); - d_Rx_clock_buffer.set_capacity(std::min(std::max(200U / d_T_rx_step_ms, 3U), 10U)); + d_Rx_clock_buffer.set_capacity(std::min(std::max(300U / d_T_rx_step_ms, 3U), 20U)); d_Rx_clock_buffer.clear(); d_channel_last_pll_lock = std::vector(d_nchannels_out, false); @@ -720,6 +720,13 @@ int hybrid_observables_gs::general_work(int noutput_items __attribute__((unused) // Push the valid tracking Gnss_Synchros to their corresponding deque if (in[n][m].Flag_valid_word) { + if (std::string(in[n][m].Signal, 2) == std::string("E6")) + { + if (d_conf.enable_E6 == false) + { + continue; + } + } if (d_gnss_synchro_history->size(n) > 0) { // Check if the last Gnss_Synchro comes from the same satellite as the previous ones diff --git a/src/algorithms/observables/libs/obs_conf.h b/src/algorithms/observables/libs/obs_conf.h index 22da24476..480a0d888 100644 --- a/src/algorithms/observables/libs/obs_conf.h +++ b/src/algorithms/observables/libs/obs_conf.h @@ -41,6 +41,7 @@ public: bool always_output_gs{false}; bool dump{false}; bool dump_mat{false}; + bool enable_E6{false}; }; /** \} */ 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 065838450..0caa240f0 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.cc @@ -59,26 +59,26 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con filename0_(configuration->property(role + ".filename", empty_string)), rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)), rf_gain_rx2_(configuration->property(role + ".gain_rx2", default_manual_gain_rx2)), + scale_dds_dbfs_(configuration->property(role + ".scale_dds_dbfs", -3.0)), + phase_dds_deg_(configuration->property(role + ".phase_dds_deg", 0.0)), + tx_attenuation_db_(configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db)), freq0_(configuration->property(role + ".freq", 0)), freq1_(configuration->property(role + ".freq1", static_cast(GPS_L5_FREQ_HZ))), sample_rate_(configuration->property(role + ".sampling_frequency", default_bandwidth)), bandwidth_(configuration->property(role + ".bandwidth", default_bandwidth)), samples_to_skip_(0), samples_(configuration->property(role + ".samples", static_cast(0))), + freq_dds_tx_hz_(configuration->property(role + ".freq_dds_tx_hz", uint64_t(10000))), + freq_rf_tx_hz_(configuration->property(role + ".freq_rf_tx_hz", static_cast(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_))), + 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), dma_buff_offset_pos_(0), - scale_dds_dbfs_(configuration->property(role + ".scale_dds_dbfs", -3.0)), - phase_dds_deg_(configuration->property(role + ".phase_dds_deg", 0.0)), - tx_attenuation_db_(configuration->property(role + ".tx_attenuation_db", default_tx_attenuation_db)), - freq_dds_tx_hz_(configuration->property(role + ".freq_dds_tx_hz", uint64_t(10000))), - freq_rf_tx_hz_(configuration->property(role + ".freq_rf_tx_hz", static_cast(GPS_L1_FREQ_HZ - GPS_L5_FREQ_HZ - freq_dds_tx_hz_))), - tx_bandwidth_(configuration->property(role + ".tx_bandwidth", static_cast(500000))), - item_size_(sizeof(int8_t)), in_stream_(in_stream), out_stream_(out_stream), switch_position_(configuration->property(role + ".switch_position", 0)), + item_size_(sizeof(int8_t)), enable_dds_lo_(configuration->property(role + ".enable_dds_lo", false)), filter_auto_(configuration->property(role + ".filter_auto", false)), quadrature_(configuration->property(role + ".quadrature", true)), @@ -93,11 +93,17 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con rf_shutdown_(configuration->property(role + ".rf_shutdown", FLAGS_rf_shutdown)), repeat_(configuration->property(role + ".repeat", false)) { - const int l1_band = configuration->property("Channels_1C.count", 0) + - configuration->property("Channels_1B.count", 0); - 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; + } if (freq0_ == 0) { @@ -135,8 +141,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()) { - num_freq_bands_ = 1; - if (l1_band != 0) + if (num_ch_rx1 != 0) { dma_buff_offset_pos_ = 2; } @@ -160,7 +165,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con if (find_uio_dev_file_name(device_io_name, switch_device_name, 0) < 0) { std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << switch_device_name << '\n'; - item_size_ = 0; return; } @@ -196,7 +200,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con else { std::cerr << "SignalSource: Unable to open the samples file " << filename0_.c_str() << '\n'; - item_size_ = 0; return; } std::streamsize ss = std::cout.precision(); @@ -224,7 +227,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con else { std::cerr << "SignalSource: Unable to open the samples file " << filename1_.c_str() << '\n'; - item_size_ = 0; return; } std::streamsize ss = std::cout.precision(); @@ -372,7 +374,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con catch (const std::runtime_error &e) { std::cerr << "Exception cached when configuring the RX chain: " << e.what() << '\n'; - item_size_ = 0; return; } // LOCAL OSCILLATOR DDS GENERATOR FOR DUAL FREQUENCY OPERATION @@ -407,7 +408,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con catch (const std::runtime_error &e) { std::cerr << "Exception cached when configuring the TX carrier: " << e.what() << '\n'; - item_size_ = 0; return; } } @@ -424,7 +424,6 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con if (find_uio_dev_file_name(device_io_name_buffer_monitor, buffer_monitor_device_name, 0) < 0) { std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << buffer_monitor_device_name << '\n'; - item_size_ = 0; return; } @@ -435,25 +434,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con // dynamic bits selection if (enable_dynamic_bit_selection_) { - std::string device_io_name_dyn_bit_sel_0; - std::string device_io_name_dyn_bit_sel_1; - - // find the uio device file corresponding to the dynamic bit selector 0 module. - if (find_uio_dev_file_name(device_io_name_dyn_bit_sel_0, 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'; - item_size_ = 0; - return; - } - - // find the uio device file corresponding to the dynamic bit selector 1 module. - if (find_uio_dev_file_name(device_io_name_dyn_bit_sel_1, dyn_bit_sel_device_name, 1) < 0) - { - std::cerr << "Cannot find the FPGA uio device file corresponding to device name " << dyn_bit_sel_device_name << '\n'; - item_size_ = 0; - return; - } - dynamic_bit_selection_fpga = std::make_shared(device_io_name_dyn_bit_sel_0, device_io_name_dyn_bit_sel_1); + dynamic_bit_selection_fpga = std::make_shared(num_freq_bands_); thread_dynamic_bit_selection = std::thread([&] { run_dynamic_bit_selection_process(); }); } 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 f16f6f274..a78b1aa00 100644 --- a/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h +++ b/src/algorithms/signal_source/adapters/ad9361_fpga_signal_source.h @@ -118,7 +118,6 @@ private: Concurrent_Queue *queue_; - // Front-end settings std::string gain_mode_rx1_; std::string gain_mode_rx2_; std::string rf_port_select_; @@ -130,30 +129,31 @@ private: double rf_gain_rx1_; double rf_gain_rx2_; + double scale_dds_dbfs_; + double phase_dds_deg_; + double tx_attenuation_db_; + uint64_t freq0_; // frequency of local oscillator for ADRV9361-A 0 uint64_t freq1_; // frequency of local oscillator for ADRV9361-B (if present) uint64_t sample_rate_; uint64_t bandwidth_; uint64_t samples_to_skip_; int64_t samples_; + uint64_t freq_dds_tx_hz_; + uint64_t freq_rf_tx_hz_; + uint64_t tx_bandwidth_; + float Fpass_; float Fstop_; uint32_t num_freq_bands_; uint32_t dma_buff_offset_pos_; - - // DDS configuration for LO generation for external mixer - double scale_dds_dbfs_; - double phase_dds_deg_; - double tx_attenuation_db_; - uint64_t freq_dds_tx_hz_; - uint64_t freq_rf_tx_hz_; - uint64_t tx_bandwidth_; - size_t item_size_; uint32_t in_stream_; uint32_t out_stream_; int32_t switch_position_; - bool enable_dds_lo_; + size_t item_size_; + + bool enable_dds_lo_; bool filter_auto_; bool quadrature_; bool rf_dc_; diff --git a/src/algorithms/signal_source/libs/ad936x_iio_samples.h b/src/algorithms/signal_source/libs/ad936x_iio_samples.h index 96fd9e6ae..63d30545b 100644 --- a/src/algorithms/signal_source/libs/ad936x_iio_samples.h +++ b/src/algorithms/signal_source/libs/ad936x_iio_samples.h @@ -18,7 +18,7 @@ #ifndef SRC_LIBS_ad936x_iio_samples_H_ #define SRC_LIBS_ad936x_iio_samples_H_ -#define IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES 32768 +#define IIO_DEFAULTAD936XAPIFIFOSIZE_SAMPLES 32768 * 4 #define IIO_INPUTRAMFIFOSIZE 256 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 0e7a5afca..c897e40f5 100644 --- a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.cc @@ -2,7 +2,7 @@ * \file fpga_dynamic_bit_selection.cc * \brief Dynamic Bit Selection in the received signal. * \authors
    - *
  • Marc Majoral, 2020. mmajoral(at)cttc.es + *
  • Marc Majoral, 2023. mmajoral(at)cttc.es *
* * Class that controls the Dynamic Bit Selection in the FPGA. @@ -13,58 +13,52 @@ * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * This file is part of GNSS-SDR. * - * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- */ #include "fpga_dynamic_bit_selection.h" +#include "uio_fpga.h" #include #include // for open, O_RDWR, O_SYNC #include // for cout #include // for mmap -Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(const std::string &device_name1, const std::string &device_name2) +Fpga_dynamic_bit_selection::Fpga_dynamic_bit_selection(uint32_t num_freq_bands) + : d_num_freq_bands(num_freq_bands) { - // dynamic bits selection corresponding to frequency band 1 - if ((d_device_descriptor1 = open(device_name1.c_str(), O_RDWR | O_SYNC)) == -1) + 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++) { - LOG(WARNING) << "Cannot open deviceio" << device_name1; + // 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)); + + 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 corresopnding to frequency band 1 + d_shift_out_bits[k] = shift_out_bits_default; + d_map_base[k][0] = d_shift_out_bits[k]; } - d_map_base1 = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE, - PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor1, 0)); - - if (d_map_base1 == 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"; - } - - // dynamic bits selection corresponding to frequency band 2 - if ((d_device_descriptor2 = open(device_name2.c_str(), O_RDWR | O_SYNC)) == -1) - { - LOG(WARNING) << "Cannot open deviceio" << device_name2; - } - d_map_base2 = reinterpret_cast(mmap(nullptr, FPGA_PAGE_SIZE, - PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor2, 0)); - - if (d_map_base2 == reinterpret_cast(-1)) - { - LOG(WARNING) << "Cannot map the FPGA dynamic bit selection module in frequency band 2 into tracking memory"; - std::cout << "Could not map dynamic bit selection memory corresponding to frequency band 2.\n"; - } - - // initialize default bit selection - shift_out_bits_band1 = shift_out_bits_default; - shift_out_bits_band2 = shift_out_bits_default; - - // init bit selection corresopnding to frequency band 1 - d_map_base1[0] = shift_out_bits_band1; - - // init bit selection corresponding to frequency band 2 - d_map_base2[0] = shift_out_bits_band2; - DLOG(INFO) << "Dynamic bit selection FPGA class created"; } @@ -77,65 +71,42 @@ Fpga_dynamic_bit_selection::~Fpga_dynamic_bit_selection() void Fpga_dynamic_bit_selection::bit_selection() { - // estimated signal power corresponding to frequency band 1 - uint32_t rx_signal_power1 = d_map_base1[1]; - // estimated signal power corresponding to frequency band 2 - uint32_t rx_signal_power2 = d_map_base2[1]; - - // dynamic bit selection corresponding to frequency band 1 - if (rx_signal_power1 > Power_Threshold_High) + for (uint32_t k = 0; k < d_num_freq_bands; k++) { - if (shift_out_bits_band1 < shift_out_bit_max) - { - shift_out_bits_band1 = shift_out_bits_band1 + 1; - } - } - else if (rx_signal_power1 < Power_Threshold_Low) - { - if (shift_out_bits_band1 > shift_out_bits_min) - { - shift_out_bits_band1 = shift_out_bits_band1 - 1; - } - } + // estimated signal power + uint32_t rx_signal_power = d_map_base[k][1]; - // dynamic bit selection corresponding to frequency band 2 - if (rx_signal_power2 > Power_Threshold_High) - { - if (shift_out_bits_band2 < shift_out_bit_max) + // dynamic bit selection + if (rx_signal_power > Power_Threshold_High) { - shift_out_bits_band2 = shift_out_bits_band2 + 1; + 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_power2 < Power_Threshold_Low) - { - if (shift_out_bits_band2 > shift_out_bits_min) + else if (rx_signal_power < Power_Threshold_Low) { - shift_out_bits_band2 = shift_out_bits_band2 - 1; + 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]; } - - // update bit selection corresopnding to frequency band 1 - d_map_base1[0] = shift_out_bits_band1; - - // udpate bit selection corresponding to frequency band 2 - d_map_base2[0] = shift_out_bits_band2; } void Fpga_dynamic_bit_selection::close_devices() { - auto *aux = const_cast(d_map_base1); - if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1) + for (uint32_t k = 0; k < d_num_freq_bands; k++) { - std::cout << "Failed to unmap memory uio\n"; + 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]); } - - aux = const_cast(d_map_base2); - if (munmap(static_cast(aux), FPGA_PAGE_SIZE) == -1) - { - std::cout << "Failed to unmap memory uio\n"; - } - - close(d_device_descriptor1); - close(d_device_descriptor2); } 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 500bb182e..f5454e299 100644 --- a/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h +++ b/src/algorithms/signal_source/libs/fpga_dynamic_bit_selection.h @@ -25,6 +25,7 @@ #include #include #include +#include /** \addtogroup Signal_Source * \{ */ @@ -42,7 +43,7 @@ public: /*! * \brief Constructor */ - explicit Fpga_dynamic_bit_selection(const std::string& device_name1, const std::string& device_name2); + explicit Fpga_dynamic_bit_selection(uint32_t num_freq_bands); /*! * \brief Destructor @@ -52,12 +53,12 @@ public: /*! * \brief This function configures the switch in th eFPGA */ - // void set_switch_position(int32_t switch_position); void bit_selection(void); private: + const std::string switch_device_name = std::string("AXIS_Switch_v1_0_0"); // Switch UIO device name + const std::string dyn_bit_sel_device_name = std::string("dynamic_bits_selector"); // Switch dhnamic bit selector device name static const size_t FPGA_PAGE_SIZE = 0x1000; - static const uint32_t Num_bits_ADC = 12; // Number of bits in the ADC static const uint32_t Num_bits_FPGA = 4; // Number of bits after the bit selection static const uint32_t shift_out_bits_default = Num_bits_ADC - Num_bits_FPGA; // take the most significant bits by default @@ -70,14 +71,11 @@ private: void close_devices(void); - uint32_t shift_out_bits_band1; // number of bits to shift for frequency band 1 - uint32_t shift_out_bits_band2; // number of bits to shift for frequency band 2 + std::vector d_map_base; + std::vector d_device_descriptors; + std::vector d_shift_out_bits; - volatile unsigned* d_map_base1; // driver memory map corresponding to frequency band 1 - int d_device_descriptor1; // driver descriptor corresponding to frequency band 1 - - volatile unsigned* d_map_base2; // driver memory map corresponding to frequency band 2 - int d_device_descriptor2; // driver descriptor corresponding to frequency band 2 + uint32_t d_num_freq_bands; // number of frequency bands }; diff --git a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc index 92e5e4071..cadc48503 100644 --- a/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc +++ b/src/algorithms/telemetry_decoder/adapters/galileo_e1b_telemetry_decoder.cc @@ -33,6 +33,7 @@ GalileoE1BTelemetryDecoder::GalileoE1BTelemetryDecoder( DLOG(INFO) << "role " << role; tlm_parameters_.SetFromConfiguration(configuration, role); tlm_parameters_.enable_reed_solomon = configuration->property(role + ".enable_reed_solomon", false); + tlm_parameters_.use_ced = configuration->property(role + ".use_reduced_ced", false); // make telemetry decoder object telemetry_decoder_ = galileo_make_telemetry_decoder_gs(satellite_, tlm_parameters_, 1); // unified galileo decoder set to INAV (frame_type=1) DLOG(INFO) << "telemetry_decoder(" << telemetry_decoder_->unique_id() << ")"; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc index aaa3bc8f3..9467f3994 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc @@ -105,8 +105,13 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs( d_enable_reed_solomon_inav(false), d_valid_timetag(false), d_E6_TOW_set(false), +<<<<<<< HEAD d_there_are_e1_channels(conf.there_are_e1_channels), d_there_are_e6_channels(conf.there_are_e6_channels) +======= + d_there_are_e6_channels(conf.there_are_e6_channels), + d_use_ced(conf.use_ced) +>>>>>>> 62a8547e62605a6b9fa6b1e128beceb046bde2dc { // prevent telemetry symbols accumulation in output buffers this->set_max_noutput_items(1); @@ -450,7 +455,7 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in else { // If we still do not have ephemeris, check if we have a reduced CED - if ((d_band == '1') && !d_first_eph_sent && (d_inav_nav.have_new_reduced_ced() == true)) + if ((d_band == '1') && d_use_ced && !d_first_eph_sent && (d_inav_nav.have_new_reduced_ced() == true)) { const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_reduced_ced()); std::cout << "New Galileo E1 I/NAV reduced CED message received in channel " << d_channel << " from satellite " << d_satellite << std::endl; diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h index eee7dd4b4..30564a6f8 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h @@ -153,6 +153,7 @@ private: bool d_E6_TOW_set; bool d_there_are_e1_channels; bool d_there_are_e6_channels; + bool d_use_ced; }; diff --git a/src/algorithms/telemetry_decoder/libs/tlm_conf.h b/src/algorithms/telemetry_decoder/libs/tlm_conf.h index c0e14695c..ecddac37e 100644 --- a/src/algorithms/telemetry_decoder/libs/tlm_conf.h +++ b/src/algorithms/telemetry_decoder/libs/tlm_conf.h @@ -44,6 +44,7 @@ public: bool enable_navdata_monitor{false}; bool there_are_e1_channels{false}; bool there_are_e6_channels{false}; + bool use_ced{false}; }; diff --git a/src/core/libs/gnss_sdr_fpga_sample_counter.cc b/src/core/libs/gnss_sdr_fpga_sample_counter.cc index a54fd6270..6aa5c44a8 100644 --- a/src/core/libs/gnss_sdr_fpga_sample_counter.cc +++ b/src/core/libs/gnss_sdr_fpga_sample_counter.cc @@ -279,7 +279,11 @@ void gnss_sdr_fpga_sample_counter::wait_for_interrupt() const // enable interrupts int32_t reenable = 1; - write(fd, reinterpret_cast(&reenable), sizeof(int32_t)); + const ssize_t nbytes = TEMP_FAILURE_RETRY(write(fd, reinterpret_cast(&reenable), sizeof(int32_t))); + if (nbytes != sizeof(int32_t)) + { + std::cerr << "Error re-enabling FPGA sample counter interrupt.\n"; + } // wait for interrupt nb = read(fd, &irq_count, sizeof(irq_count)); diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index 18da0e6b0..a6791fd52 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -55,6 +55,7 @@ #include // for find, min #include // for milliseconds #include // for floor, fmod, log +#include // for signal, SIGINT #include // for time_t, gmtime, strftime #include // for exception #include // for operator<< @@ -78,9 +79,17 @@ namespace wht = std; extern Concurrent_Map global_gps_acq_assist_map; extern Concurrent_Queue global_gps_acq_assist_queue; +ControlThread *ControlThread::me = nullptr; ControlThread::ControlThread() { + ControlThread::me = this; + + /* the class will handle signals */ + signal(SIGINT, ControlThread::handle_signal); + signal(SIGTERM, ControlThread::handle_signal); + signal(SIGHUP, ControlThread::handle_signal); + if (FLAGS_c == "-") { configuration_ = std::make_shared(FLAGS_config_file); @@ -266,6 +275,28 @@ ControlThread::~ControlThread() // NOLINT(modernize-use-equals-default) } +void ControlThread::handle_signal(int sig) +{ + LOG(INFO) << "GNSS-SDR received " << sig << " OS signal"; + if (sig == SIGINT || sig == SIGTERM || sig == SIGHUP) + { + ControlThread::me->control_queue_->push(pmt::make_any(command_event_make(200, 0))); + ControlThread::me->stop_ = true; + + // Reset signal handling to default behavior + if (sig == SIGINT) + { + signal(SIGINT, SIG_DFL); + } + } + else if (sig == SIGCHLD) + { + LOG(INFO) << "Received SIGCHLD signal"; + // todo + } +} + + void ControlThread::telecommand_listener() { if (telecommand_enabled_) diff --git a/src/core/receiver/control_thread.h b/src/core/receiver/control_thread.h index 12f6fbc49..b3340e94b 100644 --- a/src/core/receiver/control_thread.h +++ b/src/core/receiver/control_thread.h @@ -54,6 +54,7 @@ class ConfigurationInterface; class GNSSFlowgraph; class Gnss_Satellite; + /*! * \brief This class represents the main thread of the application, so the name is ControlThread. * This is the GNSS Receiver Control Plane: it connects the flowgraph, starts running it, @@ -63,6 +64,7 @@ class Gnss_Satellite; class ControlThread { public: + static ControlThread *me; /*! * \brief Default constructor */ @@ -122,6 +124,12 @@ public: } private: + /* + * Callback function for handling signals. + * sig identifier of signal + */ + static void handle_signal(int sig); + void init(); void apply_action(unsigned int what);