1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-13 11:40:33 +00:00

Merging next branch

This commit is contained in:
Javier Arribas 2021-06-21 17:00:27 +02:00
commit 514bb331ce
59 changed files with 1910 additions and 1689 deletions

View File

@ -30,14 +30,14 @@ stakeholders, make sure that all are listed, each with a separate
Before submitting your pull request, please make sure the following is done: Before submitting your pull request, please make sure the following is done:
1. You undertake the 1. You undertake the
[Contributor Covenant Code of Conduct](https://github.com/gnss-sdr/gnss-sdr/blob/master/CODE_OF_CONDUCT.md). [Contributor Covenant Code of Conduct](https://github.com/gnss-sdr/gnss-sdr/blob/main/CODE_OF_CONDUCT.md).
2. You have read the 2. You have read the
[Developer's Certificate of Origin](https://github.com/gnss-sdr/gnss-sdr/blob/next/.github/DCO.txt) [Developer's Certificate of Origin](https://github.com/gnss-sdr/gnss-sdr/blob/next/.github/DCO.txt)
and and
[signed your commits](https://gnss-sdr.org/docs/tutorials/using-git/#sign-your-commits) [signed your commits](https://gnss-sdr.org/docs/tutorials/using-git/#sign-your-commits)
as an indication of fulfillment. as an indication of fulfillment.
3. You have read the 3. You have read the
[Contributing Guidelines](https://github.com/gnss-sdr/gnss-sdr/blob/master/CONTRIBUTING.md). [Contributing Guidelines](https://github.com/gnss-sdr/gnss-sdr/blob/main/CONTRIBUTING.md).
4. You have read the [coding style guide](https://gnss-sdr.org/coding-style/). 4. You have read the [coding style guide](https://gnss-sdr.org/coding-style/).
Specifically, you have read Specifically, you have read
[about clang-format](https://gnss-sdr.org/coding-style/#use-tools-for-automated-code-formatting) [about clang-format](https://gnss-sdr.org/coding-style/#use-tools-for-automated-code-formatting)

View File

@ -56,7 +56,7 @@ jobs:
- name: install dependencies - name: install dependencies
run: brew update && brew install llvm pkg-config hdf5 armadillo lapack gflags glog gnuradio libmatio log4cpp pugixml protobuf && ln -s /usr/local/opt/llvm/bin/clang-tidy /usr/local/bin && ln -s /usr/local/Cellar/llvm/12.*/bin/clang-apply-replacements /usr/local/bin && cp /usr/local/Cellar/llvm/12.*/share/clang/run-clang-tidy.py /usr/local/bin && pip3 install mako run: brew update && brew install llvm pkg-config hdf5 armadillo lapack gflags glog gnuradio libmatio log4cpp pugixml protobuf && ln -s /usr/local/opt/llvm/bin/clang-tidy /usr/local/bin && ln -s /usr/local/Cellar/llvm/12.*/bin/clang-apply-replacements /usr/local/bin && cp /usr/local/Cellar/llvm/12.*/share/clang/run-clang-tidy.py /usr/local/bin && pip3 install mako
- name: Prepare run - name: Prepare run
run: cd build && cmake .. && make volk_gnsssdr_module gtest-1.10.x core_monitor pvt_libs run: cd build && cmake .. && make volk_gnsssdr_module gtest-1.11.0 core_monitor pvt_libs
- name: run clang-tidy - name: run clang-tidy
run: cd build && run-clang-tidy.py -fix run: cd build && run-clang-tidy.py -fix
- name: check - name: check

View File

@ -11,7 +11,7 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "Prevented in-tree build, it is bad practice.\nTry 'cd build && cmake ..' instead.") message(FATAL_ERROR "Prevented in-tree build, it is bad practice.\nTry 'cd build && cmake ..' instead.")
endif() endif()
cmake_minimum_required(VERSION 2.8.12...3.19) cmake_minimum_required(VERSION 2.8.12...3.20)
project(gnss-sdr CXX C) project(gnss-sdr CXX C)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
@ -40,8 +40,6 @@ option(ENABLE_RAW_UDP "Enable the use of high-optimized custom UDP packet sample
option(ENABLE_FLEXIBAND "Enable the use of the signal source adater for the Teleorbit Flexiband GNU Radio driver" OFF) option(ENABLE_FLEXIBAND "Enable the use of the signal source adater for the Teleorbit Flexiband GNU Radio driver" OFF)
option(ENABLE_GN3S "Enable the use of the GN3S dongle as signal source (experimental)" OFF)
option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal source (experimental)" OFF) option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal source (experimental)" OFF)
# Performance analysis tools # Performance analysis tools
@ -325,15 +323,19 @@ set(GNSSSDR_PROTOBUF_MIN_VERSION "3.0.0")
################################################################################ ################################################################################
set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2") set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2")
set(GNSSSDR_GLOG_LOCAL_VERSION "0.5.0") set(GNSSSDR_GLOG_LOCAL_VERSION "0.5.0")
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.4.x") set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.5.x")
set(GNSSSDR_GTEST_LOCAL_VERSION "1.10.x") if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) OR
set(GNSSSDR_GTEST_LOCAL_VERSION_POST_CMAKE_3_19 "f5e592d8ee5ffb1d9af5be7f715ce3576b8bf9c4") # Used with CMake >= 3.19 (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))
set(GNSSSDR_GTEST_LOCAL_VERSION "1.10.x")
else()
set(GNSSSDR_GTEST_LOCAL_VERSION "1.11.0")
endif()
set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master") set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master")
set(GNSSSDR_GPSTK_LOCAL_VERSION "8.0.0") set(GNSSSDR_GPSTK_LOCAL_VERSION "8.0.0")
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.21") set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.21")
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.11.4") set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.11.4")
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.16.0") set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.17.3")
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.5.3") set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.5.5")
set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7") set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7")
if(CMAKE_VERSION VERSION_LESS "3.3") if(CMAKE_VERSION VERSION_LESS "3.3")
@ -2060,6 +2062,10 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS
endif() endif()
message(STATUS " Matio v${GNSSSDR_MATIO_LOCAL_VERSION} will be downloaded, built, and statically linked automatically") message(STATUS " Matio v${GNSSSDR_MATIO_LOCAL_VERSION} will be downloaded, built, and statically linked automatically")
message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'.") message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'.")
set_package_properties(MATIO PROPERTIES
PURPOSE "Matio v${GNSSSDR_MATIO_LOCAL_VERSION} will be downloaded, built, and statically linked when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'."
)
# Find ZLIB library https://github.com/madler/zlib
find_package(ZLIB) find_package(ZLIB)
set_package_properties(ZLIB PROPERTIES set_package_properties(ZLIB PROPERTIES
URL "https://www.zlib.net/" URL "https://www.zlib.net/"
@ -2075,7 +2081,47 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS
DESCRIPTION "A Massively Spiffy Yet Delicately Unobtrusive Compression Library" DESCRIPTION "A Massively Spiffy Yet Delicately Unobtrusive Compression Library"
) )
endif() endif()
if(ZLIB_FOUND) if(NOT ZLIB_FOUND)
message(FATAL_ERROR "*** The zlib library is required to build Matio from source.")
endif()
# Find HDF5 library
find_package(HDF5)
set_package_properties(HDF5 PROPERTIES
URL "https://support.hdfgroup.org/HDF5/"
PURPOSE "Required to build Matio."
TYPE REQUIRED
)
if(HDF5_FOUND AND HDF5_VERSION)
set_package_properties(HDF5 PROPERTIES
DESCRIPTION "A versatile data model, a portable file format and a software library (found: v${HDF5_VERSION})"
)
else()
set_package_properties(HDF5 PROPERTIES
DESCRIPTION "A versatile data model, a portable file format and a software library"
)
endif()
if(NOT HDF5_FOUND)
message(STATUS " The hdf5 library has not been found in your system.")
message(STATUS " Please try to install it by doing:")
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
message(STATUS " $ sudo port install hdf5")
message(STATUS " or")
message(STATUS " $ brew install hdf5")
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU")
if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat" OR ${LINUX_DISTRIBUTION} MATCHES "CentOS")
message(STATUS " sudo yum install hdf5-devel")
elseif(${LINUX_DISTRIBUTION} MATCHES "openSUSE")
message(STATUS " sudo zypper install hdf5-devel")
else()
message(STATUS " sudo apt-get install libhdf5-dev")
endif()
endif()
message(FATAL_ERROR "*** The hdf5 library is required to build Matio from source.")
endif()
if(CMAKE_VERSION VERSION_LESS 3.7 OR "${HDF5_VERSION}" VERSION_LESS "1.8.13")
get_filename_component(ZLIB_BASE_DIR ${ZLIB_INCLUDE_DIRS} DIRECTORY) get_filename_component(ZLIB_BASE_DIR ${ZLIB_INCLUDE_DIRS} DIRECTORY)
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU") if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU")
if(NOT EXISTS "/usr/bin/libtoolize") if(NOT EXISTS "/usr/bin/libtoolize")
@ -2088,7 +2134,7 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS
else() else()
message(" sudo apt-get install libtool") message(" sudo apt-get install libtool")
endif() endif()
message(FATAL_ERROR "libtool is required to build matio from source") message(FATAL_ERROR "libtool is required to build matio from source.")
endif() endif()
if(EXISTS "/usr/bin/aclocal" OR if(EXISTS "/usr/bin/aclocal" OR
EXISTS "/usr/bin/aclocal-1.16" OR EXISTS "/usr/bin/aclocal-1.16" OR
@ -2108,9 +2154,10 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS
else() else()
message(" sudo apt-get install automake") message(" sudo apt-get install automake")
endif() endif()
message(FATAL_ERROR "aclocal is required to build matio from source") message(FATAL_ERROR "aclocal is required to build matio from source.")
endif() endif()
endif() endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
if((NOT EXISTS /usr/local/bin/glibtoolize AND NOT EXISTS /opt/local/bin/glibtoolize) OR if((NOT EXISTS /usr/local/bin/glibtoolize AND NOT EXISTS /opt/local/bin/glibtoolize) OR
(NOT EXISTS /usr/local/bin/aclocal AND NOT EXISTS /opt/local/bin/aclocal)) (NOT EXISTS /usr/local/bin/aclocal AND NOT EXISTS /opt/local/bin/aclocal))
@ -2134,101 +2181,82 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS
endif() endif()
endif() endif()
endif() endif()
find_package(HDF5)
set_package_properties(HDF5 PROPERTIES list(GET HDF5_LIBRARIES 0 HDF5_FIRST_DIR)
URL "https://support.hdfgroup.org/HDF5/" get_filename_component(HDF5_BASE_DIR2 ${HDF5_FIRST_DIR} DIRECTORY)
PURPOSE "Required to build Matio." get_filename_component(HDF5_BASE_DIR ${HDF5_BASE_DIR2} DIRECTORY)
TYPE REQUIRED if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
if(EXISTS /opt/local/include/hdf5.h)
set(HDF5_BASE_DIR /opt/local)
endif()
if(EXISTS /usr/local/include/hdf5.h)
set(HDF5_BASE_DIR /usr/local)
endif()
endif()
set(MATIO_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM})
if(MATIO_MAKE_PROGRAM MATCHES "ninja" OR CMAKE_GENERATOR STREQUAL Xcode)
find_program(MATIO_MAKE_EXECUTABLE make
PATHS
/usr/bin
/usr/local/bin
)
if(NOT MATIO_MAKE_EXECUTABLE)
message(FATAL_ERROR "make is required to build Matio from source.")
endif()
set(MATIO_MAKE_PROGRAM ${MATIO_MAKE_EXECUTABLE})
endif()
set(MATIO_STATIC_LIB ${CMAKE_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX})
ExternalProject_Add(matio-${GNSSSDR_MATIO_LOCAL_VERSION}
PREFIX ${CMAKE_BINARY_DIR}/matio
GIT_REPOSITORY https://github.com/tbeu/matio
GIT_TAG v${GNSSSDR_MATIO_LOCAL_VERSION}
SOURCE_DIR ${CMAKE_BINARY_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}
UPDATE_COMMAND ${CMAKE_BINARY_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/autogen.sh
CONFIGURE_COMMAND ${CMAKE_BINARY_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/configure --with-hdf5=${HDF5_BASE_DIR} --with-zlib=${ZLIB_BASE_DIR} --with-default-file-ver=7.3 --enable-mat73=yes --prefix=<INSTALL_DIR>
BUILD_COMMAND ${MATIO_MAKE_PROGRAM}
) )
if(HDF5_FOUND AND HDF5_VERSION) file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/matio/lib)
set_package_properties(HDF5 PROPERTIES else() # CMake >= 3.7
DESCRIPTION "A versatile data model, a portable file format and a software library (found: v${HDF5_VERSION})" include(GNUInstallDirs)
) set(MATIO_STATIC_LIB ${CMAKE_BINARY_DIR}/matio/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX})
else() if("${HDF5_VERSION}" VERSION_GREATER "1.8.18" AND "${HDF5_VERSION}" VERSION_LESS "1.10.4")
set_package_properties(HDF5 PROPERTIES # weird workaround, but it works in all tested distros (Ubuntu, Debian, Fedora, CentOS, OpenSUSE)
DESCRIPTION "A versatile data model, a portable file format and a software library" set(EXTRA_MATIO_BUILD_FLAGS -DMATIO_WITH_ZLIB=OFF -DHAVE_ZLIB=1)
)
endif() endif()
if(HDF5_FOUND) ExternalProject_Add(matio-${GNSSSDR_MATIO_LOCAL_VERSION}
list(GET HDF5_LIBRARIES 0 HDF5_FIRST_DIR) PREFIX ${CMAKE_BINARY_DIR}/matio
get_filename_component(HDF5_BASE_DIR2 ${HDF5_FIRST_DIR} DIRECTORY) GIT_REPOSITORY https://github.com/tbeu/matio
get_filename_component(HDF5_BASE_DIR ${HDF5_BASE_DIR2} DIRECTORY) GIT_TAG v${GNSSSDR_MATIO_LOCAL_VERSION}
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") SOURCE_DIR ${CMAKE_BINARY_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}
if(EXISTS /opt/local/include/hdf5.h) BINARY_DIR ${CMAKE_BINARY_DIR}/matio
set(HDF5_BASE_DIR /opt/local) CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
endif() -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
if(EXISTS /usr/local/include/hdf5.h) -DCMAKE_BUILD_TYPE=$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug>
set(HDF5_BASE_DIR /usr/local) -DMATIO_SHARED=OFF
endif() "${EXTRA_MATIO_BUILD_FLAGS}"
endif() -DHDF5_USE_STATIC_LIBRARIES=OFF
-DMATIO_DEFAULT_FILE_VERSION:STRING=7.3
set(MATIO_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM}) -DMATIO_MAT73=ON
if(MATIO_MAKE_PROGRAM MATCHES "ninja" OR CMAKE_GENERATOR STREQUAL Xcode) -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/matio
find_program(MATIO_MAKE_EXECUTABLE make BUILD_COMMAND ${CMAKE_COMMAND}
PATHS "--build" "${CMAKE_BINARY_DIR}/matio"
/usr/bin "--config" $<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug>
/usr/local/bin BUILD_BYPRODUCTS ${MATIO_STATIC_LIB}
) )
if(NOT MATIO_MAKE_EXECUTABLE) file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/matio/${CMAKE_INSTALL_LIBDIR})
message(FATAL_ERROR "make is required to build Matio from source.") endif()
endif()
set(MATIO_MAKE_PROGRAM ${MATIO_MAKE_EXECUTABLE}) if(NOT TARGET Matio::matio)
endif() file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/matio/include)
add_library(Matio::matio STATIC IMPORTED)
if(CMAKE_VERSION VERSION_LESS 3.2) add_dependencies(Matio::matio matio-${GNSSSDR_MATIO_LOCAL_VERSION})
ExternalProject_Add(matio-${GNSSSDR_MATIO_LOCAL_VERSION} set_target_properties(Matio::matio PROPERTIES
PREFIX ${CMAKE_BINARY_DIR}/matio IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
GIT_REPOSITORY https://github.com/tbeu/matio IMPORTED_LOCATION ${MATIO_STATIC_LIB}
GIT_TAG v${GNSSSDR_MATIO_LOCAL_VERSION} INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/matio/include
SOURCE_DIR ${CMAKE_BINARY_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION} INTERFACE_LINK_LIBRARIES "${MATIO_STATIC_LIB};${HDF5_LIBRARIES};${ZLIB_LIBRARIES}"
UPDATE_COMMAND ${CMAKE_BINARY_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/autogen.sh )
CONFIGURE_COMMAND ${CMAKE_BINARY_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/configure --with-hdf5=${HDF5_BASE_DIR} --with-zlib=${ZLIB_BASE_DIR} --with-default-file-ver=7.3 --enable-mat73=yes --prefix=<INSTALL_DIR>
BUILD_COMMAND ${MATIO_MAKE_PROGRAM}
)
else()
ExternalProject_Add(matio-${GNSSSDR_MATIO_LOCAL_VERSION}
PREFIX ${CMAKE_BINARY_DIR}/matio
GIT_REPOSITORY https://github.com/tbeu/matio
GIT_TAG v${GNSSSDR_MATIO_LOCAL_VERSION}
SOURCE_DIR ${CMAKE_BINARY_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}
UPDATE_COMMAND ${CMAKE_BINARY_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/autogen.sh
CONFIGURE_COMMAND ${CMAKE_BINARY_DIR}/thirdparty/matio/matio-${GNSSSDR_MATIO_LOCAL_VERSION}/configure --with-hdf5=${HDF5_BASE_DIR} --with-zlib=${ZLIB_BASE_DIR} --with-default-file-ver=7.3 --enable-mat73=yes --prefix=<INSTALL_DIR>
BUILD_COMMAND ${MATIO_MAKE_PROGRAM}
BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX}
)
endif()
set(MATIO_LOCAL TRUE)
if(NOT TARGET Matio::matio)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/matio/include)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/matio/lib)
add_library(Matio::matio STATIC IMPORTED)
add_dependencies(Matio::matio matio-${GNSSSDR_MATIO_LOCAL_VERSION})
set_target_properties(Matio::matio PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX}"
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/matio/include
INTERFACE_LINK_LIBRARIES "${CMAKE_BINARY_DIR}/matio/lib/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX};${HDF5_LIBRARIES};${ZLIB_LIBRARIES}"
)
endif()
else()
message(STATUS " The hdf5 library has not been found in your system.")
message(STATUS " Please try to install it by doing:")
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
message(STATUS " $ sudo port install hdf5")
message(STATUS " or")
message(STATUS " $ brew install hdf5")
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU")
message(STATUS " $ sudo apt-get install libhdf5-dev")
endif()
message(FATAL_ERROR "*** The hdf5 library is required to build gnss-sdr")
endif()
else()
message(FATAL_ERROR "*** The zlib library is required to build gnss-sdr")
endif() endif()
set_package_properties(MATIO PROPERTIES
PURPOSE "Matio v${GNSSSDR_MATIO_LOCAL_VERSION} will be downloaded, built, and statically linked when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'."
)
endif() endif()
@ -3031,32 +3059,6 @@ if(ENABLE_FLEXIBAND)
endif() endif()
######################
# GN3S - OPTIONAL
######################
if(DEFINED ENV{GN3S_DRIVER})
message(STATUS "GN3S_DRIVER environment variable found.")
set(ENABLE_GN3S ON)
endif()
if(GN3S_DRIVER)
set(ENABLE_GN3S ON)
endif()
find_package(GRGN3S QUIET)
set_package_properties(GRGN3S PROPERTIES
URL "https://github.com/gnss-sdr/gr-gn3s"
DESCRIPTION "The GN3S v2 front-end GNU Radio block."
PURPOSE "Used for communication with the GN3S v2 front-end."
TYPE OPTIONAL
)
if(ENABLE_GN3S)
message(STATUS "The GN3S driver will be compiled.")
message(STATUS " You can disable it with 'cmake -DENABLE_GN3S=OFF ..'")
else()
message(STATUS "The (optional and experimental) GN3S driver is not enabled.")
message(STATUS " Enable it with 'cmake -DENABLE_GN3S=ON ..' to add support for the GN3S dongle.")
endif()
####################################################### #######################################################
# CTTC's digital array beamformer prototype - OPTIONAL # CTTC's digital array beamformer prototype - OPTIONAL
####################################################### #######################################################
@ -3265,7 +3267,6 @@ add_feature_info(ENABLE_PLUTOSDR ENABLE_PLUTOSDR "Enables Plutosdr_Signal_Source
add_feature_info(ENABLE_AD9361 ENABLE_AD9361 "Enables Ad9361_Fpga_Signal_Source for devices with the AD9361 chipset. Requires libiio and libad9361-dev.") add_feature_info(ENABLE_AD9361 ENABLE_AD9361 "Enables Ad9361_Fpga_Signal_Source for devices with the AD9361 chipset. Requires libiio and libad9361-dev.")
add_feature_info(ENABLE_RAW_UDP ENABLE_RAW_UDP "Enables Custom_UDP_Signal_Source for custom UDP packet sample source. Requires libpcap.") add_feature_info(ENABLE_RAW_UDP ENABLE_RAW_UDP "Enables Custom_UDP_Signal_Source for custom UDP packet sample source. Requires libpcap.")
add_feature_info(ENABLE_FLEXIBAND ENABLE_FLEXIBAND "Enables Flexiband_Signal_Source for using Teleorbit's Flexiband RF front-end. Requires gr-teleorbit.") add_feature_info(ENABLE_FLEXIBAND ENABLE_FLEXIBAND "Enables Flexiband_Signal_Source for using Teleorbit's Flexiband RF front-end. Requires gr-teleorbit.")
add_feature_info(ENABLE_GN3S ENABLE_GN3S "Enables Gn3s_Signal_Source for using the GN3S v2 dongle. Requires gr-gn3s.")
add_feature_info(ENABLE_ARRAY ENABLE_ARRAY "Enables Raw_Array_Signal_Source and Array_Signal_Conditioner for using CTTC's antenna array. Requires gr-dbfcttc.") add_feature_info(ENABLE_ARRAY ENABLE_ARRAY "Enables Raw_Array_Signal_Source and Array_Signal_Conditioner for using CTTC's antenna array. Requires gr-dbfcttc.")
add_feature_info(ENABLE_GPERFTOOLS ENABLE_GPERFTOOLS "Enables performance analysis. Requires Gperftools.") add_feature_info(ENABLE_GPERFTOOLS ENABLE_GPERFTOOLS "Enables performance analysis. Requires Gperftools.")
add_feature_info(ENABLE_GPROF ENABLE_GPROF "Enables performance analysis with 'gprof'.") add_feature_info(ENABLE_GPROF ENABLE_GPROF "Enables performance analysis with 'gprof'.")

359
README.md
View File

@ -18,7 +18,7 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
This program is a software-defined receiver which is able to process (that is, This program is a software-defined receiver which is able to process (that is,
to perform detection, synchronization, demodulation and decoding of the to perform detection, synchronization, demodulation and decoding of the
navigation message, computation of observables and, finally, computation of navigation message, computation of observables, and, finally, computation of
position fixes) the following Global Navigation Satellite System's signals: position fixes) the following Global Navigation Satellite System's signals:
In the L1 band: In the L1 band:
@ -44,7 +44,70 @@ raw sample file formats, generates processing outputs in standard formats,
allows for the full inspection of the whole signal processing chain, and offers allows for the full inspection of the whole signal processing chain, and offers
a framework for the development of new features. Please visit a framework for the development of new features. Please visit
[https://gnss-sdr.org](https://gnss-sdr.org "GNSS-SDR website") for more [https://gnss-sdr.org](https://gnss-sdr.org "GNSS-SDR website") for more
information about this open source software-defined GNSS receiver. information about this open-source, software-defined GNSS receiver.
:sparkles: See what's new in the [changelog](./docs/CHANGELOG.md).
# Table of Contents
<details>
<summary><b>(click to expand)</b></summary>
<!-- MarkdownTOC -->
1. [How to build GNSS-SDR](#how-to-build-gnss-sdr)
1. [GNU/Linux](#gnulinux)
1. [Alternative 1: Install dependencies using software packages](#alternative-1-install-dependencies-using-software-packages)
- [Debian / Ubuntu](#debian--ubuntu)
- [Arch Linux](#arch-linux)
- [CentOS](#centos)
- [Fedora](#fedora)
- [OpenSUSE](#opensuse)
1. [Alternative 2: Install dependencies using PyBOMBS](#alternative-2-install-dependencies-using-pybombs)
- [Manual installation of other required dependencies](#manual-installation-of-other-required-dependencies)
- [Armadillo](#install-armadillo-a-c-linear-algebra-library)
- [gflags](#install-gflags-a-commandline-flags-processing-module-for-c)
- [google-glog](#install-glog-a-library-that-implements-application-level-logging)
- [googletest](#download-the-google-c-testing-framework-also-known-as-google-test)
- [GnuTLS or OpenSSL](#install-the-gnutls-or-openssl-libraries)
- [matio](#install-matio-matlab-mat-file-io-library)
- [Protocol Buffers](#install-protocol-buffers-a-portable-mechanism-for-serialization-of-structured-data)
- [pugixml](#install-pugixml-a-light-weight-c-xml-processing-library)
1. [Clone GNSS-SDR's Git repository](#clone-gnss-sdrs-git-repository)
1. [Build and install GNSS-SDR](#build-and-install-gnss-sdr)
- [Build OsmoSDR support (optional)](#build-osmosdr-support-optional)
- [Build IIO support (optional)](#build-fmcomms2-based-sdr-hardware-support-optional)
- [Build OpenCL support (optional)](#build-opencl-support-optional)
- [Build CUDA support (optional)](#build-cuda-support-optional)
- [Build a portable binary](#build-a-portable-binary)
1. [macOS](#macos)
1. [Macports](#macports)
1. [Homebrew](#homebrew)
1. [Build GNSS-SDR](#build-gnss-sdr)
1. [Other builds](#other-builds)
1. [Updating GNSS-SDR](#updating-gnss-sdr)
1. [Getting started](#getting-started)
1. [Using GNSS-SDR](#using-gnss-sdr)
1. [Control Plane](#control-plane)
1. [Configuration](#configuration)
1. [GNSS block factory](#gnss-block-factory)
1. [Signal Processing Plane](#signal-processing-plane)
1. [Signal Source](#signal-source)
1. [Signal Conditioner](#signal-conditioner)
- [Data type adapter](#data-type-adapter)
- [Input filter](#input-filter)
- [Resampler](#resampler)
1. [Channel](#channel)
- [Acquisition](#acquisition)
- [Tracking](#tracking)
- [Decoding of the navigation message](#decoding-of-the-navigation-message)
1. [Observables](#observables)
1. [Computation of Position, Velocity and Time](#computation-of-position-velocity-and-time)
1. [About the software license](#about-the-software-license)
1. [Publications and Credits](#publications-and-credits)
1. [Ok, now what?](#ok-now-what)
<!-- /MarkdownTOC -->
</details>
# How to build GNSS-SDR # How to build GNSS-SDR
@ -59,7 +122,7 @@ This section describes how to set up the compilation environment in GNU/Linux or
- Supported microprocessor architectures: - Supported microprocessor architectures:
- i386: Intel x86 instruction set (32-bit microprocessors). - i386: Intel x86 instruction set (32-bit microprocessors).
- amd64: also known as x86-64, the 64-bit version of the x86 instruction set, - amd64: also known as x86-64, the 64-bit version of the x86 instruction set,
originally created by AMD and implemented by AMD, Intel, VIA and others. originally created by AMD and implemented by AMD, Intel, VIA, and others.
- armel: ARM embedded ABI, supported on ARM v4t and higher. - armel: ARM embedded ABI, supported on ARM v4t and higher.
- armhf: ARM hard float, ARMv7 + VFP3-D16 floating-point hardware extension + - armhf: ARM hard float, ARMv7 + VFP3-D16 floating-point hardware extension +
Thumb-2 instruction set and above. Thumb-2 instruction set and above.
@ -68,7 +131,7 @@ This section describes how to set up the compilation environment in GNU/Linux or
- mipsel: MIPS architecture (little-endian, such as Loongson 3). - mipsel: MIPS architecture (little-endian, such as Loongson 3).
- mips64el: 64-bit version of MIPS architecture. - mips64el: 64-bit version of MIPS architecture.
- powerpc: the RISC 32-bit microprocessor architecture developed by IBM, - powerpc: the RISC 32-bit microprocessor architecture developed by IBM,
Motorola (now Freescale) and Apple. Motorola (now Freescale), and Apple.
- ppc64: 64-bit big-endian PowerPC architecture. - ppc64: 64-bit big-endian PowerPC architecture.
- ppc64el: 64-bit little-endian PowerPC architecture. - ppc64el: 64-bit little-endian PowerPC architecture.
- s390x: IBM System z architecture for mainframe computers. - s390x: IBM System z architecture for mainframe computers.
@ -82,7 +145,7 @@ the source code. It is in general not a good idea to mix both approaches.
### Alternative 1: Install dependencies using software packages ### Alternative 1: Install dependencies using software packages
If you want to start building and running GNSS-SDR as quick and easy as If you want to start building and running GNSS-SDR as quickly and easily as
possible, the best option is to install all the required dependencies as binary possible, the best option is to install all the required dependencies as binary
packages. packages.
@ -108,7 +171,7 @@ above).
**Note for Ubuntu 14.04 LTS "trusty" users:** you will need to build from source **Note for Ubuntu 14.04 LTS "trusty" users:** you will need to build from source
and install GNU Radio manually, as explained below, since GNSS-SDR requires and install GNU Radio manually, as explained below, since GNSS-SDR requires
`gnuradio-dev` >= 3.7.3, and Ubuntu 14.04 came with 3.7.2. Install all the `gnuradio-dev` >= 3.7.3, and Ubuntu 14.04 came with 3.7.2. Install all the
packages above BUT EXCEPT `libuhd-dev`, `gnuradio-dev` and `gr-osmosdr` (and packages above BUT EXCEPT `libuhd-dev`, `gnuradio-dev`, and `gr-osmosdr` (and
remove them if they are already installed in your machine), and install those remove them if they are already installed in your machine), and install those
dependencies using PyBOMBS. The same applies to `libmatio-dev`: Ubuntu 14.04 dependencies using PyBOMBS. The same applies to `libmatio-dev`: Ubuntu 14.04
came with 1.5.2 and the minimum required version is 1.5.3. Please do not install came with 1.5.2 and the minimum required version is 1.5.3. Please do not install
@ -205,9 +268,9 @@ Once you have installed these packages, you can jump directly to
### Alternative 2: Install dependencies using PyBOMBS ### Alternative 2: Install dependencies using PyBOMBS
This option is adequate if you are interested in development, in working with This option is adequate if you are interested in development, in working with
the most recent versions of software dependencies, want more fine tuning on the the most recent versions of software dependencies, want more fine-tuning on the
installed versions, or simply in building everything from the scratch just for installed versions, or simply in building everything from the scratch just for
the fun of it. In such cases, we recommend to use the fun of it. In such cases, we recommend using
[PyBOMBS](https://github.com/gnuradio/pybombs "Python Build Overlay Managed Bundle System") [PyBOMBS](https://github.com/gnuradio/pybombs "Python Build Overlay Managed Bundle System")
(Python Build Overlay Managed Bundle System), GNU Radio's meta-package manager (Python Build Overlay Managed Bundle System), GNU Radio's meta-package manager
tool that installs software from source, or whatever the local package manager tool that installs software from source, or whatever the local package manager
@ -240,7 +303,7 @@ Add list of default recipes:
$ pybombs recipes add-defaults $ pybombs recipes add-defaults
``` ```
Download, build and install GNU Radio, related drivers and some other extra Download, build and install GNU Radio, related drivers, and some other extra
modules into the directory `/path/to/prefix` (replace this path by your modules into the directory `/path/to/prefix` (replace this path by your
preferred one, for instance `$HOME/sdr`): preferred one, for instance `$HOME/sdr`):
@ -267,17 +330,17 @@ $ pybombs install gnss-sdr
``` ```
By default, PyBOMBS installs the next branch of GNSS-SDR development, which is By default, PyBOMBS installs the next branch of GNSS-SDR development, which is
the most recent version of the source code. This behaviour can be modified by the most recent version of the source code. This behavior can be modified by
altering the corresponding recipe at altering the corresponding recipe at
`$HOME/.pybombs/recipes/gr-recipes/gnss-sdr.lwr` `$HOME/.pybombs/recipes/gr-recipes/gnss-sdr.lwr`
In case you do not want to use PyBOMBS and prefer to build and install GNSS-SDR In case you do not want to use PyBOMBS and prefer to build and install GNSS-SDR
step by step (i.e., cloning the repository and doing the usual step by step (i.e., cloning the repository and doing the usual
`cmake .. && make && make install` dance), Armadillo, GFlags, Glog and GnuTLS `cmake .. && make && make install` dance), Armadillo, GFlags, Glog, GnuTLS, and
can be installed either by using PyBOMBS: Matio can be installed either by using PyBOMBS:
``` ```
$ pybombs install armadillo gflags glog gnutls $ pybombs install armadillo gflags glog gnutls matio
``` ```
or manually as explained below, and then please follow instructions on how to or manually as explained below, and then please follow instructions on how to
@ -292,9 +355,9 @@ $ sudo apt-get install libblas-dev liblapack-dev # For Debian/Ubuntu/Linux
$ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL $ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL
$ sudo zypper install lapack-devel blas-devel # For OpenSUSE $ sudo zypper install lapack-devel blas-devel # For OpenSUSE
$ sudo pacman -S blas lapack # For Arch Linux $ sudo pacman -S blas lapack # For Arch Linux
$ wget http://sourceforge.net/projects/arma/files/armadillo-10.4.0.tar.xz $ wget http://sourceforge.net/projects/arma/files/armadillo-10.5.0.tar.xz
$ tar xvfz armadillo-10.4.0.tar.xz $ tar xvfz armadillo-10.5.0.tar.xz
$ cd armadillo-10.4.0 $ cd armadillo-10.5.0
$ cmake . $ cmake .
$ make $ make
$ sudo make install $ sudo make install
@ -304,8 +367,8 @@ The full stop separated from `cmake` by a space is important.
[CMake](https://cmake.org/ "CMake's Homepage") will figure out what other [CMake](https://cmake.org/ "CMake's Homepage") will figure out what other
libraries are currently installed and will modify Armadillo's configuration libraries are currently installed and will modify Armadillo's configuration
correspondingly. CMake will also generate a run-time armadillo library, which is correspondingly. CMake will also generate a run-time armadillo library, which is
a combined alias for all the relevant libraries present on your system (eg. a combined alias for all the relevant libraries present on your system (e.g.,
BLAS, LAPACK and ATLAS). BLAS, LAPACK, and ATLAS).
#### Install [Gflags](https://github.com/gflags/gflags "Gflags' Homepage"), a commandline flags processing module for C++: #### Install [Gflags](https://github.com/gflags/gflags "Gflags' Homepage"), a commandline flags processing module for C++:
@ -335,13 +398,13 @@ $ sudo ldconfig
#### Download the [Google C++ Testing Framework](https://github.com/google/googletest "Googletest Homepage"), also known as Google Test: #### Download the [Google C++ Testing Framework](https://github.com/google/googletest "Googletest Homepage"), also known as Google Test:
``` ```
$ wget https://github.com/google/googletest/archive/v1.10.x.zip $ wget https://github.com/google/googletest/archive/release-1.11.0.zip
$ unzip v1.10.x.zip $ unzip release-1.11.0.zip
``` ```
Please **DO NOT build or install** Google Test. Every user needs to compile Please **DO NOT build or install** Google Test. Every user needs to compile
tests using the same compiler flags used to compile the Google Test libraries; tests using the same compiler flags used to compile the Google Test libraries;
otherwise he or she may run into undefined behaviors (_i.e._, the tests can otherwise, he or she may run into undefined behaviors (_i.e._, the tests can
behave strangely and may even crash for no obvious reasons). The explanation is behave strangely and may even crash for no obvious reasons). The explanation is
that C++ has the One-Definition Rule: if two C++ source files contain different that C++ has the One-Definition Rule: if two C++ source files contain different
definitions of the same class/function/variable, and you link them together, you definitions of the same class/function/variable, and you link them together, you
@ -360,10 +423,10 @@ downloaded resides. Just type in your terminal (or add it to your
`$HOME/.bashrc` file for a permanent solution) the following line: `$HOME/.bashrc` file for a permanent solution) the following line:
``` ```
export GTEST_DIR=/home/username/googletest-1.10.x export GTEST_DIR=/home/username/googletest-release-1.11.0
``` ```
changing `/home/username/googletest-1.10.x` by the actual path where you changing `/home/username/googletest-release-1.11.0` by the actual path where you
unpacked Google Test. If the CMake script does not find that folder, or the unpacked Google Test. If the CMake script does not find that folder, or the
environment variable is not defined, or the source code is not installed by a environment variable is not defined, or the source code is not installed by a
package, then it will download a fresh copy of the Google Test source code and package, then it will download a fresh copy of the Google Test source code and
@ -381,6 +444,18 @@ $ sudo pacman -S openssl # For Arch Linux
In case the GnuTLS library with openssl extensions package is not available in In case the GnuTLS library with openssl extensions package is not available in
your GNU/Linux distribution, GNSS-SDR can also work well with OpenSSL. your GNU/Linux distribution, GNSS-SDR can also work well with OpenSSL.
#### Install [Matio](https://github.com/tbeu/matio "Matio's Homepage"), MATLAB MAT file I/O library:
```
$ wget https://github.com/tbeu/matio/releases/download/v1.5.21/matio-1.5.21.tar.gz
$ tar xvfz matio-1.5.21.tar.gz
$ cd matio-1.5.21
$ ./configure
$ make
$ sudo make install
$ sudo ldconfig
```
#### Install [Protocol Buffers](https://developers.google.com/protocol-buffers/ "Protocol Buffers' Homepage"), a portable mechanism for serialization of structured data: #### Install [Protocol Buffers](https://developers.google.com/protocol-buffers/ "Protocol Buffers' Homepage"), a portable mechanism for serialization of structured data:
GNSS-SDR requires Protocol Buffers v3.0.0 or later. If the packages that come GNSS-SDR requires Protocol Buffers v3.0.0 or later. If the packages that come
@ -395,9 +470,9 @@ $ sudo apt-get install autoconf automake libtool curl make g++ unzip
and then: and then:
``` ```
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.16.0/protobuf-cpp-3.16.0.tar.gz $ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-cpp-3.17.3.tar.gz
$ tar xvfz protobuf-cpp-3.16.0.tar.gz $ tar xvfz protobuf-cpp-3.17.3.tar.gz
$ cd protobuf-3.16.0 $ cd protobuf-3.17.3
$ ./autogen.sh $ ./autogen.sh
$ ./configure $ ./configure
$ make $ make
@ -405,6 +480,19 @@ $ sudo make install
$ sudo ldconfig $ sudo ldconfig
``` ```
#### Install [Pugixml](https://pugixml.org/ "Pugixml's Homepage"), a light-weight C++ XML processing library:
```
$ wget https://github.com/zeux/pugixml/releases/download/v1.11.4/pugixml-1.11.4.tar.gz
$ tar xvfz pugixml-1.11.4.tar.gz
$ cd pugixml-1.11.4
$ mkdir build && cd build
$ cmake ..
$ make
$ sudo make install
$ sudo ldconfig
```
### <a name="download-and-build-linux">Clone GNSS-SDR's Git repository</a>: ### <a name="download-and-build-linux">Clone GNSS-SDR's Git repository</a>:
``` ```
@ -430,7 +518,7 @@ gnss-sdr with the following structure:
|-----utils <- some utilities (e.g. Matlab scripts). |-----utils <- some utilities (e.g. Matlab scripts).
``` ```
By default, you will be in the 'master' branch of the Git repository, which By default, you will be in the 'main' branch of the Git repository, which
corresponds to the latest stable release. If you want to try the latest corresponds to the latest stable release. If you want to try the latest
developments, you can use the 'next' branch by going to the newly created developments, you can use the 'next' branch by going to the newly created
gnss-sdr folder doing: gnss-sdr folder doing:
@ -460,7 +548,7 @@ $ make
By default, CMake will build the Release version, meaning that the compiler will By default, CMake will build the Release version, meaning that the compiler will
generate a fast, optimized executable. This is the recommended build type when generate a fast, optimized executable. This is the recommended build type when
using an RF front-end and you need to attain real time. If working with a file using an RF front-end and you need to attain real-time. If working with a file
(and thus without real-time constraints), you may want to obtain more (and thus without real-time constraints), you may want to obtain more
information about the internals of the receiver, as well as more fine-grained information about the internals of the receiver, as well as more fine-grained
logging. This can be done by building the Debug version, by doing: logging. This can be done by building the Debug version, by doing:
@ -480,9 +568,9 @@ $ sudo make install
``` ```
This will also make a copy of the conf/ folder into This will also make a copy of the conf/ folder into
/usr/local/share/gnss-sdr/conf for your reference. We suggest to create a /usr/local/share/gnss-sdr/conf for your reference. We suggest creating a working
working directory at your preferred location and store your own configuration directory at your preferred location and store your own configuration and data
and data files there. files there.
You could be interested in creating the documentation (requires: You could be interested in creating the documentation (requires:
`sudo apt-get install doxygen-latex` in Ubuntu/Debian) by doing: `sudo apt-get install doxygen-latex` in Ubuntu/Debian) by doing:
@ -505,10 +593,10 @@ will create a PDF manual at build/docs/GNSS-SDR_manual.pdf. Finally,
$ make doc-clean $ make doc-clean
``` ```
will remove the content of previously-generated documentation. will remove the content of previously generated documentation.
GNSS-SDR comes with a library which is a module of the Vector-Optimized Library GNSS-SDR comes with a library which is a module of the Vector-Optimized Library
of Kernels (so called of Kernels (so-called
[VOLK_GNSSSDR](./src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md)) [VOLK_GNSSSDR](./src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md))
and a profiler that will build a config file for the best SIMD architecture for and a profiler that will build a config file for the best SIMD architecture for
your processor. Run `volk_gnsssdr_profile` that is installed into `$PREFIX/bin`. your processor. Run `volk_gnsssdr_profile` that is installed into `$PREFIX/bin`.
@ -544,40 +632,6 @@ and then import the created project into Eclipse:
After building the project, you will find the generated binaries at After building the project, you will find the generated binaries at
`eclipse/install`. `eclipse/install`.
###### Build GN3S V2 Custom firmware and driver (OPTIONAL):
Install the GNU Radio module:
```
$ git clone https://github.com/gnss-sdr/gr-gn3s
$ cd gr-gn3s/build
$ cmake ..
$ make
$ sudo make install
$ sudo ldconfig
```
Then configure GNSS-SDR to build the `GN3S_Signal_Source` by:
```
$ cd gnss-sdr/build
$ cmake -DENABLE_GN3S=ON ..
$ make
$ sudo make install
```
In order to gain access to USB ports, gnss-sdr should be used as root. In
addition, the driver requires access to the GN3S firmware binary file. It should
be available in the same path where the application is called. GNSS-SDR comes
with a pre-compiled custom GN3S firmware available at
gr-gn3s/firmware/GN3S_v2/bin/gn3s_firmware.ihx. Please copy this file to the
application path.
(in order to disable the `GN3S_Signal_Source` compilation, you can pass
`-DENABLE_GN3S=OFF` to cmake and build GNSS-SDR again).
More info at https://github.com/gnss-sdr/gr-gn3s
###### Build OSMOSDR support (OPTIONAL): ###### Build OSMOSDR support (OPTIONAL):
Install the [OsmoSDR](https://osmocom.org/projects/sdr "OsmoSDR's Homepage") Install the [OsmoSDR](https://osmocom.org/projects/sdr "OsmoSDR's Homepage")
@ -834,7 +888,7 @@ $ open ./docs/html/index.html
``` ```
GNSS-SDR comes with a library which is a module of the Vector-Optimized Library GNSS-SDR comes with a library which is a module of the Vector-Optimized Library
of Kernels (so called of Kernels (so-called
[VOLK_GNSSSDR](./src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md)) [VOLK_GNSSSDR](./src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md))
and a profiler that will build a config file for the best SIMD architecture for and a profiler that will build a config file for the best SIMD architecture for
your processor. Run `volk_gnsssdr_profile` that is installed into `$PREFIX/bin`. your processor. Run `volk_gnsssdr_profile` that is installed into `$PREFIX/bin`.
@ -914,8 +968,8 @@ $ git remote add upstream https://github.com/gnss-sdr/gnss-sdr.git
and then you can update your working copy by doing: and then you can update your working copy by doing:
``` ```
$ git checkout master # Switch to branch you want to update $ git checkout main # Switch to branch you want to update
$ git pull upstream master # Download the newest code from our repository $ git pull upstream main # Download the newest code from our repository
``` ```
or, if you want to test the latest developments: or, if you want to test the latest developments:
@ -951,24 +1005,24 @@ Git commands `fetch` and `merge`, as described in our
The signal file can be easily recorded using the GNU Radio file sink in The signal file can be easily recorded using the GNU Radio file sink in
`gr_complex<float>` mode. 2. You will need a GPS active antenna, a `gr_complex<float>` mode. 2. You will need a GPS active antenna, a
[USRP](https://www.ettus.com/products/) and a suitable USRP daughter board to [USRP](https://www.ettus.com/products/) and a suitable USRP daughter board to
receive GPS L1 C/A signals. GNSS-SDR require to have at least 2 MHz of receive GPS L1 C/A signals. GNSS-SDR requires to have at least 2 MHz of
bandwidth in 1.57542 GHz. (remember to enable the DC bias with the daughter bandwidth in 1.57542 GHz. (remember to enable the DC bias with the
board jumper). We use a [DBSRX2](https://www.ettus.com/all-products/DBSRX2/) daughterboard jumper). We use a
to do the task, but you can try the newer Ettus' daughter boards as well. 3. [DBSRX2](https://www.ettus.com/all-products/DBSRX2/) to do the task, but you
The easiest way to capture a signal file is to use the GNU Radio Companion can try the newer Ettus' daughter boards as well. 3. The easiest way to
GUI. Only two blocks are needed: a USRP signal source connected to complex capture a signal file is to use the GNU Radio Companion GUI. Only two blocks
float file sink. You need to tune the USRP central frequency and decimation are needed: a USRP signal source connected to a complex float file sink. You
factor using USRP signal source properties box. We suggest using a decimation need to tune the USRP central frequency and decimation factor using the USRP
factor of 20 if you use the USRP2. This will give you 100/20 = 5 MSPS which signal source properties box. We suggest using a decimation factor of 20 if
will be enough to receive GPS L1 C/A signals. The front-end gain should also you use the USRP2. This will give you 100/20 = 5 MSPS which will be enough to
be configured. In our test with the DBSRX2 we obtained good results with receive GPS L1 C/A signals. The front-end gain should also be configured. In
`G=50`. 4. Capture at least 80 seconds of signal in open sky conditions. our test with the DBSRX2 we obtained good results with `G=50`. 4. Capture at
During the process, be aware of USRP driver buffer underruns messages. If least 80 seconds of signal in open sky conditions. During the process, be
your hard disk is not fast enough to write data at this speed you can capture aware of USRP driver buffer underruns messages. If your hard disk is not fast
to a virtual RAM drive. 80 seconds of signal at 5 MSPS occupies less than 3 enough to write data at this speed you can capture it to a virtual RAM drive.
Gbytes using `gr_complex<float>`. 5. If you have no access to an RF 80 seconds of signal at 5 MSPS occupies less than 3 Gbytes using
front-end, you can download a sample raw data file (that contains GPS and `gr_complex<float>`. If you have no access to an RF front-end, you can
Galileo signals) from download a sample raw data file (that contains GPS and Galileo signals) from
[here](https://sourceforge.net/projects/gnss-sdr/files/data/). [here](https://sourceforge.net/projects/gnss-sdr/files/data/).
3. You are ready to configure the receiver to use your captured file among other 3. You are ready to configure the receiver to use your captured file among other
parameters: parameters:
@ -1035,29 +1089,29 @@ file.
GNSS-SDR's main method initializes the logging library, processes the command GNSS-SDR's main method initializes the logging library, processes the command
line flags, if any, provided by the user and instantiates a line flags, if any, provided by the user and instantiates a
[ControlThread](./src/core/receiver/control_thread.h) object. Its constructor [ControlThread](./src/core/receiver/control_thread.h) object. Its constructor
reads the configuration file, creates a control queue and creates a flowgraph reads the configuration file, creates a control queue, and creates a flowgraph
according to the configuration. Then, the program's main method calls the run() according to the configuration. Then, the program's main method calls the run()
method of the instantiated object, an action that connects the flowgraph and method of the instantiated object, an action that connects the flowgraph and
starts running it. After that, and until a stop message is received, it reads starts running it. After that, and until a stop message is received, it reads
control messages sent by the receiver's modules through a safe-thread queue and control messages sent by the receiver's modules through a safe-thread queue and
processes them. Finally, when a stop message is received, the main method processes them. Finally, when a stop message is received, the main method
executes the destructor of the ControlThread object, which deallocates memory, executes the destructor of the ControlThread object, which deallocates memory,
does other cleanup and exits the program. does other cleanup, and exits the program.
The [GNSSFlowgraph](./src/core/receiver/gnss_flowgraph.h) class is responsible The [GNSSFlowgraph](./src/core/receiver/gnss_flowgraph.h) class is responsible
for preparing the graph of blocks according to the configuration, running it, for preparing the graph of blocks according to the configuration, running it,
modifying it during run-time and stopping it. Blocks are identified by its role. modifying it during run-time, and stopping it. Blocks are identified by their
This class knows which roles it has to instantiate and how to connect them. It role. This class knows which roles it has to instantiate and how to connect
relies on the configuration to get the correct instances of the roles it needs them. It relies on the configuration to get the correct instances of the roles
and then it applies the connections between GNU Radio blocks to make the graph it needs and then it applies the connections between GNU Radio blocks to make
ready to be started. The complexity related to managing the blocks and the data the graph ready to be started. The complexity related to managing the blocks and
stream is handled by GNU Radio's `gr::top_block` class. GNSSFlowgraph wraps the the data stream is handled by GNU Radio's `gr::top_block` class. GNSSFlowgraph
`gr::top_block` instance so we can take advantage of the `gnss_block_factory` wraps the `gr::top_block` instance so we can take advantage of the
(see below), the configuration system and the processing blocks. This class is `gnss_block_factory` (see below), the configuration system, and the processing
also responsible for applying changes to the configuration of the flowgraph blocks. This class is also responsible for applying changes to the configuration
during run-time, dynamically reconfiguring channels: it selects the strategy for of the flowgraph during run-time, dynamically reconfiguring channels: it selects
selecting satellites. This can range from a sequential search over all the the strategy for selecting satellites. This can range from a sequential search
satellites' ID to other more efficient approaches. over all the satellites' ID to other more efficient approaches.
The Control Plane is in charge of creating a flowgraph according to the The Control Plane is in charge of creating a flowgraph according to the
configuration and then managing the modules. Configuration allows users to configuration and then managing the modules. Configuration allows users to
@ -1066,7 +1120,7 @@ define in an easy way their own custom receiver by specifying the flowgraph
channel and each module, strategies for satellite selection, type of output channel and each module, strategies for satellite selection, type of output
format, etc.). Since it is difficult to foresee what future module format, etc.). Since it is difficult to foresee what future module
implementations will be needed in terms of configuration, we used a very simple implementations will be needed in terms of configuration, we used a very simple
approach that can be extended without a major impact in the code. This can be approach that can be extended without a major impact on the code. This can be
achieved by simply mapping the names of the variables in the modules with the achieved by simply mapping the names of the variables in the modules with the
names of the parameters in the configuration. names of the parameters in the configuration.
@ -1122,7 +1176,7 @@ encapsulates the complexity of blocks' instantiation. With that approach, adding
a new block that requires new parameters will be as simple as adding the block a new block that requires new parameters will be as simple as adding the block
class and modifying the factory to be able to instantiate it. This loose class and modifying the factory to be able to instantiate it. This loose
coupling between the blocks' implementations and the syntax of the configuration coupling between the blocks' implementations and the syntax of the configuration
enables extending the application capacities in a high degree. It also allows enables extending the application capacities to a high degree. It also allows
producing fully customized receivers, for instance a testbed for acquisition producing fully customized receivers, for instance a testbed for acquisition
algorithms, and to place observers at any point of the receiver chain. algorithms, and to place observers at any point of the receiver chain.
@ -1154,16 +1208,16 @@ are required to be implemented by a derived class.
Subclassing GNSSBlockInterface, we defined interfaces for the GNSS receiver Subclassing GNSSBlockInterface, we defined interfaces for the GNSS receiver
blocks depicted in the figure above. This hierarchy provides the definition of blocks depicted in the figure above. This hierarchy provides the definition of
different algorithms and different implementations, which will be instantiated different algorithms and different implementations, which will be instantiated
according to the configuration. This strategy allows multiple implementations according to the configuration. This strategy allows multiple implementations to
sharing a common interface, achieving the objective of decoupling interfaces share a common interface, achieving the objective of decoupling interfaces from
from implementations: it defines a family of algorithms, encapsulates each one, implementations: it defines a family of algorithms, encapsulates each one, and
and makes them interchangeable. Hence, we let the algorithm vary independently makes them interchangeable. Hence, we let the algorithm vary independently of
of the program that uses it. the program that uses it.
Internally, GNSS-SDR makes use of the complex data types defined by Internally, GNSS-SDR makes use of the complex data types defined by
[VOLK](https://www.libvolk.org/ "Vector-Optimized Library of Kernels home"). [VOLK](https://www.libvolk.org/ "Vector-Optimized Library of Kernels home").
They are fundamental for handling sample streams in which samples are complex They are fundamental for handling sample streams in which samples are complex
numbers with real and imaginary components of 8, 16 or 32 bits, common formats numbers with real and imaginary components of 8, 16, or 32 bits, common formats
delivered by GNSS (and generic SDR) radio frequency front-ends. The following delivered by GNSS (and generic SDR) radio frequency front-ends. The following
list shows the data type names that GNSS-SDR exposes through the configuration list shows the data type names that GNSS-SDR exposes through the configuration
file: file:
@ -1192,7 +1246,7 @@ parameters can be found at the
### Signal Source ### Signal Source
The input of a software receiver are the raw bits that come out from the The inputs of a software receiver are the raw bits that come out from the
front-end's analog-to-digital converter (ADC). Those bits can be read from a front-end's analog-to-digital converter (ADC). Those bits can be read from a
file stored in the hard disk or directly in real-time from a hardware device file stored in the hard disk or directly in real-time from a hardware device
through USB or Ethernet buses. through USB or Ethernet buses.
@ -1204,8 +1258,8 @@ USB or Ethernet buses. Since real-time processing requires a highly optimized
implementation of the whole receiver, this module also allows reading samples implementation of the whole receiver, this module also allows reading samples
from a file stored in a hard disk, and thus processing without time constraints. from a file stored in a hard disk, and thus processing without time constraints.
Relevant parameters of those samples are the intermediate frequency (or baseband Relevant parameters of those samples are the intermediate frequency (or baseband
I&Q components), the sampling rate and number of bits per sample, that must be I&Q components), the sampling rate, and the number of bits per sample, which
specified by the user in the configuration file. must be specified by the user in the configuration file.
This module also performs bit-depth adaptation, since most of the existing RF This module also performs bit-depth adaptation, since most of the existing RF
front-ends provide samples quantized with 2 or 3 bits, while operations inside front-ends provide samples quantized with 2 or 3 bits, while operations inside
@ -1213,7 +1267,7 @@ the processor are performed on 32- or 64-bit words, depending on its
architecture. Although there are implementations of the most intensive architecture. Although there are implementations of the most intensive
computational processes (mainly correlation) that take advantage of specific computational processes (mainly correlation) that take advantage of specific
data types and architectures for the sake of efficiency, the approach is data types and architectures for the sake of efficiency, the approach is
processor-specific and hardly portable. We suggest to keep signal samples in processor-specific and hardly portable. We suggest keeping signal samples in
standard data types and letting the compiler select the best library version standard data types and letting the compiler select the best library version
(implemented using SIMD or any other processor-specific technology) of the (implemented using SIMD or any other processor-specific technology) of the
required routines for a given processor. required routines for a given processor.
@ -1246,14 +1300,14 @@ complex stream via Data Type Adapter block (see below).
**_Example: Two-bit packed file source_** **_Example: Two-bit packed file source_**
Sometimes, samples are stored in files with a format which is not in the list of Sometimes, samples are stored in files with a format that is not in the list of
_native_ types supported by the `File_Signal_Source` implementation (i.e, it is _native_ types supported by the `File_Signal_Source` implementation (i.e, it is
not among `byte`, `ibyte`, `short`, `ishort`, `float` or `gr_complex`). This is not among `byte`, `ibyte`, `short`, `ishort`, `float`, or `gr_complex`). This is
the case of 2-bit samples, which is a common format delivered by GNSS RF the case of 2-bit samples, which is a common format delivered by GNSS RF
front-ends. The `Two_Bit_Packed_File_Signal_Source` implementation allows front-ends. The `Two_Bit_Packed_File_Signal_Source` implementation allows
reading two-bit length samples from a file. The data is assumed to be packed as reading two-bit length samples from a file. The data is assumed to be packed as
bytes `item_type=byte` or shorts `item_type=short` so that there are 4 two bit bytes `item_type=byte` or shorts `item_type=short` so that there are 4 two-bit
samples in each byte. The two bit values are assumed to have the following samples in each byte. The two-bit values are assumed to have the following
interpretation: interpretation:
| **b_1** | **b_0** | **Value** | | **b_1** | **b_0** | **Value** |
@ -1263,14 +1317,14 @@ interpretation:
| 1 | 0 | -3 | | 1 | 0 | -3 |
| 1 | 1 | -1 | | 1 | 1 | -1 |
Within a byte the samples may be packed in big endian `big_endian_bytes=true` Within a byte the samples may be packed in big-endian `big_endian_bytes=true`
(if the most significant byte value is stored at the memory location with the (if the most significant byte value is stored at the memory location with the
lowest address, the next byte value in significance is stored at the following lowest address, the next byte value in significance is stored at the following
memory location, and so on) or little endian `big_endian_bytes=false` (if the memory location, and so on) or little-endian `big_endian_bytes=false` (if the
least significant byte value is at the lowest address, and the other bytes least significant byte value is at the lowest address, and the other bytes
follow in increasing order of significance). If the order is big endian then the follow in increasing order of significance). If the order is big-endian then the
most significant two bits will form the first sample output, otherwise the least most significant two bits will form the first sample output. Otherwise, the
significant two bits will be used. least significant two bits will be used.
Additionally, the samples may be either real `sample_type=real`, or complex. If Additionally, the samples may be either real `sample_type=real`, or complex. If
the sample type is complex, then the samples are either stored in the order: the sample type is complex, then the samples are either stored in the order:
@ -1278,8 +1332,8 @@ real, imag, real, imag, ... `sample_type=iq` or in the order: imag, real, imag,
real, ... `sample_type=qi`. real, ... `sample_type=qi`.
Finally, if the data is stored as shorts `item_type=short`, then it may be Finally, if the data is stored as shorts `item_type=short`, then it may be
stored in either big endian `big_endian_items=true` or little endian stored in either big-endian `big_endian_items=true` or little-endian
`big_endian_items=false`. If the shorts are big endian then the 2nd byte in each `big_endian_items=false`. If the shorts are big-endian then the 2nd byte in each
short is output first. short is output first.
The output data type is either `float` or `gr_complex` depending on whether or The output data type is either `float` or `gr_complex` depending on whether or
@ -1443,8 +1497,9 @@ More documentation and examples are available at the
The signal conditioner is in charge of resampling the signal and delivering a The signal conditioner is in charge of resampling the signal and delivering a
reference sample rate to the downstream processing blocks, acting as a facade reference sample rate to the downstream processing blocks, acting as a facade
between the signal source and the synchronization channels, providing a between the signal source and the synchronization channels, providing a
simplified interface to the input signal. In case of multiband front-ends, this simplified interface to the input signal. In the case of multiband front-ends,
module would be in charge of providing a separated data stream for each band. this module would be in charge of providing a separated data stream for each
band.
If your signal source is providing baseband signal samples of type `gr_complex` If your signal source is providing baseband signal samples of type `gr_complex`
at 4 Msps, you can bypass the Signal Conditioner block by: at 4 Msps, you can bypass the Signal Conditioner block by:
@ -1455,7 +1510,7 @@ SignalConditioner.implementation=Pass_Through
If you need to adapt some aspect of your signal, you can enable the Signal If you need to adapt some aspect of your signal, you can enable the Signal
Conditioner and configure three internal blocks: a data type adapter, an input Conditioner and configure three internal blocks: a data type adapter, an input
signal and a resampler. signal, and a resampler.
``` ```
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks ;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
@ -1485,7 +1540,7 @@ More documentation at the
This block filters the input data. It can be combined with frequency translation This block filters the input data. It can be combined with frequency translation
for IF signals. The computation of the filter taps is based on parameters of GNU for IF signals. The computation of the filter taps is based on parameters of GNU
Radio's function Radio's function
[pm_remez](https://www.gnuradio.org/doc/doxygen/pm__remez_8h.html), that [pm_remez](https://www.gnuradio.org/doc/doxygen/pm__remez_8h.html), which
calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse calculates the optimal (in the Chebyshev/minimax sense) FIR filter impulse
response given a set of band edges, the desired response on those bands, and the response given a set of band edges, the desired response on those bands, and the
weight given to the error in those bands. weight given to the error in those bands.
@ -1566,7 +1621,7 @@ More documentation at the
A channel encapsulates all signal processing devoted to a single satellite. A channel encapsulates all signal processing devoted to a single satellite.
Thus, it is a large composite object which encapsulates the acquisition, Thus, it is a large composite object which encapsulates the acquisition,
tracking and navigation data decoding modules. As a composite object, it can be tracking, and navigation data decoding modules. As a composite object, it can be
treated as a single entity, meaning that it can be easily replicated. Since the treated as a single entity, meaning that it can be easily replicated. Since the
number of channels is selectable by the user in the configuration file, this number of channels is selectable by the user in the configuration file, this
approach helps to improve the scalability and maintainability of the receiver. approach helps to improve the scalability and maintainability of the receiver.
@ -1624,10 +1679,10 @@ ephemeris and almanac data is still valid, or this information is provided by
other means), and an acquisition process can finish deciding that the satellite other means), and an acquisition process can finish deciding that the satellite
is not present, that longer integration is needed in order to confirm the is not present, that longer integration is needed in order to confirm the
presence of the satellite, or declaring the satellite present. In the latter presence of the satellite, or declaring the satellite present. In the latter
case, acquisition process should stop and trigger the tracking module with case, the acquisition process should stop and trigger the tracking module with
coarse estimations of the synchronization parameters. The mathematical coarse estimations of the synchronization parameters. The mathematical
abstraction used to design this logic is known as finite state machine (FSM), abstraction used to design this logic is known as a finite state machine (FSM),
that is a behavior model composed of a finite number of states, transitions which is a behavior model composed of a finite number of states, transitions
between those states, and actions. between those states, and actions.
The abstract class [ChannelInterface](./src/core/interfaces/channel_interface.h) The abstract class [ChannelInterface](./src/core/interfaces/channel_interface.h)
@ -1643,11 +1698,11 @@ More documentation at the
The first task of a GNSS receiver is to detect the presence or absence of The first task of a GNSS receiver is to detect the presence or absence of
in-view satellites. This is done by the acquisition system process, which also in-view satellites. This is done by the acquisition system process, which also
provides a coarse estimation of two signal parameters: the frequency shift with provides a coarse estimation of two signal parameters: the frequency shift with
respect to the nominal frequency, and a delay term which allows the receiver to respect to the nominal frequency, and a delay term that allows the receiver to
create a local code aligned with the incoming code. create a local code aligned with the incoming code.
[AcquisitionInterface](./src/core/interfaces/acquisition_interface.h) is the [AcquisitionInterface](./src/core/interfaces/acquisition_interface.h) is the
common interface for all the acquisition algorithms and their corresponding common interface for all the acquisition algorithms and their corresponding
implementations. Algorithms' interface, that may vary depending on the use of implementations. Algorithms' interface, which may vary depending on the use of
information external to the receiver, such as in Assisted GNSS, is defined in information external to the receiver, such as in Assisted GNSS, is defined in
classes referred to as _adapters_. These adapters wrap the GNU Radio blocks classes referred to as _adapters_. These adapters wrap the GNU Radio blocks
interface into a compatible interface expected by AcquisitionInterface. This interface into a compatible interface expected by AcquisitionInterface. This
@ -1789,13 +1844,13 @@ More documentation at the
Most of GNSS signal links are modulated by a navigation message containing the Most of GNSS signal links are modulated by a navigation message containing the
time the message was transmitted, orbital parameters of satellites (also known time the message was transmitted, orbital parameters of satellites (also known
as ephemeris) and an almanac (information about the general system health, rough as ephemeris), and an almanac (information about the general system health,
orbits of all satellites in the network as well as data related to error rough orbits of all satellites in the network as well as data related to error
correction). Navigation data bits are structured in words, pages, subframes, correction). Navigation data bits are structured in words, pages, subframes,
frames and superframes. Sometimes, bits corresponding to a single parameter are frames, and superframes. Sometimes, bits corresponding to a single parameter are
spread over different words, and values extracted from different frames are spread over different words, and values extracted from different frames are
required for proper decoding. Some words are for synchronization purposes, required for proper decoding. Some words are for synchronization purposes,
others for error control and others contain actual information. There are also others for error control, and others contain actual information. There are also
error control mechanisms, from parity checks to forward error correction (FEC) error control mechanisms, from parity checks to forward error correction (FEC)
encoding and interleaving, depending on the system. All this decoding complexity encoding and interleaving, depending on the system. All this decoding complexity
is managed by a finite state machine. is managed by a finite state machine.
@ -1837,7 +1892,7 @@ More documentation at the
GNSS systems provide different kinds of observations. The most commonly used are GNSS systems provide different kinds of observations. The most commonly used are
the code observations, also called pseudoranges. The _pseudo_ comes from the the code observations, also called pseudoranges. The _pseudo_ comes from the
fact that on the receiver side the clock error is unknown and thus the fact that on the receiver side the clock error is unknown and thus the
measurement is not a pure range observation. High accuracy applications also use measurement is not a pure range observation. High-accuracy applications also use
the carrier phase observations, which are based on measuring the difference the carrier phase observations, which are based on measuring the difference
between the carrier phase transmitted by the GNSS satellites and the phase of between the carrier phase transmitted by the GNSS satellites and the phase of
the carrier generated in the receiver. Both observables are computed from the the carrier generated in the receiver. Both observables are computed from the
@ -1865,14 +1920,14 @@ More documentation at the
Although data processing for obtaining high-accuracy PVT solutions is out of the Although data processing for obtaining high-accuracy PVT solutions is out of the
scope of GNSS-SDR, we provide a module that can compute position fixes (stored scope of GNSS-SDR, we provide a module that can compute position fixes (stored
in GIS-friendly formats such as [GeoJSON](https://tools.ietf.org/html/rfc7946), in GIS-friendly formats such as [GeoJSON](https://tools.ietf.org/html/rfc7946),
[GPX](https://www.topografix.com/gpx.asp) and [GPX](https://www.topografix.com/gpx.asp), and
[KML](https://www.opengeospatial.org/standards/kml), or transmitted via serial [KML](https://www.opengeospatial.org/standards/kml), or transmitted via serial
port as [NMEA 0183](https://en.wikipedia.org/wiki/NMEA_0183) messages), and port as [NMEA 0183](https://en.wikipedia.org/wiki/NMEA_0183) messages), and
leaves room for more sophisticated positioning methods by storing observables leaves room for more sophisticated positioning methods by storing observables
and navigation data in [RINEX](https://en.wikipedia.org/wiki/RINEX) files (v2.11 and navigation data in [RINEX](https://en.wikipedia.org/wiki/RINEX) files (v2.11
or v3.02), and generating or v3.02), and generating
[RTCM](https://www.rtcm.org/ "Radio Technical Commission for Maritime Services") [RTCM](https://www.rtcm.org/ "Radio Technical Commission for Maritime Services")
3.2 messages that can be disseminated through the Internet in real time. 3.2 messages that can be disseminated through the Internet in real-time.
The common interface is [PvtInterface](./src/core/interfaces/pvt_interface.h). The common interface is [PvtInterface](./src/core/interfaces/pvt_interface.h).
@ -1926,7 +1981,7 @@ PVT.rtcm_MT1077_rate_ms=1000
[Marble](https://marble.kde.org), [osgEarth](http://osgearth.org), or used [Marble](https://marble.kde.org), [osgEarth](http://osgearth.org), or used
with the [NASA World Wind SDK for Java](https://worldwind.arc.nasa.gov/java/). with the [NASA World Wind SDK for Java](https://worldwind.arc.nasa.gov/java/).
- **GPX** (the GPS Exchange Format) is a light-weight XML data format for the - **GPX** (the GPS Exchange Format) is a lightweight XML data format for the
interchange of GPS data (waypoints, routes, and tracks) between applications interchange of GPS data (waypoints, routes, and tracks) between applications
and Web services on the Internet. The format is open and can be used without and Web services on the Internet. The format is open and can be used without
the need to pay license fees, and it is supported by a the need to pay license fees, and it is supported by a
@ -1934,7 +1989,7 @@ PVT.rtcm_MT1077_rate_ms=1000
- **NMEA 0183** is a combined electrical and data specification for - **NMEA 0183** is a combined electrical and data specification for
communication between marine electronics such as echo sounder, sonars, communication between marine electronics such as echo sounder, sonars,
anemometer, gyrocompass, autopilot, GPS receivers and many other types of anemometer, gyrocompass, autopilot, GPS receivers, and many other types of
instruments. It has been defined by, and is controlled by, the U.S. instruments. It has been defined by, and is controlled by, the U.S.
[National Marine Electronics Association](https://www.nmea.org/). The NMEA [National Marine Electronics Association](https://www.nmea.org/). The NMEA
0183 standard uses a simple ASCII, serial communications protocol that defines 0183 standard uses a simple ASCII, serial communications protocol that defines
@ -1959,7 +2014,7 @@ PVT.rtcm_MT1077_rate_ms=1000
(usually with other data unknown to the original receiver, such as better (usually with other data unknown to the original receiver, such as better
models of the atmospheric conditions at time of measurement). RINEX files can models of the atmospheric conditions at time of measurement). RINEX files can
be used by software packages such as [GPSTk](https://github.com/SGL-UT/GPSTk), be used by software packages such as [GPSTk](https://github.com/SGL-UT/GPSTk),
[RTKLIB](http://www.rtklib.com/) and [gLAB](https://gage.upc.edu/gLAB/). [RTKLIB](http://www.rtklib.com/), and [gLAB](https://gage.upc.edu/gLAB/).
GNSS-SDR by default generates RINEX version GNSS-SDR by default generates RINEX version
[3.02](ftp://igs.org/pub/data/format/rinex302.pdf). If [3.02](ftp://igs.org/pub/data/format/rinex302.pdf). If
[2.11](ftp://igs.org/pub/data/format/rinex211.txt) is needed, it can be [2.11](ftp://igs.org/pub/data/format/rinex211.txt) is needed, it can be
@ -1974,7 +2029,7 @@ PVT.rinex_version=2
correction applications. Developed by the Radio Technical Commission for correction applications. Developed by the Radio Technical Commission for
Maritime Services Maritime Services
([RTCM](https://www.rtcm.org/ "Radio Technical Commission for Maritime Services")), ([RTCM](https://www.rtcm.org/ "Radio Technical Commission for Maritime Services")),
they have become an industry standard for communication of correction they have become an industry standard for the communication of correction
information. GNSS-SDR implements RTCM version 3.2, defined in the document information. GNSS-SDR implements RTCM version 3.2, defined in the document
_RTCM 10403.2, Differential GNSS (Global Navigation Satellite Systems) _RTCM 10403.2, Differential GNSS (Global Navigation Satellite Systems)
Services - Version 3_ (February 1, 2013), which can be Services - Version 3_ (February 1, 2013), which can be
@ -1993,7 +2048,7 @@ PVT.rinex_version=2
operate on port 2101 (which is the recommended port for RTCM services operate on port 2101 (which is the recommended port for RTCM services
according to the Internet Assigned Numbers Authority, according to the Internet Assigned Numbers Authority,
[IANA](https://www.iana.org/assignments/service-names-port-numbers/ "Service Name and Transport Protocol Port Number Registry")), [IANA](https://www.iana.org/assignments/service-names-port-numbers/ "Service Name and Transport Protocol Port Number Registry")),
and will identify the Reference Station with ID=1234. This behaviour can be and will identify the Reference Station with ID=1234. This behavior can be
changed in the configuration file: changed in the configuration file:
``` ```
@ -2004,9 +2059,9 @@ PVT.rtcm_station_id=1111
**Important note:** **Important note:**
In order to get well-formatted GeoJSON, KML and RINEX files, always terminate In order to get well-formatted GeoJSON, KML, and RINEX files, always terminate
`gnss-sdr` execution by pressing key `q` and then key `ENTER`. Those files will `gnss-sdr` execution by pressing key `q` and then key `ENTER`. Those files will
be automatically deleted if no position fix have been obtained during the be automatically deleted if no position fix has been obtained during the
execution of the software receiver. execution of the software receiver.
More documentation at the More documentation at the
@ -2084,9 +2139,9 @@ processed.
Another interesting option is working in real-time with an RF front-end. We Another interesting option is working in real-time with an RF front-end. We
provide drivers for UHD-compatible hardware such as the provide drivers for UHD-compatible hardware such as the
[USRP family](https://www.ettus.com/product), for OsmoSDR and other front-ends [USRP family](https://www.ettus.com/product), for OsmoSDR and other front-ends
(HackRF, bladeRF, LimeSDR), for the GN3S v2 USB dongle and for some DVB-T USB (HackRF, bladeRF, LimeSDR, and for some DVB-T USB dongles). Start with a low
dongles. Start with a low number of channels and then increase it in order to number of channels and then increase it in order to test how many channels your
test how many channels your processor can handle in real-time. processor can handle in real-time.
You can find more information at the You can find more information at the
[GNSS-SDR Documentation page](https://gnss-sdr.org/docs/) or directly asking to [GNSS-SDR Documentation page](https://gnss-sdr.org/docs/) or directly asking to

View File

@ -7,10 +7,16 @@
execute_process(COMMAND uname -v OUTPUT_VARIABLE DARWIN_VERSION) execute_process(COMMAND uname -v OUTPUT_VARIABLE DARWIN_VERSION)
string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION}) string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION})
if(${DARWIN_VERSION} MATCHES "20") if(${DARWIN_VERSION} VERSION_GREATER "19")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++17") execute_process(COMMAND awk "/SOFTWARE LICENSE AGREEMENT FOR macOS/" "/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf" OUTPUT_VARIABLE macOS_NAME)
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") if(macOS_NAME)
set(MACOS_DISTRIBUTION "macOS Big Sur 11") string(REGEX MATCH "macOS*([^\n\r]*)" macOS_NAME ${macOS_NAME})
string(REGEX REPLACE "macOS " "" macOS_NAME ${macOS_NAME})
string(REGEX REPLACE ".$" "" macOS_NAME ${macOS_NAME})
execute_process(COMMAND sw_vers -productVersion OUTPUT_VARIABLE macOS_VERSION)
string(REGEX REPLACE "\n$" "" macOS_VERSION ${macOS_VERSION})
set(MACOS_DISTRIBUTION "macOS ${macOS_NAME} ${macOS_VERSION}")
endif()
endif() endif()
if(${DARWIN_VERSION} MATCHES "19") if(${DARWIN_VERSION} MATCHES "19")

View File

@ -20,7 +20,7 @@ if(DEFINED ENV{GFORTRAN_ROOT})
) )
endif() endif()
set(GCC_MAJOR_SERIES 11 10 9 8 7 6 5) set(GCC_MAJOR_SERIES 12 11 10 9 8 7 6 5)
set(GCC4_SERIES 4.9.1 4.9 4.8.3 4.8.1 4.7.2 4.7 4.8.2 4.8 4.7 4.6 4.5 4.4.4 4.4) set(GCC4_SERIES 4.9.1 4.9 4.8.3 4.8.1 4.7.2 4.7 4.8.2 4.8 4.7 4.6 4.5 4.4.4 4.4)
set(GCC_SERIES ${GCC_MAJOR_SERIES} ${GCC4_SERIES}) set(GCC_SERIES ${GCC_MAJOR_SERIES} ${GCC4_SERIES})

View File

@ -1,80 +0,0 @@
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
# This file is part of GNSS-SDR.
#
# SPDX-FileCopyrightText: 2011-2020 C. Fernandez-Prades cfernandez(at)cttc.es
# SPDX-License-Identifier: BSD-3-Clause
########################################################################
# Find GR-GN3S Module
########################################################################
#
# Provides the following imported target:
# Gnuradio::gn3s
#
if(NOT PKG_CONFIG_FOUND)
include(FindPkgConfig)
endif()
pkg_check_modules(PC_GR_GN3S gr-gn3s)
if(NOT GRGN3S_ROOT)
set(GRGN3S_ROOT_USER_DEFINED /usr/local)
else()
set(GRGN3S_ROOT_USER_DEFINED ${GRGN3S_ROOT})
endif()
if(DEFINED ENV{GRGN3S_ROOT})
set(GRGN3S_ROOT_USER_DEFINED
${GRGN3S_ROOT_USER_DEFINED}
$ENV{GRGN3S_ROOT}
)
endif()
if(DEFINED ENV{GR_GN3S_DIR})
set(GRGN3S_ROOT_USER_DEFINED
${GRGN3S_ROOT_USER_DEFINED}
$ENV{GR_GN3S_DIR}
)
endif()
set(GRGN3S_ROOT_USER_DEFINED
${GRGN3S_ROOT_USER_DEFINED}
${CMAKE_INSTALL_PREFIX}
)
find_path(
GR_GN3S_INCLUDE_DIRS
NAMES gn3s/gn3s_api.h
HINTS ${PC_GR_GN3S_INCLUDEDIR}
PATHS ${GRGN3S_ROOT_USER_DEFINED}/include
/usr/include
/usr/local/include
/opt/local/include
)
find_library(
GR_GN3S_LIBRARIES
NAMES gr-gn3s
HINTS ${PC_GR_GN3S_LIBDIR}
PATHS ${GRGN3S_ROOT_USER_DEFINED}/lib
${GRGN3S_ROOT_USER_DEFINED}/lib64
/usr/lib
/usr/lib64
/usr/local/lib
/usr/local/lib64
/opt/local/lib
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GRGN3S DEFAULT_MSG GR_GN3S_LIBRARIES GR_GN3S_INCLUDE_DIRS)
if(GRGN3S_FOUND AND NOT TARGET Gnuradio::gn3s)
add_library(Gnuradio::gn3s SHARED IMPORTED)
set_target_properties(Gnuradio::gn3s PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${GR_GN3S_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${GR_GN3S_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${GR_GN3S_LIBRARIES}"
)
endif()
mark_as_advanced(GR_GN3S_LIBRARIES GR_GN3S_INCLUDE_DIRS)

View File

@ -1,115 +0,0 @@
; This is a GNSS-SDR configuration file
; The configuration API is described at https://gnss-sdr.org/docs/sp-blocks/
; SPDX-License-Identifier: GPL-3.0-or-later
; SPDX-FileCopyrightText: (C) 2010-2020 (see AUTHORS file for a list of contributors)
; You can define your own receiver and invoke it by doing
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
;
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second].
GNSS-SDR.internal_fs_sps=2727933.33 ; 8183800/3
;######### SIGNAL_SOURCE CONFIG ############
;#implementation:
;#Notes for GN3S source:
; - The front-end sampling frequency is fixed to 8.1838 MSPS (8183800 Hz).
; - The baseband signal is shifted to an IF of 38400 Hz. It should be corrected with the signal conditioner block
GNSS-SDR.internal_fs_sps=2727933.33 ; 8183800/3
;######### SIGNAL_SOURCE CONFIG ############
SignalSource.implementation=GN3S_Signal_Source
SignalSource.item_type=gr_complex
SignalSource.sampling_frequency=8183800
SignalSource.dump=false
SignalSource.dump_filename=../signal_source.dat
;######### SIGNAL_CONDITIONER CONFIG ############
SignalConditioner.implementation=Signal_Conditioner
;######### DATA_TYPE_ADAPTER CONFIG ############
DataTypeAdapter.implementation=Pass_Through
;######### INPUT_FILTER CONFIG ############
InputFilter.implementation=Freq_Xlating_Fir_Filter
InputFilter.dump=false
InputFilter.dump_filename=../data/input_filter.dat
InputFilter.input_item_type=gr_complex
InputFilter.output_item_type=gr_complex
InputFilter.taps_item_type=float
InputFilter.number_of_taps=5
InputFilter.number_of_bands=2
InputFilter.band1_begin=0.0
InputFilter.band1_end=0.45
InputFilter.band2_begin=0.55
InputFilter.band2_end=1.0
InputFilter.ampl1_begin=1.0
InputFilter.ampl1_end=1.0
InputFilter.ampl2_begin=0.0
InputFilter.ampl2_end=0.0
InputFilter.band1_error=1.0
InputFilter.band2_error=1.0
InputFilter.filter_type=bandpass
InputFilter.grid_density=16
InputFilter.sampling_frequency=8183800
InputFilter.IF=38400
InputFilter.decimation_factor=3
;######### RESAMPLER CONFIG ############
Resampler.implementation=Pass_Through
Resampler.dump=false
Resampler.dump_filename=../data/resampler.dat
;######### CHANNELS GLOBAL CONFIG ############
Channels_1C.count=5
Channels.in_acquisition=1
Channel.signal=1C
;######### ACQUISITION GLOBAL CONFIG ############
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
Acquisition_1C.item_type=gr_complex
Acquisition_1C.coherent_integration_time_ms=1
Acquisition_1C.pfa=0.01
Acquisition_1C.doppler_max=10000
Acquisition_1C.doppler_step=500
Acquisition_1C.dump=false
Acquisition_1C.dump_filename=./acq_dump.dat
;######### TRACKING GLOBAL CONFIG ############
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
Tracking_1C.item_type=gr_complex
Tracking_1C.pll_bw_hz=45.0;
Tracking_1C.dll_bw_hz=2.0;
Tracking_1C.order=3;
Tracking_1C.dump=false
Tracking_1C.dump_filename=../data/epl_tracking_ch_
;######### TELEMETRY DECODER GPS CONFIG ############
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_1C.dump=false
;######### OBSERVABLES CONFIG ############
Observables.implementation=Hybrid_Observables
Observables.dump=false.
Observables.dump_filename=./observables.dat
;######### PVT CONFIG ############
PVT.implementation=RTKLIB_PVT
PVT.positioning_mode=PPP_Static ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic
PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX
PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad
PVT.output_rate_ms=10
PVT.display_rate_ms=500
PVT.dump_filename=./PVT
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea
PVT.flag_nmea_tty_port=false;
PVT.nmea_dump_devname=/dev/pts/4
PVT.dump=false
PVT.flag_rtcm_server=false
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1

View File

@ -13,7 +13,7 @@ GNSS-SDR.internal_fs_sps=2560000
;GNSS-SDR.internal_fs_sps=5120000 ;GNSS-SDR.internal_fs_sps=5120000
;######### SIGNAL_SOURCE CONFIG ############ ;######### SIGNAL_SOURCE CONFIG ############
;#implementation: Use [File_Signal_Source] [Nsr_File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) ;#implementation: Use [File_Signal_Source] [Nsr_File_Signal_Source] or [UHD_Signal_Source]
SignalSource.implementation=Nsr_File_Signal_Source SignalSource.implementation=Nsr_File_Signal_Source
;#filename: path to file with the captured GNSS signal samples to be processed ;#filename: path to file with the captured GNSS signal samples to be processed

View File

@ -8,6 +8,10 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
) )
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
# Changelog
All notable changes to GNSS-SDR will be documented in this file.
## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next) ## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next)
### Improvements in Availability: ### Improvements in Availability:
@ -15,13 +19,13 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
- Added the reading of reduced clock and ephemeris data (CED) in the Galileo E1B - Added the reading of reduced clock and ephemeris data (CED) in the Galileo E1B
INAV message introduced in Galileo OS SIS ICD Issue 2.0. If the reduced CED is INAV message introduced in Galileo OS SIS ICD Issue 2.0. If the reduced CED is
available before the full ephemeris set, it is used for PVT computation until available before the full ephemeris set, it is used for PVT computation until
the full set has not yet been received. This can contribute to shorten the the full set has not yet been received. This can contribute to shortening the
Time-To-First-Fix. Time-To-First-Fix.
- Added the exploitation of the FEC2 Erasure Correction in the Galileo E1B INAV - Added the exploitation of the FEC2 Erasure Correction in the Galileo E1B INAV
message introduced in Galileo OS SIS ICD Issue 2.0. This can contribute to message introduced in Galileo OS SIS ICD Issue 2.0. This can contribute to
shorten the Time-To-First-Fix. Since the added computational cost could break shortening the Time-To-First-Fix. Since the added computational cost could
some real-time configurations, this feature is disabled by default. It can be break some real-time configurations, this feature is disabled by default. It
activated from the configuration file by adding can be activated from the configuration file by adding
`TelemetryDecoder_1B.enable_reed_solomon=true`. `TelemetryDecoder_1B.enable_reed_solomon=true`.
### Improvements in Maintainability: ### Improvements in Maintainability:
@ -36,39 +40,41 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
- Improved handling of change in GNU Radio 3.9 FFT API. - Improved handling of change in GNU Radio 3.9 FFT API.
- Improved handling of the filesystem library. - Improved handling of the filesystem library.
- Added an abstract class `SignalSourceInterface` and a common base class - Added an abstract class `SignalSourceInterface` and a common base class
`SignalSourceBase`, which allow to remove a lot of duplicated code in Signal `SignalSourceBase`, which allow removing a lot of duplicated code in Signal
Source blocks, and further abstract file-based interfaces behind them. Source blocks, and further abstract file-based interfaces behind them.
- Do not apply clang-tidy fixes to protobuf-generated headers. - Do not apply clang-tidy fixes to protobuf-generated headers.
- Refactored private implementation of flow graph connection and disconnection - Refactored private implementation of flow graph connection and disconnection
for improved source code readability. for improved source code readability.
- Added a base class for GNSS ephemeris, saving some duplicated code and - Added a base class for GNSS ephemeris, saving some duplicated code and
providing a common nomenclature for ephemeris' parameters. New generated XML providing a common nomenclature for ephemeris' parameters. New generated XML
files make use of the new parameters' name. files make use of the new parameters' names.
- Update GSL implementation to 0.38.1. See - Update GSL implementation to 0.38.1. See
https://github.com/gsl-lite/gsl-lite/releases/tag/v0.38.1 https://github.com/gsl-lite/gsl-lite/releases/tag/v0.38.1
### Improvements in Portability: ### Improvements in Portability:
- Avoid collision of the `cpu_features` library when installing the - Avoid collision of the `cpu_features` library when installing the
`volk_gnsssdr` library by its own, and VOLK has already installed its version. `volk_gnsssdr` library on its own, and VOLK has already installed its version.
Added a new building option `ENABLE_OWN_CPUFEATURES`, defaulting to `ON` when Added a new building option `ENABLE_OWN_CPUFEATURES`, defaulting to `ON` when
building `gnss-sdr` but defaulting to `OFF` when building a stand-alone building `gnss-sdr` but defaulting to `OFF` when building a stand-alone
version of `volk_gnsssdr`. When this building option is set to `ON`, it forces version of `volk_gnsssdr`. When this building option is set to `ON`, it forces
the building of the local version of the cpu_features library, regardless of the building of the local version of the `cpu_features` library, regardless of
whether it is already installed or not. whether it is already installed or not.
- Fix building when using the Xcode generator, Xcode >= 12 and CMake >= 3.19. - Fix building when using the Xcode generator, Xcode >= 12 and CMake >= 3.19.
- Fix building of FPGA blocks when linking against GNU Radio >= 3.9 and/or - Fix building of FPGA blocks when linking against GNU Radio >= 3.9 and/or
Boost >= 1.74. Boost >= 1.74.
- Fix linking of the `<filesystem>` library when using GCC 8.x and GNU Radio >= - Fix linking of the `<filesystem>` library when using GCC 8.x and GNU Radio >=
3.8. 3.8.
- If the Matio library is not found, now it is configured and built by CMake
instead of using autotools.
### Improvements in Usability: ### Improvements in Usability:
- Added a new `Fifo_Signal_Source` implementation that allows using a - Added a new `Fifo_Signal_Source` implementation that allows using a
[Unix FIFO](https://en.wikipedia.org/wiki/Named_pipe) as a signal source, thus [Unix FIFO](https://en.wikipedia.org/wiki/Named_pipe) as a signal source, thus
allowing to multiplex signal streams outside of `gnss-sdr`, letting another allowing to multiplex signal streams outside of `gnss-sdr`, letting another
program to hold access to the receiver, or allowing signal sources that are program hold access to the receiver, or allowing signal sources that are not
not supported by `gnss-sdr` but can dump the signal to a FIFO. supported by `gnss-sdr` but can dump the signal to a FIFO.
- Avoid segmentation faults in the flow graph connection and/or starting due to - Avoid segmentation faults in the flow graph connection and/or starting due to
some common inconsistencies in the configuration file. some common inconsistencies in the configuration file.
- Provide hints to the user in case of failed flow graph connection due to - Provide hints to the user in case of failed flow graph connection due to
@ -93,17 +99,29 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
different settings for the `-DENABLE_FMCOMMS2` or `-DENABLE_PLUTOSDR` building different settings for the `-DENABLE_FMCOMMS2` or `-DENABLE_PLUTOSDR` building
options. options.
- Fix building when using UHD v4.0.0.0. - Fix building when using UHD v4.0.0.0.
- Fix building for `-DENABLE_FMCOMMS2=ON` and/or `-DENABLE_PLUTOSDR=ON` when the
built-in gr-iio module introduced in GNU Radio 3.10 is found. This in-tree GNU
Radio module takes precedence over the gr-iio package provided at
https://github.com/analogdevicesinc/gr-iio. If the GNU Radio module is found,
the other one is ignored.
- File `changelog.md` renamed to the more usual `CHANGELOG.md` uppercase name.
- New global configuration parameter `GNSS-SDR.observable_interval_ms`, set by
default to 20 [ms], allows to control the internal rate at which computed
observables sets are processed (50 observables sets per second by default).
See the definitions of concepts and metrics at
https://gnss-sdr.org/design-forces/
&nbsp; &nbsp;
## [GNSS-SDR v0.0.14](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.14) ## [GNSS-SDR v0.0.14](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.14) - 2021-01-08
### Improvements in Availability: ### Improvements in Availability:
- Fixed bug in acquisition detection when the configuration parameter - Fixed bug in acquisition detection when the configuration parameter
`Acquisition_XX.threshold` was set but `Acquisition_XX.pfa` was not, causing `Acquisition_XX.threshold` was set but `Acquisition_XX.pfa` was not, causing
false locks. false locks.
- Fixed anti-jamming filters: `Pulse_Blanking_Filter`, `Notch_Filter` and - Fixed anti-jamming filters: `Pulse_Blanking_Filter`, `Notch_Filter`, and
`Notch_Filter_Lite`. `Notch_Filter_Lite`.
### Improvements in Efficiency: ### Improvements in Efficiency:
@ -121,8 +139,8 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
### Improvements in Maintainability: ### Improvements in Maintainability:
- Added a common shared pointer definition `gnss_shared_ptr`, which allows to - Added a common shared pointer definition `gnss_shared_ptr`, which allows
handle the `boost::shared_ptr` to `std::shared_ptr` transition in GNU Radio handling the `boost::shared_ptr` to `std::shared_ptr` transition in GNU Radio
3.9 API more nicely. 3.9 API more nicely.
- Support new FFT and firdes blocks' API in GNU Radio 3.9. - Support new FFT and firdes blocks' API in GNU Radio 3.9.
- Added detection of inconsistent function prototypes in `volk_gnsssdr` library - Added detection of inconsistent function prototypes in `volk_gnsssdr` library
@ -165,7 +183,7 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
- Fixed a bug introduced in v0.0.13 that prevented getting Galileo-only PVT - Fixed a bug introduced in v0.0.13 that prevented getting Galileo-only PVT
fixes in some environments. fixes in some environments.
- Fixed duplication of protobuf build tree if it was locally built and then - Fixed duplication of protobuf build tree if it was locally built and then
installed with DESTDIR variable set. installed with `DESTDIR` variable set.
### Improvements in Usability: ### Improvements in Usability:
@ -200,9 +218,12 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
`.dat` binary file is also delivered in `.mat` format, which is readable from `.dat` binary file is also delivered in `.mat` format, which is readable from
Matlab and Python. Matlab and Python.
See the definitions of concepts and metrics at
https://gnss-sdr.org/design-forces/
&nbsp; &nbsp;
## [GNSS-SDR v0.0.13](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.13) ## [GNSS-SDR v0.0.13](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.13) - 2020-07-29
### Improvements in Efficiency: ### Improvements in Efficiency:
@ -223,7 +244,7 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
- Improved usage of smart pointers to better express ownership of resources. - Improved usage of smart pointers to better express ownership of resources.
- Add definition of `std::make_unique` for buildings with C++11, and make use of - Add definition of `std::make_unique` for buildings with C++11, and make use of
it along the source code. it through the source code.
- Private members in headers have been sorted by type and size, minimizing - Private members in headers have been sorted by type and size, minimizing
padding space in the stack and making the files more readable for humans. padding space in the stack and making the files more readable for humans.
- Simpler, less error-prone design of the `GNSSBlockFactory` class public API - Simpler, less error-prone design of the `GNSSBlockFactory` class public API
@ -231,14 +252,14 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
- Simpler API for the `Pvt_Solution` class. - Simpler API for the `Pvt_Solution` class.
- Improved system constant definition headers, numerical values are only written - Improved system constant definition headers, numerical values are only written
once. once.
- Improved const correctness. - Improved `const` correctness.
- The software can now be built against the GNU Radio 3.9 API that uses standard - The software can now be built against the GNU Radio 3.9 API that uses standard
library's smart pointers instead of Boost's. Minimum GNU Radio required library's smart pointers instead of Boost's. Minimum GNU Radio required
version still remains at 3.7.3. version still remains at 3.7.3.
- The software can now be built against Boost <= 1.73 (minimum version: 1.53). - The software can now be built against Boost <= 1.73 (minimum version: 1.53).
- Fixed building with GCC 10 (gcc-10 and above flipped a default from `-fcommon` - Fixed building with GCC 10 (gcc-10 and above flipped a default from `-fcommon`
to `-fno-common`, causing an error due to multiple defined lambda functions). to `-fno-common`, causing an error due to multiple defined lambda functions).
- Fixed warnings risen by GCC 10 and Clang 10. - Fixed warnings raised by GCC 10 and Clang 10.
- Various improvements in the CMake scripts: better decision on the C++ standard - Various improvements in the CMake scripts: better decision on the C++ standard
to use; simplifications for various API dependency and environment versions to use; simplifications for various API dependency and environment versions
requirements, with more intuitive naming for variables; fixed the requirements, with more intuitive naming for variables; fixed the
@ -249,10 +270,10 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
- The software can now be cross-compiled on Petalinux environments. - The software can now be cross-compiled on Petalinux environments.
- Removed python six module as a dependency if using Python 3.x. - Removed python six module as a dependency if using Python 3.x.
- Make use of `std::span` if the compiler supports it, and use gsl-lite as a - Make use of `std::span` if the compiler supports it, and use `gsl-lite` as a
fallback. The latter has been updated to version fallback. The latter has been updated to version
[0.37.0](https://github.com/gsl-lite/gsl-lite/releases/tag/0.37.0). [0.37.0](https://github.com/gsl-lite/gsl-lite/releases/tag/0.37.0).
- Improved finding of libgfortran in openSUSE and Fedora distributions. - Improved finding of `libgfortran` in openSUSE and Fedora distributions.
- Improved interface for FPGA off-loading. - Improved interface for FPGA off-loading.
- Allow a random name for the build type. If not recognized, it is set to - Allow a random name for the build type. If not recognized, it is set to
`None`. This allows packaging in some distributions that pass an arbitrary `None`. This allows packaging in some distributions that pass an arbitrary
@ -269,7 +290,7 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
### Improvements in Reproducibility: ### Improvements in Reproducibility:
- Improved reproducibility of the volk_gnsssdr library: Drop compile-time CPU - Improved reproducibility of the `volk_gnsssdr` library: Drop compile-time CPU
detection. detection.
### Improvements in Testability: ### Improvements in Testability:
@ -282,7 +303,7 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
- Do not pollute the source directory if the software is built from an - Do not pollute the source directory if the software is built from an
out-of-source-tree directory. Downloaded external sources and test raw files out-of-source-tree directory. Downloaded external sources and test raw files
are now stored in a `./thirdparty` folder under the building directory. In are now stored in a `./thirdparty` folder under the building directory. In the
case of an out-of-source-tree build, the generated binaries are stored in an case of an out-of-source-tree build, the generated binaries are stored in an
`./install` folder, also under the building directory. The old behavior for `./install` folder, also under the building directory. The old behavior for
generated binaries is maintained if the building is done from any source tree generated binaries is maintained if the building is done from any source tree
@ -316,7 +337,7 @@ https://gnss-sdr.org/design-forces/
&nbsp; &nbsp;
## [GNSS-SDR v0.0.12](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.12) ## [GNSS-SDR v0.0.12](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.12) - 2020-03-13
### Improvements in Accuracy: ### Improvements in Accuracy:
@ -338,7 +359,7 @@ https://gnss-sdr.org/design-forces/
### Improvements in Flexibility: ### Improvements in Flexibility:
- New Tracking parameters allow the configuration of the C/N0 and lock detector - New Tracking parameters allow the configuration of the C/N0 and lock detector
smoothers, as well as the activation of the FLL in pull-in and steady state smoothers, as well as the activation of the FLL in pull-in and steady-state
stages. stages.
- Added new Tracking parameter `Tracking_XX.carrier_aiding`, allowing - Added new Tracking parameter `Tracking_XX.carrier_aiding`, allowing
enabling/disabling of carrier aiding to the code tracking loop. enabling/disabling of carrier aiding to the code tracking loop.
@ -389,8 +410,8 @@ https://gnss-sdr.org/design-forces/
- Apply more clang-tidy checks related to readability: - Apply more clang-tidy checks related to readability:
`readability-avoid-const-params-in-decls`, `readability-avoid-const-params-in-decls`,
`readability-braces-around-statements`, `readability-isolate-declaration`, `readability-braces-around-statements`, `readability-isolate-declaration`,
`readability-redundant-control-flow`, `readability-uppercase-literal-suffix`. `readability-redundant-control-flow`, and
Fixed raised warnings. `readability-uppercase-literal-suffix`. Fixed raised warnings.
- Fixed a number of defects detected by `cpplint.py`. Filters applied: - Fixed a number of defects detected by `cpplint.py`. Filters applied:
`+build/class`, `+build/c++14`, `+build/deprecated`, `+build/class`, `+build/c++14`, `+build/deprecated`,
`+build/explicit_make_pair`, `+build/include_what_you_use`, `+build/explicit_make_pair`, `+build/include_what_you_use`,
@ -399,19 +420,19 @@ https://gnss-sdr.org/design-forces/
`+runtime/casting`, `+runtime/explicit`, `+runtime/indentation_namespace`, `+runtime/casting`, `+runtime/explicit`, `+runtime/indentation_namespace`,
`+runtime/init`, `+runtime/invalid_increment`, `+runtime/init`, `+runtime/invalid_increment`,
`+runtime/member_string_references`, `+runtime/memset`, `+runtime/operator`, `+runtime/member_string_references`, `+runtime/memset`, `+runtime/operator`,
`+runtime/printf`, `+runtime/printf_format`, `+whitespace/blank_line`. `+runtime/printf`, `+runtime/printf_format`, and `+whitespace/blank_line`.
- `clang-format` can now be applied to the whole code tree without breaking - `clang-format` can now be applied to the whole code tree without breaking
compilation. compilation.
- Added more check options to `.clang-tidy` file. - Added more check options to `.clang-tidy` file.
- Default Python version is now >= 3.4. Python 2.7 still can be used in systems - Default Python version is now >= 3.4. Python 2.7 still can be used in systems
where Python 3 is not available (e.g., CentOS 7, Debian 8, Ubuntu 10.04). where Python 3 is not available (e.g., CentOS 7, Debian 8, Ubuntu 10.04).
- CMake now passes the `-DCMAKE_BUILD_TYPE` (or configuration in - CMake now passes the `-DCMAKE_BUILD_TYPE` (or configuration in
multi-configuration generators like Xcode) to modules built along gnss-sdr multi-configuration generators like Xcode) to modules built along with
(e.g, the volk_gnsssdr library and googletest). Build types available: `None`, `gnss-sdr` (e.g, the `volk_gnsssdr` library and googletest). Build types
`Release` (by default), `Debug`, `RelWithDebInfo`, `MinSizeRel`, `Coverage`, available: `None`, `Release` (by default), `Debug`, `RelWithDebInfo`,
`NoOptWithASM`, `O2WithASM`, `O3WithASM`, `ASAN`. `MinSizeRel`, `Coverage`, `NoOptWithASM`, `O2WithASM`, `O3WithASM`, `ASAN`.
- Fix runtime errors when compiling in `Debug` mode on macOS. - Fix runtime errors when compiling in `Debug` mode on macOS.
- Updated links in comments along the source code and in CMake scripts. - Updated links in comments through the source code and in CMake scripts.
- Update GSL implementation to 0.36.0. See - Update GSL implementation to 0.36.0. See
https://github.com/gsl-lite/gsl-lite/releases/tag/v0.36.0 https://github.com/gsl-lite/gsl-lite/releases/tag/v0.36.0
- Create a CI job on GitHub to ensure that `clang-tidy` has been applied in most - Create a CI job on GitHub to ensure that `clang-tidy` has been applied in most
@ -433,18 +454,20 @@ https://gnss-sdr.org/design-forces/
### Improvements in Portability: ### Improvements in Portability:
- The CMake scripts now find dependencies in Debian's riscv64 architecture. - The CMake scripts now find dependencies in Debian's riscv64 architecture.
- Enable AVX2 kernels of the volk_gnsssdr library when using the Clang compiler. - Enable AVX2 kernels of the `volk_gnsssdr` library when using the Clang
compiler.
- Fixed building in some ARM-based devices. Now Clang and ARMClang can be used - Fixed building in some ARM-based devices. Now Clang and ARMClang can be used
for native building. for native building.
- Added toolchain files for building gnss-sdr and the volk_gnsssdr library in - Added toolchain files for building gnss-sdr and the `volk_gnsssdr` library in
several ARM processor architectures, including those in Raspberry Pi 3 and 4. several ARM processor architectures, including those in Raspberry Pi 3 and 4.
- The software can now be built using Xcode (passing `-GXcode` to CMake) without - The software can now be built using Xcode (passing `-GXcode` to CMake) without
previous manual installation of volk_gnsssdr. previous manual installation of `volk_gnsssdr`.
- The software can now be built using Xcode (passing `-GXcode` to CMake) without - The software can now be built using Xcode (passing `-GXcode` to CMake) without
gflags, glog, matio, PugiXML, Protocol Buffers or googletest previously gflags, glog, matio, PugiXML, Protocol Buffers or googletest previously
installed. installed.
- Now the volk_gnsssdr library can be built on Microsoft Windows. - Now the `volk_gnsssdr` library can be built on Microsoft Windows.
- Now the volk_gnsssdr library makes use of C11 `aligned_alloc` where available. - Now the `volk_gnsssdr` library makes use of C11 `aligned_alloc` where
available.
- Improved CMake script for cross-compilation and for the detection of AVX, AVX2 - Improved CMake script for cross-compilation and for the detection of AVX, AVX2
and NEON (v7 and v8) instructions. and NEON (v7 and v8) instructions.
- Fixed warnings raised by CMake 3.17. - Fixed warnings raised by CMake 3.17.
@ -490,10 +513,10 @@ https://gnss-sdr.org/design-forces/
- Improved DLL-PLL binary dump MATLAB/Octave plot script. Old versions removed. - Improved DLL-PLL binary dump MATLAB/Octave plot script. Old versions removed.
- Simplified RTKLIB error log. - Simplified RTKLIB error log.
- Added a Python 3 plotting script to show relative performance of generic - Added a Python 3 plotting script to show relative performance of generic
volk_gnsssdr kernels wrt SIMD fastest versions. `volk_gnsssdr` kernels wrt. SIMD fastest versions.
- Added reporting of velocity in the terminal. - Added reporting of velocity in the terminal.
- Added reporting of user clock drift estimation, in ppm, in the Pvt_Monitor and - Added reporting of user clock drift estimation, in ppm, in the `Pvt_Monitor`
in internal logging (`Debug` mode). and in internal logging (`Debug` mode).
- Updated documentation generated by Doxygen, now the `pdfmanual` target works - Updated documentation generated by Doxygen, now the `pdfmanual` target works
when using ninja. when using ninja.
- CMake now generates an improved summary of required/optional dependency - CMake now generates an improved summary of required/optional dependency
@ -508,7 +531,7 @@ https://gnss-sdr.org/design-forces/
&nbsp; &nbsp;
## [GNSS-SDR v0.0.11](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.11) ## [GNSS-SDR v0.0.11](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.11) - 2019-08-04
This release has several improvements in different dimensions, addition of new This release has several improvements in different dimensions, addition of new
features and bug fixes: features and bug fixes:
@ -541,14 +564,15 @@ features and bug fixes:
messages (acceleration by x1.6 on average per channel). messages (acceleration by x1.6 on average per channel).
- Shortened Acquisition to Tracking transition time. - Shortened Acquisition to Tracking transition time.
- Applied clang-tidy checks and fixes related to performance: - Applied clang-tidy checks and fixes related to performance:
performance-faster-string-find, performance-for-range-copy, `performance-faster-string-find`, `performance-for-range-copy`,
performance-implicit-conversion-in-loop, performance-inefficient-algorithm, `performance-implicit-conversion-in-loop`,
performance-inefficient-string-concatenation, `performance-inefficient-algorithm`,
performance-inefficient-vector-operation, performance-move-const-arg, `performance-inefficient-string-concatenation`,
performance-move-constructor-init, performance-noexcept-move-constructor, `performance-inefficient-vector-operation`, `performance-move-const-arg`,
performance-type-promotion-in-math-fn, `performance-move-constructor-init`, `performance-noexcept-move-constructor`,
performance-unnecessary-copy-initialization, `performance-type-promotion-in-math-fn`,
performance-unnecessary-value-param, readability-string-compare. `performance-unnecessary-copy-initialization`,
`performance-unnecessary-value-param`, `readability-string-compare`.
### Improvements in Flexibility: ### Improvements in Flexibility:
@ -566,36 +590,36 @@ features and bug fixes:
- Added a custom UDP/IP output for PVT data streaming. - Added a custom UDP/IP output for PVT data streaming.
- Improved Monitor block with UDP/IP output for internal receiver's data - Improved Monitor block with UDP/IP output for internal receiver's data
streaming. streaming.
- Custom output formats described with .proto files, making easier to other - Custom output formats described with `.proto` files, making easier to other
applications reading them in a forward and backward-compatible fashion upon applications reading them in a forward and backward-compatible fashion upon
future format changes. New dependency: Protocol Buffers >= 3.0.0 future format changes. New dependency: Protocol Buffers >= 3.0.0
- Fixes in RINEX generation: week rollover, annotations are not repeated anymore - Fixes in RINEX generation: week rollover, annotations are not repeated anymore
in navigation files. Parameter rinexnav_rate_ms has been removed, annotations in navigation files. Parameter `PVT.rinexnav_rate_ms` has been removed,
are made as new ephemeris arrive. annotations are made as new ephemeris arrive.
- Fixes in RTCM messages generation: week rollover. - Fixes in RTCM messages generation: week rollover.
### Improvements in Maintainability: ### Improvements in Maintainability:
- The internal communication mechanism based on gr::msg_queue has been replaced - The internal communication mechanism based on `gr::msg_queue` has been
by a thread-safe, built-in asynchronous message passing system based on GNU replaced by a thread-safe, built-in asynchronous message passing system based
Radio's Polymorphic Types. This change is backwards-compatible and prevents on GNU Radio's Polymorphic Types. This change is backwards-compatible and
from a failure in case of a possible future deprecation or removal of the prevents from a failure in case of a possible future deprecation or removal of
gr::msg_queue API. the `gr::msg_queue` API.
- Deprecated boost::asio::io_service replaced by boost::asio::io_context if - Deprecated `boost::asio::io_service` replaced by `boost::asio::io_context` if
Boost > 1.65 Boost > 1.65
- CMake turns all policies to ON according to the running version up to version - CMake turns all policies to ON according to the running version up to version
3.15. 3.15.
- Usage of clang-tidy integrated into CMake scripts. New option - Usage of clang-tidy integrated into CMake scripts. New option
-DENABLE_CLANG_TIDY=ON executes clang-tidy along with compilation. Requires `-DENABLE_CLANG_TIDY=ON` executes clang-tidy along with compilation. Requires
clang compiler. clang compiler.
- Applied clang-tidy checks and fixes related to readability: - Applied clang-tidy checks and fixes related to readability:
readability-container-size-empty, readability-identifier-naming, `readability-container-size-empty`, `readability-identifier-naming`,
readability-inconsistent-declaration-parameter-name, `readability-inconsistent-declaration-parameter-name`,
readability-named-parameter, readability-non-const-parameter, `readability-named-parameter`, `readability-non-const-parameter`,
readability-string-compare. `readability-string-compare`.
- Improved includes selection following suggestions by include-what-you-use (see - Improved includes selection following suggestions by `include-what-you-use`
https://include-what-you-use.org/), allowing faster compiles, fewer recompiles (see https://include-what-you-use.org/), allowing faster compiles, fewer
and making refactoring easier. recompiles and making refactoring easier.
- Massive reduction of warnings triggered by clang-tidy checks. - Massive reduction of warnings triggered by clang-tidy checks.
- Throughout code cleaning and formatting performed with automated tools in - Throughout code cleaning and formatting performed with automated tools in
order to reduce future commit noise. order to reduce future commit noise.
@ -609,12 +633,12 @@ features and bug fixes:
- Improvements for macOS users using Homebrew. - Improvements for macOS users using Homebrew.
- The software builds against GNU Radio >= 3.7.3, including 3.8.0. Automatically - The software builds against GNU Radio >= 3.7.3, including 3.8.0. Automatically
detected, no user intervention is required. detected, no user intervention is required.
- The volk_gnsssdr library can now be built without requiring Boost if the - The `volk_gnsssdr` library can now be built without requiring Boost if the
compiler supports C++17 or higher. compiler supports C++17 or higher.
- The Boost Filesystem library is not anymore a required dependency in cases - The Boost Filesystem library is not anymore a required dependency in cases
where it can be replaced by std::filesystem. Automatically detected, no user where it can be replaced by `std::filesystem`. Automatically detected, no user
intervention is required. intervention is required.
- CMake scripts automatically select among C++11, C++14, C++17 or C++20 - CMake scripts automatically select among C++11, C++14, C++17, or C++20
standards, the most recent as possible, depending on compiler and dependencies standards, the most recent as possible, depending on compiler and dependencies
versions. versions.
- Drawback in portability: Protocol Buffers >= 3.0.0 is a new required - Drawback in portability: Protocol Buffers >= 3.0.0 is a new required
@ -625,10 +649,11 @@ features and bug fixes:
- Included the Guidelines Support Library. General improvement of memory - Included the Guidelines Support Library. General improvement of memory
management, replacement of raw pointers by containers or smart pointers. management, replacement of raw pointers by containers or smart pointers.
- Applied clang-tidy checks and fixes related to High Integrity C++: - Applied clang-tidy checks and fixes related to High Integrity C++:
performance-move-const-arg, modernize-use-auto, modernize-use-equals-default, `performance-move-const-arg`, `modernize-use-auto`,
modernize-use-equals-delete, modernize-use-noexcept, modernize-use-nullptr, `modernize-use-equals-default`, `modernize-use-equals-delete`,
cert-dcl21-cpp, misc-new-delete-overloads, cert-dcl58-cpp, cert-err52-cpp, `modernize-use-noexcept`, `modernize-use-nullptr`, `cert-dcl21-cpp`,
cert-err60-cpp, hicpp-exception-baseclass, hicpp-explicit-conversions. `misc-new-delete-overloads`, `cert-dcl58-cpp`, `cert-err52-cpp`,
`cert-err60-cpp`, `hicpp-exception-baseclass`, `hicpp-explicit-conversions`.
- Fixed a number of defects detected by Coverity Scan (version June 2019). - Fixed a number of defects detected by Coverity Scan (version June 2019).
### Improvements in Usability: ### Improvements in Usability:
@ -638,12 +663,12 @@ features and bug fixes:
channels per signal in multiple bands. channels per signal in multiple bands.
- Fixed program termination (avoiding hangs and segfaults in some - Fixed program termination (avoiding hangs and segfaults in some
platforms/configurations). platforms/configurations).
- The Labsat_Signal_Source now terminates the receiver's execution when the end - The `Labsat_Signal_Source` now terminates the receiver's execution when the
of file(s) is reached. It now accepts LabSat 2 filenames and series of LabSat end of file(s) is reached. It now accepts LabSat 2 filenames and series of
3 files. LabSat 3 files.
- Added configuration parameters to set the annotation rate in KML, GPX, GeoJSON - Added configuration parameters to set the annotation rate in KML, GPX, GeoJSON
and NMEA outputs, set by default to 1 s. and NMEA outputs, set by default to 1 s.
- New parameter PVT.show_local_time_zone displays time in the local time zone. - New parameter `PVT.show_local_time_zone` displays time in the local time zone.
Subject to the proper system configuration of the machine running the software Subject to the proper system configuration of the machine running the software
receiver. This feature is not available in old compilers. receiver. This feature is not available in old compilers.
- CMake now generates a summary of required/optional dependency packages found - CMake now generates a summary of required/optional dependency packages found
@ -651,13 +676,15 @@ features and bug fixes:
features.log in the building directory. features.log in the building directory.
- Improved information provided to the user in case of building configuration - Improved information provided to the user in case of building configuration
and runtime failures. and runtime failures.
- Remove abandoned building option `-DENABLE_GN3S` and `Gn3s_Signal_Source`
implementation.
See the definitions of concepts and metrics at See the definitions of concepts and metrics at
https://gnss-sdr.org/design-forces/ https://gnss-sdr.org/design-forces/
&nbsp; &nbsp;
## [GNSS-SDR v0.0.10](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.10) ## [GNSS-SDR v0.0.10](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.10) - 2018-12-14
This release has several improvements in different dimensions, addition of new This release has several improvements in different dimensions, addition of new
features and bug fixes: features and bug fixes:
@ -693,11 +720,11 @@ features and bug fixes:
band are immediately searched in others. band are immediately searched in others.
- Complex local codes have been replaced by real codes, alleviating the - Complex local codes have been replaced by real codes, alleviating the
computational burden. computational burden.
- New volk_gnsssdr kernels: volk_gnsssdr_16i_xn_resampler_16i_xn.h, - New `volk_gnsssdr` kernels: `volk_gnsssdr_16i_xn_resampler_16i_xn.h`,
volk_gnsssdr_16ic_16i_rotator_dot_prod_16ic_xn.h, `volk_gnsssdr_16ic_16i_rotator_dot_prod_16ic_xn.h`,
volk_gnsssdr_32f_xn_resampler_32f_xn.h, `volk_gnsssdr_32f_xn_resampler_32f_xn.h`, and
volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h `volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h`.
- Some AVX2 implementations added to the volk_gnsssdr library. - Some AVX2 implementations added to the `volk_gnsssdr` library.
- Improvement in C++ usage: Use of const container calls when result is - Improvement in C++ usage: Use of const container calls when result is
immediately converted to a const iterator. Using these members removes an immediately converted to a const iterator. Using these members removes an
implicit conversion from iterator to const_iterator. implicit conversion from iterator to const_iterator.
@ -722,13 +749,13 @@ features and bug fixes:
- Added the GLONASS L2 SP receiver chain. - Added the GLONASS L2 SP receiver chain.
- Improvements in the Galileo E5a and GPS L2C receiver chains. - Improvements in the Galileo E5a and GPS L2C receiver chains.
- Updated list of available GNSS satellites. - Updated list of available GNSS satellites.
- Added five more signal sources: "Fmcomms2_Signal_Source" (requires gr-iio), - Added five more signal sources: `Fmcomms2_Signal_Source` (requires gr-iio),
"Plutosdr_Signal Source" (requires gr-iio), "Spir_GSS6450_File_Signal_Source", `Plutosdr_Signal Source` (requires gr-iio), `Spir_GSS6450_File_Signal_Source`,
"Labsat_Signal_Source" and "Custom_UDP_Signal_Source" (requires libpcap). `Labsat_Signal_Source` and `Custom_UDP_Signal_Source` (requires libpcap).
Documented in https://gnss-sdr.org/docs/sp-blocks/signal-source/ Documented in https://gnss-sdr.org/docs/sp-blocks/signal-source/
- Improved support for BladeRF, HackRF and RTL-SDR front-ends. - Improved support for BladeRF, HackRF and RTL-SDR front-ends.
- Added tools for the interaction with front-ends based on the AD9361 chipset. - Added tools for the interaction with front-ends based on the AD9361 chipset.
- Intermediate results are now saved in MAT-file format (.mat), readable from - Intermediate results are now saved in MAT-file format (`.mat`), readable from
Matlab/Octave and from Python via h5py. Matlab/Octave and from Python via h5py.
- Added the GPX output format. - Added the GPX output format.
- Improvements in the generation of KML files. - Improvements in the generation of KML files.
@ -741,7 +768,7 @@ features and bug fixes:
https://www.gsc-europa.eu/system-status/almanac-data https://www.gsc-europa.eu/system-status/almanac-data
- Own-defined XML schemas for navigation data published at - Own-defined XML schemas for navigation data published at
https://github.com/gnss-sdr/gnss-sdr/tree/next/docs/xml-schemas https://github.com/gnss-sdr/gnss-sdr/tree/next/docs/xml-schemas
- Added program rinex2assist to convert RINEX navigation files into XML files - Added program `rinex2assist` to convert RINEX navigation files into XML files
usable for Assisted GNSS. Only available building from source. See usable for Assisted GNSS. Only available building from source. See
https://github.com/gnss-sdr/gnss-sdr/tree/next/src/utils/rinex2assist https://github.com/gnss-sdr/gnss-sdr/tree/next/src/utils/rinex2assist
@ -769,7 +796,7 @@ features and bug fixes:
system headers. This helps to detect missing includes. system headers. This helps to detect missing includes.
- Improvement in C++ usage: Enhanced const correctness. Misuses of those - Improvement in C++ usage: Enhanced const correctness. Misuses of those
variables are detected by the compiler. variables are detected by the compiler.
- Improved code with clang-tidy and generation of a compile_commands.json file - Improved code with clang-tidy and generation of a `compile_commands.json` file
containing the exact compiler calls for all translation units of the project containing the exact compiler calls for all translation units of the project
in machine-readable form if clang-tidy is detected. in machine-readable form if clang-tidy is detected.
- Applied some style rules to CMake scripts. - Applied some style rules to CMake scripts.
@ -787,16 +814,16 @@ features and bug fixes:
- The software can now be built using GCC >= 4.7.2 or LLVM/Clang >= 3.4.0 - The software can now be built using GCC >= 4.7.2 or LLVM/Clang >= 3.4.0
compilers on GNU/Linux, and with Clang/AppleClang on macOS. compilers on GNU/Linux, and with Clang/AppleClang on macOS.
- The Ninja build system can be used in replacement of make. - The Ninja build system can be used in replacement of make.
- The volk_gnsssdr library can be built using Python 2.7+ or Python 3.6+. - The `volk_gnsssdr` library can be built using Python 2.7+ or Python 3.6+.
- The volk_gnsssdr library is now ready for AArch64 NEON instructions. - The `volk_gnsssdr` library is now ready for AArch64 NEON instructions.
- Improved detection of required and optional dependencies in many GNU/Linux - Improved detection of required and optional dependencies in many GNU/Linux
distributions and processor architectures. distributions and processor architectures.
- Improvement in C++ usage: The <ctime> library has been replaced by the more - Improvement in C++ usage: The `<ctime>` library has been replaced by the more
modern and portable <chrono> (except for the interaction with RTKLIB). modern and portable `<chrono>` (except for the interaction with RTKLIB).
- Improvement in C++ usage: The <stdio.h> library has been replaced by the more - Improvement in C++ usage: The `<stdio.h>` library has been replaced by the
modern and portable <fstream> for file handling. more modern and portable `<fstream>` for file handling.
- Improvement in C++ usage: C++ libraries preferred over C libraries (e.g., - Improvement in C++ usage: C++ libraries preferred over C libraries (e.g.,
<cctype> instead of <ctype.h>, <cmath> instead of <math.h>). `<cctype>` instead of `<ctype.h>`, `<cmath>` instead of `<math.h>`).
- Fix compatibility with Boost 1.67 (closes Debian bug #911882 - Fix compatibility with Boost 1.67 (closes Debian bug #911882
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=911882) https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=911882)
- Fixes required by Debian packaging. - Fixes required by Debian packaging.
@ -822,9 +849,9 @@ features and bug fixes:
- Fixed a number of defects detected by Coverity Scan. - Fixed a number of defects detected by Coverity Scan.
- Improvement of QA code and addition of a number of new tests. Documented at - Improvement of QA code and addition of a number of new tests. Documented at
https://gnss-sdr.org/docs/tutorials/testing-software-receiver-2/ https://gnss-sdr.org/docs/tutorials/testing-software-receiver-2/
- Improvement in C++ usage: rand() function replaced by <random> library. - Improvement in C++ usage: `rand()` function replaced by `<random>` library.
- Improvement in C++ usage: strlen and strncpy have been replaced by safer C++ - Improvement in C++ usage: `strlen` and `strncpy` have been replaced by safer
counterparts. C++ counterparts.
- Improvement in C++ usage: Some destructors have been fixed, avoiding - Improvement in C++ usage: Some destructors have been fixed, avoiding
segmentation faults when exiting the program. segmentation faults when exiting the program.
- Website switched from http to https. Links in the source tree switched when - Website switched from http to https. Links in the source tree switched when
@ -835,7 +862,7 @@ features and bug fixes:
- Setup of a Continuous Reproducibility system at GitLab for the automatic - Setup of a Continuous Reproducibility system at GitLab for the automatic
reproduction of experiments. The concept was introduced in reproduction of experiments. The concept was introduced in
https://ieeexplore.ieee.org/document/8331069/ Example added in the https://ieeexplore.ieee.org/document/8331069/ Example added in the
src/utils/reproducibility/ieee-access18/ folder. `src/utils/reproducibility/ieee-access18/` folder.
- Fixes of Lintian warnings related to build reproducibility. - Fixes of Lintian warnings related to build reproducibility.
### Improvements in Scalability: ### Improvements in Scalability:
@ -849,17 +876,17 @@ features and bug fixes:
- Several Unit Tests added. Documentation of testing concepts and available - Several Unit Tests added. Documentation of testing concepts and available
tests at https://gnss-sdr.org/docs/tutorials/testing-software-receiver/ tests at https://gnss-sdr.org/docs/tutorials/testing-software-receiver/
- New extra unit test AcquisitionPerformanceTest checks the performance of - New extra unit test `AcquisitionPerformanceTest` checks the performance of
Acquisition blocks. Acquisition blocks.
- New extra unit test TrackingPullInTest checks acquisition to tracking - New extra unit test `TrackingPullInTest` checks acquisition to tracking
transition. transition.
- New extra unit test HybridObservablesTest checks the generation of - New extra unit test `HybridObservablesTest` checks the generation of
observables. observables.
- Improved system testing: position_test accepts a wide list of parameters and - Improved system testing: position_test accepts a wide list of parameters and
can be used with external files. can be used with external files.
- Receiver channels can now be fixed to a given satellite. - Receiver channels can now be fixed to a given satellite.
- Testing integrated in a Continuous Reproducibility system (see above). - Testing integrated in a Continuous Reproducibility system (see above).
- Improved CTest support in volk_gnsssdr. - Improved CTest support in `volk_gnsssdr`.
### Improvements in Usability: ### Improvements in Usability:
@ -867,8 +894,8 @@ features and bug fixes:
implementation for all kinds of GNSS signals, making it easier to configure. implementation for all kinds of GNSS signals, making it easier to configure.
- All PVT block implementations have been merged into a single implementation - All PVT block implementations have been merged into a single implementation
for all kinds of GNSS signals, making it easier to configure. for all kinds of GNSS signals, making it easier to configure.
- Misleading parameter name GNSS-SDR.internal_fs_hz has been replaced by - Misleading parameter name `GNSS-SDR.internal_fs_hz` has been replaced by
GNSS-SDR.internal_fs_sps. The old parameter name is still read. If found, a `GNSS-SDR.internal_fs_sps`. The old parameter name is still read. If found, a
warning is provided to the user. The old name will be removed in future warning is provided to the user. The old name will be removed in future
releases. releases.
- Updated and improved online documentation of processing blocks at - Updated and improved online documentation of processing blocks at
@ -882,14 +909,14 @@ features and bug fixes:
template in the source tree. template in the source tree.
- Added colors to the commandline user interface. - Added colors to the commandline user interface.
- Updated manfiles. - Updated manfiles.
- Updated examples of configuration files under the conf/ folder. - Updated examples of configuration files under the `conf/` folder.
See the definitions of concepts and metrics at See the definitions of concepts and metrics at
https://gnss-sdr.org/design-forces/ https://gnss-sdr.org/design-forces/
&nbsp; &nbsp;
## [GNSS-SDR v0.0.9](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.9) ## [GNSS-SDR v0.0.9](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.9) - 2017-02-13
DOI: https://doi.org/10.5281/zenodo.291371 DOI: https://doi.org/10.5281/zenodo.291371
@ -914,8 +941,8 @@ many dimensions:
### Improvements in Efficiency: ### Improvements in Efficiency:
- VOLK_GNSSSDR: Added NEON,AVX and unaligned protokernels for - VOLK_GNSSSDR: Added NEON,AVX and unaligned protokernels for
volk_gnsssdr_32f_index_max_32 kernel. `volk_gnsssdr_32f_index_max_32` kernel.
- VOLK_GNSSSDR: Added volk_gnsssdr-config-info to the list of generated - VOLK_GNSSSDR: Added `volk_gnsssdr-config-info` to the list of generated
executables. executables.
### Improvements in Flexibility: ### Improvements in Flexibility:
@ -970,24 +997,24 @@ many dimensions:
### Improvements in Testability: ### Improvements in Testability:
- Major QA source code refactoring: they has been split into - Major QA source code refactoring: they has been split into
src/tests/unit-tests and src/tests/system-tests folders. They are optionally `src/tests/unit-tests` and `src/tests/system-tests` folders. They are
built with the ENABLE_UNIT_TESTING=ON (unit testing QA code), optionally built with the `ENABLE_UNIT_TESTING=ON` (unit testing QA code),
ENABLE_UNIT_TESTING_EXTRA=ON (unit tests that require extra files downloaded `ENABLE_UNIT_TESTING_EXTRA=ON` (unit tests that require extra files downloaded
at configure time), ENABLE_SYSTEM_TESTING=ON (system tests, such as at configure time), `ENABLE_SYSTEM_TESTING=ON` (system tests, such as
measurement of Time-To-First-Fix) and ENABLE_SYSTEM_TESTING_EXTRA=ON (extra measurement of Time-To-First-Fix) and `ENABLE_SYSTEM_TESTING_EXTRA=ON` (extra
system test requiring external tools, automatically downloaded and built at system test requiring external tools, automatically downloaded and built at
building time) configuration flags. The EXTRA options also download and build building time) configuration flags. The EXTRA options also download and build
a custom software-defined signal generator and version 2.9 of GPSTk, if not a custom software-defined signal generator and version 2.9 of GPSTk, if not
already found on the system. Download and local link of version 2.9 can be already found on the system. Download and local link of version 2.9 can be
forced by ENABLE_OWN_GPSTK=ON building configuration flag. Only forced by `ENABLE_OWN_GPSTK=ON` building configuration flag. Only
ENABLE_UNIT_TESTING is set to ON by default. `ENABLE_UNIT_TESTING` is set to ON by default.
- Unit tests added: CPU_multicorrelator_test and GPU_multicorrelator_test - Unit tests added: `CPU_multicorrelator_test` and `GPU_multicorrelator_test`
measure computer performance in multicorrelator setups. measure computer performance in multicorrelator setups.
- Unit tests added: GpsL1CADllPllTracking and GpsL1CATelemetryDecoderTest. - Unit tests added: `GpsL1CADllPllTracking` and `GpsL1CATelemetryDecoderTest`.
- System test added: ttff_gps_l1 performs a set of cold / assisted runs of the - System test added: `ttff_gps_l1` performs a set of cold / assisted runs of the
software receiver and computes statistics about the obtained Time To First software receiver and computes statistics about the obtained Time To First
Fix. Fix.
- System test added: obs_gps_l1_system_test uses an external software-defined - System test added: `obs_gps_l1_system_test` uses an external software-defined
signal generator to produce raw digital GNSS signal from a RINEX navigation signal generator to produce raw digital GNSS signal from a RINEX navigation
file and a position (static or dynamic), processes it with GNSS-SDR, and then file and a position (static or dynamic), processes it with GNSS-SDR, and then
compares the RINEX observation file produced by the software receiver to that compares the RINEX observation file produced by the software receiver to that
@ -1010,7 +1037,7 @@ https://gnss-sdr.org/design-forces/
&nbsp; &nbsp;
## [GNSS-SDR v0.0.8](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.8) ## [GNSS-SDR v0.0.8](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.8) - 2016-07-04
DOI: https://doi.org/10.5281/zenodo.57022 DOI: https://doi.org/10.5281/zenodo.57022
@ -1025,7 +1052,7 @@ respect to v0.0.7. The main changes are:
- Improved CUDA-based correlation. - Improved CUDA-based correlation.
- Updated documentation - Updated documentation
- Fixed building in mips and powerpc architectures. - Fixed building in mips and powerpc architectures.
- gr-gn3s and gr-dbfcttc moved to its own repository. - `gr-gn3s` and `gr-dbfcttc` moved to its own repository.
- Improved package reproducibility - Improved package reproducibility
- VOLK_GNSSSDR: Fixed a bug in AVX2 puppet - VOLK_GNSSSDR: Fixed a bug in AVX2 puppet
- VOLK_GNSSSDR: can now be built using the C98 standard - VOLK_GNSSSDR: can now be built using the C98 standard
@ -1036,7 +1063,7 @@ respect to v0.0.7. The main changes are:
&nbsp; &nbsp;
## [GNSS-SDR v0.0.7](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.7) ## [GNSS-SDR v0.0.7](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.7) - 2016-05-15
DOI: https://doi.org/10.5281/zenodo.51521 DOI: https://doi.org/10.5281/zenodo.51521
@ -1058,9 +1085,9 @@ This release has several improvements, addition of new features and bug fixes:
approach addresses both efficiency and portability. Now the library provides approach addresses both efficiency and portability. Now the library provides
the key kernels for GNSS signal processing in 16ic and 32fc versions, the key kernels for GNSS signal processing in 16ic and 32fc versions,
including SSE2, SSE3, SSE4.1, AVX, AV2 and NEON implementations. Please including SSE2, SSE3, SSE4.1, AVX, AV2 and NEON implementations. Please
execute volk_gnsssdr_profile and volk_profile to use the fastest execute `volk_gnsssdr_profile` and `volk_profile` to use the fastest
implementation for your host machine. implementation for your host machine.
- New source block: Two_Bit_Packed_File_Signal_Source. This block takes 2 bit - New source block: `Two_Bit_Packed_File_Signal_Source`. This block takes 2 bit
samples that have been packed into bytes or shorts as input and generates a samples that have been packed into bytes or shorts as input and generates a
byte for each sample. byte for each sample.
- Fixes in SUPL assistance (supl.nokia.com removed). - Fixes in SUPL assistance (supl.nokia.com removed).
@ -1075,38 +1102,38 @@ This release has several improvements, addition of new features and bug fixes:
- Improvements in tracking sensitivity: Added configuration option to customize - Improvements in tracking sensitivity: Added configuration option to customize
the extension of the GPS L1 CA correlation length after bit synchronization the extension of the GPS L1 CA correlation length after bit synchronization
(options are: [1,2,4,5,10,20] ms). Only available in the (options are: [1,2,4,5,10,20] ms). Only available in the
GPS_L1_CA_DLL_PLL_C_Aid_Tracking implementation. `GPS_L1_CA_DLL_PLL_C_Aid_Tracking` implementation.
- New tracking block introduced: GPS_L1_CA_DLL_PLL_C_Aid_Tracking is a GPS L1 - New tracking block introduced: `GPS_L1_CA_DLL_PLL_C_Aid_Tracking` is a GPS L1
C/A carrier PLL and code DLL with optional carrier-aid feedback. It is C/A carrier PLL and code DLL with optional carrier-aid feedback. It is
available in both 32 bits gr_complex input samples and in 16 bits short int available in both 32 bits `gr_complex` input samples and in 16 bits short int
complex samples. The gr_complex version has also the capability to extend the complex samples. The `gr_complex` version has also the capability to extend
coherent correlation period from 1ms to 20ms using telemetry symbol the coherent correlation period from 1 ms to 20 ms using telemetry symbol
synchronization. synchronization.
- Increased resolution in CN0 estimator internal variables. - Increased resolution in CN0 estimator internal variables.
- Fixed a bug in computation of GPS L1 C/A carrier phase observable. - Fixed a bug in computation of GPS L1 C/A carrier phase observable.
- Fixed a bug in the internal state machine that was blocking the receiver after - Fixed a bug in the internal state machine that was blocking the receiver after
a few hours of usage. Now the receiver can work continually (tested for more a few hours of usage. Now the receiver can work continually (tested for more
than one week, no known limit). than one week, no known limit).
- New tracking block introduced: GPS_L1_CA_DLL_PLL_Tracking_GPU is a GPS L1 C/A - New tracking block introduced: `GPS_L1_CA_DLL_PLL_Tracking_GPU` is a GPS L1
carrier PLL and code DLL that uses the CUDA-compatible GPU to compute carrier C/A carrier PLL and code DLL that uses the CUDA-compatible GPU to compute
wipe off and correlation operations, alleviating the CPU load. carrier wipe off and correlation operations, alleviating the CPU load.
- Obsolete/buggy blocks removed: GPS_L1_CA_DLL_FLL_PLL_Tracking, - Obsolete/buggy blocks removed: `GPS_L1_CA_DLL_FLL_PLL_Tracking`,
GPS_L1_CA_DLL_PLL_Optim_Tracking. `GPS_L1_CA_DLL_PLL_Optim_Tracking`.
- Added a RTCM printer and TCP server in PVT blocks (still experimental). The - Added a RTCM printer and TCP server in PVT blocks (still experimental). The
receiver is now able to stream data in real time, serving RTCM 3.2 messages to receiver is now able to stream data in real time, serving RTCM 3.2 messages to
multiple clients. For instance, it can act as a Ntrip Source feeding a Ntrip multiple clients. For instance, it can act as a Ntrip Source feeding a Ntrip
Server, or to be used as data input in RTKLIB, obtaining Precise Point Server, or to be used as data input in RTKLIB, obtaining Precise Point
Positioning fixes in real-time. The TCP port, Station ID, and rate of Positioning fixes in real-time. The TCP port, Station ID, and rate of
MT1019/MT1045 and MSM can be configured. GPS_L1_CA_PVT serves MT1019 (GPS MT1019/MT1045 and MSM can be configured. `GPS_L1_CA_PVT` serves MT1019 (GPS
Ephemeris) and MSM7 (MT1077, full GPS pseudoranges, phase ranges, phase range Ephemeris) and MSM7 (MT1077, full GPS pseudoranges, phase ranges, phase range
rates and CNR - high resolution) messages, while GALILEO_E1_PVT serves MT1045 rates and CNR - high resolution) messages, while `GALILEO_E1_PVT` serves
(Galileo ephemeris) and MSM7 (MT1097, full Galileo pseudoranges, phase ranges, MT1045 (Galileo ephemeris) and MSM7 (MT1097, full Galileo pseudoranges, phase
phase range rates and CNR - high resolution). ranges, phase range rates and CNR - high resolution).
- Added a GeoJSON printer. Basic (least-squares) position fixes can be now also - Added a GeoJSON printer. Basic (least-squares) position fixes can be now also
stored in this format, in addition to KML. stored in this format, in addition to KML.
- Obsolete block removed: output filter. - Obsolete block removed: output filter.
- QA code migrated to the new asynchronous message passing system. - QA code migrated to the new asynchronous message passing system.
- Improvements in documentation: update of README.md file, addition of - Improvements in documentation: update of `README.md` file, addition of
documentation for the VOLK_GNSSSDR library, updated links to new ICDs. documentation for the VOLK_GNSSSDR library, updated links to new ICDs.
- Improvements in documentation: Satellite identification updated to current - Improvements in documentation: Satellite identification updated to current
constellation status. constellation status.
@ -1128,7 +1155,7 @@ This release has several improvements, addition of new features and bug fixes:
&nbsp; &nbsp;
## [GNSS-SDR v0.0.6](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.6) ## [GNSS-SDR v0.0.6](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.6) - 2015-09-02
This release has several improvements and bug fixes: This release has several improvements and bug fixes:
@ -1151,12 +1178,13 @@ This release has several improvements and bug fixes:
on the Realtek's RTL2832U chipset. on the Realtek's RTL2832U chipset.
- Fixed bug in UTC time computation for GPS signals. - Fixed bug in UTC time computation for GPS signals.
- Updated satellite identification for GPS and Galileo. - Updated satellite identification for GPS and Galileo.
- Defined cbyte as a new input data type (std::complex<unsigned char>) - Defined `cbyte` as a new input data type (`std::complex<signed char>`).
- Adding a new data_type_adapter, from interleaved short to std::complex<short> - Adding a new data_type_adapter, from interleaved short to
`std::complex<short>`.
- Adding a filter for complex short streams. - Adding a filter for complex short streams.
- Adding a fir_filter for std::complex<signed char> (aka cbyte). It converts the - Adding a fir_filter for `std::complex<signed char>` (aka `cbyte`). It converts
data type to floats, filters, and converts back to cbyte. the data type to floats, filters, and converts back to cbyte.
- Added a resampler for cbytes and cshorts. - Added a resampler for `cbyte`s and `cshort`s.
- First working version of a GPS tracking block implementation using CUDA with - First working version of a GPS tracking block implementation using CUDA with
multi-GPU device support. multi-GPU device support.
- Updating RINEX obs header when leap second is available. - Updating RINEX obs header when leap second is available.
@ -1177,34 +1205,34 @@ This release has several improvements and bug fixes:
&nbsp; &nbsp;
## [GNSS-SDR v0.0.5](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.5) ## [GNSS-SDR v0.0.5](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.5) - 2015-01-13
This release has several improvements and bug fixes: This release has several improvements and bug fixes:
- Now GNSS-SDR can be installed on the system with the usual cmake ../ && make - Now GNSS-SDR can be installed on the system with the usual
&& sudo make install. `cmake ../ && make && sudo make install`.
- Added volk_gnsssdr library, a volk-like library implementing some specific - Added `volk_gnsssdr` library, a volk-like library implementing some specific
kernels and ensuring portable executables. It comes with a kernels and ensuring portable executables. It comes with a
volk_gnsssdr_profile executable, in the fashion of volk_profile. Volk and `volk_gnsssdr_profile` executable, in the fashion of `volk_profile`. Volk and
volk_gnsssdr are compatible and can be mixed together. This is expected to `volk_gnsssdr` are compatible and can be mixed together. This is expected to
enable faster execution of the software receiver in upcoming versions. enable faster execution of the software receiver in upcoming versions.
- The former rtlsdr_signal_source has been replaced by a more general - The former `rtlsdr_signal_source` has been replaced by a more general
osmosdr_signal_source compatible with all those front-ends accessible by the `osmosdr_signal_source` compatible with all those front-ends accessible by the
OsmoSDR driver (bladeRF, hackRF, etc.) in addition to RTL-based dongles. OsmoSDR driver (bladeRF, hackRF, etc.) in addition to RTL-based dongles.
- Added manpages when binaries gnss-sdr, volk_gnsssdr_profile and front-end-cal - Added manpages when binaries `gnss-sdr`, `volk_gnsssdr_profile` and
are installed. `front-end-cal` are installed.
- Now GNSS-SDR can be built on i386, amd64, armhf, armel and arm64 - Now GNSS-SDR can be built on i386, amd64, armhf, armel and arm64
architectures. architectures.
- Now GNSS-SDR builds on Ubuntu 14.04 and 14.10, Debian jessie/sid and Mac OS X - Now GNSS-SDR builds on Ubuntu 14.04 and 14.10, Debian jessie/sid and Mac OS X
10.9 and 10.10. 10.9 and 10.10.
- Improved detection of dependencies, specially when installed as .deb packages. - Improved detection of dependencies, specially when installed as .deb packages.
- Added a check' target with some minimal tests. - Added a `check` target with some minimal tests.
- Added support for interleaved I/Q byte-size sample files. - Added support for interleaved I/Q byte-size sample files.
- Minor bug fixes, updated documentation and code cleaning. - Minor bug fixes, updated documentation and code cleaning.
&nbsp; &nbsp;
## [GNSS-SDR v0.0.4](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.4) ## [GNSS-SDR v0.0.4](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.4) - 2014-09-08
This release has several improvements and bug fixes: This release has several improvements and bug fixes:
@ -1218,14 +1246,14 @@ This release has several improvements and bug fixes:
same receiver. same receiver.
- Added tropospheric corrections to GPS and Galileo PVT solution. - Added tropospheric corrections to GPS and Galileo PVT solution.
- Improved precision obtained by changing some variables from float to double. - Improved precision obtained by changing some variables from float to double.
- New building options: ENABLE_GN3S, ENABLE_RTLSDR and ENABLE_ARRAY and - New building options: `ENABLE_GN3S`, `ENABLE_RTLSDR`, `ENABLE_ARRAY`, and
ENABLE_OPENCL. `ENABLE_OPENCL`.
- Improved documentation on how to enable optional drivers. - Improved documentation on how to enable optional drivers.
- Fixed bug in memory alignment that caused problems with high data rates. - Fixed bug in memory alignment that caused problems with high data rates.
- Added ENABLE_GENERIC_ARCH, an option to build the binary without detecting the - Added `ENABLE_GENERIC_ARCH`, an option to build the binary without detecting
SIMD instruction set present in the compiling machine, so it can be executed the SIMD instruction set present in the compiling machine, so it can be
in other machines without those specific sets. executed in other machines without those specific sets.
- Added ENABLE_GPERFTOOLS, which links the executable to tcmalloc and profiler - Added `ENABLE_GPERFTOOLS`, which links the executable to tcmalloc and profiler
if Gperftools is available on the system. if Gperftools is available on the system.
- Added carrier phase, Doppler shift and signal strength observables to the - Added carrier phase, Doppler shift and signal strength observables to the
RINEX files. Static PPP solutions are available for GPS with RTKLIB via RINEX RINEX files. Static PPP solutions are available for GPS with RTKLIB via RINEX
@ -1241,7 +1269,7 @@ This release has several improvements and bug fixes:
&nbsp; &nbsp;
## [GNSS-SDR v0.0.3](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.3) ## [GNSS-SDR v0.0.3](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.3) - 2014-06-30
This release has several improvements and bug fixes, completing the transition This release has several improvements and bug fixes, completing the transition
from Subversion to Git. The main changes are: from Subversion to Git. The main changes are:

View File

@ -61,7 +61,6 @@ As signal inputs, it accepts:
\li Raw data file captured with a data grabber (digitized at some intermediate frequency or directly at baseband). \li Raw data file captured with a data grabber (digitized at some intermediate frequency or directly at baseband).
\li Any suitable RF configuration that can be driven by the Universal Software Radio Peripheral Hardware Driver (<a href="https://files.ettus.com/uhd_docs/manual/html/" target="_blank">UHD</a>). \li Any suitable RF configuration that can be driven by the Universal Software Radio Peripheral Hardware Driver (<a href="https://files.ettus.com/uhd_docs/manual/html/" target="_blank">UHD</a>).
This includes all current and future <a href="https://www.ettus.com/">Ettus Research</a> products. The USRP1 + DBSRX 2.2 daughterboard is an example of working configuration for GPS L1 C/A and Galileo E1B and E1C signals. This includes all current and future <a href="https://www.ettus.com/">Ettus Research</a> products. The USRP1 + DBSRX 2.2 daughterboard is an example of working configuration for GPS L1 C/A and Galileo E1B and E1C signals.
\li The <a href="https://gnss-sdr.org/docs/tutorials/sige-gn3s-sampler-v2-usb-front-end/" target="blank">GN3S v2 USB dongle</a> (GN3S v3 might work with small modifications).
\li Experimentally, with some <a href="https://gnss-sdr.org/docs/tutorials/gnss-sdr-operation-realtek-rtl2832u-usb-dongle-dvb-t-receiver/" target="_blank">USB DVB-T dongles based on the Realtek RTL2832U chipset</a>. \li Experimentally, with some <a href="https://gnss-sdr.org/docs/tutorials/gnss-sdr-operation-realtek-rtl2832u-usb-dongle-dvb-t-receiver/" target="_blank">USB DVB-T dongles based on the Realtek RTL2832U chipset</a>.
\li For mathematical representations of the targeted signals, check out the \ref the_signal_model page. \li For mathematical representations of the targeted signals, check out the \ref the_signal_model page.
@ -630,8 +629,8 @@ of a Radio Frequency front-end's Analog-to_Digital converter. GNSS-SDR needs sig
Prepare your configuration file, and then you are ready for going to the <tt> gnss-sdr/install</tt> folder, running <tt>./gnss-sdr</tt>, and see how the file is processed. Prepare your configuration file, and then you are ready for going to the <tt> gnss-sdr/install</tt> folder, running <tt>./gnss-sdr</tt>, and see how the file is processed.
Please ask the Developer Team for a signal sample if you need one, and they will do their best ;-) Please ask the Developer Team for a signal sample if you need one, and they will do their best ;-)
Another interesting option is working in real-time with a RF front-end. We provide drivers for UHD-compatible hardware (see \ref signal_source), for the GN3S v2 USB dongle Another interesting option is working in real-time with a RF front-end. We provide drivers for UHD-compatible hardware (see \ref signal_source) and for some DVB-T USB dongles.
and for some DVB-T USB dongles. Start with a low number of channels and then increase it in order to test how many channels your processor can handle in real-time. Start with a low number of channels and then increase it in order to test how many channels your processor can handle in real-time.
You can find more information at the <a href="https://gnss-sdr.org/docs/" target="_blank"><b>GNSS-SDR Documentation page</b></a> or directly asking to the You can find more information at the <a href="https://gnss-sdr.org/docs/" target="_blank"><b>GNSS-SDR Documentation page</b></a> or directly asking to the
<a href="https://lists.sourceforge.net/lists/listinfo/gnss-sdr-developers" target="_blank"><b>GNSS-SDR Developers mailing list</b></a>. <a href="https://lists.sourceforge.net/lists/listinfo/gnss-sdr-developers" target="_blank"><b>GNSS-SDR Developers mailing list</b></a>.

View File

@ -58,7 +58,9 @@ Rtklib_Pvt::Rtklib_Pvt(const ConfigurationInterface* configuration,
pvt_output_parameters.pre_2009_file = configuration->property("GNSS-SDR.pre_2009_file", false); pvt_output_parameters.pre_2009_file = configuration->property("GNSS-SDR.pre_2009_file", false);
// output rate // output rate
pvt_output_parameters.output_rate_ms = bc::lcm(20, configuration->property(role + ".output_rate_ms", 500)); pvt_output_parameters.observable_interval_ms = configuration->property("GNSS-SDR.observable_interval_ms", pvt_output_parameters.observable_interval_ms);
pvt_output_parameters.output_rate_ms = bc::lcm(static_cast<int>(pvt_output_parameters.observable_interval_ms), configuration->property(role + ".output_rate_ms", 500));
// display rate // display rate
pvt_output_parameters.display_rate_ms = bc::lcm(pvt_output_parameters.output_rate_ms, configuration->property(role + ".display_rate_ms", 500)); pvt_output_parameters.display_rate_ms = bc::lcm(pvt_output_parameters.output_rate_ms, configuration->property(role + ".display_rate_ms", 500));
@ -590,7 +592,7 @@ Rtklib_Pvt::Rtklib_Pvt(const ConfigurationInterface* configuration,
{ {
nsys += SYS_GPS; nsys += SYS_GPS;
} }
if ((gal_1B_count > 0) || (gal_E5a_count > 0) || (gal_E5b_count > 0)) if ((gal_1B_count > 0) || (gal_E5a_count > 0) || (gal_E5b_count > 0) || (gal_E6_count > 0))
{ {
nsys += SYS_GAL; nsys += SYS_GAL;
} }

View File

@ -176,6 +176,7 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
d_nchannels = nchannels; d_nchannels = nchannels;
d_type_of_rx = conf_.type_of_receiver; d_type_of_rx = conf_.type_of_receiver;
d_observable_interval_ms = conf_.observable_interval_ms;
// GPS Ephemeris data message port in // GPS Ephemeris data message port in
this->message_port_register_in(pmt::mp("telemetry")); this->message_port_register_in(pmt::mp("telemetry"));
@ -189,6 +190,20 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
boost::bind(&rtklib_pvt_gs::msg_handler_telemetry, this, _1)); boost::bind(&rtklib_pvt_gs::msg_handler_telemetry, this, _1));
#endif #endif
#endif #endif
// Galileo E6 HAS messages port in
this->message_port_register_in(pmt::mp("E6_HAS_to_PVT"));
this->set_msg_handler(pmt::mp("E6_HAS_to_PVT"),
#if HAS_GENERIC_LAMBDA
[this](auto&& PH1) { msg_handler_has_data(PH1); });
#else
#if USE_BOOST_BIND_PLACEHOLDERS
boost::bind(&rtklib_pvt_gs::msg_handler_has_data, this, boost::placeholders::_1));
#else
boost::bind(&rtklib_pvt_gs::msg_handler_has_data, this, _1));
#endif
#endif
// initialize kml_printer // initialize kml_printer
const std::string kml_dump_filename = d_dump_filename; const std::string kml_dump_filename = d_dump_filename;
d_kml_output_enabled = conf_.kml_output_enabled; d_kml_output_enabled = conf_.kml_output_enabled;
@ -512,6 +527,7 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
d_beidou_dnav_iono_sptr_type_hash_code = typeid(std::shared_ptr<Beidou_Dnav_Iono>).hash_code(); d_beidou_dnav_iono_sptr_type_hash_code = typeid(std::shared_ptr<Beidou_Dnav_Iono>).hash_code();
d_beidou_dnav_utc_model_sptr_type_hash_code = typeid(std::shared_ptr<Beidou_Dnav_Utc_Model>).hash_code(); d_beidou_dnav_utc_model_sptr_type_hash_code = typeid(std::shared_ptr<Beidou_Dnav_Utc_Model>).hash_code();
d_beidou_dnav_almanac_sptr_type_hash_code = typeid(std::shared_ptr<Beidou_Dnav_Almanac>).hash_code(); d_beidou_dnav_almanac_sptr_type_hash_code = typeid(std::shared_ptr<Beidou_Dnav_Almanac>).hash_code();
d_galileo_has_data_sptr_type_hash_code = typeid(std::shared_ptr<Galileo_HAS_data>).hash_code();
//timetag //timetag
d_log_timetag = conf_.log_source_timetag; d_log_timetag = conf_.log_source_timetag;
@ -1485,6 +1501,25 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
} }
void rtklib_pvt_gs::msg_handler_has_data(const pmt::pmt_t& msg) const
{
try
{
const size_t msg_type_hash_code = pmt::any_ref(msg).type().hash_code();
if (msg_type_hash_code == d_galileo_has_data_sptr_type_hash_code)
{
const auto has_data = boost::any_cast<std::shared_ptr<Galileo_HAS_data>>(pmt::any_ref(msg));
// TODO: Dump HAS message
// std::cout << "HAS data received at PVT block.\n";
}
}
catch (const boost::bad_any_cast& e)
{
LOG(WARNING) << "msg_handler_has_data Bad any_cast: " << e.what();
}
}
std::map<int, Gps_Ephemeris> rtklib_pvt_gs::get_gps_ephemeris_map() const std::map<int, Gps_Ephemeris> rtklib_pvt_gs::get_gps_ephemeris_map() const
{ {
return d_internal_pvt_solver->gps_ephemeris_map; return d_internal_pvt_solver->gps_ephemeris_map;
@ -2060,8 +2095,8 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
if (!d_gnss_observables_map_t0.empty()) if (!d_gnss_observables_map_t0.empty())
{ {
const auto t0_int_ms = static_cast<uint32_t>(d_gnss_observables_map_t0.cbegin()->second.RX_time * 1000.0); const auto t0_int_ms = static_cast<uint32_t>(d_gnss_observables_map_t0.cbegin()->second.RX_time * 1000.0);
const uint32_t adjust_next_20ms = 20 - t0_int_ms % 20; const uint32_t adjust_next_obs_interval_ms = d_observable_interval_ms - t0_int_ms % d_observable_interval_ms;
current_RX_time_ms = t0_int_ms + adjust_next_20ms; current_RX_time_ms = t0_int_ms + adjust_next_obs_interval_ms;
if (current_RX_time_ms % d_output_rate_ms == 0) if (current_RX_time_ms % d_output_rate_ms == 0)
{ {

View File

@ -137,6 +137,8 @@ private:
void msg_handler_telemetry(const pmt::pmt_t& msg); void msg_handler_telemetry(const pmt::pmt_t& msg);
void msg_handler_has_data(const pmt::pmt_t& msg) const;
void initialize_and_apply_carrier_phase_offset(); void initialize_and_apply_carrier_phase_offset();
void apply_rx_clock_offset(std::map<int, Gnss_Synchro>& observables_map, void apply_rx_clock_offset(std::map<int, Gnss_Synchro>& observables_map,
@ -233,6 +235,7 @@ private:
size_t d_beidou_dnav_iono_sptr_type_hash_code; size_t d_beidou_dnav_iono_sptr_type_hash_code;
size_t d_beidou_dnav_utc_model_sptr_type_hash_code; size_t d_beidou_dnav_utc_model_sptr_type_hash_code;
size_t d_beidou_dnav_almanac_sptr_type_hash_code; size_t d_beidou_dnav_almanac_sptr_type_hash_code;
size_t d_galileo_has_data_sptr_type_hash_code;
double d_rinex_version; double d_rinex_version;
double d_rx_time; double d_rx_time;
@ -260,6 +263,7 @@ private:
uint32_t d_nchannels; uint32_t d_nchannels;
uint32_t d_type_of_rx; uint32_t d_type_of_rx;
uint32_t d_observable_interval_ms;
bool d_dump; bool d_dump;
bool d_dump_mat; bool d_dump_mat;

View File

@ -19,6 +19,7 @@
Pvt_Conf::Pvt_Conf() Pvt_Conf::Pvt_Conf()
{ {
type_of_receiver = 0U; type_of_receiver = 0U;
observable_interval_ms = 20U;
output_rate_ms = 0; output_rate_ms = 0;
display_rate_ms = 0; display_rate_ms = 0;
kml_rate_ms = 1000; kml_rate_ms = 1000;

View File

@ -51,6 +51,8 @@ public:
std::string udp_eph_addresses; std::string udp_eph_addresses;
uint32_t type_of_receiver; uint32_t type_of_receiver;
uint32_t observable_interval_ms;
int32_t output_rate_ms; int32_t output_rate_ms;
int32_t display_rate_ms; int32_t display_rate_ms;
int32_t kml_rate_ms; int32_t kml_rate_ms;

View File

@ -235,6 +235,10 @@ std::string galileo_e6_c_secondary_code(int32_t prn)
{ {
std::string dest(static_cast<size_t>(GALILEO_E6_C_SECONDARY_CODE_LENGTH_CHIPS), '0'); std::string dest(static_cast<size_t>(GALILEO_E6_C_SECONDARY_CODE_LENGTH_CHIPS), '0');
const uint32_t prn_ = prn - 1; const uint32_t prn_ = prn - 1;
if ((prn < 1) || (prn > 50))
{
return dest;
}
uint32_t index = 0; uint32_t index = 0;
for (size_t i = 0; i < GALILEO_E6_C_SECONDARY_CODE_STR_LENGTH; i++) for (size_t i = 0; i < GALILEO_E6_C_SECONDARY_CODE_STR_LENGTH; i++)
{ {

View File

@ -8,7 +8,7 @@
######################################################################## ########################################################################
# Project setup # Project setup
######################################################################## ########################################################################
cmake_minimum_required(VERSION 2.8.12...3.19) cmake_minimum_required(VERSION 2.8.12...3.20)
if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release") set(CMAKE_BUILD_TYPE "Release")
endif() endif()
@ -204,7 +204,7 @@ message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
set(VERSION_INFO_MAJOR_VERSION 0) set(VERSION_INFO_MAJOR_VERSION 0)
set(VERSION_INFO_MINOR_VERSION 0) set(VERSION_INFO_MINOR_VERSION 0)
set(VERSION_INFO_MAINT_VERSION 14.git) set(VERSION_INFO_MAINT_VERSION 14.git)
include(VolkVersion) # setup version info include(VolkGnsssdrVersion) # setup version info

View File

@ -0,0 +1,99 @@
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
# This file is part of GNSS-SDR.
#
# Copyright (C) 2015-2021 (see AUTHORS file for a list of contributors)
# SPDX-License-Identifier: BSD-3-Clause
if(DEFINED __INCLUDED_VOLK_VERSION_CMAKE)
return()
endif()
set(__INCLUDED_VOLK_VERSION_CMAKE TRUE)
#eventually, replace version.sh and fill in the variables below
set(MAJOR_VERSION ${VERSION_INFO_MAJOR_VERSION})
set(MINOR_VERSION ${VERSION_INFO_MINOR_VERSION})
set(MAINT_VERSION ${VERSION_INFO_MAINT_VERSION})
########################################################################
# Extract the version string from git describe.
########################################################################
find_package(Git)
if(GIT_FOUND)
message(STATUS "Extracting version information from git...")
# was this info set in the CMake commandline?
if(NOT GIT_BRANCH)
# no: try to find it
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
# was this info set in the CMake commandline?
if(NOT GIT_COMMIT_HASH)
# Get the latest abbreviated commit hash of the working branch
execute_process(
COMMAND ${GIT_EXECUTABLE} log -1 --format=%h
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
set(VOLK_GNSSSDR_GIT_BRANCH "${GIT_BRANCH}")
set(VOLK_GNSSSDR_GIT_HASH "${GIT_COMMIT_HASH}")
else()
if(GIT_COMMIT_HASH)
set(VOLK_GNSSSDR_GIT_HASH "${GIT_COMMIT_HASH}")
else()
set(VOLK_GNSSSDR_GIT_HASH "unknown")
endif()
if(GIT_BRANCH)
set(VOLK_GNSSSDR_GIT_BRANCH "${GIT_BRANCH}")
else()
set(VOLK_GNSSSDR_GIT_BRANCH "unknown")
endif()
endif()
if("${MAINT_VERSION}" MATCHES "git")
set(GIT_DESCRIBE "v${MAJOR_VERSION}.${MINOR_VERSION}.${MAINT_VERSION}-${VOLK_GNSSSDR_GIT_BRANCH}-${VOLK_GNSSSDR_GIT_HASH}")
else()
set(GIT_DESCRIBE "v${MAJOR_VERSION}.${MINOR_VERSION}.${MAINT_VERSION}")
endif()
########################################################################
# Use the logic below to set the version constants
########################################################################
if("${MINOR_VERSION}" STREQUAL "git")
# VERSION: 1.0git-xxx-gxxxxxxxx
# DOCVER: 1.0git
# LIBVER: 1.0git
# SOVERSION: 1.0git
set(VERSION "${GIT_DESCRIBE}")
set(DOCVER "${MAJOR_VERSION}.0${MINOR_VERSION}")
set(LIBVER "${MAJOR_VERSION}.0${MINOR_VERSION}")
set(SOVERSION "${MAJOR_VERSION}.0${MINOR_VERSION}")
elseif("${MAINT_VERSION}" MATCHES "git")
# VERSION: 1.2.3.git-xxx-gxxxxxxxx
# DOCVER: 1.2.3.git
# LIBVER: 1.2.3.git
# SOVERSION: 1.2.3.git
set(VERSION "${GIT_DESCRIBE}")
set(DOCVER "${MAJOR_VERSION}.${MINOR_VERSION}.${MAINT_VERSION}")
set(LIBVER "${MAJOR_VERSION}.${MINOR_VERSION}.${MAINT_VERSION}")
set(SOVERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MAINT_VERSION}")
else()
# This is a numbered release.
# VERSION: 1.2{.3}
# DOCVER: 1.2{.3}
# SOVERSION: 1.2.3
if("${MAINT_VERSION}" STREQUAL "0")
set(VERSION "${MAJOR_VERSION}.${MINOR_VERSION}")
else()
set(VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MAINT_VERSION}")
endif()
set(DOCVER "${VERSION}")
set(SOVERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MAINT_VERSION}")
endif()

View File

@ -1,76 +0,0 @@
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
# This file is part of GNSS-SDR.
#
# Copyright (C) 2015-2020 (see AUTHORS file for a list of contributors)
# SPDX-License-Identifier: BSD-3-Clause
if(DEFINED __INCLUDED_VOLK_VERSION_CMAKE)
return()
endif()
set(__INCLUDED_VOLK_VERSION_CMAKE TRUE)
#eventually, replace version.sh and fill in the variables below
set(MAJOR_VERSION ${VERSION_INFO_MAJOR_VERSION})
set(MINOR_VERSION ${VERSION_INFO_MINOR_VERSION})
set(MAINT_VERSION ${VERSION_INFO_MAINT_VERSION})
########################################################################
# Extract the version string from git describe.
########################################################################
find_package(Git)
if(GIT_FOUND AND EXISTS ${PROJECT_SOURCE_DIR}/.git)
message(STATUS "Extracting version information from git describe...")
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --always --abbrev=8 --long
OUTPUT_VARIABLE GIT_DESCRIBE OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
else()
if(NOT VOLK_GIT_COUNT)
set(VOLK_GIT_COUNT "0")
endif()
if(NOT VOLK_GIT_HASH)
set(VOLK_GIT_HASH "unknown")
endif()
set(GIT_DESCRIBE "v${MAJOR_VERSION}.${MINOR_VERSION}-${VOLK_GIT_COUNT}-${VOLK_GIT_HASH}")
endif()
########################################################################
# Use the logic below to set the version constants
########################################################################
if("${MINOR_VERSION}" STREQUAL "git")
# VERSION: 1.0git-xxx-gxxxxxxxx
# DOCVER: 1.0git
# LIBVER: 1.0git
set(VERSION "${GIT_DESCRIBE}")
set(DOCVER "${MAJOR_VERSION}.0${MINOR_VERSION}")
set(LIBVER "${MAJOR_VERSION}.0${MINOR_VERSION}")
set(RC_MINOR_VERSION "0")
set(RC_MAINT_VERSION "0")
elseif("${MAINT_VERSION}" STREQUAL "git")
# VERSION: 1.xgit-xxx-gxxxxxxxx
# DOCVER: 1.xgit
# LIBVER: 1.xgit
set(VERSION "${GIT_DESCRIBE}")
set(DOCVER "${MAJOR_VERSION}.${MINOR_VERSION}${MAINT_VERSION}")
set(LIBVER "${MAJOR_VERSION}.${MINOR_VERSION}${MAINT_VERSION}")
math(EXPR RC_MINOR_VERSION "${MINOR_VERSION} - 1")
set(RC_MAINT_VERSION "0")
else()
# This is a numbered release.
# VERSION: 1.1{.x}
# DOCVER: 1.1{.x}
# LIBVER: 1.1{.x}
if("${MAINT_VERSION}" STREQUAL "0")
set(VERSION "${MAJOR_VERSION}.${MINOR_VERSION}")
else()
set(VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MAINT_VERSION}")
endif()
set(DOCVER "${VERSION}")
set(LIBVER "${VERSION}")
set(RC_MINOR_VERSION ${MINOR_VERSION})
set(RC_MAINT_VERSION ${MAINT_VERSION})
endif()

View File

@ -23,6 +23,16 @@ if(NOT CMAKE_BUILD_TYPE)
FORCE) FORCE)
endif() endif()
# Workaround for cross-compilation with SDK
if(DEFINED ENV{OECORE_TARGET_SYSROOT})
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/Toolchains/oe-sdk_cross.cmake)
set(CMAKE_CROSSCOMPILING ON)
include(${CMAKE_TOOLCHAIN_FILE})
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^cortexa9hf")
set(CMAKE_SYSTEM_PROCESSOR arm-${CMAKE_SYSTEM_PROCESSOR})
endif()
endif()
# BUILD_TESTING is a standard CMake variable, but we declare it here to make it # BUILD_TESTING is a standard CMake variable, but we declare it here to make it
# prominent in the GUI. # prominent in the GUI.
option(BUILD_TESTING "Enable test (depends on googletest)." OFF) option(BUILD_TESTING "Enable test (depends on googletest)." OFF)

View File

@ -44,7 +44,7 @@ instructions) at runtime.
## Code samples ## Code samples
**Note:** For C++ code, the library functions are defined in the `CpuFeatures` **Note:** For C++ code, the library functions are defined in the `cpu_features`
namespace. namespace.
### Checking features at runtime ### Checking features at runtime
@ -55,7 +55,7 @@ AES and the SSE4.2 instruction sets:
```c ```c
#include "cpuinfo_x86.h" #include "cpuinfo_x86.h"
// For C++, add `using namespace CpuFeatures;` // For C++, add `using namespace cpu_features;`
static const X86Features features = GetX86Info().features; static const X86Features features = GetX86Info().features;
void Compute(void) { void Compute(void) {
@ -77,7 +77,7 @@ features and then check whether AES and NEON are supported.
#include <stdbool.h> #include <stdbool.h>
#include "cpuinfo_arm.h" #include "cpuinfo_arm.h"
// For C++, add `using namespace CpuFeatures;` // For C++, add `using namespace cpu_features;`
static const ArmFeatures features = GetArmInfo().features; static const ArmFeatures features = GetArmInfo().features;
static const bool has_aes_and_neon = features.aes && features.neon; static const bool has_aes_and_neon = features.aes && features.neon;
@ -97,7 +97,7 @@ instruction set (e.g., `g++ -mavx`) and sets `has_avx` accordingly.
#include <stdbool.h> #include <stdbool.h>
#include "cpuinfo_x86.h" #include "cpuinfo_x86.h"
// For C++, add `using namespace CpuFeatures;` // For C++, add `using namespace cpu_features;`
static const X86Features features = GetX86Info().features; static const X86Features features = GetX86Info().features;
static const bool has_avx = CPU_FEATURES_COMPILED_X86_AVX || features.avx; static const bool has_avx = CPU_FEATURES_COMPILED_X86_AVX || features.avx;
@ -120,7 +120,7 @@ set&mdash;but only if it's not Sandy Bridge.
#include <stdbool.h> #include <stdbool.h>
#include "cpuinfo_x86.h" #include "cpuinfo_x86.h"
// For C++, add `using namespace CpuFeatures;` // For C++, add `using namespace cpu_features;`
static const X86Info info = GetX86Info(); static const X86Info info = GetX86Info();
static const X86Microarchitecture uarch = GetX86Microarchitecture(&info); static const X86Microarchitecture uarch = GetX86Microarchitecture(&info);
static const bool has_fast_avx = info.features.avx && uarch != INTEL_SNB; static const bool has_fast_avx = info.features.avx && uarch != INTEL_SNB;

View File

@ -79,6 +79,7 @@ typedef struct
int dca : 1; int dca : 1;
int ss : 1; int ss : 1;
int adx : 1;
// Make sure to update X86FeaturesEnum below if you add a field here. // Make sure to update X86FeaturesEnum below if you add a field here.
} X86Features; } X86Features;
@ -207,6 +208,7 @@ typedef enum
X86_RDRND, X86_RDRND,
X86_DCA, X86_DCA,
X86_SS, X86_SS,
X86_ADX,
X86_LAST_, X86_LAST_,
} X86FeaturesEnum; } X86FeaturesEnum;

View File

@ -74,7 +74,8 @@
FEATURE(X86_MOVBE, movbe, "movbe", 0, 0) \ FEATURE(X86_MOVBE, movbe, "movbe", 0, 0) \
FEATURE(X86_RDRND, rdrnd, "rdrnd", 0, 0) \ FEATURE(X86_RDRND, rdrnd, "rdrnd", 0, 0) \
FEATURE(X86_DCA, dca, "dca", 0, 0) \ FEATURE(X86_DCA, dca, "dca", 0, 0) \
FEATURE(X86_SS, ss, "ss", 0, 0) FEATURE(X86_SS, ss, "ss", 0, 0) \
FEATURE(X86_ADX, adx, "adx", 0, 0)
#define DEFINE_TABLE_FEATURE_TYPE X86Features #define DEFINE_TABLE_FEATURE_TYPE X86Features
#define DEFINE_TABLE_DONT_GENERATE_HWCAPS #define DEFINE_TABLE_DONT_GENERATE_HWCAPS
#include "define_tables.h" #include "define_tables.h"
@ -201,11 +202,13 @@ static bool HasYmmOsXSave(uint32_t xcr0_eax)
// Checks that operating system saves and restores zmm registers during context // Checks that operating system saves and restores zmm registers during context
// switches. // switches.
#if !defined(CPU_FEATURES_OS_DARWIN)
static bool HasZmmOsXSave(uint32_t xcr0_eax) static bool HasZmmOsXSave(uint32_t xcr0_eax)
{ {
return HasMask(xcr0_eax, MASK_XMM | MASK_YMM | MASK_MASKREG | MASK_ZMM0_15 | return HasMask(xcr0_eax, MASK_XMM | MASK_YMM | MASK_MASKREG | MASK_ZMM0_15 |
MASK_ZMM16_31); MASK_ZMM16_31);
} }
#endif
// Checks that operating system saves and restores AMX/TMUL state during context // Checks that operating system saves and restores AMX/TMUL state during context
// switches. // switches.
@ -1184,6 +1187,20 @@ static void ParseLeaf4(const int max_cpuid_leaf, CacheInfo* info)
} }
} }
#if defined(CPU_FEATURES_OS_DARWIN)
#if defined(CPU_FEATURES_MOCK_CPUID_X86)
extern bool GetDarwinSysCtlByName(const char*);
#else // CPU_FEATURES_MOCK_CPUID_X86
static bool GetDarwinSysCtlByName(const char* name)
{
int enabled;
size_t enabled_len = sizeof(enabled);
const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0);
return failure ? false : enabled;
}
#endif
#endif // CPU_FEATURES_OS_DARWIN
// Internal structure to hold the OS support for vector operations. // Internal structure to hold the OS support for vector operations.
// Avoid to recompute them since each call to cpuid is ~100 cycles. // Avoid to recompute them since each call to cpuid is ~100 cycles.
typedef struct typedef struct
@ -1212,7 +1229,11 @@ static OsSupport CheckOsSupport(const uint32_t max_cpuid_leaf)
const uint32_t xcr0_eax = GetXCR0Eax(); const uint32_t xcr0_eax = GetXCR0Eax();
os_support.have_sse_via_cpuid = HasXmmOsXSave(xcr0_eax); os_support.have_sse_via_cpuid = HasXmmOsXSave(xcr0_eax);
os_support.have_avx = HasYmmOsXSave(xcr0_eax); os_support.have_avx = HasYmmOsXSave(xcr0_eax);
#if defined(CPU_FEATURES_OS_DARWIN)
os_support.have_avx512 = GetDarwinSysCtlByName("hw.optional.avx512f");
#else
os_support.have_avx512 = HasZmmOsXSave(xcr0_eax); os_support.have_avx512 = HasZmmOsXSave(xcr0_eax);
#endif // CPU_FEATURES_OS_DARWIN
os_support.have_amx = HasTmmOsXSave(xcr0_eax); os_support.have_amx = HasTmmOsXSave(xcr0_eax);
} }
else else
@ -1235,20 +1256,6 @@ static bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)
#endif #endif
#endif // CPU_FEATURES_OS_WINDOWS #endif // CPU_FEATURES_OS_WINDOWS
#if defined(CPU_FEATURES_OS_DARWIN)
#if defined(CPU_FEATURES_MOCK_CPUID_X86)
extern bool GetDarwinSysCtlByName(const char*);
#else // CPU_FEATURES_MOCK_CPUID_X86
static bool GetDarwinSysCtlByName(const char* name)
{
int enabled;
size_t enabled_len = sizeof(enabled);
const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0);
return failure ? false : enabled;
}
#endif
#endif // CPU_FEATURES_OS_DARWIN
static void DetectSseViaOs(X86Features* features) static void DetectSseViaOs(X86Features* features)
{ {
#if defined(CPU_FEATURES_OS_WINDOWS) #if defined(CPU_FEATURES_OS_WINDOWS)
@ -1347,6 +1354,7 @@ static void ParseCpuId(const uint32_t max_cpuid_leaf,
features->sha = IsBitSet(leaf_7.ebx, 29); features->sha = IsBitSet(leaf_7.ebx, 29);
features->vaes = IsBitSet(leaf_7.ecx, 9); features->vaes = IsBitSet(leaf_7.ecx, 9);
features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10); features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10);
features->adx = IsBitSet(leaf_7.ebx, 19);
if (os_support.have_sse_via_os) if (os_support.have_sse_via_os)
{ {

View File

@ -150,6 +150,7 @@ TEST_F(CpuidX86Test, SandyBridge)
EXPECT_TRUE(features.popcnt); EXPECT_TRUE(features.popcnt);
EXPECT_FALSE(features.movbe); EXPECT_FALSE(features.movbe);
EXPECT_FALSE(features.rdrnd); EXPECT_FALSE(features.rdrnd);
EXPECT_FALSE(features.adx);
} }
const int KiB = 1024; const int KiB = 1024;

View File

@ -599,7 +599,8 @@ endif()
if(NOT MSVC) if(NOT MSVC)
target_link_libraries(volk_gnsssdr PUBLIC m) target_link_libraries(volk_gnsssdr PUBLIC m)
endif() endif()
set_target_properties(volk_gnsssdr PROPERTIES SOVERSION ${LIBVER}) set_target_properties(volk_gnsssdr PROPERTIES VERSION ${VERSION})
set_target_properties(volk_gnsssdr PROPERTIES SOVERSION ${SOVERSION})
set_target_properties(volk_gnsssdr PROPERTIES DEFINE_SYMBOL "volk_gnsssdr_EXPORTS") set_target_properties(volk_gnsssdr PROPERTIES DEFINE_SYMBOL "volk_gnsssdr_EXPORTS")
# Install locations # Install locations

View File

@ -10,6 +10,6 @@ LV_CXXFLAGS=@LV_CXXFLAGS@
Name: volk_gnsssdr Name: volk_gnsssdr
Description: VOLK_GNSSSDR: Vector Optimized Library of Kernels specific for GNSS-SDR Description: VOLK_GNSSSDR: Vector Optimized Library of Kernels specific for GNSS-SDR
Requires: Requires:
Version: @LIBVER@ Version: @SOVERSION@
Libs: -L${libdir} -lvolk_gnsssdr Libs: -L${libdir} -lvolk_gnsssdr
Cflags: -I${includedir} ${LV_CXXFLAGS} Cflags: -I${includedir} ${LV_CXXFLAGS}

View File

@ -31,13 +31,14 @@ HybridObservables::HybridObservables(const ConfigurationInterface* configuration
dump_mat_ = configuration->property(role + ".dump_mat", true); dump_mat_ = configuration->property(role + ".dump_mat", true);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
Obs_Conf conf; Obs_Conf conf{};
conf.dump = dump_; conf.dump = dump_;
conf.dump_mat = dump_mat_; conf.dump_mat = dump_mat_;
conf.dump_filename = dump_filename_; conf.dump_filename = dump_filename_;
conf.nchannels_in = in_streams_; conf.nchannels_in = in_streams_;
conf.nchannels_out = out_streams_; conf.nchannels_out = out_streams_;
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.enable_carrier_smoothing = configuration->property(role + ".enable_carrier_smoothing", conf.enable_carrier_smoothing);
if (FLAGS_carrier_smoothing_factor == DEFAULT_CARRIER_SMOOTHING_FACTOR) if (FLAGS_carrier_smoothing_factor == DEFAULT_CARRIER_SMOOTHING_FACTOR)

View File

@ -26,6 +26,7 @@
#include <glog/logging.h> #include <glog/logging.h>
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <matio.h> #include <matio.h>
#include <algorithm> // for std::min
#include <array> #include <array>
#include <cmath> // for round #include <cmath> // for round
#include <cstdlib> // for size_t, llabs #include <cstdlib> // for size_t, llabs
@ -117,13 +118,11 @@ hybrid_observables_gs::hybrid_observables_gs(const Obs_Conf &conf_) : gr::block(
} }
} }
d_T_rx_TOW_ms = 0U; d_T_rx_TOW_ms = 0U;
d_T_rx_step_ms = 20; // read from config at the adapter GNSS-SDR.observable_interval_ms!! d_T_rx_step_ms = conf_.observable_interval_ms;
d_T_rx_TOW_set = false; d_T_rx_TOW_set = false;
d_T_status_report_timer_ms = 0; d_T_status_report_timer_ms = 0;
// rework d_Rx_clock_buffer.set_capacity(std::min(std::max(200U / d_T_rx_step_ms, 3U), 10U));
d_Rx_clock_buffer.set_capacity(5); // 10*20 ms = 200 ms of data in buffer d_Rx_clock_buffer.clear();
d_Rx_clock_buffer.clear(); // Clear all the elements in the buffer
d_channel_last_pll_lock = std::vector<bool>(d_nchannels_out, false); d_channel_last_pll_lock = std::vector<bool>(d_nchannels_out, false);
d_channel_last_pseudorange_smooth = std::vector<double>(d_nchannels_out, 0.0); d_channel_last_pseudorange_smooth = std::vector<double>(d_nchannels_out, 0.0);
d_channel_last_carrier_phase_rads = std::vector<double>(d_nchannels_out, 0.0); d_channel_last_carrier_phase_rads = std::vector<double>(d_nchannels_out, 0.0);
@ -197,11 +196,10 @@ void hybrid_observables_gs::msg_handler_pvt_to_observables(const pmt::pmt_t &msg
double old_tow_corrected = static_cast<double>(d_T_rx_TOW_ms) - new_rx_clock_offset_s * 1000.0; double old_tow_corrected = static_cast<double>(d_T_rx_TOW_ms) - new_rx_clock_offset_s * 1000.0;
d_T_rx_TOW_ms = d_T_rx_TOW_ms - static_cast<int>(round(new_rx_clock_offset_s * 1000.0)); d_T_rx_TOW_ms = d_T_rx_TOW_ms - static_cast<int>(round(new_rx_clock_offset_s * 1000.0));
// align the receiver clock to integer multiple of d_T_rx_step_ms
// align the receiver clock to integer multiple of 20 ms if (d_T_rx_TOW_ms % d_T_rx_step_ms)
if (d_T_rx_TOW_ms % 20)
{ {
d_T_rx_TOW_ms += 20 - d_T_rx_TOW_ms % 20; d_T_rx_TOW_ms += d_T_rx_step_ms - d_T_rx_TOW_ms % d_T_rx_step_ms;
} }
last_rx_clock_round20ms_error = static_cast<double>(d_T_rx_TOW_ms) - old_tow_corrected; last_rx_clock_round20ms_error = static_cast<double>(d_T_rx_TOW_ms) - old_tow_corrected;
// d_Rx_clock_buffer.clear(); // Clear all the elements in the buffer // d_Rx_clock_buffer.clear(); // Clear all the elements in the buffer
@ -379,7 +377,7 @@ bool hybrid_observables_gs::interp_trk_obs(Gnss_Synchro &interpolated_obs, uint3
if (nearest_element != -1 and nearest_element != static_cast<int32_t>(d_gnss_synchro_history->size(ch))) if (nearest_element != -1 and nearest_element != static_cast<int32_t>(d_gnss_synchro_history->size(ch)))
{ {
if ((static_cast<double>(old_abs_diff) / static_cast<double>(d_gnss_synchro_history->get(ch, nearest_element).fs)) < 0.02) if ((static_cast<double>(old_abs_diff) / static_cast<double>(d_gnss_synchro_history->get(ch, nearest_element).fs)) < static_cast<double>(d_T_rx_step_ms) / 1000.0)
{ {
int32_t neighbor_element; int32_t neighbor_element;
if (rx_clock > d_gnss_synchro_history->get(ch, nearest_element).Tracking_sample_counter) if (rx_clock > d_gnss_synchro_history->get(ch, nearest_element).Tracking_sample_counter)
@ -491,10 +489,10 @@ void hybrid_observables_gs::update_TOW(const std::vector<Gnss_Synchro> &data)
} }
} }
d_T_rx_TOW_ms = TOW_ref; d_T_rx_TOW_ms = TOW_ref;
// align the receiver clock to integer multiple of 20 ms // align the receiver clock to integer multiple of d_T_rx_step_ms
if (d_T_rx_TOW_ms % 20) if (d_T_rx_TOW_ms % d_T_rx_step_ms)
{ {
d_T_rx_TOW_ms += 20 - d_T_rx_TOW_ms % 20; d_T_rx_TOW_ms += d_T_rx_step_ms - d_T_rx_TOW_ms % d_T_rx_step_ms;
} }
} }
else else

View File

@ -22,8 +22,9 @@ Obs_Conf::Obs_Conf()
{ {
dump_filename = std::string("obs_dump.dat"); dump_filename = std::string("obs_dump.dat");
smoothing_factor = FLAGS_carrier_smoothing_factor; smoothing_factor = FLAGS_carrier_smoothing_factor;
nchannels_in = 0; nchannels_in = 0U;
nchannels_out = 0; nchannels_out = 0U;
observable_interval_ms = 20U;
enable_carrier_smoothing = false; enable_carrier_smoothing = false;
dump = false; dump = false;
dump_mat = false; dump_mat = false;

View File

@ -36,6 +36,7 @@ public:
int32_t smoothing_factor; int32_t smoothing_factor;
uint32_t nchannels_in; uint32_t nchannels_in;
uint32_t nchannels_out; uint32_t nchannels_out;
uint32_t observable_interval_ms;
bool enable_carrier_smoothing; bool enable_carrier_smoothing;
bool dump; bool dump;
bool dump_mat; bool dump_mat;

View File

@ -42,19 +42,6 @@ if(ENABLE_AD9361)
endif() endif()
if(ENABLE_GN3S)
##############################################
# GN3S (USB dongle)
##############################################
if(NOT GRGN3S_FOUND)
message(" gr-gn3s not found, install it from https://github.com/gnss-sdr/gr-gn3s")
message(FATAL_ERROR "gr-gn3s required for building gnss-sdr with this option enabled")
endif()
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} gn3s_signal_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} gn3s_signal_source.h)
endif()
if(ENABLE_FLEXIBAND AND TELEORBIT_FOUND) if(ENABLE_FLEXIBAND AND TELEORBIT_FOUND)
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} flexiband_signal_source.cc) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} flexiband_signal_source.cc)
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} flexiband_signal_source.h) set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} flexiband_signal_source.h)
@ -241,13 +228,6 @@ if(ENABLE_FLEXIBAND AND TELEORBIT_FOUND)
) )
endif() endif()
if(ENABLE_GN3S AND GRGN3S_FOUND)
target_link_libraries(signal_source_adapters
PRIVATE
Gnuradio::gn3s
)
endif()
if(ENABLE_ARRAY AND GRDBFCTTC_FOUND) if(ENABLE_ARRAY AND GRDBFCTTC_FOUND)
target_link_libraries(signal_source_adapters target_link_libraries(signal_source_adapters
PRIVATE PRIVATE

View File

@ -29,6 +29,7 @@
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <utility> #include <utility>
#include <vector>
using namespace std::string_literals; using namespace std::string_literals;
@ -170,7 +171,7 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configu
std::cout << "device address: " << uri_ << '\n'; std::cout << "device address: " << uri_ << '\n';
std::cout << "LO frequency : " << freq_ << " Hz\n"; std::cout << "LO frequency : " << freq_ << " Hz\n";
std::cout << "sample rate: " << sample_rate_ << " Hz\n"; std::cout << "sample rate: " << sample_rate_ << " Sps\n";
if (item_type_ == "gr_complex") if (item_type_ == "gr_complex")
{ {
@ -183,15 +184,24 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configu
else else
{ {
#if GNURADIO_API_IIO #if GNURADIO_API_IIO
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make( std::vector<bool> enable_channels{rx1_en_, rx2_en_};
uri_.c_str(), freq_, sample_rate_, fmcomms2_source_f32c_ = gr::iio::fmcomms2_source::make(uri_, enable_channels, buffer_size_);
bandwidth_, fmcomms2_source_f32c_->set_frequency(freq_);
rx1_en_, rx2_en_, fmcomms2_source_f32c_->set_samplerate(sample_rate_);
buffer_size_, quadrature_, rf_dc_, if (rx1_en_)
bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_, {
gain_mode_rx2_.c_str(), rf_gain_rx2_, fmcomms2_source_f32c_->set_gain_mode(0, gain_mode_rx1_);
rf_port_select_.c_str(), filter_source_.c_str(), fmcomms2_source_f32c_->set_gain(0, rf_gain_rx1_);
filter_filename_.c_str(), Fpass_, Fstop_); }
if (rx2_en_)
{
fmcomms2_source_f32c_->set_gain_mode(1, gain_mode_rx2_);
fmcomms2_source_f32c_->set_gain(1, rf_gain_rx2_);
}
fmcomms2_source_f32c_->set_quadrature(quadrature_);
fmcomms2_source_f32c_->set_rfdc(rf_dc_);
fmcomms2_source_f32c_->set_bbdc(bb_dc_);
fmcomms2_source_f32c_->set_filter_params(filter_source_, filter_filename_, Fpass_, Fstop_);
#else #else
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make( fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make(
uri_.c_str(), freq_, sample_rate_, uri_.c_str(), freq_, sample_rate_,
@ -250,15 +260,18 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configu
else else
{ {
#if GNURADIO_API_IIO #if GNURADIO_API_IIO
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make( std::vector<bool> enable_channels{rx1_en_, rx2_en_};
uri_.c_str(), freq_, sample_rate_, fmcomms2_source_f32c_ = gr::iio::fmcomms2_source::make(uri_, enable_channels, buffer_size_);
bandwidth_, fmcomms2_source_f32c_->set_frequency(freq_);
rx1_en_, rx2_en_, fmcomms2_source_f32c_->set_samplerate(sample_rate_);
buffer_size_, quadrature_, rf_dc_, fmcomms2_source_f32c_->set_gain_mode(0, gain_mode_rx1_);
bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_, fmcomms2_source_f32c_->set_gain(0, rf_gain_rx1_);
gain_mode_rx2_.c_str(), rf_gain_rx2_, fmcomms2_source_f32c_->set_gain_mode(1, gain_mode_rx2_);
rf_port_select_.c_str(), filter_source_.c_str(), fmcomms2_source_f32c_->set_gain(1, rf_gain_rx2_);
filter_filename_.c_str(), Fpass_, Fstop_); fmcomms2_source_f32c_->set_quadrature(quadrature_);
fmcomms2_source_f32c_->set_rfdc(rf_dc_);
fmcomms2_source_f32c_->set_bbdc(bb_dc_);
fmcomms2_source_f32c_->set_filter_params(filter_source_, filter_filename_, Fpass_, Fstop_);
#else #else
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make( fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make(
uri_.c_str(), freq_, sample_rate_, uri_.c_str(), freq_, sample_rate_,

View File

@ -61,7 +61,11 @@ public:
gr::basic_block_sptr get_right_block() override; gr::basic_block_sptr get_right_block() override;
private: private:
#if GNURADIO_API_IIO
gr::iio::fmcomms2_source::sptr fmcomms2_source_f32c_;
#else
gr::iio::fmcomms2_source_f32c::sptr fmcomms2_source_f32c_; gr::iio::fmcomms2_source_f32c::sptr fmcomms2_source_f32c_;
#endif
gnss_shared_ptr<gr::block> valve_; gnss_shared_ptr<gr::block> valve_;
gr::blocks::file_sink::sptr file_sink_; gr::blocks::file_sink::sptr file_sink_;

View File

@ -1,104 +0,0 @@
/*!
* \file gn3s_signal_source.cc
* \brief GN3S USB dongle GPS RF front-end signal sampler driver
* \author Javier Arribas, jarribas(at)cttc.es
*
* -----------------------------------------------------------------------------
*
* 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)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#include "gn3s_signal_source.h"
#include "configuration_interface.h"
#include "gnss_sdr_string_literals.h"
#include <glog/logging.h>
#include <gnuradio/blocks/file_sink.h>
#include <gn3s/gn3s_source_cc.h>
using namespace std::string_literals;
Gn3sSignalSource::Gn3sSignalSource(const ConfigurationInterface* configuration,
std::string role,
unsigned int in_stream,
unsigned int out_stream,
Concurrent_Queue<pmt::pmt_t>* queue)
: SignalSourceBase(configuration, role, "Gn3s_Signal_Source"s), in_stream_(in_stream), out_stream_(out_stream)
{
const std::string default_item_type("short");
const std::string default_dump_file("./data/gn3s_source.dat");
item_type_ = configuration->property(role + ".item_type", default_item_type);
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file);
if (item_type_.compare("gr_complex") == 0)
{
item_size_ = sizeof(gr_complex);
gn3s_source_ = gn3s_make_source_cc();
DLOG(INFO) << "Item size " << item_size_;
DLOG(INFO) << "gn3s_source(" << gn3s_source_->unique_id() << ")";
}
// else if (item_type_.compare("short") == 0)
// {
// item_size_ = sizeof(short);
// resampler_ = direct_resampler_make_conditioner_ss(sample_freq_in_,
// sample_freq_out_);
// }
else
{
LOG(WARNING) << item_type_
<< " unrecognized item type for resampler";
item_size_ = sizeof(short);
}
if (dump_)
{
DLOG(INFO) << "Dumping output into file " << dump_filename_;
file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str());
}
if (dump_)
{
DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")";
}
}
void Gn3sSignalSource::connect(gr::top_block_sptr top_block)
{
if (dump_)
{
top_block->connect(gn3s_source_, 0, file_sink_, 0);
DLOG(INFO) << "connected gn3s_source to file sink";
}
else
{
DLOG(INFO) << "nothing to connect internally";
}
}
void Gn3sSignalSource::disconnect(gr::top_block_sptr top_block)
{
if (dump_)
{
top_block->disconnect(gn3s_source_, 0, file_sink_, 0);
}
}
gr::basic_block_sptr Gn3sSignalSource::get_left_block()
{
LOG(WARNING) << "Left block of a signal source should not be retrieved";
return gr::block_sptr();
}
gr::basic_block_sptr Gn3sSignalSource::get_right_block()
{
return gn3s_source_;
}

View File

@ -1,75 +0,0 @@
/*!
* \file gn3s_signal_source.h
* \brief GN3S USB dongle GPS RF front-end signal sampler driver
* \author Javier Arribas, jarribas(at)cttc.es
*
* -----------------------------------------------------------------------------
*
* 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)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GN3S_SIGNAL_SOURCE_H
#define GNSS_SDR_GN3S_SIGNAL_SOURCE_H
#include "concurrent_queue.h"
#include "signal_source_base.h"
#include <gnuradio/blocks/file_sink.h>
#include <gnuradio/hier_block2.h>
#include <pmt/pmt.h>
#include <cstdint>
#include <memory>
#include <string>
/** \addtogroup Signal_Source
* \{ */
/** \addtogroup Signal_Source_adapters
* \{ */
class ConfigurationInterface;
/*!
* \brief This class reads samples from a GN3S USB dongle, a RF front-end signal sampler
*/
class Gn3sSignalSource : public SignalSourceBase
{
public:
Gn3sSignalSource(const ConfigurationInterface* configuration,
std::string role, unsigned int in_stream,
unsigned int out_stream, Concurrent_Queue<pmt::pmt_t>* queue);
~Gn3sSignalSource() = default;
inline size_t item_size() override
{
return item_size_;
}
void connect(gr::top_block_sptr top_block) override;
void disconnect(gr::top_block_sptr top_block) override;
gr::basic_block_sptr get_left_block() override;
gr::basic_block_sptr get_right_block() override;
private:
gr::block_sptr gn3s_source_;
gr::blocks::file_sink::sptr file_sink_;
std::string item_type_;
std::string dump_filename_;
size_t item_size_;
[[maybe_unused]] int64_t samples_;
unsigned int in_stream_;
unsigned int out_stream_;
bool dump_;
};
/** \} */
/** \} */
#endif // GNSS_SDR_GN3S_SIGNAL_SOURCE_H

View File

@ -121,15 +121,20 @@ PlutosdrSignalSource::PlutosdrSignalSource(const ConfigurationInterface* configu
std::cout << "device address: " << uri_ << '\n'; std::cout << "device address: " << uri_ << '\n';
std::cout << "frequency : " << freq_ << " Hz\n"; std::cout << "frequency : " << freq_ << " Hz\n";
std::cout << "sample rate: " << sample_rate_ << " Hz\n"; std::cout << "sample rate: " << sample_rate_ << " Sps\n";
std::cout << "gain mode: " << gain_mode_ << '\n'; std::cout << "gain mode: " << gain_mode_ << '\n';
std::cout << "item type: " << item_type_ << '\n'; std::cout << "item type: " << item_type_ << '\n';
#if GNURADIO_API_IIO #if GNURADIO_API_IIO
plutosdr_source_ = gr::iio::pluto_source::make(uri_, freq_, sample_rate_, plutosdr_source_ = gr::iio::pluto_source::make(uri_, buffer_size_);
bandwidth_, buffer_size_, quadrature_, rf_dc_, bb_dc_, plutosdr_source_->set_frequency(freq_);
gain_mode_.c_str(), rf_gain_, filter_source_.c_str(), plutosdr_source_->set_samplerate(sample_rate_);
filter_filename_.c_str(), Fpass_, Fstop_); plutosdr_source_->set_gain_mode(gain_mode_);
plutosdr_source_->set_gain(rf_gain_);
plutosdr_source_->set_quadrature(quadrature_);
plutosdr_source_->set_rfdc(rf_dc_);
plutosdr_source_->set_bbdc(bb_dc_);
plutosdr_source_->set_filter_params(filter_source_, filter_filename_, Fpass_, Fstop_);
#else #else
plutosdr_source_ = gr::iio::pluto_source::make(uri_, freq_, sample_rate_, plutosdr_source_ = gr::iio::pluto_source::make(uri_, freq_, sample_rate_,
bandwidth_, buffer_size_, quadrature_, rf_dc_, bb_dc_, bandwidth_, buffer_size_, quadrature_, rf_dc_, bb_dc_,

View File

@ -37,7 +37,7 @@
class ConfigurationInterface; class ConfigurationInterface;
/*! /*!
* \brief This class reads samples from a GN3S USB dongle, a RF front-end signal sampler * \brief This class reads samples from an antenna array RF front-end signal sampler
*/ */
class RawArraySignalSource : public SignalSourceBase class RawArraySignalSource : public SignalSourceBase
{ {

View File

@ -26,7 +26,7 @@
#include "display.h" #include "display.h"
#include "galileo_almanac_helper.h" // for Galileo_Almanac_Helper #include "galileo_almanac_helper.h" // for Galileo_Almanac_Helper
#include "galileo_ephemeris.h" // for Galileo_Ephemeris #include "galileo_ephemeris.h" // for Galileo_Ephemeris
#include "galileo_has_data.h" // For Galileo HAS messages #include "galileo_has_page.h" // For Galileo_HAS_page
#include "galileo_iono.h" // for Galileo_Iono #include "galileo_iono.h" // for Galileo_Iono
#include "galileo_utc_model.h" // for Galileo_Utc_Model #include "galileo_utc_model.h" // for Galileo_Utc_Model
#include "gnss_synchro.h" #include "gnss_synchro.h"
@ -65,6 +65,9 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
this->message_port_register_out(pmt::mp("telemetry")); this->message_port_register_out(pmt::mp("telemetry"));
// Control messages to tracking block // Control messages to tracking block
this->message_port_register_out(pmt::mp("telemetry_to_trk")); this->message_port_register_out(pmt::mp("telemetry_to_trk"));
// register Gal E6 messages HAS out
this->message_port_register_out(pmt::mp("E6_HAS_from_TLM"));
d_last_valid_preamble = 0; d_last_valid_preamble = 0;
d_sent_tlm_failed_msg = false; d_sent_tlm_failed_msg = false;
d_band = '1'; d_band = '1';
@ -202,6 +205,8 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
d_channel = 0; d_channel = 0;
d_flag_PLL_180_deg_phase_locked = false; d_flag_PLL_180_deg_phase_locked = false;
d_symbol_history.set_capacity(d_required_symbols + 1); d_symbol_history.set_capacity(d_required_symbols + 1);
d_cnav_dummy_page = false;
d_print_cnav_page = true;
// vars for Viterbi decoder // vars for Viterbi decoder
const int32_t max_states = 1U << static_cast<uint32_t>(d_mm); // 2^d_mm const int32_t max_states = 1U << static_cast<uint32_t>(d_mm); // 2^d_mm
@ -528,18 +533,35 @@ void galileo_telemetry_decoder_gs::decode_CNAV_word(float *page_symbols, int32_t
} }
d_cnav_nav.read_HAS_page(page_String); d_cnav_nav.read_HAS_page(page_String);
// 4. If we have a new full message, read it // 4. If we have a new HAS page, read it
if (d_cnav_nav.have_new_HAS_message() == true) if (d_cnav_nav.have_new_HAS_page() == true)
{ {
if (d_cnav_nav.is_HAS_message_dummy() == true) bool is_page_dummy = d_cnav_nav.is_HAS_page_dummy();
if (is_page_dummy == true)
{ {
std::cout << TEXT_MAGENTA << "New Galileo E6 HAS dummy message received in channel " << d_channel << " from satellite " << d_satellite << TEXT_RESET << '\n'; d_print_cnav_page = true;
// Only print the message once
if (is_page_dummy != d_cnav_dummy_page)
{
d_cnav_dummy_page = is_page_dummy;
std::cout << TEXT_MAGENTA << "Receiving Galileo E6 CNAV dummy pages in channel "
<< d_channel << " from satellite " << d_satellite
<< TEXT_RESET << '\n';
}
} }
else else
{ {
const std::shared_ptr<Galileo_HAS_data> tmp_obj = std::make_shared<Galileo_HAS_data>(d_cnav_nav.get_HAS_data()); const std::shared_ptr<Galileo_HAS_page> tmp_obj = std::make_shared<Galileo_HAS_page>(d_cnav_nav.get_HAS_encoded_page());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("E6_HAS_from_TLM"), pmt::make_any(tmp_obj));
std::cout << TEXT_MAGENTA << "New Galileo E6 HAS message received in channel " << d_channel << " from satellite " << d_satellite << TEXT_RESET << '\n'; if (d_print_cnav_page == true)
{
d_print_cnav_page = false; // only print the first page
std::cout << TEXT_MAGENTA << "Receiving Galileo E6 HAS pages"
<< (d_cnav_nav.is_HAS_in_test_mode() == true ? " (test mode) " : " ")
<< "in channel " << d_channel << " from satellite " << d_satellite
<< TEXT_RESET << '\n';
}
} }
} }
} }
@ -761,7 +783,7 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
break; break;
} }
d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P) d_preamble_index = d_sample_counter; // record the preamble sample stamp (t_P)
if (d_inav_nav.get_flag_CRC_test() == true or d_fnav_nav.get_flag_CRC_test() == true) if (d_inav_nav.get_flag_CRC_test() == true or d_fnav_nav.get_flag_CRC_test() == true or d_cnav_nav.get_flag_CRC_test() == true)
{ {
d_CRC_error_counter = 0; d_CRC_error_counter = 0;
d_flag_preamble = true; // valid preamble indicator (initialized to false every work()) d_flag_preamble = true; // valid preamble indicator (initialized to false every work())
@ -894,6 +916,7 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
case 3: // CNAV case 3: // CNAV
{ {
// TODO // TODO
d_TOW_at_current_symbol_ms += d_PRN_code_period_ms; // this is not the TOW!
break; break;
} }
} }
@ -930,7 +953,7 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
} }
} }
if (d_inav_nav.get_flag_TOW_set() == true or d_fnav_nav.get_flag_TOW_set() == true) if (d_inav_nav.get_flag_TOW_set() == true or d_fnav_nav.get_flag_TOW_set() == true or d_cnav_nav.get_flag_CRC_test() == true)
{ {
current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms;
// todo: Galileo to GPS time conversion should be moved to observable block. // todo: Galileo to GPS time conversion should be moved to observable block.
@ -977,7 +1000,7 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
LOG(WARNING) << "Exception writing observables dump file " << e.what(); LOG(WARNING) << "Exception writing navigation data dump file " << e.what();
} }
} }
// 3. Make the output (copy the object contents to the GNURadio reserved memory) // 3. Make the output (copy the object contents to the GNURadio reserved memory)

View File

@ -140,6 +140,8 @@ private:
bool d_dump_mat; bool d_dump_mat;
bool d_remove_dat; bool d_remove_dat;
bool d_first_eph_sent; bool d_first_eph_sent;
bool d_cnav_dummy_page;
bool d_print_cnav_page;
}; };

View File

@ -734,7 +734,7 @@ void dll_pll_veml_tracking::start_tracking()
{ {
if (d_trk_parameters.track_pilot) if (d_trk_parameters.track_pilot)
{ {
d_secondary_code_string = galileo_e6_c_secondary_code(d_acquisition_gnss_synchro->PRN - 1); d_secondary_code_string = galileo_e6_c_secondary_code(d_acquisition_gnss_synchro->PRN);
galileo_e6_b_code_gen_float_primary(d_data_code, d_acquisition_gnss_synchro->PRN); galileo_e6_b_code_gen_float_primary(d_data_code, d_acquisition_gnss_synchro->PRN);
galileo_e6_c_code_gen_float_primary(d_tracking_code, d_acquisition_gnss_synchro->PRN); galileo_e6_c_code_gen_float_primary(d_tracking_code, d_acquisition_gnss_synchro->PRN);
d_Prompt_Data[0] = gr_complex(0.0, 0.0); d_Prompt_Data[0] = gr_complex(0.0, 0.0);

View File

@ -15,6 +15,7 @@ set(CORE_LIBS_SOURCES
channel_status_msg_receiver.cc channel_status_msg_receiver.cc
channel_event.cc channel_event.cc
command_event.cc command_event.cc
galileo_e6_has_msg_receiver.cc
) )
set(CORE_LIBS_HEADERS set(CORE_LIBS_HEADERS

View File

@ -0,0 +1,723 @@
/*!
* \file galileo_e6_has_msg_receiver.cc
* \brief GNU Radio block that processes Galileo HAS message pages received from
* Galileo E6B telemetry blocks. After successful decoding, sends the content to
* the PVT block.
* \author Javier Arribas, 2021. jarribas(at)cttc.es
* \author Carles Fernandez-Prades, 2021. cfernandez(at)cttc.es
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#include "galileo_e6_has_msg_receiver.h"
#include "display.h"
#include "galileo_has_page.h" // for Galileo_HAS_page
#include "gnss_sdr_make_unique.h"
#include "reed_solomon.h"
#include <boost/any.hpp>
#include <glog/logging.h>
#include <gnuradio/io_signature.h>
#include <algorithm> // std::find
#include <cstddef> // size_t
#include <numeric> // std::accumulate
#include <sstream> // std::stringstream
#include <typeinfo> // typeid
#if HAS_GENERIC_LAMBDA
#else
#include <boost/bind/bind.hpp>
#endif
galileo_e6_has_msg_receiver_sptr galileo_e6_has_msg_receiver_make()
{
return galileo_e6_has_msg_receiver_sptr(new galileo_e6_has_msg_receiver());
}
galileo_e6_has_msg_receiver::galileo_e6_has_msg_receiver() : gr::block("galileo_e6_has_msg_receiver", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0))
{
// register Gal E6 HAS input message port from telemetry blocks
this->message_port_register_in(pmt::mp("E6_HAS_from_TLM"));
this->set_msg_handler(pmt::mp("E6_HAS_from_TLM"),
#if HAS_GENERIC_LAMBDA
[this](auto&& PH1) { msg_handler_galileo_e6_has(PH1); });
#else
#if USE_BOOST_BIND_PLACEHOLDERS
boost::bind(&galileo_e6_has_msg_receiver::msg_handler_galileo_e6_has, this, boost::placeholders::_1));
#else
boost::bind(&galileo_e6_has_msg_receiver::msg_handler_galileo_e6_has, this, _1));
#endif
#endif
// register Gal E6 processed HAS async output message port towards PVT
this->message_port_register_out(pmt::mp("E6_HAS_to_PVT"));
// initialize Reed-Solomon decoder
d_rs = std::make_unique<ReedSolomon>();
}
void galileo_e6_has_msg_receiver::msg_handler_galileo_e6_has(const pmt::pmt_t& msg)
{
gr::thread::scoped_lock lock(d_setlock); // require mutex with msg_handler_galileo_e6_has function called by the scheduler
try
{
const size_t msg_type_hash_code = pmt::any_ref(msg).type().hash_code();
if (msg_type_hash_code == typeid(std::shared_ptr<Galileo_HAS_page>).hash_code())
{
const auto HAS_data_page = boost::any_cast<std::shared_ptr<Galileo_HAS_page>>(pmt::any_ref(msg));
DLOG(INFO) << "New HAS page received: "
<< "Status: " << static_cast<float>(HAS_data_page->has_status) << ", "
<< "MT: " << static_cast<float>(HAS_data_page->message_type) << ", "
<< "MID: " << static_cast<float>(HAS_data_page->message_id) << ", "
<< "MS: " << static_cast<float>(HAS_data_page->message_size) << ", "
<< "PID: " << static_cast<float>(HAS_data_page->message_page_id);
process_HAS_page(*HAS_data_page.get());
}
else
{
LOG(WARNING) << "galileo_e6_has_msg_receiver received an unknown object type!";
}
}
catch (const boost::bad_any_cast& e)
{
LOG(WARNING) << "galileo_e6_has_msg_receiver Bad any_cast: " << e.what();
}
// Send the resulting decoded HAS data (if available) to PVT
if (d_new_message == true)
{
auto has_data_ptr = std::make_shared<Galileo_HAS_data>(d_HAS_data);
this->message_port_pub(pmt::mp("E6_HAS_to_PVT"), pmt::make_any(has_data_ptr));
d_new_message = false;
DLOG(INFO) << "HAS message sent to the PVT block through the E6_HAS_to_PVT async message port";
}
}
void galileo_e6_has_msg_receiver::process_HAS_page(const Galileo_HAS_page& has_page)
{
if (has_page.has_status == 0 || has_page.has_status == 1)
{
std::string page_string(has_page.has_message_string);
if (has_page.message_page_id != 0) // PID=0 is reserved, ignore it
{
if (has_page.message_type == 1) // contains satellite corrections
{
if (has_page.message_id < 32) // MID range is from 0 to 31
{
if (std::find(d_received_pids[has_page.message_id].begin(), d_received_pids[has_page.message_id].end(), has_page.message_page_id) == d_received_pids[has_page.message_id].end())
{
// New pid! Annotate it.
d_received_pids[has_page.message_id].push_back(has_page.message_page_id);
for (int k = 0; k < GALILEO_CNAV_OCTETS_IN_SUBPAGE; k++)
{
std::string bits8 = page_string.substr(k * 8, 8);
std::bitset<8> bs(bits8);
d_C_matrix[has_page.message_id][has_page.message_page_id - 1][k] = static_cast<uint8_t>(bs.to_ulong());
}
}
}
}
}
}
// If we have received for this message ID a number of pages equal to the message size
if (d_received_pids[has_page.message_id].size() == has_page.message_size)
{
// Try to decode the message
int res = decode_message_type1(has_page.message_id, has_page.message_size);
if (res == 0)
{
// Successful decoding, we have a valid HAS message stored at d_HAS_data
std::cout << TEXT_MAGENTA << "New Galileo HAS message type " << static_cast<float>(has_page.message_id)
<< " received and successfully decoded" << TEXT_RESET << '\n';
d_new_message = true;
}
else
{
d_new_message = false;
}
}
}
int galileo_e6_has_msg_receiver::decode_message_type1(uint8_t message_id, uint8_t message_size)
{
DLOG(INFO) << "Start decoding of a HAS message";
// Compute erasure positions
std::vector<int> erasure_positions;
erasure_positions.reserve(223); // Maximum erasure positions ( = number of parity symbols in a block)
for (uint8_t i = 1; i < message_size + 1; i++) // we know that from message_size to 32, the value is 0
{
if (std::find(d_received_pids[message_id].begin(), d_received_pids[message_id].end(), i) == d_received_pids[message_id].end())
{
erasure_positions.push_back(i - 1);
}
}
for (int i = 33; i < 256; i++)
{
if (std::find(d_received_pids[message_id].begin(), d_received_pids[message_id].end(), static_cast<uint8_t>(i)) == d_received_pids[message_id].end())
{
erasure_positions.push_back(i - 1);
}
}
DLOG(INFO) << debug_print_vector("List of received PIDs", d_received_pids[message_id]);
DLOG(INFO) << debug_print_vector("erasure_positions", erasure_positions);
DLOG(INFO) << debug_print_matrix("d_C_matrix produced", d_C_matrix[message_id]);
// Reset HAS decoded message matrix
d_M_matrix = {GALILEO_CNAV_INFORMATION_VECTOR_LENGTH, std::vector<uint8_t>(GALILEO_CNAV_OCTETS_IN_SUBPAGE)};
// Vertical decoding of d_C_matrix
for (int col = 0; col < GALILEO_CNAV_OCTETS_IN_SUBPAGE; col++)
{
std::vector<uint8_t> C_column(GALILEO_CNAV_MAX_NUMBER_SYMBOLS_ENCODED_BLOCK, 0);
for (auto pid : d_received_pids[message_id])
{
C_column[pid - 1] = d_C_matrix[message_id][pid - 1][col];
}
DLOG(INFO) << debug_print_vector("C_column entering the decoder", C_column);
int result = d_rs->decode(C_column, erasure_positions);
if (result < 0)
{
DLOG(ERROR) << "Decoding of HAS page failed";
return -1;
}
DLOG(INFO) << "Successful HAS page decoding";
std::vector<uint8_t> M_column(C_column.begin(), C_column.begin() + GALILEO_CNAV_INFORMATION_VECTOR_LENGTH);
for (int i = 0; i < GALILEO_CNAV_INFORMATION_VECTOR_LENGTH; i++)
{
d_M_matrix[i][col] = M_column[i];
}
}
DLOG(INFO) << debug_print_matrix("M_matrix", d_M_matrix);
// Form the decoded HAS message by reading rows of d_M_matrix
std::string decoded_message_type_1;
decoded_message_type_1.reserve(message_size * GALILEO_CNAV_OCTETS_IN_SUBPAGE * 8);
for (uint8_t row = 0; row < message_size; row++)
{
for (int col = 0; col < GALILEO_CNAV_OCTETS_IN_SUBPAGE; col++)
{
std::bitset<8> bs(d_M_matrix[row][col]);
decoded_message_type_1 += bs.to_string();
}
}
DLOG(INFO) << "Decoded message ID " << static_cast<float>(message_id)
<< " (size: " << static_cast<float>(message_size) << ") with body: "
<< std::string(decoded_message_type_1.begin() + GALILEO_CNAV_MT1_HEADER_BITS, decoded_message_type_1.end());
// reset data for next decoding
d_C_matrix[message_id] = {GALILEO_CNAV_MAX_NUMBER_SYMBOLS_ENCODED_BLOCK, std::vector<uint8_t>(GALILEO_CNAV_OCTETS_IN_SUBPAGE, 0)};
d_received_pids[message_id].clear();
// Trigger HAS message content reading and fill the d_HAS_data object
d_HAS_data = Galileo_HAS_data();
read_MT1_header(decoded_message_type_1.substr(0, GALILEO_CNAV_MT1_HEADER_BITS));
read_MT1_body(std::string(decoded_message_type_1.begin() + GALILEO_CNAV_MT1_HEADER_BITS, decoded_message_type_1.end()));
return 0;
}
void galileo_e6_has_msg_receiver::read_MT1_header(const std::string& message_header)
{
// ICD v1.2 Table 6: MT1 Message Header
const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS> has_mt1_header(message_header);
d_HAS_data.header.toh = read_has_message_header_parameter_uint16(has_mt1_header, GALILEO_MT1_HEADER_TOH);
d_HAS_data.header.mask_id = read_has_message_header_parameter_uint8(has_mt1_header, GALILEO_MT1_HEADER_MASK_ID);
d_HAS_data.header.iod_id = read_has_message_header_parameter_uint8(has_mt1_header, GALILEO_MT1_HEADER_IOD_ID);
d_HAS_data.header.mask_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_MASK_FLAG);
d_HAS_data.header.orbit_correction_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_ORBIT_CORRECTION_FLAG);
d_HAS_data.header.clock_fullset_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_CLOCK_FULLSET_FLAG);
d_HAS_data.header.clock_subset_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_CLOCK_SUBSET_FLAG);
d_HAS_data.header.code_bias_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_CODE_BIAS_FLAG);
d_HAS_data.header.phase_bias_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_PHASE_BIAS_FLAG);
d_HAS_data.header.ura_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_URA_FLAG);
DLOG(INFO) << "MT1 header " << message_header << ": "
<< "TOH: " << static_cast<float>(d_HAS_data.header.toh) << ", "
<< "mask ID: " << static_cast<float>(d_HAS_data.header.mask_id) << ", "
<< "iod ID: " << static_cast<float>(d_HAS_data.header.iod_id) << ", "
<< "mask_flag: " << static_cast<float>(d_HAS_data.header.mask_flag) << ", "
<< "orbit_correction_flag: " << static_cast<float>(d_HAS_data.header.orbit_correction_flag) << ", "
<< "clock_fullset_flag: " << static_cast<float>(d_HAS_data.header.clock_fullset_flag) << ", "
<< "clock_subset_flag: " << static_cast<float>(d_HAS_data.header.clock_subset_flag) << ", "
<< "code_bias_flag: " << static_cast<float>(d_HAS_data.header.code_bias_flag) << ", "
<< "phase_bias_flag: " << static_cast<float>(d_HAS_data.header.phase_bias_flag) << ", "
<< "ura_flag: " << static_cast<float>(d_HAS_data.header.ura_flag);
}
void galileo_e6_has_msg_receiver::read_MT1_body(const std::string& message_body)
{
// ICD v1.2 Table 7: MT1 Message Body.
auto message = std::string(message_body);
// int Nsat = 0;
if (d_HAS_data.header.mask_flag)
{
// read mask
d_HAS_data.Nsys = read_has_message_body_uint8(message.substr(0, HAS_MSG_NSYS_LENGTH));
DLOG(INFO) << "Nsys " << static_cast<float>(d_HAS_data.Nsys);
message = std::string(message.begin() + HAS_MSG_NSYS_LENGTH, message.end());
d_HAS_data.gnss_id_mask.reserve(d_HAS_data.Nsys);
d_HAS_data.cell_mask.reserve(d_HAS_data.Nsys);
d_HAS_data.cell_mask_availability_flag.reserve(d_HAS_data.Nsys);
d_HAS_data.nav_message.reserve(d_HAS_data.Nsys);
for (uint8_t i = 0; i < d_HAS_data.Nsys; i++)
{
// d_HAS_data.gnss_id_mask[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_ID_MASK_LENGTH));
// // DLOG(ERROR) << "GNSS ID" << static_cast<float>(i) << ": " << static_cast<float>(d_HAS_data.gnss_id_mask[i]);
// message = std::string(message.begin() + HAS_MSG_ID_MASK_LENGTH, message.end());
// std::string msg = message.substr(0, HAS_MSG_SATELLITE_MASK_LENGTH);
// d_HAS_data.satellite_mask[i] = read_has_message_body_uint64(msg);
// int ones_in_satellite_mask = 0;
// for (char c : msg)
// {
// if (c == '1')
// {
// ones_in_satellite_mask++;
// }
// }
// Nsat += ones_in_satellite_mask;
// message = std::string(message.begin() + HAS_MSG_SATELLITE_MASK_LENGTH, message.end());
//
// msg = message.substr(0, HAS_MSG_SIGNAL_MASK_LENGTH);
// d_HAS_data.signal_mask[i] = read_has_message_body_uint16(msg);
// int ones_in_signal_mask = 0;
// for (char c : msg)
// {
// if (c == '1')
// {
// ones_in_signal_mask++;
// }
// }
// message = std::string(message.begin() + HAS_MSG_SIGNAL_MASK_LENGTH, message.end());
//
// if (message.substr(0, 1) == "1")
// {
// d_HAS_data.cell_mask_availability_flag[i] = true;
// }
// else
// {
// d_HAS_data.cell_mask_availability_flag[i] = false;
// }
// message = std::string(message.begin() + 1, message.end());
// int size_cell = ones_in_satellite_mask * ones_in_signal_mask;
//
// d_HAS_data.cell_mask[i].reserve(ones_in_satellite_mask);
// for (int s = 0; s < ones_in_satellite_mask; s++)
// {
// d_HAS_data.cell_mask[i][s].reserve(ones_in_signal_mask);
// for (int sig = 0; sig < ones_in_signal_mask; sig++)
// {
// d_HAS_data.cell_mask[i][s][sig] = (message[sig] == '1' ? true : false);
// }
// }
// message = std::string(message.begin() + size_cell, message.end());
//
// d_HAS_data.nav_message[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_NAV_MESSAGE_LENGTH));
// message = std::string(message.begin() + HAS_MSG_NAV_MESSAGE_LENGTH, message.end());
}
}
// if (d_HAS_data.header.orbit_correction_flag)
// {
// // read orbit corrections
// d_HAS_data.validity_interval_index_orbit_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
// message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
// d_HAS_data.gnss_iod.reserve(Nsat);
// d_HAS_data.delta_radial.reserve(Nsat);
// d_HAS_data.delta_along_track.reserve(Nsat);
// d_HAS_data.delta_cross_track.reserve(Nsat);
// for (int i = 0; i < Nsat; i++)
// {
// if (d_HAS_data.gnss_id_mask[i] == HAS_MSG_GPS_SYSTEM)
// {
// d_HAS_data.gnss_iod[i] = read_has_message_body_uint16(message.substr(0, HAS_MSG_IOD_GPS_LENGTH));
// message = std::string(message.begin() + HAS_MSG_IOD_GPS_LENGTH, message.end());
// }
// if (d_HAS_data.gnss_id_mask[i] == HAS_MSG_GALILEO_SYSTEM)
// {
// d_HAS_data.gnss_iod[i] = read_has_message_body_uint16(message.substr(0, HAS_MSG_IOD_GAL_LENGTH));
// message = std::string(message.begin() + HAS_MSG_IOD_GAL_LENGTH, message.end());
// }
// d_HAS_data.delta_radial[i] = read_has_message_body_int16(message.substr(0, HAS_MSG_DELTA_RADIAL_LENGTH));
// message = std::string(message.begin() + HAS_MSG_DELTA_RADIAL_LENGTH, message.end());
//
// d_HAS_data.delta_along_track[i] = read_has_message_body_int16(message.substr(0, HAS_MSG_DELTA_ALONG_TRACK_LENGTH));
// message = std::string(message.begin() + HAS_MSG_DELTA_ALONG_TRACK_LENGTH, message.end());
//
// d_HAS_data.delta_cross_track[i] = read_has_message_body_int16(message.substr(0, HAS_MSG_DELTA_CROSS_TRACK_LENGTH));
// message = std::string(message.begin() + HAS_MSG_DELTA_CROSS_TRACK_LENGTH, message.end());
// }
// }
// if (d_HAS_data.header.clock_fullset_flag)
// {
// // read clock full-set corrections
// d_HAS_data.validity_interval_index_clock_fullset_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
// message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
//
// d_HAS_data.delta_clock_c0_multiplier.reserve(d_HAS_data.Nsys);
// for (uint8_t i = 0; i < d_HAS_data.Nsys; i++)
// {
// if (d_HAS_data.gnss_id_mask[i] != HAS_MSG_GALILEO_SYSTEM)
// {
// d_HAS_data.delta_clock_c0_multiplier[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_DELTA_CLOCK_C0_MULTIPLIER_LENGTH));
// message = std::string(message.begin() + HAS_MSG_DELTA_CLOCK_C0_MULTIPLIER_LENGTH, message.end());
// }
// }
// d_HAS_data.iod_change_flag.reserve(Nsat);
// d_HAS_data.delta_clock_c0.reserve(Nsat);
// for (int i = 0; i < Nsat; i++)
// {
// d_HAS_data.iod_change_flag[i] = (message[0] == '1' ? true : false);
// message = std::string(message.begin() + 1, message.end());
// d_HAS_data.delta_clock_c0[i] = read_has_message_body_int16(message.substr(0, HAS_MSG_DELTA_CLOCK_C0_LENGTH));
// message = std::string(message.begin() + HAS_MSG_DELTA_CLOCK_C0_LENGTH, message.end());
// }
// }
// if (d_HAS_data.header.clock_subset_flag)
// {
// // read clock subset corrections
// d_HAS_data.validity_interval_index_clock_subset_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
// message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
//
// d_HAS_data.Nsysprime = read_has_message_body_uint8(message.substr(0, HAS_MSG_NSYSPRIME_LENGTH));
// DLOG(INFO) << "Nsysprime: " << static_cast<float>(d_HAS_data.Nsysprime);
// message = std::string(message.begin() + HAS_MSG_NSYSPRIME_LENGTH, message.end());
//
// d_HAS_data.gnss_id_clock_subset.reserve(d_HAS_data.Nsysprime);
// d_HAS_data.delta_clock_c0_multiplier_clock_subset.reserve(d_HAS_data.Nsysprime);
// d_HAS_data.satellite_submask.reserve(d_HAS_data.Nsysprime);
// d_HAS_data.iod_change_flag_clock_subset.reserve(d_HAS_data.Nsysprime);
// d_HAS_data.delta_clock_c0_clock_subset.reserve(d_HAS_data.Nsysprime);
// for (uint8_t i = 0; i < d_HAS_data.Nsysprime; i++)
// {
// d_HAS_data.gnss_id_clock_subset[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_ID_CLOCK_SUBSET_LENGTH));
// message = std::string(message.begin() + HAS_MSG_ID_CLOCK_SUBSET_LENGTH, message.end());
// if (d_HAS_data.gnss_id_clock_subset[i] != HAS_MSG_GALILEO_SYSTEM)
// {
// d_HAS_data.delta_clock_c0_multiplier_clock_subset[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_DELTA_CLOCK_MULTIPLIER_SUBSET_LENGTH));
// message = std::string(message.begin() + HAS_MSG_DELTA_CLOCK_MULTIPLIER_SUBSET_LENGTH, message.end());
// }
// uint64_t number_sats_this_gnss_id = 0;
// for (uint8_t j = 0; j < d_HAS_data.Nsys; j++)
// {
// if (d_HAS_data.gnss_id_mask[j] == d_HAS_data.gnss_id_clock_subset[i])
// {
// uint64_t n = d_HAS_data.satellite_mask[j];
// while (n)
// {
// number_sats_this_gnss_id += n & 1;
// n >>= 1;
// }
// break;
// }
// }
//
// d_HAS_data.satellite_submask[i].reserve(number_sats_this_gnss_id);
// for (uint64_t j = 0; j < number_sats_this_gnss_id; j++)
// {
// d_HAS_data.satellite_submask[i][j] = read_has_message_body_uint64(message.substr(0, 1));
// message = std::string(message.begin() + 1, message.end());
// }
// d_HAS_data.iod_change_flag_clock_subset[i] = (message[0] == '1' ? true : false);
// message = std::string(message.begin() + 1, message.end());
//
// d_HAS_data.delta_clock_c0_clock_subset[i] = read_has_message_body_int16(message.substr(0, HAS_MSG_DELTA_CLOCK_C0_SUBSET_LENGTH));
// message = std::string(message.begin() + HAS_MSG_DELTA_CLOCK_C0_SUBSET_LENGTH, message.end());
// }
// }
// if (d_HAS_data.header.code_bias_flag)
// {
// // read code bias
// d_HAS_data.validity_interval_index_code_bias_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
// message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
// std::vector<uint64_t> number_sats(d_HAS_data.Nsys, 0);
// std::vector<uint64_t> number_codes(d_HAS_data.Nsys, 0);
// for (int sys = 0; sys < d_HAS_data.Nsys; sys++)
// {
// uint64_t number_sats_this_gnss_id = 0;
// uint64_t number_signals_this_gnss_id = 0;
// if (d_HAS_data.cell_mask_availability_flag[sys] == true)
// {
// uint64_t n = d_HAS_data.satellite_mask[sys];
// while (n)
// {
// number_sats_this_gnss_id += n & 1;
// n >>= 1;
// }
// uint64_t m = d_HAS_data.signal_mask[sys];
// while (m)
// {
// number_signals_this_gnss_id += m & 1;
// m >>= 1;
// }
// }
// else
// {
// number_sats_this_gnss_id = HAS_MSG_MAX_SATS;
// number_signals_this_gnss_id = HAS_MSG_MAX_SIGNALS;
// }
// number_sats[sys] = number_sats_this_gnss_id;
// number_codes[sys] = number_signals_this_gnss_id;
// }
// uint64_t Nsat_b = std::accumulate(number_sats.begin(), number_sats.end(), 0ULL);
//
// d_HAS_data.code_bias.reserve(Nsat_b);
// int sat = 0;
// for (int sys = 0; sys < d_HAS_data.Nsys; sys++)
// {
// d_HAS_data.code_bias[sat].reserve(number_codes[sys]);
// for (uint64_t c = 0; c < number_codes[sys]; c++)
// {
// d_HAS_data.code_bias[sat][c] = read_has_message_body_int16(message.substr(0, HAS_MSG_CODE_BIAS_LENGTH));
// message = std::string(message.begin() + HAS_MSG_CODE_BIAS_LENGTH, message.end());
// sat += 1;
// }
// }
// }
// if (d_HAS_data.header.phase_bias_flag)
// {
// // read phase bias
// d_HAS_data.validity_interval_index_phase_bias_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
// message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
//
// std::vector<uint64_t> number_sats(d_HAS_data.Nsys, 0);
// std::vector<uint64_t> number_phases(d_HAS_data.Nsys, 0);
// for (int sys = 0; sys < d_HAS_data.Nsys; sys++)
// {
// uint64_t number_sats_this_gnss_id = 0;
// uint64_t number_signals_this_gnss_id = 0;
// if (d_HAS_data.cell_mask_availability_flag[sys] == true)
// {
// uint64_t n = d_HAS_data.satellite_mask[sys];
// while (n)
// {
// number_sats_this_gnss_id += n & 1;
// n >>= 1;
// }
// uint64_t m = d_HAS_data.signal_mask[sys];
// while (m)
// {
// number_signals_this_gnss_id += m & 1;
// m >>= 1;
// }
// }
// else
// {
// number_sats_this_gnss_id = HAS_MSG_MAX_SATS;
// number_signals_this_gnss_id = HAS_MSG_MAX_SIGNALS;
// }
// number_sats[sys] = number_sats_this_gnss_id;
// number_phases[sys] = number_signals_this_gnss_id;
// }
// uint64_t Nsat_p = std::accumulate(number_sats.begin(), number_sats.end(), 0ULL);
//
// d_HAS_data.phase_bias.reserve(Nsat_p);
// d_HAS_data.phase_discontinuity_indicator.reserve(Nsat_p);
// int sat = 0;
// for (int sys = 0; sys < d_HAS_data.Nsys; sys++)
// {
// d_HAS_data.phase_bias[sat].reserve(number_phases[sys]);
// d_HAS_data.phase_discontinuity_indicator[sat].reserve(number_phases[sys]);
// for (uint64_t p = 0; p < number_phases[sys]; p++)
// {
// d_HAS_data.phase_bias[sat][p] = read_has_message_body_int16(message.substr(0, HAS_MSG_PHASE_BIAS_LENGTH));
// message = std::string(message.begin() + HAS_MSG_PHASE_BIAS_LENGTH, message.end());
//
// d_HAS_data.phase_discontinuity_indicator[sat][p] = read_has_message_body_uint8(message.substr(0, HAS_MSG_PHASE_DISCONTINUITY_INDICATOR_LENGTH));
// message = std::string(message.begin() + HAS_MSG_PHASE_DISCONTINUITY_INDICATOR_LENGTH, message.end());
// sat += 1;
// }
// }
// }
// if (d_HAS_data.header.ura_flag)
// {
// // read URA
// d_HAS_data.validity_interval_index_ura_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
// message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
// d_HAS_data.ura.reserve(Nsat);
// for (int i = 0; i < Nsat; i++)
// {
// d_HAS_data.ura[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_URA_LENGTH));
// message = std::string(message.begin() + HAS_MSG_URA_LENGTH, message.end());
// }
// }
}
uint8_t galileo_e6_has_msg_receiver::read_has_message_header_parameter_uint8(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const
{
uint8_t value = 0U;
for (int j = 0; j < parameter.second; j++)
{
value <<= 1U; // shift left
if (static_cast<int>(bits[GALILEO_CNAV_MT1_HEADER_BITS - parameter.first - j]) == 1)
{
value += 1; // insert the bit
}
}
return value;
}
uint16_t galileo_e6_has_msg_receiver::read_has_message_header_parameter_uint16(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const
{
uint16_t value = 0U;
for (int j = 0; j < parameter.second; j++)
{
value <<= 1U; // shift left
if (static_cast<int>(bits[GALILEO_CNAV_MT1_HEADER_BITS - parameter.first - j]) == 1)
{
value += 1; // insert the bit
}
}
return value;
}
bool galileo_e6_has_msg_receiver::read_has_message_header_parameter_bool(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const
{
bool value = false;
if (static_cast<int>(bits[GALILEO_CNAV_MT1_HEADER_BITS - parameter.first]) == 1)
{
value = true;
}
return value;
}
uint8_t galileo_e6_has_msg_receiver::read_has_message_body_uint8(const std::string& bits) const
{
uint8_t value = 0U;
const size_t len = bits.length();
for (size_t j = 0; j < len; j++)
{
value <<= 1U; // shift left
if (bits[j] == '1')
{
value += 1; // insert the bit
}
}
return value;
}
uint16_t galileo_e6_has_msg_receiver::read_has_message_body_uint16(const std::string& bits) const
{
uint16_t value = 0U;
const size_t len = bits.length();
for (size_t j = 0; j < len; j++)
{
value <<= 1U; // shift left
if (bits[j] == '1')
{
value += 1; // insert the bit
}
}
return value;
}
uint64_t galileo_e6_has_msg_receiver::read_has_message_body_uint64(const std::string& bits) const
{
uint64_t value = 0U;
const size_t len = bits.length();
for (size_t j = 0; j < len; j++)
{
value <<= 1U; // shift left
if (bits[j] == '1')
{
value += 1; // insert the bit
}
}
return value;
}
int16_t galileo_e6_has_msg_receiver::read_has_message_body_int16(const std::string& bits) const
{
int16_t value = 0;
const size_t len = bits.length();
// read the MSB and perform the sign extension
if (static_cast<int>(bits[0]) == 1)
{
value ^= 0xFFFF; // 16 bits variable
}
else
{
value &= 0;
}
for (size_t j = 0; j < len; j++)
{
value *= 2; // shift left the signed integer
value &= 0xFFFE; // reset the corresponding bit (for the 16 bits variable)
if (bits[j] == '1')
{
value += 1; // insert the bit
}
}
return value;
}
template <class T>
std::string galileo_e6_has_msg_receiver::debug_print_vector(const std::string& title, const std::vector<T>& vec) const
{
std::string msg(title);
msg += ": \n";
std::stringstream ss;
for (auto el : vec)
{
ss << static_cast<float>(el) << " ";
}
msg += ss.str();
return msg;
}
std::string galileo_e6_has_msg_receiver::debug_print_matrix(const std::string& title, const std::vector<std::vector<uint8_t>>& mat) const
{
std::string msg(title);
msg += ": \n";
std::stringstream ss;
for (size_t row = 0; row < mat.size(); row++)
{
for (size_t col = 0; col < mat[0].size(); col++)
{
ss << static_cast<float>(mat[row][col]) << " ";
}
ss << '\n';
}
msg += ss.str();
return msg;
}

View File

@ -0,0 +1,92 @@
/*!
* \file galileo_e6_has_msg_receiver.h
* \brief GNU Radio block that processes Galileo HAS message pages received from
* Galileo E6B telemetry blocks. After successful decoding, sends the content to
* the PVT block.
* \author Javier Arribas, 2021. jarribas(at)cttc.es
* \author Carles Fernandez-Prades, 2021. cfernandez(at)cttc.es
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GALILEO_E6_HAS_MSG_RECEIVER_H
#define GNSS_SDR_GALILEO_E6_HAS_MSG_RECEIVER_H
#include "Galileo_CNAV.h"
#include "galileo_has_data.h"
#include "gnss_block_interface.h"
#include <gnuradio/block.h>
#include <pmt/pmt.h>
#include <bitset>
#include <cstdint>
#include <memory>
#include <string>
#include <utility> // std::pair
#include <vector>
/** \addtogroup Core
* \{ */
/** \addtogroup Core_Receiver_Library
* \{ */
class Galileo_HAS_page;
class ReedSolomon;
class galileo_e6_has_msg_receiver;
using galileo_e6_has_msg_receiver_sptr = gnss_shared_ptr<galileo_e6_has_msg_receiver>;
galileo_e6_has_msg_receiver_sptr galileo_e6_has_msg_receiver_make();
/*!
* \brief GNU Radio block that receives asynchronous Galileo HAS message pages
* from the telemetry blocks, stores them in memory, and decodes HAS messages
* when enough data have been received.
* The decoded HAS message is sent to the PVT block.
*/
class galileo_e6_has_msg_receiver : public gr::block
{
public:
~galileo_e6_has_msg_receiver() = default; //!< Default destructor
private:
friend galileo_e6_has_msg_receiver_sptr galileo_e6_has_msg_receiver_make();
galileo_e6_has_msg_receiver();
void msg_handler_galileo_e6_has(const pmt::pmt_t& msg);
void process_HAS_page(const Galileo_HAS_page& has_page);
void read_MT1_header(const std::string& message_header);
void read_MT1_body(const std::string& message_body);
int decode_message_type1(uint8_t message_id, uint8_t message_size);
uint8_t read_has_message_header_parameter_uint8(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const;
uint16_t read_has_message_header_parameter_uint16(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const;
bool read_has_message_header_parameter_bool(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const;
uint8_t read_has_message_body_uint8(const std::string& bits) const;
uint16_t read_has_message_body_uint16(const std::string& bits) const;
uint64_t read_has_message_body_uint64(const std::string& bits) const;
int16_t read_has_message_body_int16(const std::string& bits) const;
template <class T>
std::string debug_print_vector(const std::string& title, const std::vector<T>& vec) const; // only for debug purposes
std::string debug_print_matrix(const std::string& title, const std::vector<std::vector<uint8_t>>& mat) const; // only for debug purposes
std::unique_ptr<ReedSolomon> d_rs;
Galileo_HAS_data d_HAS_data{};
std::vector<std::vector<std::vector<uint8_t>>> d_C_matrix{32, std::vector<std::vector<uint8_t>>(GALILEO_CNAV_MAX_NUMBER_SYMBOLS_ENCODED_BLOCK, std::vector<uint8_t>(GALILEO_CNAV_OCTETS_IN_SUBPAGE, 0))}; // 32 x 255 x 53
std::vector<std::vector<uint8_t>> d_M_matrix{GALILEO_CNAV_INFORMATION_VECTOR_LENGTH, std::vector<uint8_t>(GALILEO_CNAV_OCTETS_IN_SUBPAGE, 0)}; // HAS message matrix 32 x 53
std::vector<std::vector<uint8_t>> d_received_pids{32, std::vector<uint8_t>()};
bool d_new_message{};
};
/** \} */
/** \} */
#endif // GNSS_SDR_GALILEO_E6_HAS_MSG_RECEIVER_H

View File

@ -100,10 +100,6 @@ if(ENABLE_OSMOSDR)
endif() endif()
endif() endif()
if(ENABLE_GN3S)
target_compile_definitions(core_receiver PRIVATE -DGN3S_DRIVER=1)
endif()
if(ENABLE_ARRAY) if(ENABLE_ARRAY)
target_compile_definitions(core_receiver PRIVATE -DRAW_ARRAY_DRIVER=1) target_compile_definitions(core_receiver PRIVATE -DRAW_ARRAY_DRIVER=1)
endif() endif()
@ -224,13 +220,6 @@ if(ENABLE_FLEXIBAND AND TELEORBIT_FOUND)
) )
endif() endif()
if(ENABLE_GN3S AND GRGN3S_FOUND)
target_link_libraries(core_receiver
PRIVATE
Gnuradio::gn3s
)
endif()
if(ENABLE_ARRAY AND GRDBFCTTC_FOUND) if(ENABLE_ARRAY AND GRDBFCTTC_FOUND)
target_link_libraries(core_receiver target_link_libraries(core_receiver
PRIVATE PRIVATE

View File

@ -139,10 +139,6 @@
#include "gps_l1_ca_pcps_opencl_acquisition.h" #include "gps_l1_ca_pcps_opencl_acquisition.h"
#endif #endif
#if GN3S_DRIVER
#include "gn3s_signal_source.h"
#endif
#if RAW_ARRAY_DRIVER #if RAW_ARRAY_DRIVER
#include "raw_array_signal_source.h" #include "raw_array_signal_source.h"
#endif #endif
@ -733,15 +729,6 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
} }
#endif #endif
#if GN3S_DRIVER
else if (implementation == "GN3S_Signal_Source")
{
std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<Gn3sSignalSource>(configuration, role, in_streams,
out_streams, queue);
block = std::move(block_);
}
#endif
#if RAW_ARRAY_DRIVER #if RAW_ARRAY_DRIVER
else if (implementation == "Raw_Array_Signal_Source") else if (implementation == "Raw_Array_Signal_Source")
{ {

View File

@ -99,6 +99,8 @@ void GNSSFlowgraph::init()
channels_status_ = channel_status_msg_receiver_make(); channels_status_ = channel_status_msg_receiver_make();
gal_e6_has_rx_ = galileo_e6_has_msg_receiver_make();
// 1. read the number of RF front-ends available (one file_source per RF front-end) // 1. read the number of RF front-ends available (one file_source per RF front-end)
int sources_count_deprecated = configuration_->property("Receiver.sources_count", 1); int sources_count_deprecated = configuration_->property("Receiver.sources_count", 1);
sources_count_ = configuration_->property("GNSS-SDR.num_sources", sources_count_deprecated); sources_count_ = configuration_->property("GNSS-SDR.num_sources", sources_count_deprecated);
@ -443,6 +445,11 @@ int GNSSFlowgraph::connect_desktop_flowgraph()
return 1; return 1;
} }
if (connect_gal_e6_has() != 0)
{
return 1;
}
// Activate acquisition in enabled channels // Activate acquisition in enabled channels
for (int i = 0; i < channels_count_; i++) for (int i = 0; i < channels_count_; i++)
{ {
@ -1045,7 +1052,7 @@ int GNSSFlowgraph::connect_signal_sources_to_signal_conditioners()
{ {
// Connect the multichannel signal source to multiple signal conditioners // Connect the multichannel signal source to multiple signal conditioners
// GNURADIO max_streams=-1 means infinite ports! // GNURADIO max_streams=-1 means infinite ports!
size_t output_size = src->item_size(); size_t output_size = src->get_right_block()->output_signature()->sizeof_stream_item(0);
size_t input_size = sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()->sizeof_stream_item(0); size_t input_size = sig_conditioner_.at(signal_conditioner_ID)->get_left_block()->input_signature()->sizeof_stream_item(0);
// Check configuration inconsistencies // Check configuration inconsistencies
if (output_size != input_size) if (output_size != input_size)
@ -1539,6 +1546,42 @@ int GNSSFlowgraph::connect_monitors()
return 0; return 0;
} }
int GNSSFlowgraph::connect_gal_e6_has()
{
try
{
bool gal_e6_channels = false;
for (int i = 0; i < channels_count_; i++)
{
const std::string gnss_signal = channels_.at(i)->get_signal().get_signal_str();
std::string gnss_system;
Gnss_Signal signal_value;
switch (mapStringValues_[gnss_signal])
{
case evGAL_E6:
top_block_->msg_connect(channels_.at(i)->get_right_block(), pmt::mp("E6_HAS_from_TLM"), gal_e6_has_rx_, pmt::mp("E6_HAS_from_TLM"));
gal_e6_channels = true;
break;
default:
break;
}
}
if (gal_e6_channels == true)
{
top_block_->msg_connect(gal_e6_has_rx_, pmt::mp("E6_HAS_to_PVT"), pvt_->get_left_block(), pmt::mp("E6_HAS_to_PVT"));
}
}
catch (const std::exception& e)
{
LOG(ERROR) << "Can't connect Galileo E6 HAS msg ports: " << e.what();
top_block_->disconnect_all();
return 1;
}
DLOG(INFO) << "Galileo E6 HAS message ports connected";
return 0;
}
int GNSSFlowgraph::disconnect_monitors() int GNSSFlowgraph::disconnect_monitors()
{ {

View File

@ -26,6 +26,7 @@
#include "channel_status_msg_receiver.h" #include "channel_status_msg_receiver.h"
#include "concurrent_queue.h" #include "concurrent_queue.h"
#include "galileo_e6_has_msg_receiver.h"
#include "gnss_sdr_sample_counter.h" #include "gnss_sdr_sample_counter.h"
#include "gnss_signal.h" #include "gnss_signal.h"
#include "pvt_interface.h" #include "pvt_interface.h"
@ -176,6 +177,7 @@ private:
int connect_channels_to_observables(); int connect_channels_to_observables();
int connect_observables_to_pvt(); int connect_observables_to_pvt();
int connect_monitors(); int connect_monitors();
int connect_gal_e6_has();
int connect_gnss_synchro_monitor(); int connect_gnss_synchro_monitor();
int connect_acquisition_monitor(); int connect_acquisition_monitor();
int connect_tracking_monitor(); int connect_tracking_monitor();
@ -244,6 +246,8 @@ private:
gr::basic_block_sptr GnssSynchroAcquisitionMonitor_; gr::basic_block_sptr GnssSynchroAcquisitionMonitor_;
gr::basic_block_sptr GnssSynchroTrackingMonitor_; gr::basic_block_sptr GnssSynchroTrackingMonitor_;
channel_status_msg_receiver_sptr channels_status_; // class that receives and stores the current status of the receiver channels channel_status_msg_receiver_sptr channels_status_; // class that receives and stores the current status of the receiver channels
galileo_e6_has_msg_receiver_sptr gal_e6_has_rx_;
gnss_sdr_sample_counter_sptr ch_out_sample_counter_; gnss_sdr_sample_counter_sptr ch_out_sample_counter_;
#if ENABLE_FPGA #if ENABLE_FPGA
gnss_sdr_fpga_sample_counter_sptr ch_out_fpga_sample_counter_; gnss_sdr_fpga_sample_counter_sptr ch_out_fpga_sample_counter_;

View File

@ -86,6 +86,7 @@ set(SYSTEM_PARAMETERS_HEADERS
Beidou_DNAV.h Beidou_DNAV.h
MATH_CONSTANTS.h MATH_CONSTANTS.h
reed_solomon.h reed_solomon.h
galileo_has_page.h
) )
list(SORT SYSTEM_PARAMETERS_HEADERS) list(SORT SYSTEM_PARAMETERS_HEADERS)

View File

@ -63,7 +63,7 @@ constexpr int32_t GALILEO_CNAV_TELEMETRY_RATE_BITS_SECOND = 1000; // bps
constexpr int32_t GALILEO_CNAV_HAS_PAGE_DATA_BITS = 448; constexpr int32_t GALILEO_CNAV_HAS_PAGE_DATA_BITS = 448;
constexpr int32_t GALILEO_CNAV_PAGE_RESERVED_BITS = 14; constexpr int32_t GALILEO_CNAV_PAGE_RESERVED_BITS = 14;
constexpr int32_t GALILEO_CNAV_BITS_FOR_CRC = GALILEO_CNAV_HAS_PAGE_DATA_BITS + GALILEO_CNAV_PAGE_RESERVED_BITS; // 462 constexpr int32_t GALILEO_CNAV_BITS_FOR_CRC = GALILEO_CNAV_HAS_PAGE_DATA_BITS + GALILEO_CNAV_PAGE_RESERVED_BITS; // 462
constexpr int32_t GALILEO_CNAV_BYTES_FOR_CRC = 60; constexpr int32_t GALILEO_CNAV_BYTES_FOR_CRC = 58;
constexpr int32_t GALILEO_CNAV_CRC_LENGTH = 24; constexpr int32_t GALILEO_CNAV_CRC_LENGTH = 24;
constexpr int32_t GALILEO_CNAV_MESSAGE_BITS_PER_PAGE = 424; constexpr int32_t GALILEO_CNAV_MESSAGE_BITS_PER_PAGE = 424;
constexpr int32_t GALILEO_CNAV_PAGE_HEADER_BITS = 24; constexpr int32_t GALILEO_CNAV_PAGE_HEADER_BITS = 24;
@ -82,6 +82,7 @@ constexpr uint8_t HAS_MSG_GALILEO_SYSTEM = 2; // Table 8 ICD v1.2
constexpr char GALILEO_CNAV_PREAMBLE[17] = "1011011101110000"; constexpr char GALILEO_CNAV_PREAMBLE[17] = "1011011101110000";
const std::pair<int32_t, int32_t> GALILEO_HAS_STATUS({1, 2}); const std::pair<int32_t, int32_t> GALILEO_HAS_STATUS({1, 2});
const std::pair<int32_t, int32_t> GALILEO_HAS_RESERVED({3, 2});
const std::pair<int32_t, int32_t> GALILEO_HAS_MESSAGE_TYPE({5, 2}); const std::pair<int32_t, int32_t> GALILEO_HAS_MESSAGE_TYPE({5, 2});
const std::pair<int32_t, int32_t> GALILEO_HAS_MESSAGE_ID({7, 5}); const std::pair<int32_t, int32_t> GALILEO_HAS_MESSAGE_ID({7, 5});
const std::pair<int32_t, int32_t> GALILEO_HAS_MESSAGE_SIZE({12, 5}); const std::pair<int32_t, int32_t> GALILEO_HAS_MESSAGE_SIZE({12, 5});

View File

@ -19,30 +19,31 @@
#include "galileo_cnav_message.h" #include "galileo_cnav_message.h"
#include <boost/crc.hpp> // for boost::crc_basic, boost::crc_optimal #include <boost/crc.hpp> // for boost::crc_basic, boost::crc_optimal
#include <boost/dynamic_bitset.hpp> // for boost::dynamic_bitset #include <boost/dynamic_bitset.hpp> // for boost::dynamic_bitset
#include <algorithm> // for reverse, find #include <glog/logging.h>
#include <numeric> // for accumulate #include <algorithm> // for reverse
#include <vector>
using CRC_Galileo_CNAV_type = boost::crc_optimal<24, 0x1864CFBU, 0x0, 0x0, false, false>; using CRC_Galileo_CNAV_type = boost::crc_optimal<24, 0x1864CFBU, 0x0, 0x0, false, false>;
bool Galileo_Cnav_Message::CRC_test(const std::bitset<GALILEO_CNAV_BITS_FOR_CRC>& bits, uint32_t checksum) const bool Galileo_Cnav_Message::CRC_test(const std::bitset<GALILEO_CNAV_BITS_FOR_CRC>& bits, uint32_t checksum) const
{ {
CRC_Galileo_CNAV_type CRC_Galileo; CRC_Galileo_CNAV_type crc_galileo_e6b;
// Galileo CNAV frame for CRC is not an integer multiple of bytes // Galileo CNAV frame for CRC is not an integer multiple of bytes
// it needs to be filled with zeroes at the start of the frame. // it needs to be filled with zeroes at the start of the frame.
// This operation is done in the transformation from bits to bytes // This operation is done in the transformation from bits to bytes
// using boost::dynamic_bitset. // using boost::dynamic_bitset.
boost::dynamic_bitset<unsigned char> frame_bits(std::string(bits.to_string())); boost::dynamic_bitset<uint8_t> frame_bits(bits.to_string());
std::vector<unsigned char> bytes; std::vector<uint8_t> bytes;
bytes.reserve(GALILEO_CNAV_BYTES_FOR_CRC);
boost::to_block_range(frame_bits, std::back_inserter(bytes)); boost::to_block_range(frame_bits, std::back_inserter(bytes));
std::reverse(bytes.begin(), bytes.end()); std::reverse(bytes.begin(), bytes.end());
CRC_Galileo.process_bytes(bytes.data(), GALILEO_CNAV_BYTES_FOR_CRC); crc_galileo_e6b.process_bytes(bytes.data(), GALILEO_CNAV_BYTES_FOR_CRC);
const uint32_t crc_computed = CRC_Galileo.checksum(); const uint32_t crc_computed = crc_galileo_e6b.checksum();
if (checksum == crc_computed) if (checksum == crc_computed)
{ {
return true; return true;
@ -57,38 +58,49 @@ void Galileo_Cnav_Message::read_HAS_page(const std::string& page_string)
const std::string CRC_data = page_string.substr(GALILEO_CNAV_BITS_FOR_CRC, GALILEO_CNAV_CRC_LENGTH); const std::string CRC_data = page_string.substr(GALILEO_CNAV_BITS_FOR_CRC, GALILEO_CNAV_CRC_LENGTH);
const std::bitset<GALILEO_CNAV_BITS_FOR_CRC> Word_for_CRC_bits(has_page_bits); const std::bitset<GALILEO_CNAV_BITS_FOR_CRC> Word_for_CRC_bits(has_page_bits);
const std::bitset<GALILEO_CNAV_CRC_LENGTH> checksum(CRC_data); const std::bitset<GALILEO_CNAV_CRC_LENGTH> checksum(CRC_data);
if (CRC_test(Word_for_CRC_bits, checksum.to_ulong()) == true) d_new_HAS_page = false;
has_page = Galileo_HAS_page();
d_flag_CRC_test = CRC_test(Word_for_CRC_bits, checksum.to_ulong());
if (d_flag_CRC_test == true)
{ {
d_flag_CRC_test = true;
// CRC correct: Read 24 bits of HAS page header // CRC correct: Read 24 bits of HAS page header
read_HAS_page_header(page_string.substr(GALILEO_CNAV_PAGE_RESERVED_BITS, GALILEO_CNAV_PAGE_HEADER_BITS)); read_HAS_page_header(page_string.substr(GALILEO_CNAV_PAGE_RESERVED_BITS, GALILEO_CNAV_PAGE_HEADER_BITS));
bool use_has = false; bool use_has = false;
d_test_mode = false; d_test_mode = false;
// HAS status as defined in ICD v1.2 Table 5 HAS Page Header // HAS status as defined in ICD v1.2 Table 5 HAS Page Header
switch (d_has_page_status) if (!d_page_dummy)
{ {
case 0: // HAS is in Test Mode switch (d_has_page_status)
use_has = true; {
d_test_mode = true; case 0: // HAS is in Test Mode
break; use_has = true;
case 1: // HAS is in Operational Mode d_test_mode = true;
use_has = true; break;
break; case 1: // HAS is in Operational Mode
case 2: // HAS is in "reserved" status use_has = true;
case 3: // Do not use HAS break;
default: case 2: // HAS is in "reserved" status
break; case 3: // Do not use HAS
default:
break;
}
} }
if (use_has) if (use_has or d_page_dummy)
{ {
// Process the 424 bits of encoded data // Store the 424 bits of encoded data (CNAV page) and the page header
process_HAS_page(page_string.substr(GALILEO_CNAV_PAGE_RESERVED_BITS + GALILEO_CNAV_PAGE_HEADER_BITS, GALILEO_CNAV_MESSAGE_BITS_PER_PAGE)); has_page.has_message_string = page_string.substr(GALILEO_CNAV_PAGE_RESERVED_BITS + GALILEO_CNAV_PAGE_HEADER_BITS, GALILEO_CNAV_MESSAGE_BITS_PER_PAGE);
if (!d_page_dummy)
{
has_page.has_status = d_has_page_status;
has_page.reserved = d_has_reserved;
has_page.message_type = d_received_message_type;
has_page.message_id = d_received_message_id;
has_page.message_size = d_received_message_size;
has_page.message_page_id = d_received_message_page_id;
}
d_new_HAS_page = true;
} }
} }
else
{
d_flag_CRC_test = false;
}
} }
@ -98,6 +110,7 @@ void Galileo_Cnav_Message::read_HAS_page_header(const std::string& page_string)
if (page_string == "101011110011101111000011") // Equivalent to AF3BC3 if (page_string == "101011110011101111000011") // Equivalent to AF3BC3
{ {
d_page_dummy = true; d_page_dummy = true;
DLOG(INFO) << "HAS page with dummy header received.";
} }
else else
{ {
@ -108,462 +121,19 @@ void Galileo_Cnav_Message::read_HAS_page_header(const std::string& page_string)
// ICD v1.2 Table 5: HAS page header // ICD v1.2 Table 5: HAS page header
const std::bitset<GALILEO_CNAV_PAGE_HEADER_BITS> has_page_header(page_string); const std::bitset<GALILEO_CNAV_PAGE_HEADER_BITS> has_page_header(page_string);
d_has_page_status = read_has_page_header_parameter(has_page_header, GALILEO_HAS_STATUS); d_has_page_status = read_has_page_header_parameter(has_page_header, GALILEO_HAS_STATUS);
d_has_reserved = read_has_page_header_parameter(has_page_header, GALILEO_HAS_RESERVED);
d_received_message_type = read_has_page_header_parameter(has_page_header, GALILEO_HAS_MESSAGE_TYPE); d_received_message_type = read_has_page_header_parameter(has_page_header, GALILEO_HAS_MESSAGE_TYPE);
d_received_message_id = read_has_page_header_parameter(has_page_header, GALILEO_HAS_MESSAGE_ID); d_received_message_id = read_has_page_header_parameter(has_page_header, GALILEO_HAS_MESSAGE_ID);
d_received_message_size = read_has_page_header_parameter(has_page_header, GALILEO_HAS_MESSAGE_SIZE) + 1; // "0" means 1 d_received_message_size = read_has_page_header_parameter(has_page_header, GALILEO_HAS_MESSAGE_SIZE) + 1; // "0" means 1
d_received_message_page_id = read_has_page_header_parameter(has_page_header, GALILEO_HAS_MESSAGE_PAGE_ID); d_received_message_page_id = read_has_page_header_parameter(has_page_header, GALILEO_HAS_MESSAGE_PAGE_ID);
}
}
DLOG(INFO) << "HAS page header received " << page_string << ":\n"
void Galileo_Cnav_Message::process_HAS_page(const std::string& page_string) << "d_has_page_status: " << static_cast<float>(d_has_page_status) << "\n"
{ << "d_has_reserved: " << static_cast<float>(d_has_reserved) << "\n"
if (d_current_message_id == d_received_message_id) << "d_received_message_type: " << static_cast<float>(d_received_message_type) << "\n"
{ << "d_received_message_id: " << static_cast<float>(d_received_message_id) << "\n"
// if receiver pid was not there, store it. << "d_received_message_size: " << static_cast<float>(d_received_message_size) << "\n"
if (d_received_message_page_id == 0) << "d_received_message_page_id: " << static_cast<float>(d_received_message_page_id);
{
// reserved, ignore it
}
else
{
if (std::find(d_list_pid.begin(), d_list_pid.end(), d_received_message_page_id) == d_list_pid.end())
{
if (d_received_message_type == 1) // contains satellite corrections
{
d_received_encoded_messages++;
d_list_pid.push_back(d_received_message_page_id);
// Pack encoded string into 53 octets and put it in
// the corresponding row of d_C_matrix.
for (int k = 0; k < GALILEO_CNAV_OCTETS_IN_SUBPAGE; k++)
{
std::string bits8 = page_string.substr(k * 8, 8);
std::bitset<8> bs(bits8);
d_C_matrix[d_received_message_page_id - 1][k] = static_cast<uint8_t>(bs.to_ulong());
}
}
}
}
}
else
{
// Start new message
d_current_message_id = d_received_message_id;
d_received_encoded_messages = 0;
d_new_message = false;
d_current_message_size = d_received_message_size;
// erase stored pages and data, and start storing again
d_list_pid.clear();
d_HAS_data = Galileo_HAS_data();
if (d_received_message_type == 1)
{
d_received_encoded_messages++;
d_list_pid.push_back(d_received_message_page_id);
// Pack encoded string into 53 octets and put it in
// the corresponding row of d_C_matrix.
for (int k = 0; k < GALILEO_CNAV_OCTETS_IN_SUBPAGE; k++)
{
std::string bits8 = page_string.substr(k * 8, 8);
std::bitset<8> bs(bits8);
d_C_matrix[d_received_message_page_id - 1][k] = static_cast<uint8_t>(bs.to_ulong());
}
}
}
if (d_received_encoded_messages == d_current_message_size)
{
// we have a full encoded message stored in d_C_matrix
d_received_encoded_messages = 0;
d_current_message_id = 0;
int res = decode_message_type1();
if (res == 0)
{
d_new_message = true;
}
else
{
d_new_message = false;
}
}
}
int Galileo_Cnav_Message::decode_message_type1()
{
// All rows in d_C_matrix with no data are erasure positions
std::vector<int> erasure_positions;
erasure_positions.reserve(GALILEO_CNAV_MAX_NUMBER_SYMBOLS_ENCODED_BLOCK - d_list_pid.size());
for (int mpid = 1; mpid <= GALILEO_CNAV_MAX_NUMBER_SYMBOLS_ENCODED_BLOCK; mpid++)
{
if (std::find(d_list_pid.begin(), d_list_pid.end(), static_cast<uint8_t>(mpid)) == d_list_pid.end())
{
erasure_positions.push_back(static_cast<uint8_t>(mpid - 1));
}
else
{
d_list_pid.remove(static_cast<uint8_t>(mpid));
}
}
// Vertical decoding of d_C_matrix
for (int col = 0; col < GALILEO_CNAV_OCTETS_IN_SUBPAGE; col++)
{
std::vector<uint8_t> C_column(GALILEO_CNAV_MAX_NUMBER_SYMBOLS_ENCODED_BLOCK, 0);
for (int row = 0; row < GALILEO_CNAV_MAX_NUMBER_SYMBOLS_ENCODED_BLOCK; row++)
{
C_column[row] = d_C_matrix[row][col];
}
int result = rs.decode(C_column, erasure_positions);
if (result < 0)
{
// Decoding failed
d_C_matrix = {GALILEO_CNAV_MAX_NUMBER_SYMBOLS_ENCODED_BLOCK, std::vector<uint8_t>(GALILEO_CNAV_OCTETS_IN_SUBPAGE, 0)};
d_M_matrix = {GALILEO_CNAV_INFORMATION_VECTOR_LENGTH, std::vector<uint8_t>(GALILEO_CNAV_OCTETS_IN_SUBPAGE)};
return -1;
}
std::vector<uint8_t> M_column(C_column.begin(), C_column.begin() + GALILEO_CNAV_INFORMATION_VECTOR_LENGTH);
for (int i = 0; i < GALILEO_CNAV_INFORMATION_VECTOR_LENGTH; i++)
{
d_M_matrix[i][col] = M_column[i];
}
}
// Form the decoded HAS message by reading rows of d_M_matrix
std::string decoded_message_type_1;
decoded_message_type_1.reserve(d_current_message_size * GALILEO_CNAV_OCTETS_IN_SUBPAGE * 8);
for (uint8_t row = 0; row < d_current_message_size; row++)
{
for (int col = 0; col < GALILEO_CNAV_OCTETS_IN_SUBPAGE; col++)
{
std::bitset<8> bs(d_M_matrix[row][col]);
decoded_message_type_1 += bs.to_string();
}
}
// reset d_C_matrix and d_M_matrix for next decoding
d_C_matrix = {GALILEO_CNAV_MAX_NUMBER_SYMBOLS_ENCODED_BLOCK, std::vector<uint8_t>(GALILEO_CNAV_OCTETS_IN_SUBPAGE, 0)};
d_M_matrix = {GALILEO_CNAV_INFORMATION_VECTOR_LENGTH, std::vector<uint8_t>(GALILEO_CNAV_OCTETS_IN_SUBPAGE, 0)};
// Trigger HAS message content reading
read_MT1_header(decoded_message_type_1);
read_MT1_body(decoded_message_type_1);
return 0;
}
void Galileo_Cnav_Message::read_MT1_header(const std::string& message_string)
{
// ICD v1.2 Table 6: MT1 Message Header.
const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS> has_mt1_header(message_string);
d_HAS_data.header.toh = read_has_message_header_parameter_uint16(has_mt1_header, GALILEO_MT1_HEADER_TOH);
d_HAS_data.header.mask_id = read_has_message_header_parameter_uint8(has_mt1_header, GALILEO_MT1_HEADER_MASK_ID);
d_HAS_data.header.iod_id = read_has_message_header_parameter_uint8(has_mt1_header, GALILEO_MT1_HEADER_IOD_ID);
d_HAS_data.header.mask_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_MASK_FLAG);
d_HAS_data.header.orbit_correction_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_ORBIT_CORRECTION_FLAG);
d_HAS_data.header.clock_fullset_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_CLOCK_FULLSET_FLAG);
d_HAS_data.header.clock_subset_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_CLOCK_SUBSET_FLAG);
d_HAS_data.header.code_bias_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_CODE_BIAS_FLAG);
d_HAS_data.header.phase_bias_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_PHASE_BIAS_FLAG);
d_HAS_data.header.ura_flag = read_has_message_header_parameter_bool(has_mt1_header, GALILEO_MT1_HEADER_URA_FLAG);
}
void Galileo_Cnav_Message::read_MT1_body(const std::string& message_string)
{
// ICD v1.2 Table 7: MT1 Message Body.
auto message = std::string(message_string.begin() + GALILEO_CNAV_MT1_HEADER_BITS, message_string.end()); // Remove header
int Nsat = 0;
if (d_HAS_data.header.mask_flag)
{
// read mask
d_HAS_data.Nsys = read_has_message_body_uint8(message.substr(0, HAS_MSG_NSYS_LENGTH));
message = std::string(message.begin() + HAS_MSG_NSYS_LENGTH, message.end());
d_HAS_data.gnss_id_mask.reserve(d_HAS_data.Nsys);
d_HAS_data.cell_mask.reserve(d_HAS_data.Nsys);
d_HAS_data.cell_mask_availability_flag.reserve(d_HAS_data.Nsys);
d_HAS_data.nav_message.reserve(d_HAS_data.Nsys);
for (uint8_t i = 0; i < d_HAS_data.Nsys; i++)
{
d_HAS_data.gnss_id_mask[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_ID_MASK_LENGTH));
message = std::string(message.begin() + HAS_MSG_ID_MASK_LENGTH, message.end());
std::string msg = message.substr(0, HAS_MSG_SATELLITE_MASK_LENGTH);
d_HAS_data.satellite_mask[i] = read_has_message_body_uint64(msg);
int ones_in_satellite_mask = 0;
for (char c : msg)
{
if (c == '1')
{
ones_in_satellite_mask++;
}
}
Nsat += ones_in_satellite_mask;
message = std::string(message.begin() + HAS_MSG_SATELLITE_MASK_LENGTH, message.end());
msg = message.substr(0, HAS_MSG_SIGNAL_MASK_LENGTH);
d_HAS_data.signal_mask[i] = read_has_message_body_uint16(msg);
int ones_in_signal_mask = 0;
for (char c : msg)
{
if (c == '1')
{
ones_in_signal_mask++;
}
}
message = std::string(message.begin() + HAS_MSG_SIGNAL_MASK_LENGTH, message.end());
if (message.substr(0, 1) == "1")
{
d_HAS_data.cell_mask_availability_flag[i] = true;
}
else
{
d_HAS_data.cell_mask_availability_flag[i] = false;
}
message = std::string(message.begin() + 1, message.end());
int size_cell = ones_in_satellite_mask * ones_in_signal_mask;
d_HAS_data.cell_mask[i].reserve(ones_in_satellite_mask);
for (int s = 0; s < ones_in_satellite_mask; s++)
{
d_HAS_data.cell_mask[i][s].reserve(ones_in_signal_mask);
for (int sig = 0; sig < ones_in_signal_mask; sig++)
{
d_HAS_data.cell_mask[i][s][sig] = (message[sig] == '1' ? true : false);
}
}
message = std::string(message.begin() + size_cell, message.end());
d_HAS_data.nav_message[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_NAV_MESSAGE_LENGTH));
message = std::string(message.begin() + HAS_MSG_NAV_MESSAGE_LENGTH, message.end());
}
}
if (d_HAS_data.header.orbit_correction_flag)
{
// read orbit corrections
d_HAS_data.validity_interval_index_orbit_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
d_HAS_data.gnss_iod.reserve(Nsat);
d_HAS_data.delta_radial.reserve(Nsat);
d_HAS_data.delta_along_track.reserve(Nsat);
d_HAS_data.delta_cross_track.reserve(Nsat);
for (int i = 0; i < Nsat; i++)
{
if (d_HAS_data.gnss_id_mask[i] == HAS_MSG_GPS_SYSTEM)
{
d_HAS_data.gnss_iod[i] = read_has_message_body_uint16(message.substr(0, HAS_MSG_IOD_GPS_LENGTH));
message = std::string(message.begin() + HAS_MSG_IOD_GPS_LENGTH, message.end());
}
if (d_HAS_data.gnss_id_mask[i] == HAS_MSG_GALILEO_SYSTEM)
{
d_HAS_data.gnss_iod[i] = read_has_message_body_uint16(message.substr(0, HAS_MSG_IOD_GAL_LENGTH));
message = std::string(message.begin() + HAS_MSG_IOD_GAL_LENGTH, message.end());
}
d_HAS_data.delta_radial[i] = read_has_message_body_int16(message.substr(0, HAS_MSG_DELTA_RADIAL_LENGTH));
message = std::string(message.begin() + HAS_MSG_DELTA_RADIAL_LENGTH, message.end());
d_HAS_data.delta_along_track[i] = read_has_message_body_int16(message.substr(0, HAS_MSG_DELTA_ALONG_TRACK_LENGTH));
message = std::string(message.begin() + HAS_MSG_DELTA_ALONG_TRACK_LENGTH, message.end());
d_HAS_data.delta_cross_track[i] = read_has_message_body_int16(message.substr(0, HAS_MSG_DELTA_CROSS_TRACK_LENGTH));
message = std::string(message.begin() + HAS_MSG_DELTA_CROSS_TRACK_LENGTH, message.end());
}
}
if (d_HAS_data.header.clock_fullset_flag)
{
// read clock full-set corrections
d_HAS_data.validity_interval_index_clock_fullset_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
d_HAS_data.delta_clock_c0_multiplier.reserve(d_HAS_data.Nsys);
for (uint8_t i = 0; i < d_HAS_data.Nsys; i++)
{
if (d_HAS_data.gnss_id_mask[i] != HAS_MSG_GALILEO_SYSTEM)
{
d_HAS_data.delta_clock_c0_multiplier[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_DELTA_CLOCK_C0_MULTIPLIER_LENGTH));
message = std::string(message.begin() + HAS_MSG_DELTA_CLOCK_C0_MULTIPLIER_LENGTH, message.end());
}
}
d_HAS_data.iod_change_flag.reserve(Nsat);
d_HAS_data.delta_clock_c0.reserve(Nsat);
for (int i = 0; i < Nsat; i++)
{
d_HAS_data.iod_change_flag[i] = (message[0] == '1' ? true : false);
message = std::string(message.begin() + 1, message.end());
d_HAS_data.delta_clock_c0[i] = read_has_message_body_int16(message.substr(0, HAS_MSG_DELTA_CLOCK_C0_LENGTH));
message = std::string(message.begin() + HAS_MSG_DELTA_CLOCK_C0_LENGTH, message.end());
}
}
if (d_HAS_data.header.clock_subset_flag)
{
// read clock subset corrections
d_HAS_data.validity_interval_index_clock_subset_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
d_HAS_data.Nsysprime = read_has_message_body_uint8(message.substr(0, HAS_MSG_NSYSPRIME_LENGTH));
message = std::string(message.begin() + HAS_MSG_NSYSPRIME_LENGTH, message.end());
d_HAS_data.gnss_id_clock_subset.reserve(d_HAS_data.Nsysprime);
d_HAS_data.delta_clock_c0_multiplier_clock_subset.reserve(d_HAS_data.Nsysprime);
d_HAS_data.satellite_submask.reserve(d_HAS_data.Nsysprime);
d_HAS_data.iod_change_flag_clock_subset.reserve(d_HAS_data.Nsysprime);
d_HAS_data.delta_clock_c0_clock_subset.reserve(d_HAS_data.Nsysprime);
for (uint8_t i = 0; i < d_HAS_data.Nsysprime; i++)
{
d_HAS_data.gnss_id_clock_subset[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_ID_CLOCK_SUBSET_LENGTH));
message = std::string(message.begin() + HAS_MSG_ID_CLOCK_SUBSET_LENGTH, message.end());
if (d_HAS_data.gnss_id_clock_subset[i] != HAS_MSG_GALILEO_SYSTEM)
{
d_HAS_data.delta_clock_c0_multiplier_clock_subset[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_DELTA_CLOCK_MULTIPLIER_SUBSET_LENGTH));
message = std::string(message.begin() + HAS_MSG_DELTA_CLOCK_MULTIPLIER_SUBSET_LENGTH, message.end());
}
uint64_t number_sats_this_gnss_id = 0;
for (uint8_t j = 0; j < d_HAS_data.Nsys; j++)
{
if (d_HAS_data.gnss_id_mask[j] == d_HAS_data.gnss_id_clock_subset[i])
{
uint64_t n = d_HAS_data.satellite_mask[j];
while (n)
{
number_sats_this_gnss_id += n & 1;
n >>= 1;
}
break;
}
}
d_HAS_data.satellite_submask[i].reserve(number_sats_this_gnss_id);
for (uint64_t j = 0; j < number_sats_this_gnss_id; j++)
{
d_HAS_data.satellite_submask[i][j] = read_has_message_body_uint64(message.substr(0, 1));
message = std::string(message.begin() + 1, message.end());
}
d_HAS_data.iod_change_flag_clock_subset[i] = (message[0] == '1' ? true : false);
message = std::string(message.begin() + 1, message.end());
d_HAS_data.delta_clock_c0_clock_subset[i] = read_has_message_body_int16(message.substr(0, HAS_MSG_DELTA_CLOCK_C0_SUBSET_LENGTH));
message = std::string(message.begin() + HAS_MSG_DELTA_CLOCK_C0_SUBSET_LENGTH, message.end());
}
}
if (d_HAS_data.header.code_bias_flag)
{
// read code bias
d_HAS_data.validity_interval_index_code_bias_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
std::vector<uint64_t> number_sats(d_HAS_data.Nsys, 0);
std::vector<uint64_t> number_codes(d_HAS_data.Nsys, 0);
for (int sys = 0; sys < d_HAS_data.Nsys; sys++)
{
uint64_t number_sats_this_gnss_id = 0;
uint64_t number_signals_this_gnss_id = 0;
if (d_HAS_data.cell_mask_availability_flag[sys] == true)
{
uint64_t n = d_HAS_data.satellite_mask[sys];
while (n)
{
number_sats_this_gnss_id += n & 1;
n >>= 1;
}
uint64_t m = d_HAS_data.signal_mask[sys];
while (m)
{
number_signals_this_gnss_id += m & 1;
m >>= 1;
}
}
else
{
number_sats_this_gnss_id = HAS_MSG_MAX_SATS;
number_signals_this_gnss_id = HAS_MSG_MAX_SIGNALS;
}
number_sats[sys] = number_sats_this_gnss_id;
number_codes[sys] = number_signals_this_gnss_id;
}
uint64_t Nsat_b = std::accumulate(number_sats.begin(), number_sats.end(), 0ULL);
d_HAS_data.code_bias.reserve(Nsat_b);
int sat = 0;
for (int sys = 0; sys < d_HAS_data.Nsys; sys++)
{
d_HAS_data.code_bias[sat].reserve(number_codes[sys]);
for (uint64_t c = 0; c < number_codes[sys]; c++)
{
d_HAS_data.code_bias[sat][c] = read_has_message_body_int16(message.substr(0, HAS_MSG_CODE_BIAS_LENGTH));
message = std::string(message.begin() + HAS_MSG_CODE_BIAS_LENGTH, message.end());
sat += 1;
}
}
}
if (d_HAS_data.header.phase_bias_flag)
{
// read phase bias
d_HAS_data.validity_interval_index_phase_bias_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
std::vector<uint64_t> number_sats(d_HAS_data.Nsys, 0);
std::vector<uint64_t> number_phases(d_HAS_data.Nsys, 0);
for (int sys = 0; sys < d_HAS_data.Nsys; sys++)
{
uint64_t number_sats_this_gnss_id = 0;
uint64_t number_signals_this_gnss_id = 0;
if (d_HAS_data.cell_mask_availability_flag[sys] == true)
{
uint64_t n = d_HAS_data.satellite_mask[sys];
while (n)
{
number_sats_this_gnss_id += n & 1;
n >>= 1;
}
uint64_t m = d_HAS_data.signal_mask[sys];
while (m)
{
number_signals_this_gnss_id += m & 1;
m >>= 1;
}
}
else
{
number_sats_this_gnss_id = HAS_MSG_MAX_SATS;
number_signals_this_gnss_id = HAS_MSG_MAX_SIGNALS;
}
number_sats[sys] = number_sats_this_gnss_id;
number_phases[sys] = number_signals_this_gnss_id;
}
uint64_t Nsat_p = std::accumulate(number_sats.begin(), number_sats.end(), 0ULL);
d_HAS_data.phase_bias.reserve(Nsat_p);
d_HAS_data.phase_discontinuity_indicator.reserve(Nsat_p);
int sat = 0;
for (int sys = 0; sys < d_HAS_data.Nsys; sys++)
{
d_HAS_data.phase_bias[sat].reserve(number_phases[sys]);
d_HAS_data.phase_discontinuity_indicator[sat].reserve(number_phases[sys]);
for (uint64_t p = 0; p < number_phases[sys]; p++)
{
d_HAS_data.phase_bias[sat][p] = read_has_message_body_int16(message.substr(0, HAS_MSG_PHASE_BIAS_LENGTH));
message = std::string(message.begin() + HAS_MSG_PHASE_BIAS_LENGTH, message.end());
d_HAS_data.phase_discontinuity_indicator[sat][p] = read_has_message_body_uint8(message.substr(0, HAS_MSG_PHASE_DISCONTINUITY_INDICATOR_LENGTH));
message = std::string(message.begin() + HAS_MSG_PHASE_DISCONTINUITY_INDICATOR_LENGTH, message.end());
sat += 1;
}
}
}
if (d_HAS_data.header.ura_flag)
{
// read URA
d_HAS_data.validity_interval_index_ura_corrections = read_has_message_body_uint8(message.substr(0, HAS_MSG_VALIDITY_INDEX_LENGTH));
message = std::string(message.begin() + HAS_MSG_VALIDITY_INDEX_LENGTH, message.end());
d_HAS_data.ura.reserve(Nsat);
for (int i = 0; i < Nsat; i++)
{
d_HAS_data.ura[i] = read_has_message_body_uint8(message.substr(0, HAS_MSG_URA_LENGTH));
message = std::string(message.begin() + HAS_MSG_URA_LENGTH, message.end());
}
} }
} }
@ -581,124 +151,3 @@ uint8_t Galileo_Cnav_Message::read_has_page_header_parameter(const std::bitset<G
} }
return value; return value;
} }
uint8_t Galileo_Cnav_Message::read_has_message_header_parameter_uint8(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const
{
uint8_t value = 0U;
for (int j = 0; j < parameter.second; j++)
{
value <<= 1U; // shift left
if (static_cast<int>(bits[GALILEO_CNAV_MT1_HEADER_BITS - parameter.first - j]) == 1)
{
value += 1; // insert the bit
}
}
return value;
}
uint16_t Galileo_Cnav_Message::read_has_message_header_parameter_uint16(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const
{
uint16_t value = 0U;
for (int j = 0; j < parameter.second; j++)
{
value <<= 1U; // shift left
if (static_cast<int>(bits[GALILEO_CNAV_MT1_HEADER_BITS - parameter.first - j]) == 1)
{
value += 1; // insert the bit
}
}
return value;
}
bool Galileo_Cnav_Message::read_has_message_header_parameter_bool(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const
{
bool value = false;
if (static_cast<int>(bits[GALILEO_CNAV_MT1_HEADER_BITS - parameter.first]) == 1)
{
value = true;
}
return value;
}
uint8_t Galileo_Cnav_Message::read_has_message_body_uint8(const std::string& bits) const
{
uint8_t value = 0U;
size_t len = bits.length();
for (size_t j = 0; j < len; j++)
{
value <<= 1U; // shift left
if (static_cast<int>(bits[len - 1 - j]) == 1)
{
value += 1; // insert the bit
}
}
return value;
}
uint16_t Galileo_Cnav_Message::read_has_message_body_uint16(const std::string& bits) const
{
uint16_t value = 0U;
size_t len = bits.length();
for (size_t j = 0; j < len; j++)
{
value <<= 1U; // shift left
if (static_cast<int>(bits[len - 1 - j]) == 1)
{
value += 1; // insert the bit
}
}
return value;
}
uint64_t Galileo_Cnav_Message::read_has_message_body_uint64(const std::string& bits) const
{
uint64_t value = 0U;
size_t len = bits.length();
for (size_t j = 0; j < len; j++)
{
value <<= 1U; // shift left
if (static_cast<int>(bits[len - 1 - j]) == 1)
{
value += 1; // insert the bit
}
}
return value;
}
int16_t Galileo_Cnav_Message::read_has_message_body_int16(const std::string& bits) const
{
int16_t value = 0;
size_t len = bits.length();
// read the MSB and perform the sign extension
if (static_cast<int>(bits[len - 1]) == 1)
{
value ^= 0xFFFF; // 16 bits variable
}
else
{
value &= 0;
}
for (size_t j = 0; j < len; j++)
{
value *= 2; // shift left the signed integer
value &= 0xFFFE; // reset the corresponding bit (for the 16 bits variable)
if (static_cast<int>(bits[len - 1 - j]) == 1)
{
value += 1; // insert the bit
}
}
return value;
}

View File

@ -20,13 +20,11 @@
#define GNSS_SDR_GALILEO_CNAV_MESSAGE_H #define GNSS_SDR_GALILEO_CNAV_MESSAGE_H
#include "Galileo_CNAV.h" #include "Galileo_CNAV.h"
#include "galileo_has_data.h" #include "galileo_has_page.h"
#include "reed_solomon.h"
#include <bitset> #include <bitset>
#include <cstdint> #include <cstdint>
#include <list>
#include <string> #include <string>
#include <vector> #include <utility>
/** \addtogroup Core /** \addtogroup Core
* \{ */ * \{ */
@ -46,64 +44,49 @@ public:
void read_HAS_page(const std::string& page_string); void read_HAS_page(const std::string& page_string);
inline bool have_new_HAS_message()
{
return d_new_message;
}
inline bool is_HAS_in_test_mode() const inline bool is_HAS_in_test_mode() const
{ {
return d_test_mode; return d_test_mode;
} }
inline bool is_HAS_message_dummy() const inline bool is_HAS_page_dummy() const
{ {
return d_page_dummy; return d_page_dummy;
} }
inline Galileo_HAS_data get_HAS_data() const inline bool have_new_HAS_page() const
{ {
return d_HAS_data; return d_new_HAS_page;
}
inline Galileo_HAS_page get_HAS_encoded_page() const
{
return has_page;
}
inline bool get_flag_CRC_test() const
{
return d_flag_CRC_test;
} }
private: private:
uint8_t read_has_page_header_parameter(const std::bitset<GALILEO_CNAV_PAGE_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const;
bool CRC_test(const std::bitset<GALILEO_CNAV_BITS_FOR_CRC>& bits, uint32_t checksum) const; bool CRC_test(const std::bitset<GALILEO_CNAV_BITS_FOR_CRC>& bits, uint32_t checksum) const;
void read_HAS_page_header(const std::string& page_string); void read_HAS_page_header(const std::string& page_string);
void process_HAS_page(const std::string& page_string);
void read_MT1_header(const std::string& message_string);
void read_MT1_body(const std::string& message_string);
int decode_message_type1();
uint8_t read_has_page_header_parameter(const std::bitset<GALILEO_CNAV_PAGE_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const; Galileo_HAS_page has_page{};
uint8_t read_has_message_header_parameter_uint8(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const;
uint16_t read_has_message_header_parameter_uint16(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const;
bool read_has_message_header_parameter_bool(const std::bitset<GALILEO_CNAV_MT1_HEADER_BITS>& bits, const std::pair<int32_t, int32_t>& parameter) const;
uint8_t read_has_message_body_uint8(const std::string& bits) const;
uint16_t read_has_message_body_uint16(const std::string& bits) const;
uint64_t read_has_message_body_uint64(const std::string& bits) const;
int16_t read_has_message_body_int16(const std::string& bits) const;
Galileo_HAS_data d_HAS_data{};
ReedSolomon rs = ReedSolomon();
std::vector<std::vector<uint8_t>> d_C_matrix{GALILEO_CNAV_MAX_NUMBER_SYMBOLS_ENCODED_BLOCK, std::vector<uint8_t>(GALILEO_CNAV_OCTETS_IN_SUBPAGE, 0)}; // 255 x 53
std::vector<std::vector<uint8_t>> d_M_matrix{GALILEO_CNAV_INFORMATION_VECTOR_LENGTH, std::vector<uint8_t>(GALILEO_CNAV_OCTETS_IN_SUBPAGE, 0)}; // 32 x 53
std::list<uint8_t> d_list_pid;
uint8_t d_has_page_status{}; uint8_t d_has_page_status{};
uint8_t d_current_message_id{}; uint8_t d_has_reserved{};
uint8_t d_current_message_size{};
uint8_t d_received_message_page_id{}; uint8_t d_received_message_page_id{};
uint8_t d_received_message_type{}; uint8_t d_received_message_type{};
uint8_t d_received_message_id{}; uint8_t d_received_message_id{};
uint8_t d_received_encoded_messages{};
uint8_t d_received_message_size{}; uint8_t d_received_message_size{};
bool d_test_mode{}; bool d_test_mode{};
bool d_new_message{};
bool d_flag_CRC_test{}; bool d_flag_CRC_test{};
bool d_page_dummy{}; bool d_page_dummy{};
bool d_new_HAS_page{};
}; };

View File

@ -0,0 +1,54 @@
/*!
* \file galileo_has_page.h
* \brief Class for Galileo HAS message page storage
* \author Carles Fernandez-Prades, 2021 cfernandez(at)cttc.es
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_GALILEO_HAS_PAGE_H
#define GNSS_SDR_GALILEO_HAS_PAGE_H
#include <cstdint>
#include <string>
/** \addtogroup Core
* \{ */
/** \addtogroup System_Parameters
* \{ */
/*!
* \brief This class is a storage for Galileo HAS message page, as defined in
* Galileo High Accuracy Service E6-B Signal-In-Space Message Specification v1.2
* (April 2020).
*/
class Galileo_HAS_page
{
public:
Galileo_HAS_page() = default;
std::string has_message_string; //!< HAS message content
// HAS page header
uint8_t has_status{}; //!< HAS status
uint8_t reserved{}; //!< HAS reserved field
uint8_t message_type{}; //!< HAS message type (MT)
uint8_t message_id{}; //!< HAS message ID (MID)
uint8_t message_size{}; //!< HAS message size (MS)
uint8_t message_page_id{}; //!< HAS message page ID (PID)
};
/** \} */
/** \} */
#endif // GNSS_SDR_GALILEO_HAS_PAGE_H

View File

@ -125,7 +125,7 @@ if(NOT GZIP_NOTFOUND)
DESTINATION share/man/man1 DESTINATION share/man/man1
) )
execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/docs/changelog.md execute_process(COMMAND gzip -9 -c ${CMAKE_SOURCE_DIR}/docs/CHANGELOG.md
WORKING_DIRECTORY ${CMAKE_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
OUTPUT_FILE "${CMAKE_BINARY_DIR}/changelog.gz" OUTPUT_FILE "${CMAKE_BINARY_DIR}/changelog.gz"
) )

View File

@ -30,14 +30,23 @@ if(NOT GOOGLETEST_FOUND)
"--build" "${CMAKE_BINARY_DIR}/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}" "--build" "${CMAKE_BINARY_DIR}/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}"
"--config" $<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug> "--config" $<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug>
) )
if(CMAKE_VERSION VERSION_GREATER 3.12)
# Parallel building of gtest causes problems in some environments (e.g. Macports buildings)
set(GTEST_BUILD_COMMAND ${GTEST_BUILD_COMMAND} "--parallel 1")
endif()
if(CMAKE_GENERATOR STREQUAL Xcode) if(CMAKE_GENERATOR STREQUAL Xcode)
set(GTEST_BUILD_COMMAND "xcodebuild" "-configuration" $<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel> "-target" "gtest_main") set(GTEST_BUILD_COMMAND "xcodebuild" "-configuration" $<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel> "-target" "gtest_main")
endif() endif()
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) OR
(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))
set(GOOGLETEST_GIT_TAG v${GNSSSDR_GTEST_LOCAL_VERSION})
else()
set(GOOGLETEST_GIT_TAG release-${GNSSSDR_GTEST_LOCAL_VERSION})
endif()
if(CMAKE_VERSION VERSION_LESS 3.2) if(CMAKE_VERSION VERSION_LESS 3.2)
ExternalProject_Add(gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ExternalProject_Add(gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
GIT_REPOSITORY https://github.com/google/googletest GIT_REPOSITORY https://github.com/google/googletest
GIT_TAG v1.10.x GIT_TAG ${GOOGLETEST_GIT_TAG}
SOURCE_DIR ${CMAKE_BINARY_DIR}/thirdparty/gtest/gtest-${GNSSSDR_GTEST_LOCAL_VERSION} SOURCE_DIR ${CMAKE_BINARY_DIR}/thirdparty/gtest/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
BINARY_DIR ${CMAKE_BINARY_DIR}/gtest-${GNSSSDR_GTEST_LOCAL_VERSION} BINARY_DIR ${CMAKE_BINARY_DIR}/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
CMAKE_ARGS ${GTEST_COMPILER} CMAKE_ARGS ${GTEST_COMPILER}
@ -63,12 +72,6 @@ if(NOT GOOGLETEST_FOUND)
${CMAKE_BINARY_DIR}/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gtest_maind${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_BINARY_DIR}/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gtest_maind${CMAKE_STATIC_LIBRARY_SUFFIX}
) )
endif() endif()
set(GOOGLETEST_GIT_TAG "v${GNSSSDR_GTEST_LOCAL_VERSION}")
if(CMAKE_VERSION VERSION_GREATER 3.18.99)
# workaround to avoid warning about deprecated CMakeLists.txt with CMake >= 3.19
# Remove after a stable release of Googletest including this fix
set(GOOGLETEST_GIT_TAG ${GNSSSDR_GTEST_LOCAL_VERSION_POST_CMAKE_3_19})
endif()
ExternalProject_Add(gtest-${GNSSSDR_GTEST_LOCAL_VERSION} ExternalProject_Add(gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
GIT_REPOSITORY https://github.com/google/googletest GIT_REPOSITORY https://github.com/google/googletest
GIT_TAG ${GOOGLETEST_GIT_TAG} GIT_TAG ${GOOGLETEST_GIT_TAG}

View File

@ -25,9 +25,6 @@ if(NOT benchmark_FOUND)
"--build" "${CMAKE_BINARY_DIR}/benchmark-${GNSSSDR_BENCHMARK_LOCAL_VERSION}" "--build" "${CMAKE_BINARY_DIR}/benchmark-${GNSSSDR_BENCHMARK_LOCAL_VERSION}"
"--config" $<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug> "--config" $<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug>
) )
if(CMAKE_GENERATOR STREQUAL Xcode)
set(BENCHMARK_BUILD_COMMAND "xcodebuild" "-configuration" $<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel> "-target" "benchmark_main")
endif()
if((CMAKE_VERSION VERSION_GREATER 3.12.0) AND NOT (CMAKE_GENERATOR STREQUAL Xcode)) if((CMAKE_VERSION VERSION_GREATER 3.12.0) AND NOT (CMAKE_GENERATOR STREQUAL Xcode))
set(BENCHMARK_PARALLEL_BUILD "--parallel 2") set(BENCHMARK_PARALLEL_BUILD "--parallel 2")
@ -39,7 +36,7 @@ if(NOT benchmark_FOUND)
SOURCE_DIR ${CMAKE_BINARY_DIR}/thirdparty/benchmark SOURCE_DIR ${CMAKE_BINARY_DIR}/thirdparty/benchmark
BINARY_DIR ${CMAKE_BINARY_DIR}/benchmark-${GNSSSDR_BENCHMARK_LOCAL_VERSION} BINARY_DIR ${CMAKE_BINARY_DIR}/benchmark-${GNSSSDR_BENCHMARK_LOCAL_VERSION}
CMAKE_ARGS ${BENCHMARK_COMPILER} CMAKE_ARGS ${BENCHMARK_COMPILER}
-DBENCHMARK_ENABLE_GTEST_TESTS=OFF -DBENCHMARK_ENABLE_TESTING=OFF
${BENCHMARK_TOOLCHAIN_ARG} ${BENCHMARK_TOOLCHAIN_ARG}
-DCMAKE_BUILD_TYPE=$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug> -DCMAKE_BUILD_TYPE=$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug>
BUILD_COMMAND "${BENCHMARK_BUILD_COMMAND} ${BENCHMARK_PARALLEL_BUILD}" BUILD_COMMAND "${BENCHMARK_BUILD_COMMAND} ${BENCHMARK_PARALLEL_BUILD}"

View File

@ -203,8 +203,42 @@ void bm_e6b_correction(benchmark::State& state)
} }
} }
void bm_e6b_erasure(benchmark::State& state)
{
const std::vector<uint8_t> expected_output = {71, 12, 25, 210, 178, 81, 243, 9, 112, 98, 196, 203, 48, 125, 114, 165, 181, 193, 71, 174, 168, 42, 31, 128, 245, 87, 150, 58, 192, 66, 130, 179};
std::vector<uint8_t> encoded_input = {
71, 12, 25, 210, 178, 81, 243, 9, 112, 98, 196, 203, 48, 125, 114, 165, 181, 193, 71, 174, 168, 42, 31, 128, 245, 87, 150, 58, 192, 66, 130, 179, 133, 210, 122, 224, 75, 138, 20, 205, 14, 245, 209, 187, 246, 228, 12, 39, 244, 238, 223, 217, 84, 233, 137, 168, 153, 8, 94, 26, 99, 169, 149, 203, 115, 69, 211, 43, 70, 96, 70, 38, 160, 1, 232, 153, 223, 165, 93, 205, 101, 170, 60, 188, 198, 82, 168, 79, 95, 23, 118, 215, 187, 136, 24, 99, 252, 3, 144, 166, 117, 45, 168, 239, 77, 42, 246, 33, 122, 97, 242, 236, 13, 217, 96, 186, 71, 250, 242, 177, 125, 87, 27, 13, 118, 181, 178, 12, 27, 66, 31, 74, 127, 46, 112, 127, 116, 122, 190, 71, 240, 95, 78, 194, 113, 80, 46, 126, 74, 136, 118, 133, 105, 176, 47, 230, 162, 195, 93, 157, 72, 119, 13, 232, 151, 200, 191, 143, 75, 161, 111, 29, 158, 16, 181, 165, 92, 39, 17, 218, 228, 58, 176, 233, 55, 211, 195, 73, 37, 137, 232, 241, 150, 236, 152, 153, 53, 74, 81, 91, 160, 244, 21, 95, 176, 179, 141, 39, 61, 136, 16, 58, 160, 51, 210, 31, 134, 63, 203, 96, 219, 44, 231, 61, 220, 0, 241, 220, 207, 17, 52, 150, 117, 54, 222, 128, 101, 213, 164, 234, 74, 224, 57, 246, 70, 27, 202, 229, 4, 243, 128, 211, 158, 199, 4};
// Introduce 223 erasures:
std::vector<int> erasure_positions;
erasure_positions.reserve(223);
for (int i = 0; i < 223; i++)
{
encoded_input[i] = 0;
erasure_positions.push_back(i);
}
std::vector<uint8_t> code_vector_missing = encoded_input;
auto rs = std::make_unique<ReedSolomon>();
while (state.KeepRunning())
{
int result = rs->decode(encoded_input, erasure_positions);
if (result < 0)
{
state.SkipWithError("Failed to decode data!");
break;
}
state.PauseTiming();
encoded_input = code_vector_missing;
state.ResumeTiming();
}
}
BENCHMARK(bm_e1b_erasurecorrection_shortened); BENCHMARK(bm_e1b_erasurecorrection_shortened);
BENCHMARK(bm_e1b_erasurecorrection_unshortened); BENCHMARK(bm_e1b_erasurecorrection_unshortened);
BENCHMARK(bm_e6b_correction); BENCHMARK(bm_e6b_correction);
BENCHMARK(bm_e6b_erasure);
BENCHMARK_MAIN(); BENCHMARK_MAIN();

View File

@ -517,3 +517,27 @@ TEST(ReedSolomonE6BTest, Decode113ErrorsWithErasure)
std::vector<uint8_t> decoded(encoded_input.begin(), encoded_input.begin() + 32); std::vector<uint8_t> decoded(encoded_input.begin(), encoded_input.begin() + 32);
EXPECT_TRUE(expected_output == decoded); EXPECT_TRUE(expected_output == decoded);
} }
TEST(ReedSolomonE6BTest, DecodeErasure)
{
const std::vector<uint8_t> expected_output = {71, 12, 25, 210, 178, 81, 243, 9, 112, 98, 196, 203, 48, 125, 114, 165, 181, 193, 71, 174, 168, 42, 31, 128, 245, 87, 150, 58, 192, 66, 130, 179};
std::vector<uint8_t> encoded_input = {
71, 12, 25, 210, 178, 81, 243, 9, 112, 98, 196, 203, 48, 125, 114, 165, 181, 193, 71, 174, 168, 42, 31, 128, 245, 87, 150, 58, 192, 66, 130, 179, 133, 210, 122, 224, 75, 138, 20, 205, 14, 245, 209, 187, 246, 228, 12, 39, 244, 238, 223, 217, 84, 233, 137, 168, 153, 8, 94, 26, 99, 169, 149, 203, 115, 69, 211, 43, 70, 96, 70, 38, 160, 1, 232, 153, 223, 165, 93, 205, 101, 170, 60, 188, 198, 82, 168, 79, 95, 23, 118, 215, 187, 136, 24, 99, 252, 3, 144, 166, 117, 45, 168, 239, 77, 42, 246, 33, 122, 97, 242, 236, 13, 217, 96, 186, 71, 250, 242, 177, 125, 87, 27, 13, 118, 181, 178, 12, 27, 66, 31, 74, 127, 46, 112, 127, 116, 122, 190, 71, 240, 95, 78, 194, 113, 80, 46, 126, 74, 136, 118, 133, 105, 176, 47, 230, 162, 195, 93, 157, 72, 119, 13, 232, 151, 200, 191, 143, 75, 161, 111, 29, 158, 16, 181, 165, 92, 39, 17, 218, 228, 58, 176, 233, 55, 211, 195, 73, 37, 137, 232, 241, 150, 236, 152, 153, 53, 74, 81, 91, 160, 244, 21, 95, 176, 179, 141, 39, 61, 136, 16, 58, 160, 51, 210, 31, 134, 63, 203, 96, 219, 44, 231, 61, 220, 0, 241, 220, 207, 17, 52, 150, 117, 54, 222, 128, 101, 213, 164, 234, 74, 224, 57, 246, 70, 27, 202, 229, 4, 243, 128, 211, 158, 199, 4};
// Introduce 223 erasures:
std::vector<int> erasure_positions;
for (int i = 0; i < 223; i++)
{
encoded_input[i] = 0;
erasure_positions.push_back(i);
}
auto rs = std::make_unique<ReedSolomon>();
int result = rs->decode(encoded_input, erasure_positions);
EXPECT_TRUE(result == 223);
std::vector<uint8_t> decoded(encoded_input.begin(), encoded_input.begin() + 32);
EXPECT_TRUE(expected_output == decoded);
}

View File

@ -8,7 +8,7 @@ GNSS-SDR.internal_fs_sps=3000000
;######### SIGNAL_SOURCE CONFIG ############ ;######### SIGNAL_SOURCE CONFIG ############
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental) ;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source]
SignalSource.implementation=File_Signal_Source SignalSource.implementation=File_Signal_Source
;#filename: path to file with the captured GNSS signal samples to be processed ;#filename: path to file with the captured GNSS signal samples to be processed