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:
commit
514bb331ce
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -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:
|
||||
|
||||
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
|
||||
[Developer's Certificate of Origin](https://github.com/gnss-sdr/gnss-sdr/blob/next/.github/DCO.txt)
|
||||
and
|
||||
[signed your commits](https://gnss-sdr.org/docs/tutorials/using-git/#sign-your-commits)
|
||||
as an indication of fulfillment.
|
||||
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/).
|
||||
Specifically, you have read
|
||||
[about clang-format](https://gnss-sdr.org/coding-style/#use-tools-for-automated-code-formatting)
|
||||
|
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -56,7 +56,7 @@ jobs:
|
||||
- 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
|
||||
- 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
|
||||
run: cd build && run-clang-tidy.py -fix
|
||||
- name: check
|
||||
|
261
CMakeLists.txt
261
CMakeLists.txt
@ -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.")
|
||||
endif()
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12...3.19)
|
||||
cmake_minimum_required(VERSION 2.8.12...3.20)
|
||||
project(gnss-sdr CXX C)
|
||||
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_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)
|
||||
|
||||
# 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_GLOG_LOCAL_VERSION "0.5.0")
|
||||
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.4.x")
|
||||
set(GNSSSDR_GTEST_LOCAL_VERSION "1.10.x")
|
||||
set(GNSSSDR_GTEST_LOCAL_VERSION_POST_CMAKE_3_19 "f5e592d8ee5ffb1d9af5be7f715ce3576b8bf9c4") # Used with CMake >= 3.19
|
||||
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.5.x")
|
||||
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(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_GPSTK_LOCAL_VERSION "8.0.0")
|
||||
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.21")
|
||||
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.11.4")
|
||||
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.16.0")
|
||||
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.5.3")
|
||||
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.17.3")
|
||||
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.5.5")
|
||||
set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7")
|
||||
|
||||
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()
|
||||
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}'.")
|
||||
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)
|
||||
set_package_properties(ZLIB PROPERTIES
|
||||
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"
|
||||
)
|
||||
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)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU")
|
||||
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()
|
||||
message(" sudo apt-get install libtool")
|
||||
endif()
|
||||
message(FATAL_ERROR "libtool is required to build matio from source")
|
||||
message(FATAL_ERROR "libtool is required to build matio from source.")
|
||||
endif()
|
||||
if(EXISTS "/usr/bin/aclocal" 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()
|
||||
message(" sudo apt-get install automake")
|
||||
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()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
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))
|
||||
@ -2134,101 +2181,82 @@ if(NOT MATIO_FOUND OR MATIO_VERSION_STRING VERSION_LESS ${GNSSSDR_MATIO_MIN_VERS
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
find_package(HDF5)
|
||||
set_package_properties(HDF5 PROPERTIES
|
||||
URL "https://support.hdfgroup.org/HDF5/"
|
||||
PURPOSE "Required to build Matio."
|
||||
TYPE REQUIRED
|
||||
|
||||
list(GET HDF5_LIBRARIES 0 HDF5_FIRST_DIR)
|
||||
get_filename_component(HDF5_BASE_DIR2 ${HDF5_FIRST_DIR} DIRECTORY)
|
||||
get_filename_component(HDF5_BASE_DIR ${HDF5_BASE_DIR2} DIRECTORY)
|
||||
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)
|
||||
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"
|
||||
)
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/matio/lib)
|
||||
else() # CMake >= 3.7
|
||||
include(GNUInstallDirs)
|
||||
set(MATIO_STATIC_LIB ${CMAKE_BINARY_DIR}/matio/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}matio${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
if("${HDF5_VERSION}" VERSION_GREATER "1.8.18" AND "${HDF5_VERSION}" VERSION_LESS "1.10.4")
|
||||
# weird workaround, but it works in all tested distros (Ubuntu, Debian, Fedora, CentOS, OpenSUSE)
|
||||
set(EXTRA_MATIO_BUILD_FLAGS -DMATIO_WITH_ZLIB=OFF -DHAVE_ZLIB=1)
|
||||
endif()
|
||||
if(HDF5_FOUND)
|
||||
list(GET HDF5_LIBRARIES 0 HDF5_FIRST_DIR)
|
||||
get_filename_component(HDF5_BASE_DIR2 ${HDF5_FIRST_DIR} DIRECTORY)
|
||||
get_filename_component(HDF5_BASE_DIR ${HDF5_BASE_DIR2} DIRECTORY)
|
||||
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()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.2)
|
||||
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}
|
||||
)
|
||||
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")
|
||||
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}
|
||||
BINARY_DIR ${CMAKE_BINARY_DIR}/matio
|
||||
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-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>
|
||||
-DMATIO_SHARED=OFF
|
||||
"${EXTRA_MATIO_BUILD_FLAGS}"
|
||||
-DHDF5_USE_STATIC_LIBRARIES=OFF
|
||||
-DMATIO_DEFAULT_FILE_VERSION:STRING=7.3
|
||||
-DMATIO_MAT73=ON
|
||||
-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/matio
|
||||
BUILD_COMMAND ${CMAKE_COMMAND}
|
||||
"--build" "${CMAKE_BINARY_DIR}/matio"
|
||||
"--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>
|
||||
BUILD_BYPRODUCTS ${MATIO_STATIC_LIB}
|
||||
)
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/matio/${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET Matio::matio)
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/matio/include)
|
||||
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 ${MATIO_STATIC_LIB}
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/matio/include
|
||||
INTERFACE_LINK_LIBRARIES "${MATIO_STATIC_LIB};${HDF5_LIBRARIES};${ZLIB_LIBRARIES}"
|
||||
)
|
||||
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()
|
||||
|
||||
|
||||
@ -3031,32 +3059,6 @@ if(ENABLE_FLEXIBAND)
|
||||
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
|
||||
#######################################################
|
||||
@ -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_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_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_GPERFTOOLS ENABLE_GPERFTOOLS "Enables performance analysis. Requires Gperftools.")
|
||||
add_feature_info(ENABLE_GPROF ENABLE_GPROF "Enables performance analysis with 'gprof'.")
|
||||
|
359
README.md
359
README.md
@ -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,
|
||||
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:
|
||||
|
||||
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
|
||||
a framework for the development of new features. Please visit
|
||||
[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
|
||||
|
||||
@ -59,7 +122,7 @@ This section describes how to set up the compilation environment in GNU/Linux or
|
||||
- Supported microprocessor architectures:
|
||||
- i386: Intel x86 instruction set (32-bit microprocessors).
|
||||
- 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.
|
||||
- armhf: ARM hard float, ARMv7 + VFP3-D16 floating-point hardware extension +
|
||||
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).
|
||||
- mips64el: 64-bit version of MIPS architecture.
|
||||
- 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.
|
||||
- ppc64el: 64-bit little-endian PowerPC architecture.
|
||||
- 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
|
||||
|
||||
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
|
||||
packages.
|
||||
|
||||
@ -108,7 +171,7 @@ above).
|
||||
**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
|
||||
`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
|
||||
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
|
||||
@ -205,9 +268,9 @@ Once you have installed these packages, you can jump directly to
|
||||
### Alternative 2: Install dependencies using PyBOMBS
|
||||
|
||||
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
|
||||
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")
|
||||
(Python Build Overlay Managed Bundle System), GNU Radio's meta-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
|
||||
```
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
`$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
|
||||
step by step (i.e., cloning the repository and doing the usual
|
||||
`cmake .. && make && make install` dance), Armadillo, GFlags, Glog and GnuTLS
|
||||
can be installed either by using PyBOMBS:
|
||||
`cmake .. && make && make install` dance), Armadillo, GFlags, Glog, GnuTLS, and
|
||||
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
|
||||
@ -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 zypper install lapack-devel blas-devel # For OpenSUSE
|
||||
$ sudo pacman -S blas lapack # For Arch Linux
|
||||
$ wget http://sourceforge.net/projects/arma/files/armadillo-10.4.0.tar.xz
|
||||
$ tar xvfz armadillo-10.4.0.tar.xz
|
||||
$ cd armadillo-10.4.0
|
||||
$ wget http://sourceforge.net/projects/arma/files/armadillo-10.5.0.tar.xz
|
||||
$ tar xvfz armadillo-10.5.0.tar.xz
|
||||
$ cd armadillo-10.5.0
|
||||
$ cmake .
|
||||
$ make
|
||||
$ 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
|
||||
libraries are currently installed and will modify Armadillo's configuration
|
||||
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.
|
||||
BLAS, LAPACK and ATLAS).
|
||||
a combined alias for all the relevant libraries present on your system (e.g.,
|
||||
BLAS, LAPACK, and ATLAS).
|
||||
|
||||
#### 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:
|
||||
|
||||
```
|
||||
$ wget https://github.com/google/googletest/archive/v1.10.x.zip
|
||||
$ unzip v1.10.x.zip
|
||||
$ wget https://github.com/google/googletest/archive/release-1.11.0.zip
|
||||
$ unzip release-1.11.0.zip
|
||||
```
|
||||
|
||||
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;
|
||||
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
|
||||
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
|
||||
@ -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:
|
||||
|
||||
```
|
||||
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
|
||||
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
|
||||
@ -381,6 +444,18 @@ $ sudo pacman -S openssl # For Arch Linux
|
||||
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.
|
||||
|
||||
#### 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:
|
||||
|
||||
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:
|
||||
|
||||
```
|
||||
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.16.0/protobuf-cpp-3.16.0.tar.gz
|
||||
$ tar xvfz protobuf-cpp-3.16.0.tar.gz
|
||||
$ cd protobuf-3.16.0
|
||||
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-cpp-3.17.3.tar.gz
|
||||
$ tar xvfz protobuf-cpp-3.17.3.tar.gz
|
||||
$ cd protobuf-3.17.3
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
@ -405,6 +480,19 @@ $ sudo make install
|
||||
$ 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>:
|
||||
|
||||
```
|
||||
@ -430,7 +518,7 @@ gnss-sdr with the following structure:
|
||||
|-----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
|
||||
developments, you can use the 'next' branch by going to the newly created
|
||||
gnss-sdr folder doing:
|
||||
@ -460,7 +548,7 @@ $ make
|
||||
|
||||
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
|
||||
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
|
||||
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:
|
||||
@ -480,9 +568,9 @@ $ sudo make install
|
||||
```
|
||||
|
||||
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
|
||||
working directory at your preferred location and store your own configuration
|
||||
and data files there.
|
||||
/usr/local/share/gnss-sdr/conf for your reference. We suggest creating a working
|
||||
directory at your preferred location and store your own configuration and data
|
||||
files there.
|
||||
|
||||
You could be interested in creating the documentation (requires:
|
||||
`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
|
||||
```
|
||||
|
||||
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
|
||||
of Kernels (so called
|
||||
of Kernels (so-called
|
||||
[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
|
||||
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
|
||||
`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):
|
||||
|
||||
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
|
||||
of Kernels (so called
|
||||
of Kernels (so-called
|
||||
[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
|
||||
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:
|
||||
|
||||
```
|
||||
$ git checkout master # Switch to branch you want to update
|
||||
$ git pull upstream master # Download the newest code from our repository
|
||||
$ git checkout main # Switch to branch you want to update
|
||||
$ git pull upstream main # Download the newest code from our repository
|
||||
```
|
||||
|
||||
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
|
||||
`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
|
||||
receive GPS L1 C/A signals. GNSS-SDR require to have at least 2 MHz of
|
||||
bandwidth in 1.57542 GHz. (remember to enable the DC bias with the daughter
|
||||
board jumper). We use a [DBSRX2](https://www.ettus.com/all-products/DBSRX2/)
|
||||
to do the task, but you can try the newer Ettus' daughter boards as well. 3.
|
||||
The easiest way to capture a signal file is to use the GNU Radio Companion
|
||||
GUI. Only two blocks are needed: a USRP signal source connected to complex
|
||||
float file sink. You need to tune the USRP central frequency and decimation
|
||||
factor using USRP signal source properties box. We suggest using a decimation
|
||||
factor of 20 if you use the USRP2. This will give you 100/20 = 5 MSPS which
|
||||
will be enough to receive GPS L1 C/A signals. The front-end gain should also
|
||||
be configured. In our test with the DBSRX2 we obtained good results with
|
||||
`G=50`. 4. Capture at least 80 seconds of signal in open sky conditions.
|
||||
During the process, be aware of USRP driver buffer underruns messages. If
|
||||
your hard disk is not fast enough to write data at this speed you can capture
|
||||
to a virtual RAM drive. 80 seconds of signal at 5 MSPS occupies less than 3
|
||||
Gbytes using `gr_complex<float>`. 5. If you have no access to an RF
|
||||
front-end, you can download a sample raw data file (that contains GPS and
|
||||
Galileo signals) from
|
||||
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
|
||||
daughterboard jumper). We use a
|
||||
[DBSRX2](https://www.ettus.com/all-products/DBSRX2/) to do the task, but you
|
||||
can try the newer Ettus' daughter boards as well. 3. The easiest way to
|
||||
capture a signal file is to use the GNU Radio Companion GUI. Only two blocks
|
||||
are needed: a USRP signal source connected to a complex float file sink. You
|
||||
need to tune the USRP central frequency and decimation factor using the USRP
|
||||
signal source properties box. We suggest using a decimation factor of 20 if
|
||||
you use the USRP2. This will give you 100/20 = 5 MSPS which will be enough to
|
||||
receive GPS L1 C/A signals. The front-end gain should also be configured. In
|
||||
our test with the DBSRX2 we obtained good results with `G=50`. 4. Capture at
|
||||
least 80 seconds of signal in open sky conditions. During the process, be
|
||||
aware of USRP driver buffer underruns messages. If your hard disk is not fast
|
||||
enough to write data at this speed you can capture it to a virtual RAM drive.
|
||||
80 seconds of signal at 5 MSPS occupies less than 3 Gbytes using
|
||||
`gr_complex<float>`. If you have no access to an RF front-end, you can
|
||||
download a sample raw data file (that contains GPS and Galileo signals) from
|
||||
[here](https://sourceforge.net/projects/gnss-sdr/files/data/).
|
||||
3. You are ready to configure the receiver to use your captured file among other
|
||||
parameters:
|
||||
@ -1035,29 +1089,29 @@ file.
|
||||
GNSS-SDR's main method initializes the logging library, processes the command
|
||||
line flags, if any, provided by the user and instantiates a
|
||||
[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()
|
||||
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
|
||||
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
|
||||
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
|
||||
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.
|
||||
This class knows which roles it has to instantiate and how to connect them. It
|
||||
relies on the configuration to get the correct instances of the roles it needs
|
||||
and then it applies the connections between GNU Radio blocks to make the graph
|
||||
ready to be started. The complexity related to managing the blocks and the data
|
||||
stream is handled by GNU Radio's `gr::top_block` class. GNSSFlowgraph wraps the
|
||||
`gr::top_block` instance so we can take advantage of the `gnss_block_factory`
|
||||
(see below), the configuration system and the processing blocks. This class is
|
||||
also responsible for applying changes to the configuration of the flowgraph
|
||||
during run-time, dynamically reconfiguring channels: it selects the strategy for
|
||||
selecting satellites. This can range from a sequential search over all the
|
||||
satellites' ID to other more efficient approaches.
|
||||
modifying it during run-time, and stopping it. Blocks are identified by their
|
||||
role. This class knows which roles it has to instantiate and how to connect
|
||||
them. It relies on the configuration to get the correct instances of the roles
|
||||
it needs and then it applies the connections between GNU Radio blocks to make
|
||||
the graph ready to be started. The complexity related to managing the blocks and
|
||||
the data stream is handled by GNU Radio's `gr::top_block` class. GNSSFlowgraph
|
||||
wraps the `gr::top_block` instance so we can take advantage of the
|
||||
`gnss_block_factory` (see below), the configuration system, and the processing
|
||||
blocks. This class is also responsible for applying changes to the configuration
|
||||
of the flowgraph during run-time, dynamically reconfiguring channels: it selects
|
||||
the strategy for selecting satellites. This can range from a sequential search
|
||||
over all the satellites' ID to other more efficient approaches.
|
||||
|
||||
The Control Plane is in charge of creating a flowgraph according to the
|
||||
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
|
||||
format, etc.). Since it is difficult to foresee what future module
|
||||
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
|
||||
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
|
||||
class and modifying the factory to be able to instantiate it. This loose
|
||||
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
|
||||
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
|
||||
blocks depicted in the figure above. This hierarchy provides the definition of
|
||||
different algorithms and different implementations, which will be instantiated
|
||||
according to the configuration. This strategy allows multiple implementations
|
||||
sharing a common interface, achieving the objective of decoupling interfaces
|
||||
from implementations: it defines a family of algorithms, encapsulates each one,
|
||||
and makes them interchangeable. Hence, we let the algorithm vary independently
|
||||
of the program that uses it.
|
||||
according to the configuration. This strategy allows multiple implementations to
|
||||
share a common interface, achieving the objective of decoupling interfaces from
|
||||
implementations: it defines a family of algorithms, encapsulates each one, and
|
||||
makes them interchangeable. Hence, we let the algorithm vary independently of
|
||||
the program that uses it.
|
||||
|
||||
Internally, GNSS-SDR makes use of the complex data types defined by
|
||||
[VOLK](https://www.libvolk.org/ "Vector-Optimized Library of Kernels home").
|
||||
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
|
||||
list shows the data type names that GNSS-SDR exposes through the configuration
|
||||
file:
|
||||
@ -1192,7 +1246,7 @@ parameters can be found at the
|
||||
|
||||
### 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
|
||||
file stored in the hard disk or directly in real-time from a hardware device
|
||||
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
|
||||
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
|
||||
I&Q components), the sampling rate and number of bits per sample, that must be
|
||||
specified by the user in the configuration file.
|
||||
I&Q components), the sampling rate, and the number of bits per sample, which
|
||||
must be specified by the user in the configuration file.
|
||||
|
||||
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
|
||||
@ -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
|
||||
computational processes (mainly correlation) that take advantage of specific
|
||||
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
|
||||
(implemented using SIMD or any other processor-specific technology) of the
|
||||
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_**
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
interpretation:
|
||||
|
||||
| **b_1** | **b_0** | **Value** |
|
||||
@ -1263,14 +1317,14 @@ interpretation:
|
||||
| 1 | 0 | -3 |
|
||||
| 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
|
||||
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
|
||||
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
|
||||
significant two bits will be used.
|
||||
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 significant two bits will be used.
|
||||
|
||||
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:
|
||||
@ -1278,8 +1332,8 @@ real, imag, real, imag, ... `sample_type=iq` or in the order: imag, real, imag,
|
||||
real, ... `sample_type=qi`.
|
||||
|
||||
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
|
||||
`big_endian_items=false`. If the shorts are big endian then the 2nd byte in each
|
||||
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
|
||||
short is output first.
|
||||
|
||||
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
|
||||
reference sample rate to the downstream processing blocks, acting as a facade
|
||||
between the signal source and the synchronization channels, providing a
|
||||
simplified interface to the input signal. In case of multiband front-ends, this
|
||||
module would be in charge of providing a separated data stream for each band.
|
||||
simplified interface to the input signal. In the case of multiband front-ends,
|
||||
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`
|
||||
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
|
||||
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
|
||||
@ -1485,7 +1540,7 @@ More documentation at the
|
||||
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
|
||||
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
|
||||
response given a set of band edges, the desired response on those bands, and the
|
||||
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.
|
||||
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
|
||||
number of channels is selectable by the user in the configuration file, this
|
||||
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
|
||||
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
|
||||
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
|
||||
abstraction used to design this logic is known as finite state machine (FSM),
|
||||
that is a behavior model composed of a finite number of states, transitions
|
||||
abstraction used to design this logic is known as a finite state machine (FSM),
|
||||
which is a behavior model composed of a finite number of states, transitions
|
||||
between those states, and actions.
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
||||
[AcquisitionInterface](./src/core/interfaces/acquisition_interface.h) is the
|
||||
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
|
||||
classes referred to as _adapters_. These adapters wrap the GNU Radio blocks
|
||||
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
|
||||
time the message was transmitted, orbital parameters of satellites (also known
|
||||
as ephemeris) and an almanac (information about the general system health, rough
|
||||
orbits of all satellites in the network as well as data related to error
|
||||
as ephemeris), and an almanac (information about the general system health,
|
||||
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,
|
||||
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
|
||||
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)
|
||||
encoding and interleaving, depending on the system. All this decoding complexity
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
@ -1865,14 +1920,14 @@ More documentation at 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
|
||||
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
|
||||
port as [NMEA 0183](https://en.wikipedia.org/wiki/NMEA_0183) messages), and
|
||||
leaves room for more sophisticated positioning methods by storing observables
|
||||
and navigation data in [RINEX](https://en.wikipedia.org/wiki/RINEX) files (v2.11
|
||||
or v3.02), and generating
|
||||
[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).
|
||||
|
||||
@ -1926,7 +1981,7 @@ PVT.rtcm_MT1077_rate_ms=1000
|
||||
[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/).
|
||||
|
||||
- **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
|
||||
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
|
||||
@ -1934,7 +1989,7 @@ PVT.rtcm_MT1077_rate_ms=1000
|
||||
|
||||
- **NMEA 0183** is a combined electrical and data specification for
|
||||
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.
|
||||
[National Marine Electronics Association](https://www.nmea.org/). The NMEA
|
||||
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
|
||||
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),
|
||||
[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
|
||||
[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
|
||||
@ -1974,7 +2029,7 @@ PVT.rinex_version=2
|
||||
correction applications. Developed by the 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
|
||||
_RTCM 10403.2, Differential GNSS (Global Navigation Satellite Systems)
|
||||
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
|
||||
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")),
|
||||
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:
|
||||
|
||||
```
|
||||
@ -2004,9 +2059,9 @@ PVT.rtcm_station_id=1111
|
||||
|
||||
**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
|
||||
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.
|
||||
|
||||
More documentation at the
|
||||
@ -2084,9 +2139,9 @@ processed.
|
||||
Another interesting option is working in real-time with an RF front-end. We
|
||||
provide drivers for UHD-compatible hardware such as the
|
||||
[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
|
||||
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.
|
||||
(HackRF, bladeRF, LimeSDR, 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.
|
||||
|
||||
You can find more information at the
|
||||
[GNSS-SDR Documentation page](https://gnss-sdr.org/docs/) or directly asking to
|
||||
|
@ -7,10 +7,16 @@
|
||||
execute_process(COMMAND uname -v OUTPUT_VARIABLE DARWIN_VERSION)
|
||||
string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION})
|
||||
|
||||
if(${DARWIN_VERSION} MATCHES "20")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++17")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
|
||||
set(MACOS_DISTRIBUTION "macOS Big Sur 11")
|
||||
if(${DARWIN_VERSION} VERSION_GREATER "19")
|
||||
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)
|
||||
if(macOS_NAME)
|
||||
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()
|
||||
|
||||
if(${DARWIN_VERSION} MATCHES "19")
|
||||
|
@ -20,7 +20,7 @@ if(DEFINED ENV{GFORTRAN_ROOT})
|
||||
)
|
||||
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(GCC_SERIES ${GCC_MAJOR_SERIES} ${GCC4_SERIES})
|
||||
|
||||
|
@ -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)
|
@ -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
|
@ -13,7 +13,7 @@ GNSS-SDR.internal_fs_sps=2560000
|
||||
;GNSS-SDR.internal_fs_sps=5120000
|
||||
|
||||
;######### 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
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
|
@ -8,6 +8,10 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
|
||||
)
|
||||
<!-- 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)
|
||||
|
||||
### 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
|
||||
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
|
||||
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.
|
||||
- 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
|
||||
shorten the Time-To-First-Fix. Since the added computational cost could break
|
||||
some real-time configurations, this feature is disabled by default. It can be
|
||||
activated from the configuration file by adding
|
||||
shortening the Time-To-First-Fix. Since the added computational cost could
|
||||
break some real-time configurations, this feature is disabled by default. It
|
||||
can be activated from the configuration file by adding
|
||||
`TelemetryDecoder_1B.enable_reed_solomon=true`.
|
||||
|
||||
### 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 the filesystem library.
|
||||
- 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.
|
||||
- Do not apply clang-tidy fixes to protobuf-generated headers.
|
||||
- Refactored private implementation of flow graph connection and disconnection
|
||||
for improved source code readability.
|
||||
- Added a base class for GNSS ephemeris, saving some duplicated code and
|
||||
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
|
||||
https://github.com/gsl-lite/gsl-lite/releases/tag/v0.38.1
|
||||
|
||||
### Improvements in Portability:
|
||||
|
||||
- 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
|
||||
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
|
||||
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.
|
||||
- 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
|
||||
Boost >= 1.74.
|
||||
- Fix linking of the `<filesystem>` library when using GCC 8.x and GNU Radio >=
|
||||
3.8.
|
||||
- If the Matio library is not found, now it is configured and built by CMake
|
||||
instead of using autotools.
|
||||
|
||||
### Improvements in Usability:
|
||||
|
||||
- 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
|
||||
allowing to multiplex signal streams outside of `gnss-sdr`, letting another
|
||||
program to hold access to the receiver, or allowing signal sources that are
|
||||
not supported by `gnss-sdr` but can dump the signal to a FIFO.
|
||||
program hold access to the receiver, or allowing signal sources that are not
|
||||
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
|
||||
some common inconsistencies in the configuration file.
|
||||
- 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
|
||||
options.
|
||||
- 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/
|
||||
|
||||
|
||||
|
||||
## [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:
|
||||
|
||||
- Fixed bug in acquisition detection when the configuration parameter
|
||||
`Acquisition_XX.threshold` was set but `Acquisition_XX.pfa` was not, causing
|
||||
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`.
|
||||
|
||||
### Improvements in Efficiency:
|
||||
@ -121,8 +139,8 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
|
||||
|
||||
### Improvements in Maintainability:
|
||||
|
||||
- Added a common shared pointer definition `gnss_shared_ptr`, which allows to
|
||||
handle the `boost::shared_ptr` to `std::shared_ptr` transition in GNU Radio
|
||||
- Added a common shared pointer definition `gnss_shared_ptr`, which allows
|
||||
handling the `boost::shared_ptr` to `std::shared_ptr` transition in GNU Radio
|
||||
3.9 API more nicely.
|
||||
- Support new FFT and firdes blocks' API in GNU Radio 3.9.
|
||||
- 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
|
||||
fixes in some environments.
|
||||
- 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:
|
||||
|
||||
@ -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
|
||||
Matlab and Python.
|
||||
|
||||
See the definitions of concepts and metrics at
|
||||
https://gnss-sdr.org/design-forces/
|
||||
|
||||
|
||||
|
||||
## [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:
|
||||
|
||||
@ -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.
|
||||
- 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
|
||||
padding space in the stack and making the files more readable for humans.
|
||||
- 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.
|
||||
- Improved system constant definition headers, numerical values are only written
|
||||
once.
|
||||
- Improved const correctness.
|
||||
- Improved `const` correctness.
|
||||
- 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
|
||||
version still remains at 3.7.3.
|
||||
- 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`
|
||||
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
|
||||
to use; simplifications for various API dependency and environment versions
|
||||
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.
|
||||
- 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
|
||||
[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.
|
||||
- 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
|
||||
@ -269,7 +290,7 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
|
||||
|
||||
### 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.
|
||||
|
||||
### 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
|
||||
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
|
||||
`./install` folder, also under the building directory. The old behavior for
|
||||
generated binaries is maintained if the building is done from any source tree
|
||||
@ -316,7 +337,7 @@ https://gnss-sdr.org/design-forces/
|
||||
|
||||
|
||||
|
||||
## [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:
|
||||
|
||||
@ -338,7 +359,7 @@ https://gnss-sdr.org/design-forces/
|
||||
### Improvements in Flexibility:
|
||||
|
||||
- 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.
|
||||
- Added new Tracking parameter `Tracking_XX.carrier_aiding`, allowing
|
||||
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:
|
||||
`readability-avoid-const-params-in-decls`,
|
||||
`readability-braces-around-statements`, `readability-isolate-declaration`,
|
||||
`readability-redundant-control-flow`, `readability-uppercase-literal-suffix`.
|
||||
Fixed raised warnings.
|
||||
`readability-redundant-control-flow`, and
|
||||
`readability-uppercase-literal-suffix`. Fixed raised warnings.
|
||||
- Fixed a number of defects detected by `cpplint.py`. Filters applied:
|
||||
`+build/class`, `+build/c++14`, `+build/deprecated`,
|
||||
`+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/init`, `+runtime/invalid_increment`,
|
||||
`+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
|
||||
compilation.
|
||||
- Added more check options to `.clang-tidy` file.
|
||||
- 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).
|
||||
- CMake now passes the `-DCMAKE_BUILD_TYPE` (or configuration in
|
||||
multi-configuration generators like Xcode) to modules built along gnss-sdr
|
||||
(e.g, the volk_gnsssdr library and googletest). Build types available: `None`,
|
||||
`Release` (by default), `Debug`, `RelWithDebInfo`, `MinSizeRel`, `Coverage`,
|
||||
`NoOptWithASM`, `O2WithASM`, `O3WithASM`, `ASAN`.
|
||||
multi-configuration generators like Xcode) to modules built along with
|
||||
`gnss-sdr` (e.g, the `volk_gnsssdr` library and googletest). Build types
|
||||
available: `None`, `Release` (by default), `Debug`, `RelWithDebInfo`,
|
||||
`MinSizeRel`, `Coverage`, `NoOptWithASM`, `O2WithASM`, `O3WithASM`, `ASAN`.
|
||||
- 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
|
||||
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
|
||||
@ -433,18 +454,20 @@ https://gnss-sdr.org/design-forces/
|
||||
### Improvements in Portability:
|
||||
|
||||
- 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
|
||||
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.
|
||||
- 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
|
||||
gflags, glog, matio, PugiXML, Protocol Buffers or googletest previously
|
||||
installed.
|
||||
- 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 can be built on Microsoft Windows.
|
||||
- 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
|
||||
and NEON (v7 and v8) instructions.
|
||||
- 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.
|
||||
- Simplified RTKLIB error log.
|
||||
- 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 user clock drift estimation, in ppm, in the Pvt_Monitor and
|
||||
in internal logging (`Debug` mode).
|
||||
- Added reporting of user clock drift estimation, in ppm, in the `Pvt_Monitor`
|
||||
and in internal logging (`Debug` mode).
|
||||
- Updated documentation generated by Doxygen, now the `pdfmanual` target works
|
||||
when using ninja.
|
||||
- CMake now generates an improved summary of required/optional dependency
|
||||
@ -508,7 +531,7 @@ https://gnss-sdr.org/design-forces/
|
||||
|
||||
|
||||
|
||||
## [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
|
||||
features and bug fixes:
|
||||
@ -541,14 +564,15 @@ features and bug fixes:
|
||||
messages (acceleration by x1.6 on average per channel).
|
||||
- Shortened Acquisition to Tracking transition time.
|
||||
- Applied clang-tidy checks and fixes related to performance:
|
||||
performance-faster-string-find, performance-for-range-copy,
|
||||
performance-implicit-conversion-in-loop, performance-inefficient-algorithm,
|
||||
performance-inefficient-string-concatenation,
|
||||
performance-inefficient-vector-operation, performance-move-const-arg,
|
||||
performance-move-constructor-init, performance-noexcept-move-constructor,
|
||||
performance-type-promotion-in-math-fn,
|
||||
performance-unnecessary-copy-initialization,
|
||||
performance-unnecessary-value-param, readability-string-compare.
|
||||
`performance-faster-string-find`, `performance-for-range-copy`,
|
||||
`performance-implicit-conversion-in-loop`,
|
||||
`performance-inefficient-algorithm`,
|
||||
`performance-inefficient-string-concatenation`,
|
||||
`performance-inefficient-vector-operation`, `performance-move-const-arg`,
|
||||
`performance-move-constructor-init`, `performance-noexcept-move-constructor`,
|
||||
`performance-type-promotion-in-math-fn`,
|
||||
`performance-unnecessary-copy-initialization`,
|
||||
`performance-unnecessary-value-param`, `readability-string-compare`.
|
||||
|
||||
### Improvements in Flexibility:
|
||||
|
||||
@ -566,36 +590,36 @@ features and bug fixes:
|
||||
- Added a custom UDP/IP output for PVT data streaming.
|
||||
- Improved Monitor block with UDP/IP output for internal receiver's data
|
||||
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
|
||||
future format changes. New dependency: Protocol Buffers >= 3.0.0
|
||||
- Fixes in RINEX generation: week rollover, annotations are not repeated anymore
|
||||
in navigation files. Parameter rinexnav_rate_ms has been removed, annotations
|
||||
are made as new ephemeris arrive.
|
||||
in navigation files. Parameter `PVT.rinexnav_rate_ms` has been removed,
|
||||
annotations are made as new ephemeris arrive.
|
||||
- Fixes in RTCM messages generation: week rollover.
|
||||
|
||||
### Improvements in Maintainability:
|
||||
|
||||
- The internal communication mechanism based on gr::msg_queue has been replaced
|
||||
by a thread-safe, built-in asynchronous message passing system based on GNU
|
||||
Radio's Polymorphic Types. This change is backwards-compatible and prevents
|
||||
from a failure in case of a possible future deprecation or removal of the
|
||||
gr::msg_queue API.
|
||||
- Deprecated boost::asio::io_service replaced by boost::asio::io_context if
|
||||
- The internal communication mechanism based on `gr::msg_queue` has been
|
||||
replaced by a thread-safe, built-in asynchronous message passing system based
|
||||
on GNU Radio's Polymorphic Types. This change is backwards-compatible and
|
||||
prevents from a failure in case of a possible future deprecation or removal of
|
||||
the `gr::msg_queue` API.
|
||||
- Deprecated `boost::asio::io_service` replaced by `boost::asio::io_context` if
|
||||
Boost > 1.65
|
||||
- CMake turns all policies to ON according to the running version up to version
|
||||
3.15.
|
||||
- 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.
|
||||
- Applied clang-tidy checks and fixes related to readability:
|
||||
readability-container-size-empty, readability-identifier-naming,
|
||||
readability-inconsistent-declaration-parameter-name,
|
||||
readability-named-parameter, readability-non-const-parameter,
|
||||
readability-string-compare.
|
||||
- Improved includes selection following suggestions by include-what-you-use (see
|
||||
https://include-what-you-use.org/), allowing faster compiles, fewer recompiles
|
||||
and making refactoring easier.
|
||||
`readability-container-size-empty`, `readability-identifier-naming`,
|
||||
`readability-inconsistent-declaration-parameter-name`,
|
||||
`readability-named-parameter`, `readability-non-const-parameter`,
|
||||
`readability-string-compare`.
|
||||
- Improved includes selection following suggestions by `include-what-you-use`
|
||||
(see https://include-what-you-use.org/), allowing faster compiles, fewer
|
||||
recompiles and making refactoring easier.
|
||||
- Massive reduction of warnings triggered by clang-tidy checks.
|
||||
- Throughout code cleaning and formatting performed with automated tools in
|
||||
order to reduce future commit noise.
|
||||
@ -609,12 +633,12 @@ features and bug fixes:
|
||||
- Improvements for macOS users using Homebrew.
|
||||
- The software builds against GNU Radio >= 3.7.3, including 3.8.0. Automatically
|
||||
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.
|
||||
- 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.
|
||||
- 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
|
||||
versions.
|
||||
- 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
|
||||
management, replacement of raw pointers by containers or smart pointers.
|
||||
- Applied clang-tidy checks and fixes related to High Integrity C++:
|
||||
performance-move-const-arg, modernize-use-auto, modernize-use-equals-default,
|
||||
modernize-use-equals-delete, modernize-use-noexcept, modernize-use-nullptr,
|
||||
cert-dcl21-cpp, misc-new-delete-overloads, cert-dcl58-cpp, cert-err52-cpp,
|
||||
cert-err60-cpp, hicpp-exception-baseclass, hicpp-explicit-conversions.
|
||||
`performance-move-const-arg`, `modernize-use-auto`,
|
||||
`modernize-use-equals-default`, `modernize-use-equals-delete`,
|
||||
`modernize-use-noexcept`, `modernize-use-nullptr`, `cert-dcl21-cpp`,
|
||||
`misc-new-delete-overloads`, `cert-dcl58-cpp`, `cert-err52-cpp`,
|
||||
`cert-err60-cpp`, `hicpp-exception-baseclass`, `hicpp-explicit-conversions`.
|
||||
- Fixed a number of defects detected by Coverity Scan (version June 2019).
|
||||
|
||||
### Improvements in Usability:
|
||||
@ -638,12 +663,12 @@ features and bug fixes:
|
||||
channels per signal in multiple bands.
|
||||
- Fixed program termination (avoiding hangs and segfaults in some
|
||||
platforms/configurations).
|
||||
- The Labsat_Signal_Source now terminates the receiver's execution when the end
|
||||
of file(s) is reached. It now accepts LabSat 2 filenames and series of LabSat
|
||||
3 files.
|
||||
- The `Labsat_Signal_Source` now terminates the receiver's execution when the
|
||||
end of file(s) is reached. It now accepts LabSat 2 filenames and series of
|
||||
LabSat 3 files.
|
||||
- Added configuration parameters to set the annotation rate in KML, GPX, GeoJSON
|
||||
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
|
||||
receiver. This feature is not available in old compilers.
|
||||
- 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.
|
||||
- Improved information provided to the user in case of building configuration
|
||||
and runtime failures.
|
||||
- Remove abandoned building option `-DENABLE_GN3S` and `Gn3s_Signal_Source`
|
||||
implementation.
|
||||
|
||||
See the definitions of concepts and metrics at
|
||||
https://gnss-sdr.org/design-forces/
|
||||
|
||||
|
||||
|
||||
## [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
|
||||
features and bug fixes:
|
||||
@ -693,11 +720,11 @@ features and bug fixes:
|
||||
band are immediately searched in others.
|
||||
- Complex local codes have been replaced by real codes, alleviating the
|
||||
computational burden.
|
||||
- New volk_gnsssdr kernels: volk_gnsssdr_16i_xn_resampler_16i_xn.h,
|
||||
volk_gnsssdr_16ic_16i_rotator_dot_prod_16ic_xn.h,
|
||||
volk_gnsssdr_32f_xn_resampler_32f_xn.h,
|
||||
volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h
|
||||
- Some AVX2 implementations added to the volk_gnsssdr library.
|
||||
- New `volk_gnsssdr` kernels: `volk_gnsssdr_16i_xn_resampler_16i_xn.h`,
|
||||
`volk_gnsssdr_16ic_16i_rotator_dot_prod_16ic_xn.h`,
|
||||
`volk_gnsssdr_32f_xn_resampler_32f_xn.h`, and
|
||||
`volk_gnsssdr_32fc_32f_rotator_dot_prod_32fc_xn.h`.
|
||||
- Some AVX2 implementations added to the `volk_gnsssdr` library.
|
||||
- Improvement in C++ usage: Use of const container calls when result is
|
||||
immediately converted to a const iterator. Using these members removes an
|
||||
implicit conversion from iterator to const_iterator.
|
||||
@ -722,13 +749,13 @@ features and bug fixes:
|
||||
- Added the GLONASS L2 SP receiver chain.
|
||||
- Improvements in the Galileo E5a and GPS L2C receiver chains.
|
||||
- Updated list of available GNSS satellites.
|
||||
- Added five more signal sources: "Fmcomms2_Signal_Source" (requires gr-iio),
|
||||
"Plutosdr_Signal Source" (requires gr-iio), "Spir_GSS6450_File_Signal_Source",
|
||||
"Labsat_Signal_Source" and "Custom_UDP_Signal_Source" (requires libpcap).
|
||||
- Added five more signal sources: `Fmcomms2_Signal_Source` (requires gr-iio),
|
||||
`Plutosdr_Signal Source` (requires gr-iio), `Spir_GSS6450_File_Signal_Source`,
|
||||
`Labsat_Signal_Source` and `Custom_UDP_Signal_Source` (requires libpcap).
|
||||
Documented in https://gnss-sdr.org/docs/sp-blocks/signal-source/
|
||||
- Improved support for BladeRF, HackRF and RTL-SDR front-ends.
|
||||
- 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.
|
||||
- Added the GPX output format.
|
||||
- Improvements in the generation of KML files.
|
||||
@ -741,7 +768,7 @@ features and bug fixes:
|
||||
https://www.gsc-europa.eu/system-status/almanac-data
|
||||
- Own-defined XML schemas for navigation data published at
|
||||
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
|
||||
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.
|
||||
- Improvement in C++ usage: Enhanced const correctness. Misuses of those
|
||||
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
|
||||
in machine-readable form if clang-tidy is detected.
|
||||
- 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
|
||||
compilers on GNU/Linux, and with Clang/AppleClang on macOS.
|
||||
- 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 is now ready for AArch64 NEON instructions.
|
||||
- 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.
|
||||
- Improved detection of required and optional dependencies in many GNU/Linux
|
||||
distributions and processor architectures.
|
||||
- Improvement in C++ usage: The <ctime> library has been replaced by the more
|
||||
modern and portable <chrono> (except for the interaction with RTKLIB).
|
||||
- Improvement in C++ usage: The <stdio.h> library has been replaced by the more
|
||||
modern and portable <fstream> for file handling.
|
||||
- Improvement in C++ usage: The `<ctime>` library has been replaced by the more
|
||||
modern and portable `<chrono>` (except for the interaction with RTKLIB).
|
||||
- Improvement in C++ usage: The `<stdio.h>` library has been replaced by the
|
||||
more modern and portable `<fstream>` for file handling.
|
||||
- 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
|
||||
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=911882)
|
||||
- Fixes required by Debian packaging.
|
||||
@ -822,9 +849,9 @@ features and bug fixes:
|
||||
- Fixed a number of defects detected by Coverity Scan.
|
||||
- Improvement of QA code and addition of a number of new tests. Documented at
|
||||
https://gnss-sdr.org/docs/tutorials/testing-software-receiver-2/
|
||||
- Improvement in C++ usage: rand() function replaced by <random> library.
|
||||
- Improvement in C++ usage: strlen and strncpy have been replaced by safer C++
|
||||
counterparts.
|
||||
- Improvement in C++ usage: `rand()` function replaced by `<random>` library.
|
||||
- Improvement in C++ usage: `strlen` and `strncpy` have been replaced by safer
|
||||
C++ counterparts.
|
||||
- Improvement in C++ usage: Some destructors have been fixed, avoiding
|
||||
segmentation faults when exiting the program.
|
||||
- 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
|
||||
reproduction of experiments. The concept was introduced in
|
||||
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.
|
||||
|
||||
### Improvements in Scalability:
|
||||
@ -849,17 +876,17 @@ features and bug fixes:
|
||||
|
||||
- Several Unit Tests added. Documentation of testing concepts and available
|
||||
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.
|
||||
- New extra unit test TrackingPullInTest checks acquisition to tracking
|
||||
- New extra unit test `TrackingPullInTest` checks acquisition to tracking
|
||||
transition.
|
||||
- New extra unit test HybridObservablesTest checks the generation of
|
||||
- New extra unit test `HybridObservablesTest` checks the generation of
|
||||
observables.
|
||||
- Improved system testing: position_test accepts a wide list of parameters and
|
||||
can be used with external files.
|
||||
- Receiver channels can now be fixed to a given satellite.
|
||||
- Testing integrated in a Continuous Reproducibility system (see above).
|
||||
- Improved CTest support in volk_gnsssdr.
|
||||
- Improved CTest support in `volk_gnsssdr`.
|
||||
|
||||
### Improvements in Usability:
|
||||
|
||||
@ -867,8 +894,8 @@ features and bug fixes:
|
||||
implementation for all kinds of GNSS signals, making it easier to configure.
|
||||
- All PVT block implementations have been merged into a single implementation
|
||||
for all kinds of GNSS signals, making it easier to configure.
|
||||
- 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
|
||||
- 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
|
||||
warning is provided to the user. The old name will be removed in future
|
||||
releases.
|
||||
- Updated and improved online documentation of processing blocks at
|
||||
@ -882,14 +909,14 @@ features and bug fixes:
|
||||
template in the source tree.
|
||||
- Added colors to the commandline user interface.
|
||||
- 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
|
||||
https://gnss-sdr.org/design-forces/
|
||||
|
||||
|
||||
|
||||
## [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
|
||||
|
||||
@ -914,8 +941,8 @@ many dimensions:
|
||||
### Improvements in Efficiency:
|
||||
|
||||
- VOLK_GNSSSDR: Added NEON,AVX and unaligned protokernels for
|
||||
volk_gnsssdr_32f_index_max_32 kernel.
|
||||
- VOLK_GNSSSDR: Added volk_gnsssdr-config-info to the list of generated
|
||||
`volk_gnsssdr_32f_index_max_32` kernel.
|
||||
- VOLK_GNSSSDR: Added `volk_gnsssdr-config-info` to the list of generated
|
||||
executables.
|
||||
|
||||
### Improvements in Flexibility:
|
||||
@ -970,24 +997,24 @@ many dimensions:
|
||||
### Improvements in Testability:
|
||||
|
||||
- Major QA source code refactoring: they has been split into
|
||||
src/tests/unit-tests and src/tests/system-tests folders. They are optionally
|
||||
built with the ENABLE_UNIT_TESTING=ON (unit testing QA code),
|
||||
ENABLE_UNIT_TESTING_EXTRA=ON (unit tests that require extra files downloaded
|
||||
at configure time), ENABLE_SYSTEM_TESTING=ON (system tests, such as
|
||||
measurement of Time-To-First-Fix) and ENABLE_SYSTEM_TESTING_EXTRA=ON (extra
|
||||
`src/tests/unit-tests` and `src/tests/system-tests` folders. They are
|
||||
optionally built with the `ENABLE_UNIT_TESTING=ON` (unit testing QA code),
|
||||
`ENABLE_UNIT_TESTING_EXTRA=ON` (unit tests that require extra files downloaded
|
||||
at configure time), `ENABLE_SYSTEM_TESTING=ON` (system tests, such as
|
||||
measurement of Time-To-First-Fix) and `ENABLE_SYSTEM_TESTING_EXTRA=ON` (extra
|
||||
system test requiring external tools, automatically downloaded and built at
|
||||
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
|
||||
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
|
||||
ENABLE_UNIT_TESTING is set to ON by default.
|
||||
- Unit tests added: CPU_multicorrelator_test and GPU_multicorrelator_test
|
||||
forced by `ENABLE_OWN_GPSTK=ON` building configuration flag. Only
|
||||
`ENABLE_UNIT_TESTING` is set to ON by default.
|
||||
- Unit tests added: `CPU_multicorrelator_test` and `GPU_multicorrelator_test`
|
||||
measure computer performance in multicorrelator setups.
|
||||
- Unit tests added: GpsL1CADllPllTracking and GpsL1CATelemetryDecoderTest.
|
||||
- System test added: ttff_gps_l1 performs a set of cold / assisted runs of the
|
||||
- Unit tests added: `GpsL1CADllPllTracking` and `GpsL1CATelemetryDecoderTest`.
|
||||
- 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
|
||||
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
|
||||
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
|
||||
@ -1010,7 +1037,7 @@ https://gnss-sdr.org/design-forces/
|
||||
|
||||
|
||||
|
||||
## [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
|
||||
|
||||
@ -1025,7 +1052,7 @@ respect to v0.0.7. The main changes are:
|
||||
- Improved CUDA-based correlation.
|
||||
- Updated documentation
|
||||
- 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
|
||||
- VOLK_GNSSSDR: Fixed a bug in AVX2 puppet
|
||||
- VOLK_GNSSSDR: can now be built using the C98 standard
|
||||
@ -1036,7 +1063,7 @@ respect to v0.0.7. The main changes are:
|
||||
|
||||
|
||||
|
||||
## [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
|
||||
|
||||
@ -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
|
||||
the key kernels for GNSS signal processing in 16ic and 32fc versions,
|
||||
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.
|
||||
- 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
|
||||
byte for each sample.
|
||||
- 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
|
||||
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
|
||||
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
|
||||
`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
|
||||
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
|
||||
complex samples. The gr_complex version has also the capability to extend the
|
||||
coherent correlation period from 1ms to 20ms using telemetry symbol
|
||||
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 coherent correlation period from 1 ms to 20 ms using telemetry symbol
|
||||
synchronization.
|
||||
- Increased resolution in CN0 estimator internal variables.
|
||||
- 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
|
||||
a few hours of usage. Now the receiver can work continually (tested for more
|
||||
than one week, no known limit).
|
||||
- New tracking block introduced: GPS_L1_CA_DLL_PLL_Tracking_GPU is a GPS L1 C/A
|
||||
carrier PLL and code DLL that uses the CUDA-compatible GPU to compute carrier
|
||||
wipe off and correlation operations, alleviating the CPU load.
|
||||
- Obsolete/buggy blocks removed: GPS_L1_CA_DLL_FLL_PLL_Tracking,
|
||||
GPS_L1_CA_DLL_PLL_Optim_Tracking.
|
||||
- New tracking block introduced: `GPS_L1_CA_DLL_PLL_Tracking_GPU` is a GPS L1
|
||||
C/A carrier PLL and code DLL that uses the CUDA-compatible GPU to compute
|
||||
carrier wipe off and correlation operations, alleviating the CPU load.
|
||||
- Obsolete/buggy blocks removed: `GPS_L1_CA_DLL_FLL_PLL_Tracking`,
|
||||
`GPS_L1_CA_DLL_PLL_Optim_Tracking`.
|
||||
- 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
|
||||
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
|
||||
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
|
||||
rates and CNR - high resolution) messages, while GALILEO_E1_PVT serves MT1045
|
||||
(Galileo ephemeris) and MSM7 (MT1097, full Galileo pseudoranges, phase ranges,
|
||||
phase range rates and CNR - high resolution).
|
||||
rates and CNR - high resolution) messages, while `GALILEO_E1_PVT` serves
|
||||
MT1045 (Galileo ephemeris) and MSM7 (MT1097, full Galileo pseudoranges, phase
|
||||
ranges, phase range rates and CNR - high resolution).
|
||||
- Added a GeoJSON printer. Basic (least-squares) position fixes can be now also
|
||||
stored in this format, in addition to KML.
|
||||
- Obsolete block removed: output filter.
|
||||
- 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.
|
||||
- Improvements in documentation: Satellite identification updated to current
|
||||
constellation status.
|
||||
@ -1128,7 +1155,7 @@ This release has several improvements, addition of new features and bug fixes:
|
||||
|
||||
|
||||
|
||||
## [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:
|
||||
|
||||
@ -1151,12 +1178,13 @@ This release has several improvements and bug fixes:
|
||||
on the Realtek's RTL2832U chipset.
|
||||
- Fixed bug in UTC time computation for GPS signals.
|
||||
- Updated satellite identification for GPS and Galileo.
|
||||
- Defined ‘cbyte’ as a new input data type (std::complex<unsigned char>)
|
||||
- Adding a new data_type_adapter, from interleaved short to std::complex<short>
|
||||
- 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 filter for complex short streams.
|
||||
- Adding a fir_filter for std::complex<signed char> (aka cbyte). It converts the
|
||||
data type to floats, filters, and converts back to cbyte.
|
||||
- Added a resampler for cbytes and cshorts.
|
||||
- Adding a fir_filter for `std::complex<signed char>` (aka `cbyte`). It converts
|
||||
the data type to floats, filters, and converts back to cbyte.
|
||||
- Added a resampler for `cbyte`s and `cshort`s.
|
||||
- First working version of a GPS tracking block implementation using CUDA with
|
||||
multi-GPU device support.
|
||||
- Updating RINEX obs header when leap second is available.
|
||||
@ -1177,34 +1205,34 @@ This release has several improvements and bug fixes:
|
||||
|
||||
|
||||
|
||||
## [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:
|
||||
|
||||
- Now GNSS-SDR can be installed on the system with the usual ‘cmake ../ && make
|
||||
&& sudo make install’.
|
||||
- Added volk_gnsssdr library, a volk-like library implementing some specific
|
||||
- Now GNSS-SDR can be installed on the system with the usual
|
||||
`cmake ../ && make && sudo make install`.
|
||||
- Added `volk_gnsssdr` library, a volk-like library implementing some specific
|
||||
kernels and ensuring portable executables. It comes with a
|
||||
‘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_profile` executable, in the fashion of `volk_profile`. Volk and
|
||||
`volk_gnsssdr` are compatible and can be mixed together. This is expected to
|
||||
enable faster execution of the software receiver in upcoming versions.
|
||||
- The former ‘rtlsdr_signal_source’ has been replaced by a more general
|
||||
‘osmosdr_signal_source’ compatible with all those front-ends accessible by the
|
||||
- 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 driver (bladeRF, hackRF, etc.) in addition to RTL-based dongles.
|
||||
- Added manpages when binaries gnss-sdr, volk_gnsssdr_profile and front-end-cal
|
||||
are installed.
|
||||
- Added manpages when binaries `gnss-sdr`, `volk_gnsssdr_profile` and
|
||||
`front-end-cal` are installed.
|
||||
- Now GNSS-SDR can be built on i386, amd64, armhf, armel and arm64
|
||||
architectures.
|
||||
- Now GNSS-SDR builds on Ubuntu 14.04 and 14.10, Debian jessie/sid and Mac OS X
|
||||
10.9 and 10.10.
|
||||
- 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.
|
||||
- Minor bug fixes, updated documentation and code cleaning.
|
||||
|
||||
|
||||
|
||||
## [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:
|
||||
|
||||
@ -1218,14 +1246,14 @@ This release has several improvements and bug fixes:
|
||||
same receiver.
|
||||
- Added tropospheric corrections to GPS and Galileo PVT solution.
|
||||
- Improved precision obtained by changing some variables from float to double.
|
||||
- New building options: ENABLE_GN3S, ENABLE_RTLSDR and ENABLE_ARRAY and
|
||||
ENABLE_OPENCL.
|
||||
- New building options: `ENABLE_GN3S`, `ENABLE_RTLSDR`, `ENABLE_ARRAY`, and
|
||||
`ENABLE_OPENCL`.
|
||||
- Improved documentation on how to enable optional drivers.
|
||||
- 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
|
||||
SIMD instruction set present in the compiling machine, so it can be executed
|
||||
in other machines without those specific sets.
|
||||
- Added ENABLE_GPERFTOOLS, which links the executable to tcmalloc and profiler
|
||||
- Added `ENABLE_GENERIC_ARCH`, an option to build the binary without detecting
|
||||
the SIMD instruction set present in the compiling machine, so it can be
|
||||
executed in other machines without those specific sets.
|
||||
- Added `ENABLE_GPERFTOOLS`, which links the executable to tcmalloc and profiler
|
||||
if Gperftools is available on the system.
|
||||
- Added carrier phase, Doppler shift and signal strength observables to the
|
||||
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:
|
||||
|
||||
|
||||
|
||||
## [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
|
||||
from Subversion to Git. The main changes are:
|
@ -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 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.
|
||||
\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 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.
|
||||
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
|
||||
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.
|
||||
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.
|
||||
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
|
||||
<a href="https://lists.sourceforge.net/lists/listinfo/gnss-sdr-developers" target="_blank"><b>GNSS-SDR Developers mailing list</b></a>.
|
||||
|
@ -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);
|
||||
|
||||
// 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
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -176,6 +176,7 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
|
||||
d_nchannels = nchannels;
|
||||
|
||||
d_type_of_rx = conf_.type_of_receiver;
|
||||
d_observable_interval_ms = conf_.observable_interval_ms;
|
||||
|
||||
// GPS Ephemeris data message port in
|
||||
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));
|
||||
#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
|
||||
const std::string kml_dump_filename = d_dump_filename;
|
||||
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_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_galileo_has_data_sptr_type_hash_code = typeid(std::shared_ptr<Galileo_HAS_data>).hash_code();
|
||||
|
||||
//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
|
||||
{
|
||||
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())
|
||||
{
|
||||
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;
|
||||
current_RX_time_ms = t0_int_ms + adjust_next_20ms;
|
||||
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_obs_interval_ms;
|
||||
|
||||
if (current_RX_time_ms % d_output_rate_ms == 0)
|
||||
{
|
||||
|
@ -137,6 +137,8 @@ private:
|
||||
|
||||
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 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_utc_model_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_rx_time;
|
||||
@ -260,6 +263,7 @@ private:
|
||||
|
||||
uint32_t d_nchannels;
|
||||
uint32_t d_type_of_rx;
|
||||
uint32_t d_observable_interval_ms;
|
||||
|
||||
bool d_dump;
|
||||
bool d_dump_mat;
|
||||
|
@ -19,6 +19,7 @@
|
||||
Pvt_Conf::Pvt_Conf()
|
||||
{
|
||||
type_of_receiver = 0U;
|
||||
observable_interval_ms = 20U;
|
||||
output_rate_ms = 0;
|
||||
display_rate_ms = 0;
|
||||
kml_rate_ms = 1000;
|
||||
|
@ -51,6 +51,8 @@ public:
|
||||
std::string udp_eph_addresses;
|
||||
|
||||
uint32_t type_of_receiver;
|
||||
uint32_t observable_interval_ms;
|
||||
|
||||
int32_t output_rate_ms;
|
||||
int32_t display_rate_ms;
|
||||
int32_t kml_rate_ms;
|
||||
|
@ -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');
|
||||
const uint32_t prn_ = prn - 1;
|
||||
if ((prn < 1) || (prn > 50))
|
||||
{
|
||||
return dest;
|
||||
}
|
||||
uint32_t index = 0;
|
||||
for (size_t i = 0; i < GALILEO_E6_C_SECONDARY_CODE_STR_LENGTH; i++)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
########################################################################
|
||||
# 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)
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
endif()
|
||||
@ -204,7 +204,7 @@ message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
|
||||
set(VERSION_INFO_MAJOR_VERSION 0)
|
||||
set(VERSION_INFO_MINOR_VERSION 0)
|
||||
set(VERSION_INFO_MAINT_VERSION 14.git)
|
||||
include(VolkVersion) # setup version info
|
||||
include(VolkGnsssdrVersion) # setup version info
|
||||
|
||||
|
||||
|
||||
|
@ -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()
|
@ -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()
|
@ -23,6 +23,16 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
FORCE)
|
||||
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
|
||||
# prominent in the GUI.
|
||||
option(BUILD_TESTING "Enable test (depends on googletest)." OFF)
|
||||
|
@ -44,7 +44,7 @@ instructions) at runtime.
|
||||
|
||||
## 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.
|
||||
|
||||
### Checking features at runtime
|
||||
@ -55,7 +55,7 @@ AES and the SSE4.2 instruction sets:
|
||||
```c
|
||||
#include "cpuinfo_x86.h"
|
||||
|
||||
// For C++, add `using namespace CpuFeatures;`
|
||||
// For C++, add `using namespace cpu_features;`
|
||||
static const X86Features features = GetX86Info().features;
|
||||
|
||||
void Compute(void) {
|
||||
@ -77,7 +77,7 @@ features and then check whether AES and NEON are supported.
|
||||
#include <stdbool.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 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 "cpuinfo_x86.h"
|
||||
|
||||
// For C++, add `using namespace CpuFeatures;`
|
||||
// For C++, add `using namespace cpu_features;`
|
||||
static const X86Features features = GetX86Info().features;
|
||||
static const bool has_avx = CPU_FEATURES_COMPILED_X86_AVX || features.avx;
|
||||
|
||||
@ -120,7 +120,7 @@ set—but only if it's not Sandy Bridge.
|
||||
#include <stdbool.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 X86Microarchitecture uarch = GetX86Microarchitecture(&info);
|
||||
static const bool has_fast_avx = info.features.avx && uarch != INTEL_SNB;
|
||||
|
@ -79,6 +79,7 @@ typedef struct
|
||||
|
||||
int dca : 1;
|
||||
int ss : 1;
|
||||
int adx : 1;
|
||||
// Make sure to update X86FeaturesEnum below if you add a field here.
|
||||
} X86Features;
|
||||
|
||||
@ -207,6 +208,7 @@ typedef enum
|
||||
X86_RDRND,
|
||||
X86_DCA,
|
||||
X86_SS,
|
||||
X86_ADX,
|
||||
X86_LAST_,
|
||||
} X86FeaturesEnum;
|
||||
|
||||
|
@ -74,7 +74,8 @@
|
||||
FEATURE(X86_MOVBE, movbe, "movbe", 0, 0) \
|
||||
FEATURE(X86_RDRND, rdrnd, "rdrnd", 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_DONT_GENERATE_HWCAPS
|
||||
#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
|
||||
// switches.
|
||||
#if !defined(CPU_FEATURES_OS_DARWIN)
|
||||
static bool HasZmmOsXSave(uint32_t xcr0_eax)
|
||||
{
|
||||
return HasMask(xcr0_eax, MASK_XMM | MASK_YMM | MASK_MASKREG | MASK_ZMM0_15 |
|
||||
MASK_ZMM16_31);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Checks that operating system saves and restores AMX/TMUL state during context
|
||||
// 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.
|
||||
// Avoid to recompute them since each call to cpuid is ~100 cycles.
|
||||
typedef struct
|
||||
@ -1212,7 +1229,11 @@ static OsSupport CheckOsSupport(const uint32_t max_cpuid_leaf)
|
||||
const uint32_t xcr0_eax = GetXCR0Eax();
|
||||
os_support.have_sse_via_cpuid = HasXmmOsXSave(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);
|
||||
#endif // CPU_FEATURES_OS_DARWIN
|
||||
os_support.have_amx = HasTmmOsXSave(xcr0_eax);
|
||||
}
|
||||
else
|
||||
@ -1235,20 +1256,6 @@ static bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)
|
||||
#endif
|
||||
#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)
|
||||
{
|
||||
#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->vaes = IsBitSet(leaf_7.ecx, 9);
|
||||
features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10);
|
||||
features->adx = IsBitSet(leaf_7.ebx, 19);
|
||||
|
||||
if (os_support.have_sse_via_os)
|
||||
{
|
||||
|
@ -150,6 +150,7 @@ TEST_F(CpuidX86Test, SandyBridge)
|
||||
EXPECT_TRUE(features.popcnt);
|
||||
EXPECT_FALSE(features.movbe);
|
||||
EXPECT_FALSE(features.rdrnd);
|
||||
EXPECT_FALSE(features.adx);
|
||||
}
|
||||
|
||||
const int KiB = 1024;
|
||||
|
@ -599,7 +599,8 @@ endif()
|
||||
if(NOT MSVC)
|
||||
target_link_libraries(volk_gnsssdr PUBLIC m)
|
||||
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")
|
||||
|
||||
# Install locations
|
||||
|
@ -10,6 +10,6 @@ LV_CXXFLAGS=@LV_CXXFLAGS@
|
||||
Name: volk_gnsssdr
|
||||
Description: VOLK_GNSSSDR: Vector Optimized Library of Kernels specific for GNSS-SDR
|
||||
Requires:
|
||||
Version: @LIBVER@
|
||||
Version: @SOVERSION@
|
||||
Libs: -L${libdir} -lvolk_gnsssdr
|
||||
Cflags: -I${includedir} ${LV_CXXFLAGS}
|
||||
|
@ -31,13 +31,14 @@ HybridObservables::HybridObservables(const ConfigurationInterface* configuration
|
||||
dump_mat_ = configuration->property(role + ".dump_mat", true);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename);
|
||||
|
||||
Obs_Conf conf;
|
||||
Obs_Conf conf{};
|
||||
|
||||
conf.dump = dump_;
|
||||
conf.dump_mat = dump_mat_;
|
||||
conf.dump_filename = dump_filename_;
|
||||
conf.nchannels_in = in_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);
|
||||
|
||||
if (FLAGS_carrier_smoothing_factor == DEFAULT_CARRIER_SMOOTHING_FACTOR)
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <glog/logging.h>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <matio.h>
|
||||
#include <algorithm> // for std::min
|
||||
#include <array>
|
||||
#include <cmath> // for round
|
||||
#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_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_status_report_timer_ms = 0;
|
||||
// rework
|
||||
d_Rx_clock_buffer.set_capacity(5); // 10*20 ms = 200 ms of data in buffer
|
||||
d_Rx_clock_buffer.clear(); // Clear all the elements in the buffer
|
||||
|
||||
d_Rx_clock_buffer.set_capacity(std::min(std::max(200U / d_T_rx_step_ms, 3U), 10U));
|
||||
d_Rx_clock_buffer.clear();
|
||||
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_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;
|
||||
|
||||
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 20 ms
|
||||
if (d_T_rx_TOW_ms % 20)
|
||||
// align the receiver clock to integer multiple of d_T_rx_step_ms
|
||||
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;
|
||||
}
|
||||
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
|
||||
@ -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 ((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;
|
||||
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;
|
||||
// align the receiver clock to integer multiple of 20 ms
|
||||
if (d_T_rx_TOW_ms % 20)
|
||||
// align the receiver clock to integer multiple of d_T_rx_step_ms
|
||||
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
|
||||
|
@ -22,8 +22,9 @@ Obs_Conf::Obs_Conf()
|
||||
{
|
||||
dump_filename = std::string("obs_dump.dat");
|
||||
smoothing_factor = FLAGS_carrier_smoothing_factor;
|
||||
nchannels_in = 0;
|
||||
nchannels_out = 0;
|
||||
nchannels_in = 0U;
|
||||
nchannels_out = 0U;
|
||||
observable_interval_ms = 20U;
|
||||
enable_carrier_smoothing = false;
|
||||
dump = false;
|
||||
dump_mat = false;
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
int32_t smoothing_factor;
|
||||
uint32_t nchannels_in;
|
||||
uint32_t nchannels_out;
|
||||
uint32_t observable_interval_ms;
|
||||
bool enable_carrier_smoothing;
|
||||
bool dump;
|
||||
bool dump_mat;
|
||||
|
@ -42,19 +42,6 @@ if(ENABLE_AD9361)
|
||||
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)
|
||||
set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} flexiband_signal_source.cc)
|
||||
set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} flexiband_signal_source.h)
|
||||
@ -241,13 +228,6 @@ if(ENABLE_FLEXIBAND AND TELEORBIT_FOUND)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_GN3S AND GRGN3S_FOUND)
|
||||
target_link_libraries(signal_source_adapters
|
||||
PRIVATE
|
||||
Gnuradio::gn3s
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ARRAY AND GRDBFCTTC_FOUND)
|
||||
target_link_libraries(signal_source_adapters
|
||||
PRIVATE
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
@ -170,7 +171,7 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configu
|
||||
|
||||
std::cout << "device address: " << uri_ << '\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")
|
||||
{
|
||||
@ -183,15 +184,24 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configu
|
||||
else
|
||||
{
|
||||
#if GNURADIO_API_IIO
|
||||
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make(
|
||||
uri_.c_str(), freq_, sample_rate_,
|
||||
bandwidth_,
|
||||
rx1_en_, rx2_en_,
|
||||
buffer_size_, quadrature_, rf_dc_,
|
||||
bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_,
|
||||
gain_mode_rx2_.c_str(), rf_gain_rx2_,
|
||||
rf_port_select_.c_str(), filter_source_.c_str(),
|
||||
filter_filename_.c_str(), Fpass_, Fstop_);
|
||||
std::vector<bool> enable_channels{rx1_en_, rx2_en_};
|
||||
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source::make(uri_, enable_channels, buffer_size_);
|
||||
fmcomms2_source_f32c_->set_frequency(freq_);
|
||||
fmcomms2_source_f32c_->set_samplerate(sample_rate_);
|
||||
if (rx1_en_)
|
||||
{
|
||||
fmcomms2_source_f32c_->set_gain_mode(0, gain_mode_rx1_);
|
||||
fmcomms2_source_f32c_->set_gain(0, rf_gain_rx1_);
|
||||
}
|
||||
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
|
||||
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make(
|
||||
uri_.c_str(), freq_, sample_rate_,
|
||||
@ -250,15 +260,18 @@ Fmcomms2SignalSource::Fmcomms2SignalSource(const ConfigurationInterface *configu
|
||||
else
|
||||
{
|
||||
#if GNURADIO_API_IIO
|
||||
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make(
|
||||
uri_.c_str(), freq_, sample_rate_,
|
||||
bandwidth_,
|
||||
rx1_en_, rx2_en_,
|
||||
buffer_size_, quadrature_, rf_dc_,
|
||||
bb_dc_, gain_mode_rx1_.c_str(), rf_gain_rx1_,
|
||||
gain_mode_rx2_.c_str(), rf_gain_rx2_,
|
||||
rf_port_select_.c_str(), filter_source_.c_str(),
|
||||
filter_filename_.c_str(), Fpass_, Fstop_);
|
||||
std::vector<bool> enable_channels{rx1_en_, rx2_en_};
|
||||
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source::make(uri_, enable_channels, buffer_size_);
|
||||
fmcomms2_source_f32c_->set_frequency(freq_);
|
||||
fmcomms2_source_f32c_->set_samplerate(sample_rate_);
|
||||
fmcomms2_source_f32c_->set_gain_mode(0, gain_mode_rx1_);
|
||||
fmcomms2_source_f32c_->set_gain(0, rf_gain_rx1_);
|
||||
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
|
||||
fmcomms2_source_f32c_ = gr::iio::fmcomms2_source_f32c::make(
|
||||
uri_.c_str(), freq_, sample_rate_,
|
||||
|
@ -61,7 +61,11 @@ public:
|
||||
gr::basic_block_sptr get_right_block() override;
|
||||
|
||||
private:
|
||||
#if GNURADIO_API_IIO
|
||||
gr::iio::fmcomms2_source::sptr fmcomms2_source_f32c_;
|
||||
#else
|
||||
gr::iio::fmcomms2_source_f32c::sptr fmcomms2_source_f32c_;
|
||||
#endif
|
||||
gnss_shared_ptr<gr::block> valve_;
|
||||
gr::blocks::file_sink::sptr file_sink_;
|
||||
|
||||
|
@ -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_;
|
||||
}
|
@ -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
|
@ -121,15 +121,20 @@ PlutosdrSignalSource::PlutosdrSignalSource(const ConfigurationInterface* configu
|
||||
|
||||
std::cout << "device address: " << uri_ << '\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 << "item type: " << item_type_ << '\n';
|
||||
|
||||
#if GNURADIO_API_IIO
|
||||
plutosdr_source_ = gr::iio::pluto_source::make(uri_, freq_, sample_rate_,
|
||||
bandwidth_, buffer_size_, quadrature_, rf_dc_, bb_dc_,
|
||||
gain_mode_.c_str(), rf_gain_, filter_source_.c_str(),
|
||||
filter_filename_.c_str(), Fpass_, Fstop_);
|
||||
plutosdr_source_ = gr::iio::pluto_source::make(uri_, buffer_size_);
|
||||
plutosdr_source_->set_frequency(freq_);
|
||||
plutosdr_source_->set_samplerate(sample_rate_);
|
||||
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
|
||||
plutosdr_source_ = gr::iio::pluto_source::make(uri_, freq_, sample_rate_,
|
||||
bandwidth_, buffer_size_, quadrature_, rf_dc_, bb_dc_,
|
||||
|
@ -37,7 +37,7 @@
|
||||
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
|
||||
{
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "display.h"
|
||||
#include "galileo_almanac_helper.h" // for Galileo_Almanac_Helper
|
||||
#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_utc_model.h" // for Galileo_Utc_Model
|
||||
#include "gnss_synchro.h"
|
||||
@ -65,6 +65,9 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
|
||||
this->message_port_register_out(pmt::mp("telemetry"));
|
||||
// Control messages to tracking block
|
||||
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_sent_tlm_failed_msg = false;
|
||||
d_band = '1';
|
||||
@ -202,6 +205,8 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
|
||||
d_channel = 0;
|
||||
d_flag_PLL_180_deg_phase_locked = false;
|
||||
d_symbol_history.set_capacity(d_required_symbols + 1);
|
||||
d_cnav_dummy_page = false;
|
||||
d_print_cnav_page = true;
|
||||
|
||||
// vars for Viterbi decoder
|
||||
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);
|
||||
|
||||
// 4. If we have a new full message, read it
|
||||
if (d_cnav_nav.have_new_HAS_message() == true)
|
||||
// 4. If we have a new HAS page, read it
|
||||
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
|
||||
{
|
||||
const std::shared_ptr<Galileo_HAS_data> tmp_obj = std::make_shared<Galileo_HAS_data>(d_cnav_nav.get_HAS_data());
|
||||
this->message_port_pub(pmt::mp("telemetry"), 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';
|
||||
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("E6_HAS_from_TLM"), pmt::make_any(tmp_obj));
|
||||
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;
|
||||
}
|
||||
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_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
|
||||
{
|
||||
// TODO
|
||||
d_TOW_at_current_symbol_ms += d_PRN_code_period_ms; // this is not the TOW!
|
||||
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;
|
||||
// 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)
|
||||
{
|
||||
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)
|
||||
|
@ -140,6 +140,8 @@ private:
|
||||
bool d_dump_mat;
|
||||
bool d_remove_dat;
|
||||
bool d_first_eph_sent;
|
||||
bool d_cnav_dummy_page;
|
||||
bool d_print_cnav_page;
|
||||
};
|
||||
|
||||
|
||||
|
@ -734,7 +734,7 @@ void dll_pll_veml_tracking::start_tracking()
|
||||
{
|
||||
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_c_code_gen_float_primary(d_tracking_code, d_acquisition_gnss_synchro->PRN);
|
||||
d_Prompt_Data[0] = gr_complex(0.0, 0.0);
|
||||
|
@ -15,6 +15,7 @@ set(CORE_LIBS_SOURCES
|
||||
channel_status_msg_receiver.cc
|
||||
channel_event.cc
|
||||
command_event.cc
|
||||
galileo_e6_has_msg_receiver.cc
|
||||
)
|
||||
|
||||
set(CORE_LIBS_HEADERS
|
||||
|
723
src/core/libs/galileo_e6_has_msg_receiver.cc
Normal file
723
src/core/libs/galileo_e6_has_msg_receiver.cc
Normal 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;
|
||||
}
|
92
src/core/libs/galileo_e6_has_msg_receiver.h
Normal file
92
src/core/libs/galileo_e6_has_msg_receiver.h
Normal 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
|
@ -100,10 +100,6 @@ if(ENABLE_OSMOSDR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_GN3S)
|
||||
target_compile_definitions(core_receiver PRIVATE -DGN3S_DRIVER=1)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ARRAY)
|
||||
target_compile_definitions(core_receiver PRIVATE -DRAW_ARRAY_DRIVER=1)
|
||||
endif()
|
||||
@ -224,13 +220,6 @@ if(ENABLE_FLEXIBAND AND TELEORBIT_FOUND)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_GN3S AND GRGN3S_FOUND)
|
||||
target_link_libraries(core_receiver
|
||||
PRIVATE
|
||||
Gnuradio::gn3s
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ARRAY AND GRDBFCTTC_FOUND)
|
||||
target_link_libraries(core_receiver
|
||||
PRIVATE
|
||||
|
@ -139,10 +139,6 @@
|
||||
#include "gps_l1_ca_pcps_opencl_acquisition.h"
|
||||
#endif
|
||||
|
||||
#if GN3S_DRIVER
|
||||
#include "gn3s_signal_source.h"
|
||||
#endif
|
||||
|
||||
#if RAW_ARRAY_DRIVER
|
||||
#include "raw_array_signal_source.h"
|
||||
#endif
|
||||
@ -733,15 +729,6 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
}
|
||||
#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
|
||||
else if (implementation == "Raw_Array_Signal_Source")
|
||||
{
|
||||
|
@ -99,6 +99,8 @@ void GNSSFlowgraph::init()
|
||||
|
||||
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)
|
||||
int sources_count_deprecated = configuration_->property("Receiver.sources_count", 1);
|
||||
sources_count_ = configuration_->property("GNSS-SDR.num_sources", sources_count_deprecated);
|
||||
@ -443,6 +445,11 @@ int GNSSFlowgraph::connect_desktop_flowgraph()
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (connect_gal_e6_has() != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Activate acquisition in enabled channels
|
||||
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
|
||||
// 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);
|
||||
// Check configuration inconsistencies
|
||||
if (output_size != input_size)
|
||||
@ -1539,6 +1546,42 @@ int GNSSFlowgraph::connect_monitors()
|
||||
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()
|
||||
{
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "channel_status_msg_receiver.h"
|
||||
#include "concurrent_queue.h"
|
||||
#include "galileo_e6_has_msg_receiver.h"
|
||||
#include "gnss_sdr_sample_counter.h"
|
||||
#include "gnss_signal.h"
|
||||
#include "pvt_interface.h"
|
||||
@ -176,6 +177,7 @@ private:
|
||||
int connect_channels_to_observables();
|
||||
int connect_observables_to_pvt();
|
||||
int connect_monitors();
|
||||
int connect_gal_e6_has();
|
||||
int connect_gnss_synchro_monitor();
|
||||
int connect_acquisition_monitor();
|
||||
int connect_tracking_monitor();
|
||||
@ -244,6 +246,8 @@ private:
|
||||
gr::basic_block_sptr GnssSynchroAcquisitionMonitor_;
|
||||
gr::basic_block_sptr GnssSynchroTrackingMonitor_;
|
||||
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_;
|
||||
#if ENABLE_FPGA
|
||||
gnss_sdr_fpga_sample_counter_sptr ch_out_fpga_sample_counter_;
|
||||
|
@ -86,6 +86,7 @@ set(SYSTEM_PARAMETERS_HEADERS
|
||||
Beidou_DNAV.h
|
||||
MATH_CONSTANTS.h
|
||||
reed_solomon.h
|
||||
galileo_has_page.h
|
||||
)
|
||||
|
||||
list(SORT SYSTEM_PARAMETERS_HEADERS)
|
||||
|
@ -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_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_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_MESSAGE_BITS_PER_PAGE = 424;
|
||||
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";
|
||||
|
||||
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_ID({7, 5});
|
||||
const std::pair<int32_t, int32_t> GALILEO_HAS_MESSAGE_SIZE({12, 5});
|
||||
|
@ -19,30 +19,31 @@
|
||||
#include "galileo_cnav_message.h"
|
||||
#include <boost/crc.hpp> // for boost::crc_basic, boost::crc_optimal
|
||||
#include <boost/dynamic_bitset.hpp> // for boost::dynamic_bitset
|
||||
#include <algorithm> // for reverse, find
|
||||
#include <numeric> // for accumulate
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include <algorithm> // for reverse
|
||||
#include <vector>
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
// it needs to be filled with zeroes at the start of the frame.
|
||||
// This operation is done in the transformation from bits to bytes
|
||||
// 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));
|
||||
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)
|
||||
{
|
||||
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::bitset<GALILEO_CNAV_BITS_FOR_CRC> Word_for_CRC_bits(has_page_bits);
|
||||
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
|
||||
read_HAS_page_header(page_string.substr(GALILEO_CNAV_PAGE_RESERVED_BITS, GALILEO_CNAV_PAGE_HEADER_BITS));
|
||||
bool use_has = false;
|
||||
d_test_mode = false;
|
||||
// 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
|
||||
use_has = true;
|
||||
d_test_mode = true;
|
||||
break;
|
||||
case 1: // HAS is in Operational Mode
|
||||
use_has = true;
|
||||
break;
|
||||
case 2: // HAS is in "reserved" status
|
||||
case 3: // Do not use HAS
|
||||
default:
|
||||
break;
|
||||
switch (d_has_page_status)
|
||||
{
|
||||
case 0: // HAS is in Test Mode
|
||||
use_has = true;
|
||||
d_test_mode = true;
|
||||
break;
|
||||
case 1: // HAS is in Operational Mode
|
||||
use_has = true;
|
||||
break;
|
||||
case 2: // HAS is in "reserved" status
|
||||
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
|
||||
process_HAS_page(page_string.substr(GALILEO_CNAV_PAGE_RESERVED_BITS + GALILEO_CNAV_PAGE_HEADER_BITS, GALILEO_CNAV_MESSAGE_BITS_PER_PAGE));
|
||||
// Store the 424 bits of encoded data (CNAV page) and the page header
|
||||
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
|
||||
{
|
||||
d_page_dummy = true;
|
||||
DLOG(INFO) << "HAS page with dummy header received.";
|
||||
}
|
||||
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
|
||||
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_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_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_page_id = read_has_page_header_parameter(has_page_header, GALILEO_HAS_MESSAGE_PAGE_ID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Galileo_Cnav_Message::process_HAS_page(const std::string& page_string)
|
||||
{
|
||||
if (d_current_message_id == d_received_message_id)
|
||||
{
|
||||
// if receiver pid was not there, store it.
|
||||
if (d_received_message_page_id == 0)
|
||||
{
|
||||
// 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());
|
||||
}
|
||||
DLOG(INFO) << "HAS page header received " << page_string << ":\n"
|
||||
<< "d_has_page_status: " << static_cast<float>(d_has_page_status) << "\n"
|
||||
<< "d_has_reserved: " << static_cast<float>(d_has_reserved) << "\n"
|
||||
<< "d_received_message_type: " << static_cast<float>(d_received_message_type) << "\n"
|
||||
<< "d_received_message_id: " << static_cast<float>(d_received_message_id) << "\n"
|
||||
<< "d_received_message_size: " << static_cast<float>(d_received_message_size) << "\n"
|
||||
<< "d_received_message_page_id: " << static_cast<float>(d_received_message_page_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -581,124 +151,3 @@ uint8_t Galileo_Cnav_Message::read_has_page_header_parameter(const std::bitset<G
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -20,13 +20,11 @@
|
||||
#define GNSS_SDR_GALILEO_CNAV_MESSAGE_H
|
||||
|
||||
#include "Galileo_CNAV.h"
|
||||
#include "galileo_has_data.h"
|
||||
#include "reed_solomon.h"
|
||||
#include "galileo_has_page.h"
|
||||
#include <bitset>
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
/** \addtogroup Core
|
||||
* \{ */
|
||||
@ -46,64 +44,49 @@ public:
|
||||
|
||||
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
|
||||
{
|
||||
return d_test_mode;
|
||||
}
|
||||
|
||||
inline bool is_HAS_message_dummy() const
|
||||
inline bool is_HAS_page_dummy() const
|
||||
{
|
||||
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:
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
Galileo_HAS_page has_page{};
|
||||
|
||||
uint8_t d_has_page_status{};
|
||||
uint8_t d_current_message_id{};
|
||||
uint8_t d_current_message_size{};
|
||||
|
||||
uint8_t d_has_reserved{};
|
||||
uint8_t d_received_message_page_id{};
|
||||
uint8_t d_received_message_type{};
|
||||
uint8_t d_received_message_id{};
|
||||
uint8_t d_received_encoded_messages{};
|
||||
uint8_t d_received_message_size{};
|
||||
|
||||
bool d_test_mode{};
|
||||
bool d_new_message{};
|
||||
bool d_flag_CRC_test{};
|
||||
bool d_page_dummy{};
|
||||
bool d_new_HAS_page{};
|
||||
};
|
||||
|
||||
|
||||
|
54
src/core/system_parameters/galileo_has_page.h
Normal file
54
src/core/system_parameters/galileo_has_page.h
Normal 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
|
@ -125,7 +125,7 @@ if(NOT GZIP_NOTFOUND)
|
||||
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}
|
||||
OUTPUT_FILE "${CMAKE_BINARY_DIR}/changelog.gz"
|
||||
)
|
||||
|
@ -30,14 +30,23 @@ if(NOT GOOGLETEST_FOUND)
|
||||
"--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>
|
||||
)
|
||||
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)
|
||||
set(GTEST_BUILD_COMMAND "xcodebuild" "-configuration" $<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel> "-target" "gtest_main")
|
||||
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)
|
||||
ExternalProject_Add(gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
|
||||
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}
|
||||
BINARY_DIR ${CMAKE_BINARY_DIR}/gtest-${GNSSSDR_GTEST_LOCAL_VERSION}
|
||||
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}
|
||||
)
|
||||
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}
|
||||
GIT_REPOSITORY https://github.com/google/googletest
|
||||
GIT_TAG ${GOOGLETEST_GIT_TAG}
|
||||
|
@ -25,9 +25,6 @@ if(NOT benchmark_FOUND)
|
||||
"--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>
|
||||
)
|
||||
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))
|
||||
set(BENCHMARK_PARALLEL_BUILD "--parallel 2")
|
||||
@ -39,7 +36,7 @@ if(NOT benchmark_FOUND)
|
||||
SOURCE_DIR ${CMAKE_BINARY_DIR}/thirdparty/benchmark
|
||||
BINARY_DIR ${CMAKE_BINARY_DIR}/benchmark-${GNSSSDR_BENCHMARK_LOCAL_VERSION}
|
||||
CMAKE_ARGS ${BENCHMARK_COMPILER}
|
||||
-DBENCHMARK_ENABLE_GTEST_TESTS=OFF
|
||||
-DBENCHMARK_ENABLE_TESTING=OFF
|
||||
${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>
|
||||
BUILD_COMMAND "${BENCHMARK_BUILD_COMMAND} ${BENCHMARK_PARALLEL_BUILD}"
|
||||
|
@ -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_unshortened);
|
||||
BENCHMARK(bm_e6b_correction);
|
||||
BENCHMARK(bm_e6b_erasure);
|
||||
BENCHMARK_MAIN();
|
||||
|
@ -517,3 +517,27 @@ TEST(ReedSolomonE6BTest, Decode113ErrorsWithErasure)
|
||||
std::vector<uint8_t> decoded(encoded_input.begin(), encoded_input.begin() + 32);
|
||||
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);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ GNSS-SDR.internal_fs_sps=3000000
|
||||
|
||||
|
||||
;######### 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
|
||||
|
||||
;#filename: path to file with the captured GNSS signal samples to be processed
|
||||
|
Loading…
Reference in New Issue
Block a user